diff --git a/.github/ISSUE_TEMPLATE/incident.yml b/.github/ISSUE_TEMPLATE/incident.yml new file mode 100644 index 00000000000..65377dc6b46 --- /dev/null +++ b/.github/ISSUE_TEMPLATE/incident.yml @@ -0,0 +1,43 @@ +name: Incident ๐Ÿš’ +description: Respond to a production incident - checklist +labels: ["๐Ÿš’ incident"] +body: + - type: textarea + id: description + attributes: + label: "Incident description" + placeholder: "Please describe the issue in a few clear words" + validations: + required: true + - type: textarea + id: workaround + attributes: + label: "Is there a workaround?" + placeholder: "What's the workaround to avoid this issue?" + - type: markdown + attributes: + value: | + A production incident started. Please stay cool, no need to call 911. Follow the checklist below - you've got this :muscle:
+ You may refer to the [Wing maintainers operational guide](https://www.winglang.io/contributing/maintainers/operations) for more details. + - type: checkboxes + id: checklist + attributes: + label: Incident Response Checklist + description: + options: + - label: CREATE this issue (fill up the title, description and submit), then follow the next steps. + - label: PIN the incident issue. + - label: ACKNOWLEDGE the incident on [PagerDuty](https://monada.pagerduty.com/incidents). + - label: ACKNOWLEDGE the incident on [BetterStack](https://uptime.betterstack.com/team/48207/incidents). + - label: WORKAROUND - if there is one, make sure it is documented in the section above. + - label: PRIORITIZE (P0/P1/P2 - see the definitions [here](https://www.winglang.io/contributing/maintainers/operations#severity-levels)). + - label: (optional) CONTACT a relevant person who has more information about the incident. + - label: (optional) ANNOUNCE major incidents on Slack \#dev or \#general channels. "NOTICE - P0 incident started. {incident-description}. Track on {link to issue}". + - label: HANDLE by reverting or forward fixing. + - label: UPDATE the team on your actions in the created \#alert Slack thread throughout the incident. + - label: RESOLVE the incident on [PagerDuty](https://monada.pagerduty.com/incidents) (BetterStack resolves automatically). + - label: UPDATE the team on the issue closure. + - label: (optional) ANNOUNCE closure of major incidents on Slack \#dev or \#general channels. "NOTICE - P0 incident ended. {incident-resolution-description}. Track on {link to issue}". + - label: UNPIN the incident issue. + - label: LESSONS LEARNED should be shared via the "post-mortem" workflow on \#dev Slack channel. + - label: CLOSE the incident issue. diff --git a/.github/pull_request_template.md b/.github/pull_request_template.md index ab8c431e1c9..c88e950009a 100644 --- a/.github/pull_request_template.md +++ b/.github/pull_request_template.md @@ -1,6 +1,6 @@ ## Checklist -- [ ] Title matches [Winglang's style guide](https://docs.winglang.io/contributors/pull_requests#how-are-pull-request-titles-formatted) +- [ ] Title matches [Winglang's style guide](https://docs.winglang.io/contributing/pull_requests#how-are-pull-request-titles-formatted) - [ ] Description explains motivation and solution - [ ] Tests added (always) - [ ] Docs updated (only required for features) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 2b546512191..a978436d305 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -34,6 +34,8 @@ jobs: version: ${{ fromJson(steps.changelog.outputs.data).newVersion }} last-version: ${{ fromJson(steps.changelog.outputs.data).lastVersion }} changelog: ${{ fromJson(steps.changelog.outputs.data).changelog }} + vscode-wing-changed: ${{ steps.git-diff-vscode-wing.outputs.diff }} + steps: - name: Checkout uses: actions/checkout@v3 @@ -71,6 +73,8 @@ jobs: - name: Build run: npm run build:ci + env: + SEGMENT_WRITE_KEY: ${{ secrets.SEGMENT_WRITE_KEY }} - name: Package run: npm run package:ci @@ -87,6 +91,18 @@ jobs: name: wingconsoleserver path: apps/wing-console/console/server/*.tgz + - name: Upload Wing Console Design System + uses: actions/upload-artifact@v3 + with: + name: wingconsoledesignsystem + path: apps/wing-console/console/design-system/*.tgz + + - name: Upload Wing Console UI + uses: actions/upload-artifact@v3 + with: + name: wingconsoleui + path: apps/wing-console/console/ui/*.tgz + - name: Upload Wing Console App uses: actions/upload-artifact@v3 with: @@ -111,6 +127,19 @@ jobs: name: wingc path: target/wasm32-wasi/release/wingc.wasm + - name: Derive appropriate SHAs for base and head for `nx affected` commands + id: setSHAs + uses: nrwl/nx-set-shas@v3 + + - name: Check git diff of VSCode Extension + id: git-diff-vscode-wing + run: | + if git diff --quiet ${{ steps.setSHAs.outputs.base }} ${{ github.sha }} -- apps/vscode-wing; then + echo "::set-output name=diff::false" + else + echo "::set-output name=diff::true" + fi + - name: Upload Extension uses: actions/upload-artifact@v3 with: @@ -178,6 +207,23 @@ jobs: - name: Test run: npm run test:ci + - name: Create git patch + id: diff + run: | + git add --all + git diff --staged --patch > build.diff + if [ -s build.diff ]; then + echo "Diff found, creating a patch to apply later" + cat build.diff + echo "diff=true" >> $GITHUB_OUTPUT + fi + - name: Upload Diff + if: steps.diff.outputs.diff == 'true' + uses: actions/upload-artifact@v3 + with: + name: build.diff + path: build.diff + benchmarks: name: E2E Benchmarks runs-on: ubuntu-latest @@ -185,6 +231,10 @@ jobs: - build env: HANGAR_WING_SPEC: "file:${{ github.workspace }}/wing/winglang-${{ needs.build.outputs.version }}.tgz" + HANGAR_WINGCONSOLE_APP_SPEC: "file:${{ github.workspace }}/wingconsoleapp/wingconsole-app-${{ needs.build.outputs.version }}.tgz" + HANGAR_WINGCONSOLE_SERVER_SPEC: "file:${{ github.workspace }}/wingconsoleserver/wingconsole-server-${{ needs.build.outputs.version }}.tgz" + HANGAR_WINGCONSOLE_DESIGN_SYSTEM_SPEC: "file:${{ github.workspace }}/wingconsoledesignsystem/wingconsole-design-system-${{ needs.build.outputs.version }}.tgz" + HANGAR_WINGCONSOLE_UI_SPEC: "file:${{ github.workspace }}/wingconsoleui/wingconsole-ui-${{ needs.build.outputs.version }}.tgz" HANGAR_WINGCOMPILER_SPEC: "file:${{ github.workspace }}/wingcompiler/winglang-compiler-${{ needs.build.outputs.version }}.tgz" HANGAR_WINGSDK_SPEC: "file:${{ github.workspace }}/wingsdk/winglang-sdk-${{ needs.build.outputs.version }}.tgz" steps: @@ -247,15 +297,21 @@ jobs: full_run: false runs-on: "${{ matrix.runner }}-latest" env: - HANGAR_WING_SPEC: "file:${{ github.workspace }}/wing/winglang-${{ needs.build.outputs.version }}.tgz" - HANGAR_WINGCOMPILER_SPEC: "file:${{ github.workspace }}/wingcompiler/winglang-compiler-${{ needs.build.outputs.version }}.tgz" - HANGAR_WINGSDK_SPEC: "file:${{ github.workspace }}/wingsdk/winglang-sdk-${{ needs.build.outputs.version }}.tgz" + HANGAR_WING_SPEC: "file:${{ github.workspace }}/target/wing/winglang-${{ needs.build.outputs.version }}.tgz" + HANGAR_WINGCONSOLE_APP_SPEC: "file:${{ github.workspace }}/target/wingconsoleapp/wingconsole-app-${{ needs.build.outputs.version }}.tgz" + HANGAR_WINGCONSOLE_SERVER_SPEC: "file:${{ github.workspace }}/target/wingconsoleserver/wingconsole-server-${{ needs.build.outputs.version }}.tgz" + HANGAR_WINGCONSOLE_DESIGN_SYSTEM_SPEC: "file:${{ github.workspace }}/target/wingconsoledesignsystem/wingconsole-design-system-${{ needs.build.outputs.version }}.tgz" + HANGAR_WINGCONSOLE_UI_SPEC: "file:${{ github.workspace }}/target/wingconsoleui/wingconsole-ui-${{ needs.build.outputs.version }}.tgz" + HANGAR_WINGCOMPILER_SPEC: "file:${{ github.workspace }}/target/wingcompiler/winglang-compiler-${{ needs.build.outputs.version }}.tgz" + HANGAR_WINGSDK_SPEC: "file:${{ github.workspace }}/target/wingsdk/winglang-sdk-${{ needs.build.outputs.version }}.tgz" steps: - name: Checkout uses: actions/checkout@v3 - name: Download Build Artifacts - uses: actions/download-artifact@v2 + uses: actions/download-artifact@v3 + with: + path: target - name: Setup Node uses: actions/setup-node@v3 @@ -275,7 +331,29 @@ jobs: working-directory: tools/hangar run: | npm run test:generate - npm run test -- --shard=${{ matrix.shard }} + npm run test -- --shard=${{ matrix.shard }} --update=${{ matrix.runner == 'ubuntu' && matrix.node == '18' }} + + - name: Create mutation if needed + # we only care about the diff in our standard dev env + if: matrix.runner == 'ubuntu' && matrix.node == '18' + id: diff + env: + RAW_SHARD: ${{ matrix.shard }} + run: | + SHARD=$(echo $RAW_SHARD | sed 's/\//of/g') + DIFF_NAME="e2e-$SHARD.diff" + git add --all + git diff --staged --patch > $DIFF_NAME + if [ -s $DIFF_NAME ]; then + echo "diff=true" >> $GITHUB_OUTPUT + echo "diff_name=$DIFF_NAME" >> $GITHUB_OUTPUT + fi + - name: Upload mutation + if: matrix.runner == 'ubuntu' && matrix.node == '18' && steps.diff.outputs.diff == 'true' + uses: actions/upload-artifact@v3 + with: + name: ${{ steps.diff.outputs.diff_name }} + path: ${{ steps.diff.outputs.diff_name }} quality-gate: name: Quality Gate @@ -286,6 +364,19 @@ jobs: - benchmarks - unit-tests steps: + - name: Download patches + uses: actions/download-artifact@v3 + - name: Check patches + run: | + PATCH_COUNT=0 + for f in $(find ./*.diff/*.diff); do + PATCH_COUNT=$((PATCH_COUNT + 1)) + cat $f + done + if [ $PATCH_COUNT -gt 0 ]; then + echo "Found $PATCH_COUNT patches, build failed. A self-mutation should happen soon." + exit 1 + fi - name: All good run: echo "Builds and tests passed! ๐ŸŽ‰๐ŸŽ‰๐ŸŽ‰" @@ -298,7 +389,7 @@ jobs: runs-on: ubuntu-latest steps: - name: Download Build Artifacts - uses: actions/download-artifact@v2 + uses: actions/download-artifact@v3 - name: Tag commit uses: tvdias/github-tagger@v0.0.1 @@ -307,12 +398,8 @@ jobs: repo-token: "${{ secrets.PROJEN_GITHUB_TOKEN }}" tag: "v${{ needs.build.outputs.version }}" - - name: Check published VSCode Version - id: vscode-version - run: echo "version=$(npx -y vsce show Monada.vscode-wing --json | jq '.versions[0].version' -r)" >> $GITHUB_OUTPUT - - name: Publish Extension to Visual Studio Marketplace - if: ${{ steps.vscode-version.outputs.version != needs.build.outputs.version }} + if: needs.build.outputs.vscode-wing-changed == 'true' uses: "HaaLeo/publish-vscode-extension@v1" with: pat: ${{ secrets.VS_MARKETPLACE_TOKEN }} @@ -340,6 +427,24 @@ jobs: working-directory: wingcompiler run: npm publish *.tgz --access public + - name: Publish Wing Console Design System + if: ${{ steps.wingconsoledesignsystem-version.outputs.version != needs.build.outputs.version }} + working-directory: wingconsoledesignsystem + run: npm publish *.tgz --access public + + - name: Check published Wing Console Design System version + id: wingconsoledesignsystem-version + run: echo "version=$(npm view @wingconsole/design-system version)" >> $GITHUB_OUTPUT + + - name: Check published Wing Console UI version + id: wingconsoleui-version + run: echo "version=$(npm view @wingconsole/ui version)" >> $GITHUB_OUTPUT + + - name: Publish Wing Console UI + if: ${{ steps.wingconsoleui-version.outputs.version != needs.build.outputs.version }} + working-directory: wingconsoleui + run: npm publish *.tgz --access public + - name: Check published Wing Console Server version id: wingconsoleserver-version run: echo "version=$(npm view @wingconsole/server version)" >> $GITHUB_OUTPUT diff --git a/.github/workflows/mutation.yml b/.github/workflows/mutation.yml new file mode 100644 index 00000000000..be5884f7df8 --- /dev/null +++ b/.github/workflows/mutation.yml @@ -0,0 +1,91 @@ +name: "Pull Request Mutation" + +run-name: "Pull Request Mutation: ${{ github.event.workflow_run.head_branch }}" + +on: + workflow_run: + workflows: + - Build + types: + - completed + +concurrency: + group: "mutation-${{ github.event.workflow_run.head_branch }}" + cancel-in-progress: true + +permissions: + contents: read + packages: read + statuses: write + +jobs: + mutate: + runs-on: ubuntu-latest + # Run if the workflow run is a pull request + if: github.event.workflow_run.conclusion == 'failure' && (github.event.workflow_run.head_branch != 'main' || github.event.workflow_run.head_repository.fork) + steps: + - name: Download artifacts + id: download-artifacts + uses: dawidd6/action-download-artifact@v2 + with: + github_token: ${{secrets.GITHUB_TOKEN}} + run_id: ${{ github.event.workflow_run.id }} + name: .+\.diff$ + name_is_regexp: true + if_no_artifact_found: ignore + path: patches + - uses: marocchino/action-workflow_run-status@54b6e87d6cb552fc5f36dbe9a722a6048725917a + if: steps.download-artifacts.outputs.found_artifact == 'true' + with: + github_token: ${{secrets.GITHUB_TOKEN}} + - name: Token check + if: steps.download-artifacts.outputs.found_artifact == 'true' + run: | + if ${{ secrets.MUTATION_TOKEN && 'true' || 'false' }}; then + echo "Token available, enabling self mutation" + exit 0 + else + echo "Add a MUTATION_TOKEN repository secret with a personal access token to enable self mutation. + It requires private repo read/write permissions." >> $GITHUB_STEP_SUMMARY + exit 1 + fi + - name: Disable Git Hooks + if: steps.download-artifacts.outputs.found_artifact == 'true' + run: | + git config --global core.hooksPath /dev/null + - name: Checkout Workflow Branch + if: steps.download-artifacts.outputs.found_artifact == 'true' + uses: actions/checkout@v3 + with: + token: ${{secrets.MUTATION_TOKEN}} + ref: ${{ github.event.workflow_run.head_branch }} + repository: ${{ github.event.workflow_run.head_repository.full_name }} + path: repo + - id: self_mutation + if: steps.download-artifacts.outputs.found_artifact == 'true' + name: Apply downloaded pathes + working-directory: repo + run: | + for f in $(find ../patches/*.diff/*.diff); do + echo "Applying $f" + git apply $f + if [ $? -eq 0 ]; then + echo "Patch applied successfully" + rm $f + else + echo "Patch failed to apply" + cat $f + exit 1 + fi + done + - name: Push changes + if: steps.download-artifacts.outputs.found_artifact == 'true' + working-directory: repo + env: + HEAD_REF: ${{ github.event.workflow_run.head_branch }} + run: | + git config user.name "monada-bot[bot]" + git config user.email "monabot@monada.co" + git add --all + git commit -s -m "chore: self mutation" + git push origin HEAD:$HEAD_REF diff --git a/.github/workflows/pull-request-lint.yml b/.github/workflows/pull-request-lint.yml index 29090ad12e9..7162b676a54 100644 --- a/.github/workflows/pull-request-lint.yml +++ b/.github/workflows/pull-request-lint.yml @@ -29,6 +29,7 @@ jobs: tutorial vscode plugins + console types: |- feat fix diff --git a/.github/workflows/wingsdk-mutation.yml b/.github/workflows/wingsdk-mutation.yml deleted file mode 100644 index a915d888564..00000000000 --- a/.github/workflows/wingsdk-mutation.yml +++ /dev/null @@ -1,78 +0,0 @@ -name: WingSDK Mutation - -on: - pull_request_target: - types: - - opened - - synchronize - paths: - - libs/wingsdk/** - -permissions: - contents: write - -defaults: - run: - working-directory: libs/wingsdk - -env: - NODE_VERSION: "18.16.0" - NPM_VERSION: "8.19.3" - -jobs: - mutate: - runs-on: ubuntu-latest - steps: - - id: token-check - name: Check if mutation token is set - working-directory: ${{ github.workspace }} - run: echo "HAS_TOKEN=${{ secrets.MUTATION_TOKEN && 'true' || 'false' }}" >> $GITHUB_OUTPUT - - name: Token notice - if: steps.token-check.outputs.HAS_TOKEN == 'false' - working-directory: ${{ github.workspace }} - run: | - echo "Add a MUTATION_TOKEN repository secret with a personal access token to enable self mutation. - It requires read/write repo permissions." >> $GITHUB_STEP_SUMMARY - - name: Checkout - if: steps.token-check.outputs.HAS_TOKEN == 'true' - uses: actions/checkout@v3 - with: - ref: ${{ github.event.pull_request.head.ref }} - repository: ${{ github.event.pull_request.head.repo.full_name }} - token: ${{ secrets.MUTATION_TOKEN }} - - name: Setup Node - uses: actions/setup-node@v3 - with: - node-version: ${{ env.NODE_VERSION }} - - name: Setup NPM - run: npm install -g npm@${{ env.NPM_VERSION }} - - name: Install dependencies - if: steps.token-check.outputs.HAS_TOKEN == 'true' - run: npm ci - working-directory: "." - - name: Build transitive dependency (wing-api-checker) - if: steps.token-check.outputs.HAS_TOKEN == 'true' - run: npm run build - working-directory: apps/wing-api-checker - - name: Build transitive dependency (jsii-docgen) - if: steps.token-check.outputs.HAS_TOKEN == 'true' - run: npm run build - working-directory: apps/jsii-docgen - - name: build - if: steps.token-check.outputs.HAS_TOKEN == 'true' - run: npx projen build - - id: self_mutation - if: steps.token-check.outputs.HAS_TOKEN == 'true' - name: Find mutations - run: |- - git add --all - git diff --staged --patch --exit-code > /dev/null || echo "::set-output name=self_mutation_happened::true" - - name: Push changes - if: steps.token-check.outputs.HAS_TOKEN == 'true' && steps.self_mutation.outputs.self_mutation_happened - env: - HEAD_REF: ${{ github.event.pull_request.head.ref }} - run: |- - git config user.name "monada-bot[bot]" - git config user.email "monabot@monada.co" - git commit -s -m "chore: self mutation" - git push origin HEAD:$HEAD_REF diff --git a/.gitignore b/.gitignore index a04338e80f4..fdcd58d1b76 100644 --- a/.gitignore +++ b/.gitignore @@ -4,6 +4,7 @@ node_modules/ *.tfstate *.tfstate.* .history +*.vsix # WASI SDK (insalled by "npm install") .cargo/wasi-sdk-*/ diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 7ac61296f59..dd251ee53d8 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -17,17 +17,17 @@ the [Wing Slack]. Here is a curated list of topics from the [Wing Contributor's Handbook]: -* [How can I help?](https://docs.winglang.io/contributors/) -* [How do I submit a bug report?](https://docs.winglang.io/contributors/bugs) -* [How do I submit a pull request?](https://docs.winglang.io/contributors/pull_requests) -* [How to build Wing locally?](https://docs.winglang.io/contributors/development) -* [How do I add a resource to the SDK?](https://docs.winglang.io/contributors/wingsdk) +* [How can I help?](https://docs.winglang.io/contributing/) +* [How do I submit a bug report?](https://docs.winglang.io/contributing/bugs) +* [How do I submit a pull request?](https://docs.winglang.io/contributing/pull_requests) +* [How to build Wing locally?](https://docs.winglang.io/contributing/development) +* [How do I add a resource to the SDK?](https://docs.winglang.io/contributing/wingsdk) ## Code of Conduct The Wing community follows the [CNCF Code of Conduct](https://github.com/cncf/foundation/blob/main/code-of-conduct.md). Please review it before contributing issues, pull requests, or joining the [Wing Slack]. [Wing Slack]: https://t.winglang.io/slack -[Wing Contributor's Handbook]: https://docs.winglang.io/contributors/ +[Wing Contributor's Handbook]: https://docs.winglang.io/contributing/ [#contrib]: https://winglang.slack.com/archives/C04BJBTVDV4 [submitting an issue]: https://github.com/winglang/wing/issues/new \ No newline at end of file diff --git a/README.md b/README.md index 671cb1151ad..90caef2a843 100644 --- a/README.md +++ b/README.md @@ -14,7 +14,7 @@ โ–ช๏ธŽ Discussions โ–ช๏ธŽ - Contribute + Contribute

**Winglang** is a new open-source programming language designed for the cloud (aka "*cloud-oriented*"). @@ -78,17 +78,17 @@ You are welcome to read more about it [here](https://docs.winglang.io/faq/why-a- Wing was built from the ground up to make it an ideal choice for building applications on any cloud. It includes an assembly of different features that serve that purpose: -* [Cloud services](https://docs.winglang.io/concepts/resources) as first-class citizens, with [phase modifiers](https://docs.winglang.io/contributors/rfcs/language-spec#13-phase-modifiers) for config or runtime (`preflight` and `inflight`). -* Higher level of cloud abstraction with a [standard library](https://docs.winglang.io/contributors/rfcs/2023-01-20-wingsdk-spec) of cloud resources that lets you write cloud portable code. +* [Cloud services](https://docs.winglang.io/concepts/resources) as first-class citizens, with [phase modifiers](https://docs.winglang.io/contributing/rfcs/language-spec#13-phase-modifiers) for config or runtime (`preflight` and `inflight`). +* Higher level of cloud abstraction with a [standard library](https://docs.winglang.io/contributing/rfcs/2023-01-20-wingsdk-spec) of cloud resources that lets you write cloud portable code. * [Compiler plugins](https://docs.winglang.io/reference/compiler-plugins) that keep you in control by allowing you to customize the compilation output, such as infrastructure definitions. * Use any resource in the Terraform ecosystem as first-class citizen in your app. -* [JavaScript interoperability](https://docs.winglang.io/contributors/rfcs/language-spec#5-interoperability). +* [JavaScript interoperability](https://docs.winglang.io/contributing/rfcs/language-spec#5-interoperability). * [Distributed computing primitives](https://docs.winglang.io/concepts/inflights). * Automatic generation of IAM policies and other cloud mechanics based on intent. * Local functional simulator with a visualization and interaction [console](https://docs.winglang.io/start-here/installation#wing-console) - used for testing and debugging with instant hot-reloading. -* [Native JSON](https://docs.winglang.io/contributors/rfcs/language-spec#114-json-type) and schema validation support. +* [Native JSON](https://docs.winglang.io/contributing/rfcs/language-spec#114-json-type) and schema validation support. * [Default immutability](https://docs.winglang.io/blog/2023/02/02/good-cognitive-friction#immutable-by-default). -* [Implicit async](https://docs.winglang.io/contributors/rfcs/language-spec#113-asynchronous-model), explicit defer. +* [Implicit async](https://docs.winglang.io/contributing/rfcs/language-spec#113-asynchronous-model), explicit defer. For a more in-depth look at Wing's features and benefits, check out our [documentation](https://docs.winglang.io/). diff --git a/apps/jsii-docgen/src/docgen/view/api-reference.ts b/apps/jsii-docgen/src/docgen/view/api-reference.ts index 5890f117728..dd1c28aa0f9 100644 --- a/apps/jsii-docgen/src/docgen/view/api-reference.ts +++ b/apps/jsii-docgen/src/docgen/view/api-reference.ts @@ -4,7 +4,7 @@ import { Constructs } from "./constructs"; import { Enums } from "./enums"; import { Interfaces } from "./interfaces"; import { Structs } from "./structs"; -import { VISIBLE_SUBMODULES } from "./wing-filters"; +import { HIDDEN_CLASSES, VISIBLE_SUBMODULES } from "./wing-filters"; import { ApiReferenceSchema } from "../schema"; import { Transpile } from "../transpile/transpile"; @@ -41,6 +41,7 @@ export class ApiReference { ...assembly.classes, ...flatMap(submodules, (submod) => [...submod.classes]), ]); + classes = classes.filter((c) => !HIDDEN_CLASSES.includes(c.name)); interfaces = this.sortByName([ ...assembly.interfaces, ...flatMap(submodules, (submod) => [...submod.interfaces]), diff --git a/apps/jsii-docgen/src/docgen/view/wing-filters.ts b/apps/jsii-docgen/src/docgen/view/wing-filters.ts index f24590e019f..18701682993 100644 --- a/apps/jsii-docgen/src/docgen/view/wing-filters.ts +++ b/apps/jsii-docgen/src/docgen/view/wing-filters.ts @@ -1,5 +1,13 @@ // this file includes some special cases for wing documentation -export const VISIBLE_SUBMODULES = ["cloud", "fs", "std", "util"]; +export const VISIBLE_SUBMODULES = [ + "cloud", + "fs", + "std", + "util", + "redis", + "http", +]; export const HIDDEN_METHODS = ["toString", "toJSON"]; export const HIDDEN_PROPS = ["node", "display"]; export const HIDDEN_STATIC = ["of", "isConstruct", "addConnection"]; +export const HIDDEN_CLASSES = ["T1"]; diff --git a/apps/vscode-wing/README.md b/apps/vscode-wing/README.md index 0d6fba0f871..8bb03f9b46b 100644 --- a/apps/vscode-wing/README.md +++ b/apps/vscode-wing/README.md @@ -34,5 +34,5 @@ See [issues labeled with `vscode-extension` or `language-server`](https://github ## Contributing -See the FAQ in [Contributor's Handbook](https://docs.winglang.io/contributors/development#-how-do-i-build-the-vscode-extension) for how to contribute! +See the FAQ in [Contributor's Handbook](https://docs.winglang.io/contributing/development#-how-do-i-build-the-vscode-extension) for how to contribute! diff --git a/apps/wing-console/console/app/demo/index.w b/apps/wing-console/console/app/demo/index.w new file mode 100644 index 00000000000..451795c8287 --- /dev/null +++ b/apps/wing-console/console/app/demo/index.w @@ -0,0 +1,117 @@ +bring cloud; +// bring redis; + +let bucket = new cloud.Bucket(); +let queue = new cloud.Queue(); +let api = new cloud.Api(); + +api.get("/test-get", inflight (req: cloud.ApiRequest): cloud.ApiResponse => { + return cloud.ApiResponse { + status: 200, + body: Json.stringify({ + query: Json (Json req).get("query"), + }) + }; +}); +api.post("/test-post", inflight (req: cloud.ApiRequest): cloud.ApiResponse => { + return cloud.ApiResponse { + status: 200, + body: "Hello, POST!" + }; +}); + +let handler = inflight (message: str): str => { + bucket.put("hello.txt", "Hello, ${message}!"); + log("Hello, ${message}!"); + return message; +}; + +queue.setConsumer(handler); + +let counter = new cloud.Counter(initial: 0); +new cloud.Function(inflight (message: str): str => { + counter.inc(); + log("Counter is now ${counter.inc(0)}"); + return message; +}) as "IncrementCounter"; + +let topic = new cloud.Topic() as "Topic"; +topic.onMessage(inflight (message: str): str => { + log("Topic subscriber #1: ${message}"); + return message; +}); +topic.onMessage(inflight (message: str): str => { + log("Topic subscriber #2: ${message}"); + return message; +}); + +// let r = new redis.Redis(); +// new cloud.Function(inflight (message :str) :str => { +// log("${r.url()}"); +// r.set("wing", message); +// let value = r.get("wing"); +// log("${value}"); +// return r.url(); +// }) as "Redis interaction"; + + +let table = new cloud.Table(cloud.TableProps{ + name: "simple-table", + primaryKey: "id", + columns: { + id: cloud.ColumnType.STRING, + name: cloud.ColumnType.STRING, + date: cloud.ColumnType.DATE, + active: cloud.ColumnType.BOOLEAN, + }, +}); + +let rateSchedule = new cloud.Schedule(cloud.ScheduleProps{ + rate: 5m +}) as "Rate Schedule"; + +rateSchedule.onTick(inflight () => { + log("Rate schedule ticked!"); +}); + +let cronSchedule = new cloud.Schedule(cloud.ScheduleProps{ + cron: "* * * * ?" +}) as "Cron Schedule"; + +// cronSchedule.onTick(inflight () => { +// log("Cron schedule ticked!"); +// }); + +test "Increment counter" { + let previous = counter.inc(); + log("Assertion should fail: ${previous} === ${counter.peek()}"); + assert(previous == 1); +} + +test "Push message to the queue" { + queue.push("hey"); +} + +test "Print"{ + log("Hello World!"); + assert(true); +} + +test "without assertions nor prints" { +} + +test "Add fixtures" { + let arr = [1, 2, 3, 4, 5]; + + log("Adding ${arr.length} files in the bucket.."); + for item in arr { + bucket.put("fixture_${item}.txt", "Content for the fixture_${item}!"); + } + + log("Publishing to the topic.."); + topic.publish("Hello, topic!"); + + log("Setting up counter.."); + counter.set(0); + counter.inc(100); +} diff --git a/apps/wing-console/console/app/package-lock.json b/apps/wing-console/console/app/package-lock.json index 7c095a1d0e7..2a14d09bddc 100644 --- a/apps/wing-console/console/app/package-lock.json +++ b/apps/wing-console/console/app/package-lock.json @@ -10,22 +10,25 @@ "license": "SEE LICENSE IN LICENSE.md", "dependencies": { "@wingconsole/server": "file:../server", + "analytics-node": "^6.2.0", "express": "^4.18.2" }, "devDependencies": { "@tailwindcss/forms": "^0.5.3", + "@types/analytics-node": "^3.1.11", "@types/express": "^4.17.17", "@types/react": "^18.2.12", "@types/react-dom": "^18.2.5", "@vitejs/plugin-react": "^4.0.0", "@vitest/coverage-c8": "^0.31.4", - "@wingconsole/error-message": "file:../../tools/error-message", "@wingconsole/eslint-plugin": "file:../../tools/eslint-plugin", "@wingconsole/tsconfig": "file:../../tools/tsconfig", "@wingconsole/ui": "file:../ui", "autoprefixer": "^10.4.14", "bump-pack": "file:../../../../tools/bump-pack", + "conf": "^11.0.1", "eslint": "^8.42.0", + "nanoid": "^4.0.2", "open": "^9.1.0", "react": "^18.2.0", "react-dom": "^18.2.0", @@ -56,7 +59,7 @@ } }, "../../tools/error-message": { - "dev": true + "extraneous": true }, "../../tools/eslint-plugin": { "name": "@wingconsole/eslint-plugin", @@ -143,11 +146,32 @@ "version": "0.0.0", "dev": true, "license": "SEE LICENSE IN LICENSE.md", - "devDependencies": { - "@babel/core": "^7.22.5", + "dependencies": { "@headlessui/react": "^1.7.15", "@heroicons/react": "^2.0.18", "@popperjs/core": "^2.11.8", + "@tanstack/react-query": "^4.29.12", + "@trpc/client": "^10.30.0", + "@trpc/react-query": "^10.30.0", + "@trpc/server": "^10.30.0", + "@wingconsole/design-system": "file:../design-system", + "classnames": "^2.3.2", + "d3-selection": "^3.0.0", + "d3-zoom": "^3.0.0", + "elkjs": "^0.8.2", + "framer-motion": "^10.12.16", + "jszip": "^3.10.1", + "lodash.debounce": "^4.0.8", + "lodash.throttle": "^4.1.1", + "lodash.uniqby": "^4.7.0", + "nanoid": "^4.0.2", + "react": "^18.2.0", + "react-dom": "^18.2.0", + "react-lottie-player": "^1.5.4", + "zod": "^3.21.4" + }, + "devDependencies": { + "@babel/core": "^7.22.5", "@storybook/addon-essentials": "^7.0.20", "@storybook/addon-interactions": "^7.0.20", "@storybook/addon-links": "^7.0.20", @@ -155,49 +179,29 @@ "@storybook/react": "^7.0.20", "@storybook/react-vite": "^7.0.20", "@storybook/testing-library": "^0.1.0", - "@tanstack/react-query": "^4.29.12", - "@trpc/client": "^10.30.0", - "@trpc/react-query": "^10.30.0", - "@trpc/server": "^10.30.0", "@types/cors": "^2.8.13", "@types/d3-selection": "^3.0.5", "@types/d3-zoom": "^3.0.3", - "@types/lodash": "^4.14.195", + "@types/lodash.debounce": "^4.0.7", "@types/lodash.throttle": "^4.1.7", "@types/lodash.uniqby": "^4.7.7", "@types/react": "^18.2.12", "@types/react-dom": "^18.2.5", "@vitejs/plugin-react-swc": "^3.3.2", - "@wingconsole/design-system": "file:../design-system", "@wingconsole/eslint-plugin": "file:../../tools/eslint-plugin", "@wingconsole/server": "file:../server", "@wingconsole/tsconfig": "file:../../tools/tsconfig", "@wingconsole/use-loading": "file:../../packages/use-loading", - "classnames": "^2.3.2", - "constructs": "^10.2.51", - "d3-selection": "^3.0.0", - "d3-zoom": "^3.0.0", - "elkjs": "^0.8.2", - "esbuild-plugin-external-global": "^1.0.1", + "autoprefixer": "^10.4.14", + "bump-pack": "file:../../../../tools/bump-pack", "eslint": "^8.42.0", - "framer-motion": "^10.12.16", - "jszip": "^3.10.1", - "lodash": "^4.17.21", - "lodash.throttle": "^4.1.1", - "lodash.uniqby": "^4.7.0", - "nanoid": "^4.0.2", - "react": "^18.2.0", - "react-dom": "^18.2.0", - "react-lottie-player": "^1.5.4", - "react-use": "^17.4.0", - "require-from-string": "^2.0.2", "storybook": "^7.0.20", + "tailwindcss": "^3.3.2", "tsup": "^6.7.0", "typescript": "^5.1.3", "vite": "^4.3.9", "vitest": "^0.31.4", - "webpack": "^5.86.0", - "zod": "^3.21.4" + "webpack": "^5.86.0" } }, "node_modules/@alloc/quick-lru": { @@ -1144,6 +1148,15 @@ "node": ">= 8" } }, + "node_modules/@segment/loosely-validate-event": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/@segment/loosely-validate-event/-/loosely-validate-event-2.0.0.tgz", + "integrity": "sha512-ZMCSfztDBqwotkl848ODgVcAmN4OItEWDCkshcKz0/W6gGSQayuuCtWV/MlodFivAZD793d6UgANd6wCXUfrIw==", + "dependencies": { + "component-type": "^1.2.1", + "join-component": "^1.1.0" + } + }, "node_modules/@tailwindcss/forms": { "version": "0.5.3", "resolved": "https://registry.npmjs.org/@tailwindcss/forms/-/forms-0.5.3.tgz", @@ -1156,6 +1169,12 @@ "tailwindcss": ">=3.0.0 || >= 3.0.0-alpha.1" } }, + "node_modules/@types/analytics-node": { + "version": "3.1.11", + "resolved": "https://registry.npmjs.org/@types/analytics-node/-/analytics-node-3.1.11.tgz", + "integrity": "sha512-CNQVFhaEwL5dEzzV+OtJxt5psRQKJ+XHd0eokdPOM432tpDd4vgB6FzYRCDhDo8uxH0JPXlF6BVA9sbJPpUuug==", + "dev": true + }, "node_modules/@types/body-parser": { "version": "1.19.2", "resolved": "https://registry.npmjs.org/@types/body-parser/-/body-parser-1.19.2.tgz", @@ -1429,10 +1448,6 @@ "url": "https://opencollective.com/vitest" } }, - "node_modules/@wingconsole/error-message": { - "resolved": "../../tools/error-message", - "link": true - }, "node_modules/@wingconsole/eslint-plugin": { "resolved": "../../tools/eslint-plugin", "link": true @@ -1507,6 +1522,63 @@ "url": "https://github.com/sponsors/epoberezkin" } }, + "node_modules/ajv-formats": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/ajv-formats/-/ajv-formats-2.1.1.tgz", + "integrity": "sha512-Wx0Kx52hxE7C18hkMEggYlEifqWZtYaRgouJor+WMdPnQyEK13vgEWyVNup7SoeeoLMsr4kf5h6dOW11I15MUA==", + "dev": true, + "dependencies": { + "ajv": "^8.0.0" + }, + "peerDependencies": { + "ajv": "^8.0.0" + }, + "peerDependenciesMeta": { + "ajv": { + "optional": true + } + } + }, + "node_modules/ajv-formats/node_modules/ajv": { + "version": "8.12.0", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.12.0.tgz", + "integrity": "sha512-sRu1kpcO9yLtYxBKvqfTeh9KzZEwO3STyX1HT+4CaDzC6HpTGYhIhPIzj9XuKU7KYDwnaeh5hcOwjy1QuJzBPA==", + "dev": true, + "dependencies": { + "fast-deep-equal": "^3.1.1", + "json-schema-traverse": "^1.0.0", + "require-from-string": "^2.0.2", + "uri-js": "^4.2.2" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/epoberezkin" + } + }, + "node_modules/ajv-formats/node_modules/json-schema-traverse": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-1.0.0.tgz", + "integrity": "sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==", + "dev": true + }, + "node_modules/analytics-node": { + "version": "6.2.0", + "resolved": "https://registry.npmjs.org/analytics-node/-/analytics-node-6.2.0.tgz", + "integrity": "sha512-NLU4tCHlWt0tzEaFQL7NIoWhq2KmQSmz0JvyS2lYn6fc4fEjTMSabhJUx8H1r5995FX8fE3rZ15uIHU6u+ovlQ==", + "dependencies": { + "@segment/loosely-validate-event": "^2.0.0", + "axios": "^0.27.2", + "axios-retry": "3.2.0", + "lodash.isstring": "^4.0.1", + "md5": "^2.2.1", + "ms": "^2.0.0", + "remove-trailing-slash": "^0.1.0", + "uuid": "^8.3.2" + }, + "engines": { + "node": ">=4" + } + }, "node_modules/ansi-regex": { "version": "5.0.1", "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", @@ -1582,6 +1654,21 @@ "node": "*" } }, + "node_modules/asynckit": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz", + "integrity": "sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q==" + }, + "node_modules/atomically": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/atomically/-/atomically-2.0.1.tgz", + "integrity": "sha512-sxBhVZUFBFhqSAsYMM3X2oaUi2NVDJ8U026FsIusM8gYXls9AYs/eXzgGrufs1Qjpkxi9zunds+75QUFz+m7UQ==", + "dev": true, + "dependencies": { + "stubborn-fs": "^1.2.4", + "when-exit": "^2.0.0" + } + }, "node_modules/autoprefixer": { "version": "10.4.14", "resolved": "https://registry.npmjs.org/autoprefixer/-/autoprefixer-10.4.14.tgz", @@ -1615,6 +1702,23 @@ "postcss": "^8.1.0" } }, + "node_modules/axios": { + "version": "0.27.2", + "resolved": "https://registry.npmjs.org/axios/-/axios-0.27.2.tgz", + "integrity": "sha512-t+yRIyySRTp/wua5xEr+z1q60QmLq8ABsS5O9Me1AsE5dfKqgnCFzwiCZZ/cGNd1lq4/7akDWMxdhVlucjmnOQ==", + "dependencies": { + "follow-redirects": "^1.14.9", + "form-data": "^4.0.0" + } + }, + "node_modules/axios-retry": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/axios-retry/-/axios-retry-3.2.0.tgz", + "integrity": "sha512-RK2cLMgIsAQBDhlIsJR5dOhODPigvel18XUv1dDXW+4k1FzebyfRk+C+orot6WPZOYFKSfhLwHPwVmTVOODQ5w==", + "dependencies": { + "is-retry-allowed": "^1.1.0" + } + }, "node_modules/balanced-match": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", @@ -1912,6 +2016,14 @@ "node": ">=4" } }, + "node_modules/charenc": { + "version": "0.0.2", + "resolved": "https://registry.npmjs.org/charenc/-/charenc-0.0.2.tgz", + "integrity": "sha512-yrLQ/yVUFXkzg7EDQsPieE/53+0RlaWTs+wBrvW36cyilJ2SaDWfl4Yj7MtLTXleV9uEKefbAGUPv2/iWSooRA==", + "engines": { + "node": "*" + } + }, "node_modules/check-error": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/check-error/-/check-error-1.0.2.tgz", @@ -1986,6 +2098,17 @@ "integrity": "sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw==", "dev": true }, + "node_modules/combined-stream": { + "version": "1.0.8", + "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.8.tgz", + "integrity": "sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==", + "dependencies": { + "delayed-stream": "~1.0.0" + }, + "engines": { + "node": ">= 0.8" + } + }, "node_modules/commander": { "version": "4.1.1", "resolved": "https://registry.npmjs.org/commander/-/commander-4.1.1.tgz", @@ -1995,6 +2118,11 @@ "node": ">= 6" } }, + "node_modules/component-type": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/component-type/-/component-type-1.2.1.tgz", + "integrity": "sha512-Kgy+2+Uwr75vAi6ChWXgHuLvd+QLD7ssgpaRq2zCvt80ptvAfMc/hijcJxXkBa2wMlEZcJvC2H8Ubo+A9ATHIg==" + }, "node_modules/concat-map": { "version": "0.0.1", "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", @@ -2053,6 +2181,83 @@ "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==", "dev": true }, + "node_modules/conf": { + "version": "11.0.1", + "resolved": "https://registry.npmjs.org/conf/-/conf-11.0.1.tgz", + "integrity": "sha512-WlLiQboEjKx0bYx2IIRGedBgNjLAxtwPaCSnsjWPST5xR0DB4q8lcsO/bEH9ZRYNcj63Y9vj/JG/5Fg6uWzI0Q==", + "dev": true, + "dependencies": { + "ajv": "^8.12.0", + "ajv-formats": "^2.1.1", + "atomically": "^2.0.0", + "debounce-fn": "^5.1.2", + "dot-prop": "^7.2.0", + "env-paths": "^3.0.0", + "json-schema-typed": "^8.0.1", + "semver": "^7.3.8" + }, + "engines": { + "node": ">=14.16" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/conf/node_modules/ajv": { + "version": "8.12.0", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.12.0.tgz", + "integrity": "sha512-sRu1kpcO9yLtYxBKvqfTeh9KzZEwO3STyX1HT+4CaDzC6HpTGYhIhPIzj9XuKU7KYDwnaeh5hcOwjy1QuJzBPA==", + "dev": true, + "dependencies": { + "fast-deep-equal": "^3.1.1", + "json-schema-traverse": "^1.0.0", + "require-from-string": "^2.0.2", + "uri-js": "^4.2.2" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/epoberezkin" + } + }, + "node_modules/conf/node_modules/json-schema-traverse": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-1.0.0.tgz", + "integrity": "sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==", + "dev": true + }, + "node_modules/conf/node_modules/lru-cache": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz", + "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==", + "dev": true, + "dependencies": { + "yallist": "^4.0.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/conf/node_modules/semver": { + "version": "7.5.3", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.5.3.tgz", + "integrity": "sha512-QBlUtyVk/5EeHbi7X0fw6liDZc7BBmEaSYn01fMU1OUYbf6GPsbTtd8WmnqbI20SeycoHSeiybkE/q1Q+qlThQ==", + "dev": true, + "dependencies": { + "lru-cache": "^6.0.0" + }, + "bin": { + "semver": "bin/semver.js" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/conf/node_modules/yallist": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", + "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==", + "dev": true + }, "node_modules/content-disposition": { "version": "0.5.4", "resolved": "https://registry.npmjs.org/content-disposition/-/content-disposition-0.5.4.tgz", @@ -2105,6 +2310,14 @@ "node": ">= 8" } }, + "node_modules/crypt": { + "version": "0.0.2", + "resolved": "https://registry.npmjs.org/crypt/-/crypt-0.0.2.tgz", + "integrity": "sha512-mCxBlsHFYh9C+HVpiEacem8FEBnMXgU9gy4zmNC+SXAZNB/1idgp/aulFJ4FgCi7GPEVbfyng092GqL2k2rmow==", + "engines": { + "node": "*" + } + }, "node_modules/cssesc": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/cssesc/-/cssesc-3.0.0.tgz", @@ -2135,6 +2348,21 @@ "node": ">=6" } }, + "node_modules/debounce-fn": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/debounce-fn/-/debounce-fn-5.1.2.tgz", + "integrity": "sha512-Sr4SdOZ4vw6eQDvPYNxHogvrxmCIld/VenC5JbNrFwMiwd7lY/Z18ZFfo+EWNG4DD9nFlAujWAo/wGuOPHmy5A==", + "dev": true, + "dependencies": { + "mimic-fn": "^4.0.0" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/debug": { "version": "4.3.4", "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz", @@ -2216,6 +2444,14 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/delayed-stream": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz", + "integrity": "sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ==", + "engines": { + "node": ">=0.4.0" + } + }, "node_modules/depd": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/depd/-/depd-2.0.0.tgz", @@ -2269,6 +2505,33 @@ "node": ">=6.0.0" } }, + "node_modules/dot-prop": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/dot-prop/-/dot-prop-7.2.0.tgz", + "integrity": "sha512-Ol/IPXUARn9CSbkrdV4VJo7uCy1I3VuSiWCaFSg+8BdUOzF9n3jefIpcgAydvUZbTdEBZs2vEiTiS9m61ssiDA==", + "dev": true, + "dependencies": { + "type-fest": "^2.11.2" + }, + "engines": { + "node": "^12.20.0 || ^14.13.1 || >=16.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/dot-prop/node_modules/type-fest": { + "version": "2.19.0", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-2.19.0.tgz", + "integrity": "sha512-RAH822pAdBgcNMAfWnCBU3CFZcfZ/i1eZjwFU/dsLKumyuuP3niueg2UAukXYF0E2AAoc82ZSSf9J0WQBinzHA==", + "dev": true, + "engines": { + "node": ">=12.20" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/ee-first": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/ee-first/-/ee-first-1.1.1.tgz", @@ -2294,6 +2557,18 @@ "node": ">= 0.8" } }, + "node_modules/env-paths": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/env-paths/-/env-paths-3.0.0.tgz", + "integrity": "sha512-dtJUTepzMW3Lm/NPxRf3wP4642UWhjL2sQxc+ym2YMj1m/H2zDNQOlezafzkHwn6sMstjHTwG6iQQsctDW/b1A==", + "dev": true, + "engines": { + "node": "^12.20.0 || ^14.13.1 || >=16.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/esbuild": { "version": "0.17.19", "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.17.19.tgz", @@ -2829,6 +3104,25 @@ "integrity": "sha512-5nqDSxl8nn5BSNxyR3n4I6eDmbolI6WT+QqR547RwxQapgjQBmtktdP+HTBb/a/zLsbzERTONyUB5pefh5TtjQ==", "dev": true }, + "node_modules/follow-redirects": { + "version": "1.15.2", + "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.15.2.tgz", + "integrity": "sha512-VQLG33o04KaQ8uYi2tVNbdrWp1QWxNNea+nmIB4EVM28v0hmP17z7aG1+wAkNzVq4KeXTq3221ye5qTJP91JwA==", + "funding": [ + { + "type": "individual", + "url": "https://github.com/sponsors/RubenVerborgh" + } + ], + "engines": { + "node": ">=4.0" + }, + "peerDependenciesMeta": { + "debug": { + "optional": true + } + } + }, "node_modules/foreground-child": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/foreground-child/-/foreground-child-2.0.0.tgz", @@ -2842,6 +3136,19 @@ "node": ">=8.0.0" } }, + "node_modules/form-data": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/form-data/-/form-data-4.0.0.tgz", + "integrity": "sha512-ETEklSGi5t0QMZuiXoA/Q6vcnxcLQP5vdugSpuAyi6SVGi2clPPp+xgEhuMaHC+zGgn31Kd235W35f7Hykkaww==", + "dependencies": { + "asynckit": "^0.4.0", + "combined-stream": "^1.0.8", + "mime-types": "^2.1.12" + }, + "engines": { + "node": ">= 6" + } + }, "node_modules/forwarded": { "version": "0.2.0", "resolved": "https://registry.npmjs.org/forwarded/-/forwarded-0.2.0.tgz", @@ -3180,6 +3487,11 @@ "node": ">=8" } }, + "node_modules/is-buffer": { + "version": "1.1.6", + "resolved": "https://registry.npmjs.org/is-buffer/-/is-buffer-1.1.6.tgz", + "integrity": "sha512-NcdALwpXkTm5Zvvbk7owOUSvVvBKDgKP5/ewfXEznmQFfs4ZRmanOeKBTjRVjka3QFoN6XJ+9F3USqfHqTaU5w==" + }, "node_modules/is-core-module": { "version": "2.12.1", "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.12.1.tgz", @@ -3273,6 +3585,14 @@ "node": ">=8" } }, + "node_modules/is-retry-allowed": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/is-retry-allowed/-/is-retry-allowed-1.2.0.tgz", + "integrity": "sha512-RUbUeKwvm3XG2VYamhJL1xFktgjvPzL0Hq8C+6yrWIswDy3BIXGqCxhxkc30N9jqK311gVU137K8Ei55/zVJRg==", + "engines": { + "node": ">=0.10.0" + } + }, "node_modules/is-stream": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-3.0.0.tgz", @@ -3384,6 +3704,11 @@ "jiti": "bin/jiti.js" } }, + "node_modules/join-component": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/join-component/-/join-component-1.1.0.tgz", + "integrity": "sha512-bF7vcQxbODoGK1imE2P9GS9aw4zD0Sd+Hni68IMZLj7zRnquH7dXUmMw9hDI5S/Jzt7q+IyTXN0rSg2GI0IKhQ==" + }, "node_modules/joycon": { "version": "3.1.1", "resolved": "https://registry.npmjs.org/joycon/-/joycon-3.1.1.tgz", @@ -3438,6 +3763,12 @@ "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==", "dev": true }, + "node_modules/json-schema-typed": { + "version": "8.0.1", + "resolved": "https://registry.npmjs.org/json-schema-typed/-/json-schema-typed-8.0.1.tgz", + "integrity": "sha512-XQmWYj2Sm4kn4WeTYvmpKEbyPsL7nBsb647c7pMe6l02/yx2+Jfc4dT6UZkEXnIUb5LhD55r2HPsJ1milQ4rDg==", + "dev": true + }, "node_modules/json-stable-stringify-without-jsonify": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/json-stable-stringify-without-jsonify/-/json-stable-stringify-without-jsonify-1.0.1.tgz", @@ -3532,6 +3863,11 @@ "integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==", "dev": true }, + "node_modules/lodash.isstring": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/lodash.isstring/-/lodash.isstring-4.0.1.tgz", + "integrity": "sha512-0wJxfxH1wgO3GrbuP+dTTk7op+6L41QCXbGINEmD+ny/G/eCqGzxyCsh7159S+mgDDcoarnBw6PC1PS5+wUGgw==" + }, "node_modules/lodash.merge": { "version": "4.6.2", "resolved": "https://registry.npmjs.org/lodash.merge/-/lodash.merge-4.6.2.tgz", @@ -3601,6 +3937,16 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/md5": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/md5/-/md5-2.3.0.tgz", + "integrity": "sha512-T1GITYmFaKuO91vxyoQMFETst+O71VUPEU3ze5GNzDm0OWdP8v1ziTaAEPUr/3kLsY3Sftgz242A1SetQiDL7g==", + "dependencies": { + "charenc": "0.0.2", + "crypt": "0.0.2", + "is-buffer": "~1.1.6" + } + }, "node_modules/md5-hex": { "version": "3.0.1", "resolved": "https://registry.npmjs.org/md5-hex/-/md5-hex-3.0.1.tgz", @@ -3740,8 +4086,7 @@ "node_modules/ms": { "version": "2.1.2", "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", - "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", - "dev": true + "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==" }, "node_modules/mz": { "version": "2.7.0", @@ -3755,9 +4100,9 @@ } }, "node_modules/nanoid": { - "version": "3.3.6", - "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.6.tgz", - "integrity": "sha512-BGcqMMJuToF7i1rt+2PWSNVnWIkGCU78jBG3RxO/bZlnZPK2Cmi2QaffxGO/2RvWi9sL+FAiRiXMgsyxQ1DIDA==", + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-4.0.2.tgz", + "integrity": "sha512-7ZtY5KTCNheRGfEFxnedV5zFiORN1+Y1N6zvPTnHQd8ENUvfaDBeuJDZb2bN/oXwXxu3qkTXDzy57W5vAmDTBw==", "dev": true, "funding": [ { @@ -3766,10 +4111,10 @@ } ], "bin": { - "nanoid": "bin/nanoid.cjs" + "nanoid": "bin/nanoid.js" }, "engines": { - "node": "^10 || ^12 || ^13.7 || ^14 || >=15.0.1" + "node": "^14 || ^16 || >=18" } }, "node_modules/natural-compare": { @@ -4223,6 +4568,24 @@ "integrity": "sha512-1NNCs6uurfkVbeXG4S8JFT9t19m45ICnif8zWLd5oPSZ50QnwMfK+H3jv408d4jw/7Bttv5axS5IiHoLaVNHeQ==", "dev": true }, + "node_modules/postcss/node_modules/nanoid": { + "version": "3.3.6", + "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.6.tgz", + "integrity": "sha512-BGcqMMJuToF7i1rt+2PWSNVnWIkGCU78jBG3RxO/bZlnZPK2Cmi2QaffxGO/2RvWi9sL+FAiRiXMgsyxQ1DIDA==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "bin": { + "nanoid": "bin/nanoid.cjs" + }, + "engines": { + "node": "^10 || ^12 || ^13.7 || ^14 || >=15.0.1" + } + }, "node_modules/prelude-ls": { "version": "1.2.1", "resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.2.1.tgz", @@ -4396,6 +4759,11 @@ "node": ">=8.10.0" } }, + "node_modules/remove-trailing-slash": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/remove-trailing-slash/-/remove-trailing-slash-0.1.1.tgz", + "integrity": "sha512-o4S4Qh6L2jpnCy83ysZDau+VORNvnFw07CKSAymkd6ICNVEPisMyzlc00KlvvicsxKck94SEwhDnMNdICzO+tA==" + }, "node_modules/require-directory": { "version": "2.1.1", "resolved": "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz", @@ -4405,6 +4773,15 @@ "node": ">=0.10.0" } }, + "node_modules/require-from-string": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/require-from-string/-/require-from-string-2.0.2.tgz", + "integrity": "sha512-Xf0nWe6RseziFMu+Ap9biiUbmplq6S9/p+7w7YXP/JBHhrUDDUhwa+vANyubuqfZWTveU//DYVGsDG7RKL/vEw==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, "node_modules/resolve": { "version": "1.22.2", "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.22.2.tgz", @@ -4887,6 +5264,12 @@ "url": "https://github.com/sponsors/antfu" } }, + "node_modules/stubborn-fs": { + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/stubborn-fs/-/stubborn-fs-1.2.4.tgz", + "integrity": "sha512-KRa4nIRJ8q6uApQbPwYZVhOof8979fw4xbajBWa5kPJFa4nyY3aFaMWVyIVCDnkNCCG/3HLipUZ4QaNlYsmX1w==", + "dev": true + }, "node_modules/sucrase": { "version": "3.32.0", "resolved": "https://registry.npmjs.org/sucrase/-/sucrase-3.32.0.tgz", @@ -5462,6 +5845,14 @@ "node": ">= 0.4.0" } }, + "node_modules/uuid": { + "version": "8.3.2", + "resolved": "https://registry.npmjs.org/uuid/-/uuid-8.3.2.tgz", + "integrity": "sha512-+NYs2QeMWy+GWFOEm9xnn6HCDp0l7QBD7ml8zLUmJ+93Q5NF0NocErnwkTkXVFNiX3/fpC6afS8Dhb/gz7R7eg==", + "bin": { + "uuid": "dist/bin/uuid" + } + }, "node_modules/v8-to-istanbul": { "version": "9.1.0", "resolved": "https://registry.npmjs.org/v8-to-istanbul/-/v8-to-istanbul-9.1.0.tgz", @@ -5659,6 +6050,12 @@ "webidl-conversions": "^4.0.2" } }, + "node_modules/when-exit": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/when-exit/-/when-exit-2.1.0.tgz", + "integrity": "sha512-H85ulNwUBU1e6PGxkWUDgxnbohSXD++ah6Xw1VHAN7CtypcbZaC4aYjQ+C2PMVaDkURDuOinNAT+Lnz3utWXxQ==", + "dev": true + }, "node_modules/which": { "version": "2.0.2", "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", diff --git a/apps/wing-console/console/app/package.json b/apps/wing-console/console/app/package.json index ec64c4bb91d..d167889af59 100644 --- a/apps/wing-console/console/app/package.json +++ b/apps/wing-console/console/app/package.json @@ -10,8 +10,8 @@ "dist" ], "scripts": { - "preview": "tsx scripts/preview.ts", - "dev": "tsup --watch", + "preview": "node scripts/preview.mjs", + "dev": "node scripts/dev.mjs", "compile": "tsup", "vitest": "vitest run --coverage --passWithNoTests", "eslint": "eslint --ext .js,.cjs,.ts,.cts,.mts,.tsx --no-error-on-unmatched-pattern . --fix", @@ -19,22 +19,25 @@ }, "dependencies": { "@wingconsole/server": "file:../server", + "analytics-node": "^6.2.0", "express": "^4.18.2" }, "devDependencies": { "@tailwindcss/forms": "^0.5.3", + "@types/analytics-node": "^3.1.11", "@types/express": "^4.17.17", "@types/react": "^18.2.12", "@types/react-dom": "^18.2.5", "@vitejs/plugin-react": "^4.0.0", "@vitest/coverage-c8": "^0.31.4", - "@wingconsole/error-message": "file:../../tools/error-message", "@wingconsole/eslint-plugin": "file:../../tools/eslint-plugin", "@wingconsole/tsconfig": "file:../../tools/tsconfig", "@wingconsole/ui": "file:../ui", "autoprefixer": "^10.4.14", "bump-pack": "file:../../../../tools/bump-pack", + "conf": "^11.0.1", "eslint": "^8.42.0", + "nanoid": "^4.0.2", "open": "^9.1.0", "react": "^18.2.0", "react-dom": "^18.2.0", diff --git a/apps/wing-console/console/app/scripts/config.mjs b/apps/wing-console/console/app/scripts/config.mjs new file mode 100644 index 00000000000..a4198709aff --- /dev/null +++ b/apps/wing-console/console/app/scripts/config.mjs @@ -0,0 +1,13 @@ +import react from "@vitejs/plugin-react"; +import { fileURLToPath } from "node:url"; +import * as vite from "vite"; + +/** @type vite.InlineConfig */ +export const viteConfig = { + configFile: false, + root: fileURLToPath(new URL("../web", import.meta.url)), + plugins: [react()], + build: { + outDir: fileURLToPath(new URL("../dist/vite", import.meta.url)), + }, +}; diff --git a/apps/wing-console/console/app/scripts/dev.mjs b/apps/wing-console/console/app/scripts/dev.mjs new file mode 100644 index 00000000000..874a032519c --- /dev/null +++ b/apps/wing-console/console/app/scripts/dev.mjs @@ -0,0 +1,40 @@ +import { createConsoleServer } from "@wingconsole/server"; +import { fileURLToPath } from "node:url"; +import open from "open"; + +import { createServer as createViteServer } from "vite"; +import { viteConfig } from "./config.mjs"; + +const vite = await createViteServer({ + ...viteConfig, + server: { middlewareMode: true }, +}); + +const { port } = await createConsoleServer({ + wingfile: fileURLToPath(new URL("../demo/index.w", import.meta.url)), + async onExpressCreated(app) { + app.use(vite.middlewares); + }, + log: { + info: console.log, + error: console.error, + verbose: console.log, + }, + config: { + addEventListener(event, listener) {}, + removeEventListener(event, listener) {}, + get(key) { + return undefined; + }, + set(key, value) {}, + }, + hostUtils: { + async openExternal(url) { + await open(url); + }, + }, +}); + +await open(`http://localhost:${port}`); + +console.log(`Wing Console is running on http://localhost:${port}/`); diff --git a/apps/wing-console/console/app/scripts/preview.mjs b/apps/wing-console/console/app/scripts/preview.mjs new file mode 100644 index 00000000000..c23af6252f1 --- /dev/null +++ b/apps/wing-console/console/app/scripts/preview.mjs @@ -0,0 +1,17 @@ +import { fileURLToPath } from "node:url"; + +import open from "open"; + +import { createConsoleApp } from "../dist/index.js"; + +const { port } = await createConsoleApp({ + wingfile: fileURLToPath( + new URL("../../desktop/demo/index.w", import.meta.url), + ), + hostUtils: { + async openExternal(url) { + await open(url); + }, + }, +}); +await open(`http://localhost:${port}`); diff --git a/apps/wing-console/console/app/scripts/preview.ts b/apps/wing-console/console/app/scripts/preview.ts deleted file mode 100644 index 032c59e4263..00000000000 --- a/apps/wing-console/console/app/scripts/preview.ts +++ /dev/null @@ -1,10 +0,0 @@ -import open from "open"; - -import { createConsoleApp } from "../dist/index.js"; - -(async () => { - const { port } = await createConsoleApp({ - wingfile: "../desktop/demo/index.w", - }); - await open(`http://localhost:${port}`); -})(); diff --git a/apps/wing-console/console/app/src/analytics.ts b/apps/wing-console/console/app/src/analytics.ts new file mode 100644 index 00000000000..72f37ce22e4 --- /dev/null +++ b/apps/wing-console/console/app/src/analytics.ts @@ -0,0 +1,27 @@ +import Segment from "analytics-node"; + +export interface CreateAnalyticsOptions { + anonymousId: string; + segmentWriteKey: string; +} + +export interface Analytics { + track(event: string): void; +} + +export const createAnalytics = (options: CreateAnalyticsOptions): Analytics => { + const segment = new Segment(options.segmentWriteKey); + + segment.identify({ + anonymousId: options.anonymousId, + }); + + return { + track(event: string) { + segment.track({ + anonymousId: options.anonymousId, + event, + }); + }, + }; +}; diff --git a/apps/wing-console/console/app/src/anonymous-id.ts b/apps/wing-console/console/app/src/anonymous-id.ts new file mode 100644 index 00000000000..791859cc13a --- /dev/null +++ b/apps/wing-console/console/app/src/anonymous-id.ts @@ -0,0 +1,20 @@ +import Conf from "conf"; +import { nanoid } from "nanoid"; + +/** + * Returns the anonymous ID of the user, or generates a new one if it doesn't exist. + */ +export const getAnonymousId = (): string => { + const conf = new Conf({ + projectName: "@wingconsole/app", + }); + + let anonymousId = conf.get("anonymousId") as string | undefined; + if (anonymousId) { + return anonymousId; + } + + anonymousId = nanoid(); + conf.set("anonymousId", anonymousId); + return anonymousId; +}; diff --git a/apps/wing-console/console/app/src/index.ts b/apps/wing-console/console/app/src/index.ts index 6db025efb90..e0ec0e77e03 100644 --- a/apps/wing-console/console/app/src/index.ts +++ b/apps/wing-console/console/app/src/index.ts @@ -8,6 +8,8 @@ import { Trace, } from "@wingconsole/server"; import express from "express"; +import { createAnalytics } from "./analytics"; +import { getAnonymousId } from "./anonymous-id"; export type { LogInterface, @@ -31,13 +33,48 @@ export interface CreateConsoleAppOptions { const staticDir = `${__dirname}/vite`; +const { SEGMENT_WRITE_KEY } = process.env; + export const createConsoleApp = async (options: CreateConsoleAppOptions) => { + const analytics = SEGMENT_WRITE_KEY + ? createAnalytics({ + anonymousId: getAnonymousId(), + segmentWriteKey: SEGMENT_WRITE_KEY, + }) + : undefined; + + analytics?.track("Console Application Started"); + const server = await createConsoleServer({ ...options, onExpressCreated(app) { app.use(express.static(staticDir)); options.onExpressCreated?.(app); }, + onTrace(trace) { + if (!analytics) { + return; + } + if (trace.type !== "resource") { + return; + } + const resourceName = trace.sourceType.replace("wingsdk.cloud.", ""); + if (!trace.data.message.includes("(")) { + return; + } + // extracting the action name. + // trace message for resources looks like this: + // 'Invoke (payload="{\\"messages\\":[\\"dfd\\"]}").' + const action = trace.data.message.slice( + 0, + Math.max(0, trace.data.message.indexOf("(")), + ); + analytics.track( + `console application: ${resourceName}: ${action} ${JSON.stringify( + Object.assign({}, trace, trace.data), + )}`, + ); + }, log: options.log ?? { info() {}, error: console.error, diff --git a/apps/wing-console/console/app/tailwind.config.cjs b/apps/wing-console/console/app/tailwind.config.cjs index 15856c48bd1..bcae8293ab7 100644 --- a/apps/wing-console/console/app/tailwind.config.cjs +++ b/apps/wing-console/console/app/tailwind.config.cjs @@ -1,195 +1,9 @@ -const colors = require("tailwindcss/colors"); -const defaultTheme = require("tailwindcss/defaultTheme"); -const flattenColorPalette = require("tailwindcss/lib/util/flattenColorPalette"); -const toColorValue = require("tailwindcss/lib/util/toColorValue"); -const plugin = require("tailwindcss/plugin"); - -/** - * Extracts the value of the RGB components an hexadecimal color. - * @param {string} color - * @returns {[number, number, number]} The decimal value of the RGB components - */ -const rgbFromColor = (color) => [ - Number.parseInt(color.slice(1, 3), 16), - Number.parseInt(color.slice(3, 5), 16), - Number.parseInt(color.slice(5, 7), 16), -]; - -/** - * Returns the value between two numbers. - * @param {number} value1 - * @param {number} value2 - * @returns - */ -const mixColorComponent = (value1, value2) => { - const max = Math.max(value1, value2); - const min = Math.min(value1, value2); - return Math.round(min + (max - min) / 2); -}; - -/** - * Mix two hexadecimal colors. - * @param {string} color1 - * @param {string} color2 - * @returns The mixed hexadecimal color. - * @example ```ts - * const color = mixColor("#666666", "#888888"); // "#777777" - * ``` - */ -const mixColor = (color1, color2) => { - const rgb1 = rgbFromColor(color1); - const rgb2 = rgbFromColor(color2); - const r = mixColorComponent(rgb1[0], rgb2[0]); - const g = mixColorComponent(rgb1[1], rgb2[1]); - const b = mixColorComponent(rgb1[2], rgb2[2]); - return `#${r.toString(16)}${g.toString(16)}${b.toString(16)}`; -}; - -const expandColor = (color) => { - return { - ...color, - 150: mixColor(color[100], color[200]), - 250: mixColor(color[200], color[300]), - 350: mixColor(color[300], color[400]), - 450: mixColor(color[400], color[500]), - 550: mixColor(color[500], color[600]), - 650: mixColor(color[600], color[700]), - 750: mixColor(color[700], color[800]), - 850: mixColor(color[800], color[900]), - }; -}; +const ui = require("@wingconsole/ui/tailwind-plugin.cjs"); /** @type {import('tailwindcss').Config} */ module.exports = { darkMode: "class", - content: [ - "./index.html", - "./src/**/*.{vue,js,ts,jsx,tsx}", - "../ui/src/**/*.{vue,js,ts,jsx,tsx}", - "../design-system/src/**/*.{vue,js,ts,jsx,tsx}", - ], - theme: { - fontFamily: { - ...defaultTheme.fontFamily, - sans: ["IBM Plex Sans", ...defaultTheme.fontFamily.sans], - mono: ["IBM Plex Mono", ...defaultTheme.fontFamily.mono], - "share-tech": ["Share Tech Mono", ...defaultTheme.fontFamily.mono], - }, - - extend: { - colors: { - gray: expandColor(colors.gray), - slate: expandColor(colors.slate), - "monada-light": "#AEF8EC", - "monada-dark": "#2ad5c1", - "monada-black": "#03120E", - }, - fontSize: { - "2xs": "0.7rem", - }, - }, - }, - plugins: [ - require("@tailwindcss/forms"), - // Scrollbar plugin. - plugin(function ({ addUtilities, matchUtilities, addBase, theme }) { - addBase({ - ".scrollbar": { - "&": { - "border-color": "rgba(0, 0, 0, 0)", - }, - "&::-webkit-scrollbar, &::-webkit-scrollbar-thumb, &::-webkit-scrollbar-corner": - { - // add border to act as background-color - "border-right-style": "inset", - // sum viewport dimensions to guarantee border will fill scrollbar - "border-right-width": "calc(100vw + 100vh)", - // inherit border-color to inherit transitions - "border-color": "inherit", - }, - }, - }); - - const themeColors = flattenColorPalette.default(theme("colors")); - const colors = Object.fromEntries( - Object.entries(themeColors).map(([k, v]) => [ - k, - toColorValue.default(v), - ]), - ); - matchUtilities( - { - "scrollbar-bg": (value) => ({ - "border-color": value, - }), - "scrollbar-thumb": (value) => ({ - "&::-webkit-scrollbar-thumb": { - "border-color": value, - }, - }), - "scrollbar-thumb-hover": (value) => ({ - "&::-webkit-scrollbar-thumb:hover, &:hover::-webkit-scrollbar-thumb:hover": - { - "border-color": value, - }, - }), - "scrollbar-thumb-active": (value) => ({ - "&::-webkit-scrollbar-thumb:active, &:hover::-webkit-scrollbar-thumb:active": - { - "border-color": value, - }, - }), - }, - { values: colors, type: "color" }, - ); - - const themeWidths = flattenColorPalette.default(theme("width")); - const widths = Object.entries(themeWidths).filter( - ([, size]) => size.endsWith("px") || size.endsWith("rem"), - ); - matchUtilities( - { - "scrollbar-w": (value) => ({ - "&::-webkit-scrollbar": { - width: Array.isArray(value) ? value[1] : value, - }, - }), - }, - { - values: widths, - type: ["absolute-size", "length"], - }, - ); - - const themeHeights = flattenColorPalette.default(theme("height")); - const heights = Object.entries(themeHeights).filter( - ([, size]) => size.endsWith("px") || size.endsWith("rem"), - ); - matchUtilities( - { - "scrollbar-h": (value) => ({ - "&::-webkit-scrollbar": { - height: Array.isArray(value) ? value[1] : value, - }, - }), - }, - { - values: heights, - type: ["absolute-size", "length"], - }, - ); - - addUtilities({ - ".overflow-overlay": { - overflow: ["scroll", "overlay"], - }, - ".overflow-x-overlay": { - "overflow-x": ["scroll", "overlay"], - }, - ".overflow-y-overlay": { - "overflow-y": ["scroll", "overlay"], - }, - }); - }), - ], + content: [...ui.content, "./index.html", "./src/**/*.{vue,js,ts,jsx,tsx}"], + plugins: [...ui.plugins], + theme: { ...ui.theme }, }; diff --git a/apps/wing-console/console/app/tsup.config.ts b/apps/wing-console/console/app/tsup.config.ts index 3f3276e448e..c9e235a8dda 100644 --- a/apps/wing-console/console/app/tsup.config.ts +++ b/apps/wing-console/console/app/tsup.config.ts @@ -1,6 +1,6 @@ -import react from "@vitejs/plugin-react"; import { defineConfig } from "tsup"; import * as vite from "vite"; +import { viteConfig } from "./scripts/config.mjs"; export default defineConfig({ entry: ["src/index.ts"], @@ -12,14 +12,6 @@ export default defineConfig({ console.log("Build succeeded"); console.log("Build UI files..."); - await vite.build({ - configFile: false, - root: "./web", - plugins: [react()], - build: { - outDir: "../dist/vite", - }, - base: "./", - }); + await vite.build(viteConfig); }, }); diff --git a/apps/wing-console/console/app/web/favicon.ico b/apps/wing-console/console/app/web/favicon.ico new file mode 100644 index 00000000000..8dc9ee8d53e Binary files /dev/null and b/apps/wing-console/console/app/web/favicon.ico differ diff --git a/apps/wing-console/console/app/web/index.html b/apps/wing-console/console/app/web/index.html index e9b213ae34a..1c71d4d62d2 100644 --- a/apps/wing-console/console/app/web/index.html +++ b/apps/wing-console/console/app/web/index.html @@ -2,9 +2,10 @@ - + + Wing Console
{ // Playground and Learn need to be able to listen to all traces. diff --git a/apps/wing-console/console/design-system/package-lock.json b/apps/wing-console/console/design-system/package-lock.json index a65295fbd42..3be36c3eacc 100644 --- a/apps/wing-console/console/design-system/package-lock.json +++ b/apps/wing-console/console/design-system/package-lock.json @@ -8,36 +8,59 @@ "name": "@wingconsole/design-system", "version": "0.0.0", "license": "SEE LICENSE IN LICENSE.md", - "devDependencies": { - "@babel/core": "^7.22.5", + "dependencies": { "@headlessui/react": "^1.7.15", "@heroicons/react": "^2.0.18", "@popperjs/core": "^2.11.8", + "@tailwindcss/forms": "^0.5.3", + "classnames": "^2.3.2", + "lodash.uniq": "^4.5.0", + "nanoid": "^4.0.2", + "react": "^18.2.0", + "react-dom": "^18.2.0", + "react-lottie-player": "^1.5.4", + "react-popper": "^2.3.0", + "tailwindcss": "^3.3.2" + }, + "devDependencies": { + "@babel/core": "^7.22.5", "@storybook/react": "^7.0.20", "@testing-library/react": "^14.0.0", - "@types/lodash": "^4.14.195", + "@types/lodash.uniq": "^4.5.7", "@types/react": "^18.2.12", "@types/react-dom": "^18.2.5", "@vitejs/plugin-react": "^4.0.0", "@vitest/coverage-c8": "^0.31.4", "@wingconsole/eslint-plugin": "file:../../tools/eslint-plugin", "@wingconsole/tsconfig": "file:../../tools/tsconfig", - "classnames": "^2.3.2", + "bump-pack": "file:../../../../tools/bump-pack", "eslint": "^8.42.0", "happy-dom": "^9.20.3", - "lodash": "^4.17.21", - "nanoid": "^4.0.2", - "react": "^18.2.0", - "react-dom": "^18.2.0", - "react-lottie-player": "^1.5.4", - "react-popper": "^2.3.0", - "require-from-string": "^2.0.2", + "tsup": "^7.1.0", "typescript": "^5.1.3", "vite": "^4.3.9", "vitest": "^0.31.4", "webpack": "^5.86.0" } }, + "../../../../tools/bump-pack": { + "version": "0.0.0", + "dev": true, + "dependencies": { + "changelogen": "^0.5.3", + "npm-which": "^3.0.1", + "semver": "^7.5.2", + "tsx": "^3.12.7" + }, + "bin": { + "bump-pack": "bin/bump-pack.cjs" + }, + "devDependencies": { + "@types/node": "^18.16.18", + "@types/semver": "^7.5.0", + "typescript": "^5.1.3" + } + }, "../../tools/eslint-plugin": { "name": "@wingconsole/eslint-plugin", "version": "0.0.0", @@ -78,6 +101,17 @@ "typescript": "^4.9.4" } }, + "node_modules/@alloc/quick-lru": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/@alloc/quick-lru/-/quick-lru-5.2.0.tgz", + "integrity": "sha512-UrcABB+4bUrFABwbluTIBErXwvbsU/V7TZWfmbgJfbkwiBuziS9gxdODUyuiecfdGQ85jglMW6juS3+z5TsKLw==", + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/@ampproject/remapping": { "version": "2.2.1", "resolved": "https://registry.npmjs.org/@ampproject/remapping/-/remapping-2.2.1.tgz", @@ -883,7 +917,6 @@ "version": "1.7.15", "resolved": "https://registry.npmjs.org/@headlessui/react/-/react-1.7.15.tgz", "integrity": "sha512-OTO0XtoRQ6JPB1cKNFYBZv2Q0JMqMGNhYP1CjPvcJvjz8YGokz8oAj89HIYZGN0gZzn/4kk9iUpmMF4Q21Gsqw==", - "dev": true, "dependencies": { "client-only": "^0.0.1" }, @@ -899,7 +932,6 @@ "version": "2.0.18", "resolved": "https://registry.npmjs.org/@heroicons/react/-/react-2.0.18.tgz", "integrity": "sha512-7TyMjRrZZMBPa+/5Y8lN0iyvUU/01PeMGX2+RE7cQWpEUIcb4QotzUObFkJDejj/HUH4qjP/eQ0gzzKs2f+6Yw==", - "dev": true, "peerDependencies": { "react": ">= 16" } @@ -950,7 +982,6 @@ "version": "0.3.3", "resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.3.tgz", "integrity": "sha512-HLhSWOLRi875zjjMG/r+Nv0oCW8umGb0BgEhyX3dDX3egwZtB8PqLnjz3yedt8R5StBrzcg4aBpnh8UA9D1BoQ==", - "dev": true, "dependencies": { "@jridgewell/set-array": "^1.0.1", "@jridgewell/sourcemap-codec": "^1.4.10", @@ -964,7 +995,6 @@ "version": "3.1.0", "resolved": "https://registry.npmjs.org/@jridgewell/resolve-uri/-/resolve-uri-3.1.0.tgz", "integrity": "sha512-F2msla3tad+Mfht5cJq7LSXcdudKTWCVYUgw6pLFOOHSTtZlj6SWNYAp+AhuqLmWdBO2X5hPrLcu8cVP8fy28w==", - "dev": true, "engines": { "node": ">=6.0.0" } @@ -973,7 +1003,6 @@ "version": "1.1.2", "resolved": "https://registry.npmjs.org/@jridgewell/set-array/-/set-array-1.1.2.tgz", "integrity": "sha512-xnkseuNADM0gt2bs+BvhO0p78Mk762YnZdsuzFV018NoG1Sj1SCQvpSqa7XUaTam5vAGasABV9qXASMKnFMwMw==", - "dev": true, "engines": { "node": ">=6.0.0" } @@ -991,14 +1020,12 @@ "node_modules/@jridgewell/sourcemap-codec": { "version": "1.4.15", "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.4.15.tgz", - "integrity": "sha512-eF2rxCRulEKXHTRiDrDy6erMYWqNw4LPdQ8UQA4huuxaQsVeRPFl2oM8oDGxMFhJUWZf9McpLtJasDDZb/Bpeg==", - "dev": true + "integrity": "sha512-eF2rxCRulEKXHTRiDrDy6erMYWqNw4LPdQ8UQA4huuxaQsVeRPFl2oM8oDGxMFhJUWZf9McpLtJasDDZb/Bpeg==" }, "node_modules/@jridgewell/trace-mapping": { "version": "0.3.18", "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.18.tgz", "integrity": "sha512-w+niJYzMHdd7USdiH2U6869nqhD2nbfZXND5Yp93qIbEmnDNk7PD48o+YchRVpzMU7M6jVCbenTR7PA1FLQ9pA==", - "dev": true, "dependencies": { "@jridgewell/resolve-uri": "3.1.0", "@jridgewell/sourcemap-codec": "1.4.14" @@ -1007,14 +1034,12 @@ "node_modules/@jridgewell/trace-mapping/node_modules/@jridgewell/sourcemap-codec": { "version": "1.4.14", "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.4.14.tgz", - "integrity": "sha512-XPSJHWmi394fuUuzDnGz1wiKqWfo1yXecHQMRf2l6hztTO+nPru658AyDngaBe7isIxEkRsPR3FZh+s7iVa4Uw==", - "dev": true + "integrity": "sha512-XPSJHWmi394fuUuzDnGz1wiKqWfo1yXecHQMRf2l6hztTO+nPru658AyDngaBe7isIxEkRsPR3FZh+s7iVa4Uw==" }, "node_modules/@nodelib/fs.scandir": { "version": "2.1.5", "resolved": "https://registry.npmjs.org/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz", "integrity": "sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g==", - "dev": true, "dependencies": { "@nodelib/fs.stat": "2.0.5", "run-parallel": "^1.1.9" @@ -1027,7 +1052,6 @@ "version": "2.0.5", "resolved": "https://registry.npmjs.org/@nodelib/fs.stat/-/fs.stat-2.0.5.tgz", "integrity": "sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A==", - "dev": true, "engines": { "node": ">= 8" } @@ -1036,7 +1060,6 @@ "version": "1.2.8", "resolved": "https://registry.npmjs.org/@nodelib/fs.walk/-/fs.walk-1.2.8.tgz", "integrity": "sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg==", - "dev": true, "dependencies": { "@nodelib/fs.scandir": "2.1.5", "fastq": "^1.6.0" @@ -1049,7 +1072,6 @@ "version": "2.11.8", "resolved": "https://registry.npmjs.org/@popperjs/core/-/core-2.11.8.tgz", "integrity": "sha512-P1st0aksCrn9sGZhp8GMYwBnQsbvAWsZAX44oXNNvLHGqAOcoVxmjZiohstwQ7SqKnbR47akdNi+uleWD8+g6A==", - "dev": true, "funding": { "type": "opencollective", "url": "https://opencollective.com/popperjs" @@ -1445,6 +1467,17 @@ "url": "https://opencollective.com/storybook" } }, + "node_modules/@tailwindcss/forms": { + "version": "0.5.3", + "resolved": "https://registry.npmjs.org/@tailwindcss/forms/-/forms-0.5.3.tgz", + "integrity": "sha512-y5mb86JUoiUgBjY/o6FJSFZSEttfb3Q5gllE4xoKjAAD+vBrnIhE4dViwUuow3va8mpH4s9jyUbUbrRGoRdc2Q==", + "dependencies": { + "mini-svg-data-uri": "^1.2.3" + }, + "peerDependencies": { + "tailwindcss": ">=3.0.0 || >= 3.0.0-alpha.1" + } + }, "node_modules/@testing-library/dom": { "version": "9.3.1", "resolved": "https://registry.npmjs.org/@testing-library/dom/-/dom-9.3.1.tgz", @@ -1723,6 +1756,15 @@ "integrity": "sha512-Hwx9EUgdwf2GLarOjQp5ZH8ZmblzcbTBC2wtQWNKARBSxM9ezRIAUpeDTgoQRAFB0+8CNWXVA9+MaSOzOF3nPg==", "dev": true }, + "node_modules/@types/lodash.uniq": { + "version": "4.5.7", + "resolved": "https://registry.npmjs.org/@types/lodash.uniq/-/lodash.uniq-4.5.7.tgz", + "integrity": "sha512-qg7DeAbdZMi6DGvCxThlJycykLLhETrJrQZ6F2KaZ+o0sNK1qRHz46lgNA+nHHjwrmA2a91DyiZTp3ey3m1rEw==", + "dev": true, + "dependencies": { + "@types/lodash": "*" + } + }, "node_modules/@types/mime": { "version": "1.3.2", "resolved": "https://registry.npmjs.org/@types/mime/-/mime-1.3.2.tgz", @@ -2202,6 +2244,23 @@ "node": ">=4" } }, + "node_modules/any-promise": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/any-promise/-/any-promise-1.3.0.tgz", + "integrity": "sha512-7UvmKalWRt1wgjL1RrGxoSJW/0QZFIegpeGvZG9kjp8vrRu55XTHbwnqq2GpXm9uLbcuhxm3IqX9OB4MZR1b2A==" + }, + "node_modules/anymatch": { + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-3.1.3.tgz", + "integrity": "sha512-KMReFUr0B4t+D+OBkjR3KYqvocp2XaSzO55UcB6mgQMd3KbcE+mWTyvVV7D/zsdEbNnV6acZUutkiHQXvTr1Rw==", + "dependencies": { + "normalize-path": "^3.0.0", + "picomatch": "^2.0.4" + }, + "engines": { + "node": ">= 8" + } + }, "node_modules/app-root-dir": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/app-root-dir/-/app-root-dir-1.0.2.tgz", @@ -2227,6 +2286,11 @@ "node": ">=10" } }, + "node_modules/arg": { + "version": "5.0.2", + "resolved": "https://registry.npmjs.org/arg/-/arg-5.0.2.tgz", + "integrity": "sha512-PYjyFOLKQ9y57JvQ6QLo8dAgNqswh8M1RMJYdQduT6xbWSgK36P/Z/v+p888pM69jMMfS8Xd8F6I1kQ/I9HUGg==" + }, "node_modules/argparse": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz", @@ -2255,6 +2319,15 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/array-union": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/array-union/-/array-union-2.1.0.tgz", + "integrity": "sha512-HGyxoOTYUyCM6stUe6EJgnd4EoewAI7zMdfqO+kGjnlZmBDz/cR5pf8r/cR4Wq60sL/p0IkcjUEEPwS3GFrIyw==", + "dev": true, + "engines": { + "node": ">=8" + } + }, "node_modules/assertion-error": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/assertion-error/-/assertion-error-1.1.0.tgz", @@ -2285,8 +2358,15 @@ "node_modules/balanced-match": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", - "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==", - "dev": true + "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==" + }, + "node_modules/binary-extensions": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-2.2.0.tgz", + "integrity": "sha512-jDctJ/IVQbZoJykoeHbhXpOlNBqGNcwXJKJog42E5HDPUwQTSdjCHdihjj0DlnheQ7blbT6dHOafNAiS8ooQKA==", + "engines": { + "node": ">=8" + } }, "node_modules/blueimp-md5": { "version": "2.19.0", @@ -2298,12 +2378,22 @@ "version": "1.1.11", "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", - "dev": true, "dependencies": { "balanced-match": "^1.0.0", "concat-map": "0.0.1" } }, + "node_modules/braces": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.2.tgz", + "integrity": "sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==", + "dependencies": { + "fill-range": "^7.0.1" + }, + "engines": { + "node": ">=8" + } + }, "node_modules/browserslist": { "version": "4.21.9", "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.21.9.tgz", @@ -2342,6 +2432,25 @@ "integrity": "sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ==", "dev": true }, + "node_modules/bump-pack": { + "resolved": "../../../../tools/bump-pack", + "link": true + }, + "node_modules/bundle-require": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/bundle-require/-/bundle-require-4.0.1.tgz", + "integrity": "sha512-9NQkRHlNdNpDBGmLpngF3EFDcwodhMUuLz9PaWYciVcQF9SE4LFjM2DB/xV1Li5JiuDMv7ZUWuC3rGbqR0MAXQ==", + "dev": true, + "dependencies": { + "load-tsconfig": "^0.2.3" + }, + "engines": { + "node": "^12.20.0 || ^14.13.1 || >=16.0.0" + }, + "peerDependencies": { + "esbuild": ">=0.17" + } + }, "node_modules/c8": { "version": "7.14.0", "resolved": "https://registry.npmjs.org/c8/-/c8-7.14.0.tgz", @@ -2399,6 +2508,14 @@ "node": ">=6" } }, + "node_modules/camelcase-css": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/camelcase-css/-/camelcase-css-2.0.1.tgz", + "integrity": "sha512-QOSvevhslijgYwRx6Rv7zKdMF8lbRmx+uQGx2+vDc+KI/eBnsy9kit5aj23AgGu3pa4t9AgwbnXWqS+iOY+2aA==", + "engines": { + "node": ">= 6" + } + }, "node_modules/caniuse-lite": { "version": "1.0.30001506", "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001506.tgz", @@ -2460,6 +2577,43 @@ "node": "*" } }, + "node_modules/chokidar": { + "version": "3.5.3", + "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.5.3.tgz", + "integrity": "sha512-Dr3sfKRP6oTcjf2JmUmFJfeVMvXBdegxB0iVQ5eb2V10uFJUCAS8OByZdVAyVb8xXNz3GjjTgj9kLWsZTqE6kw==", + "funding": [ + { + "type": "individual", + "url": "https://paulmillr.com/funding/" + } + ], + "dependencies": { + "anymatch": "~3.1.2", + "braces": "~3.0.2", + "glob-parent": "~5.1.2", + "is-binary-path": "~2.1.0", + "is-glob": "~4.0.1", + "normalize-path": "~3.0.0", + "readdirp": "~3.6.0" + }, + "engines": { + "node": ">= 8.10.0" + }, + "optionalDependencies": { + "fsevents": "~2.3.2" + } + }, + "node_modules/chokidar/node_modules/glob-parent": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz", + "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==", + "dependencies": { + "is-glob": "^4.0.1" + }, + "engines": { + "node": ">= 6" + } + }, "node_modules/chrome-trace-event": { "version": "1.0.3", "resolved": "https://registry.npmjs.org/chrome-trace-event/-/chrome-trace-event-1.0.3.tgz", @@ -2472,14 +2626,12 @@ "node_modules/classnames": { "version": "2.3.2", "resolved": "https://registry.npmjs.org/classnames/-/classnames-2.3.2.tgz", - "integrity": "sha512-CSbhY4cFEJRe6/GQzIk5qXZ4Jeg5pcsP7b5peFSDpffpe1cqjASH/n9UTjBwOp6XpMSTwQ8Za2K5V02ueA7Tmw==", - "dev": true + "integrity": "sha512-CSbhY4cFEJRe6/GQzIk5qXZ4Jeg5pcsP7b5peFSDpffpe1cqjASH/n9UTjBwOp6XpMSTwQ8Za2K5V02ueA7Tmw==" }, "node_modules/client-only": { "version": "0.0.1", "resolved": "https://registry.npmjs.org/client-only/-/client-only-0.0.1.tgz", - "integrity": "sha512-IV3Ou0jSMzZrd3pZ48nLkT9DA7Ag1pnPzaiQhpW7c3RbcqqzvzzVu+L8gfqMp/8IM2MQtSiqaCxrrcfu8I8rMA==", - "dev": true + "integrity": "sha512-IV3Ou0jSMzZrd3pZ48nLkT9DA7Ag1pnPzaiQhpW7c3RbcqqzvzzVu+L8gfqMp/8IM2MQtSiqaCxrrcfu8I8rMA==" }, "node_modules/cliui": { "version": "7.0.4", @@ -2537,8 +2689,7 @@ "node_modules/concat-map": { "version": "0.0.1", "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", - "integrity": "sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==", - "dev": true + "integrity": "sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==" }, "node_modules/concordance": { "version": "5.0.4", @@ -2624,6 +2775,17 @@ "integrity": "sha512-YUifsXXuknHlUsmlgyY0PKzgPOr7/FjCePfHNt0jxm83wHZi44VDMQ7/fGNkjY3/jV1MC+1CmZbaHzugyeRtpg==", "dev": true }, + "node_modules/cssesc": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/cssesc/-/cssesc-3.0.0.tgz", + "integrity": "sha512-/Tb/JcjK111nNScGob5MNtsntNM1aCNUDipB/TkwZFhyDrrE47SOx/18wF2bbjgc3ZzCSKW1T5nt5EbFoAz/Vg==", + "bin": { + "cssesc": "bin/cssesc" + }, + "engines": { + "node": ">=4" + } + }, "node_modules/csstype": { "version": "3.1.2", "resolved": "https://registry.npmjs.org/csstype/-/csstype-3.1.2.tgz", @@ -2746,6 +2908,28 @@ "node": ">=6" } }, + "node_modules/didyoumean": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/didyoumean/-/didyoumean-1.2.2.tgz", + "integrity": "sha512-gxtyfqMg7GKyhQmb056K7M3xszy/myH8w+B4RT+QXBQsvAOdc3XymqDDPHx1BgPgsdAA5SIifona89YtRATDzw==" + }, + "node_modules/dir-glob": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/dir-glob/-/dir-glob-3.0.1.tgz", + "integrity": "sha512-WkrWp9GR4KXfKGYzOLmTuGVi1UWFfws377n9cc55/tb6DuqyF6pcQ5AbiHEshaDpY9v6oaSr2XCDidGmMwdzIA==", + "dev": true, + "dependencies": { + "path-type": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/dlv": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/dlv/-/dlv-1.1.3.tgz", + "integrity": "sha512-+HlytyjlPKnIG8XuRG8WvmBP8xs8P71y+SKKS6ZXWoEgLuePxtDoUEiH7WkdePWrQ5JBpE6aoVqfZfJUQkjXwA==" + }, "node_modules/doctrine": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-3.0.0.tgz", @@ -3240,11 +3424,33 @@ "node": ">=0.8.x" } }, + "node_modules/execa": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/execa/-/execa-5.1.1.tgz", + "integrity": "sha512-8uSpZZocAZRBAPIEINJj3Lo9HyGitllczc27Eh5YYojjMFMn8yHMDMaUHE2Jqfq05D/wucwI4JGURyXt1vchyg==", + "dev": true, + "dependencies": { + "cross-spawn": "^7.0.3", + "get-stream": "^6.0.0", + "human-signals": "^2.1.0", + "is-stream": "^2.0.0", + "merge-stream": "^2.0.0", + "npm-run-path": "^4.0.1", + "onetime": "^5.1.2", + "signal-exit": "^3.0.3", + "strip-final-newline": "^2.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sindresorhus/execa?sponsor=1" + } + }, "node_modules/fast-deep-equal": { "version": "3.1.3", "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz", - "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==", - "dev": true + "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==" }, "node_modules/fast-diff": { "version": "1.3.0", @@ -3252,6 +3458,32 @@ "integrity": "sha512-VxPP4NqbUjj6MaAOafWeUn2cXWLcCtljklUtZf0Ind4XQ+QPtmA0b18zZy0jIQx+ExRVCR/ZQpBmik5lXshNsw==", "dev": true }, + "node_modules/fast-glob": { + "version": "3.2.12", + "resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-3.2.12.tgz", + "integrity": "sha512-DVj4CQIYYow0BlaelwK1pHl5n5cRSJfM60UA0zK891sVInoPri2Ekj7+e1CT3/3qxXenpI+nBBmQAcJPJgaj4w==", + "dependencies": { + "@nodelib/fs.stat": "^2.0.2", + "@nodelib/fs.walk": "^1.2.3", + "glob-parent": "^5.1.2", + "merge2": "^1.3.0", + "micromatch": "^4.0.4" + }, + "engines": { + "node": ">=8.6.0" + } + }, + "node_modules/fast-glob/node_modules/glob-parent": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz", + "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==", + "dependencies": { + "is-glob": "^4.0.1" + }, + "engines": { + "node": ">= 6" + } + }, "node_modules/fast-json-stable-stringify": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz", @@ -3268,7 +3500,6 @@ "version": "1.15.0", "resolved": "https://registry.npmjs.org/fastq/-/fastq-1.15.0.tgz", "integrity": "sha512-wBrocU2LCXXa+lWBt8RoIRD89Fi8OdABODa/kEnyeyjS5aZO5/GNvI5sEINADqP/h8M29UHTHUb53sUu5Ihqdw==", - "dev": true, "dependencies": { "reusify": "^1.0.4" } @@ -3295,6 +3526,17 @@ "ramda": "0.29.0" } }, + "node_modules/fill-range": { + "version": "7.0.1", + "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.0.1.tgz", + "integrity": "sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ==", + "dependencies": { + "to-regex-range": "^5.0.1" + }, + "engines": { + "node": ">=8" + } + }, "node_modules/find-up": { "version": "5.0.0", "resolved": "https://registry.npmjs.org/find-up/-/find-up-5.0.0.tgz", @@ -3383,14 +3625,12 @@ "node_modules/fs.realpath": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", - "integrity": "sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw==", - "dev": true + "integrity": "sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw==" }, "node_modules/fsevents": { "version": "2.3.2", "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.2.tgz", "integrity": "sha512-xiqMQR4xAeHTuB9uWm+fFRcIOgKBMiOBP+eXiyT7jsgVCq1bkVygt00oASowB7EdtpOHaaPgKt812P9ab+DDKA==", - "dev": true, "hasInstallScript": true, "optional": true, "os": [ @@ -3403,8 +3643,7 @@ "node_modules/function-bind": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.1.tgz", - "integrity": "sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==", - "dev": true + "integrity": "sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==" }, "node_modules/functions-have-names": { "version": "1.2.3", @@ -3477,6 +3716,18 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/get-stream": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-6.0.1.tgz", + "integrity": "sha512-ts6Wi+2j3jQjqi70w5AlN8DFnkSwC+MqmxEzdEALB2qXZYV3X/b1CTfgPLGJNMeAWxdPfU8FO1ms3NUfaHCPYg==", + "dev": true, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/glob": { "version": "8.1.0", "resolved": "https://registry.npmjs.org/glob/-/glob-8.1.0.tgz", @@ -3500,7 +3751,6 @@ "version": "6.0.2", "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-6.0.2.tgz", "integrity": "sha512-XxwI8EOhVQgWp6iDL+3b0r86f4d6AX6zSU55HfB4ydCEuXLXc5FcYeOu+nnGftS4TEju/11rt4KJPTMgbfmv4A==", - "dev": true, "dependencies": { "is-glob": "^4.0.3" }, @@ -3563,6 +3813,26 @@ "node": ">=4" } }, + "node_modules/globby": { + "version": "11.1.0", + "resolved": "https://registry.npmjs.org/globby/-/globby-11.1.0.tgz", + "integrity": "sha512-jhIXaOzy1sb8IyocaruWSn1TjmnBVs8Ayhcy83rmxNJ8q2uWKCAj3CnJY+KpGSXCueAPc0i05kVvVKtP1t9S3g==", + "dev": true, + "dependencies": { + "array-union": "^2.1.0", + "dir-glob": "^3.0.1", + "fast-glob": "^3.2.9", + "ignore": "^5.2.0", + "merge2": "^1.4.1", + "slash": "^3.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/gopd": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/gopd/-/gopd-1.0.1.tgz", @@ -3626,7 +3896,6 @@ "version": "1.0.3", "resolved": "https://registry.npmjs.org/has/-/has-1.0.3.tgz", "integrity": "sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw==", - "dev": true, "dependencies": { "function-bind": "^1.1.1" }, @@ -3727,6 +3996,15 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/human-signals": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/human-signals/-/human-signals-2.1.0.tgz", + "integrity": "sha512-B4FFZ6q/T2jhhksgkbEW3HBvWIfDW85snkQgawt07S7J5QXTk6BkNV+0yAeZrM5QpMAdYlocGoljn0sJ/WQkFw==", + "dev": true, + "engines": { + "node": ">=10.17.0" + } + }, "node_modules/iconv-lite": { "version": "0.6.3", "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.6.3.tgz", @@ -3786,7 +4064,6 @@ "version": "1.0.6", "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", "integrity": "sha512-k92I/b08q4wvFscXCLvqfsHCrjrF7yiXsQuIVvVE7N82W3+aqpzuUdBbfhWcy/FZR3/4IgflMgKLOsvPDrGCJA==", - "dev": true, "dependencies": { "once": "^1.3.0", "wrappy": "1" @@ -3795,8 +4072,7 @@ "node_modules/inherits": { "version": "2.0.4", "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", - "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==", - "dev": true + "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==" }, "node_modules/internal-slot": { "version": "1.0.5", @@ -3854,6 +4130,17 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/is-binary-path": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/is-binary-path/-/is-binary-path-2.1.0.tgz", + "integrity": "sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw==", + "dependencies": { + "binary-extensions": "^2.0.0" + }, + "engines": { + "node": ">=8" + } + }, "node_modules/is-boolean-object": { "version": "1.1.2", "resolved": "https://registry.npmjs.org/is-boolean-object/-/is-boolean-object-1.1.2.tgz", @@ -3882,6 +4169,17 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/is-core-module": { + "version": "2.12.1", + "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.12.1.tgz", + "integrity": "sha512-Q4ZuBAe2FUsKtyQJoQHlvP8OvBERxO3jEmy1I7hcRXcJBGGHFh/aJBswbXuS9sgrDH2QUO8ilkwNPHvHMd8clg==", + "dependencies": { + "has": "^1.0.3" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, "node_modules/is-date-object": { "version": "1.0.5", "resolved": "https://registry.npmjs.org/is-date-object/-/is-date-object-1.0.5.tgz", @@ -3901,7 +4199,6 @@ "version": "2.1.1", "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", "integrity": "sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==", - "dev": true, "engines": { "node": ">=0.10.0" } @@ -3919,7 +4216,6 @@ "version": "4.0.3", "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.3.tgz", "integrity": "sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==", - "dev": true, "dependencies": { "is-extglob": "^2.1.1" }, @@ -3936,6 +4232,14 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/is-number": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz", + "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==", + "engines": { + "node": ">=0.12.0" + } + }, "node_modules/is-number-object": { "version": "1.0.7", "resolved": "https://registry.npmjs.org/is-number-object/-/is-number-object-1.0.7.tgz", @@ -4006,6 +4310,18 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/is-stream": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-2.0.1.tgz", + "integrity": "sha512-hFoiJiTl63nn+kstHGBtewWSKnQLpyb155KHheA1l39uvtO9nWIop1p3udqPcUd/xbF1VLMO4n7OI6p7RbngDg==", + "dev": true, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/is-string": { "version": "1.0.7", "resolved": "https://registry.npmjs.org/is-string/-/is-string-1.0.7.tgz", @@ -4184,6 +4500,23 @@ "url": "https://github.com/chalk/supports-color?sponsor=1" } }, + "node_modules/jiti": { + "version": "1.18.2", + "resolved": "https://registry.npmjs.org/jiti/-/jiti-1.18.2.tgz", + "integrity": "sha512-QAdOptna2NYiSSpv0O/BwoHBSmz4YhpzJHyi+fnMRTXFjp7B8i/YG5Z8IfusxB1ufjcD2Sre1F3R+nX3fvy7gg==", + "bin": { + "jiti": "bin/jiti.js" + } + }, + "node_modules/joycon": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/joycon/-/joycon-3.1.1.tgz", + "integrity": "sha512-34wB/Y7MW7bzjKRjUKTa46I2Z7eV62Rkhva+KkopW7Qvv/OSWBqvkSY7vusOPrNuZcUG3tApvdVgNB8POj3SPw==", + "dev": true, + "engines": { + "node": ">=10" + } + }, "node_modules/js-string-escape": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/js-string-escape/-/js-string-escape-1.0.1.tgz", @@ -4196,8 +4529,7 @@ "node_modules/js-tokens": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz", - "integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==", - "dev": true + "integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==" }, "node_modules/js-yaml": { "version": "4.1.0", @@ -4298,17 +4630,39 @@ "node": ">= 0.8.0" } }, - "node_modules/loader-runner": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/loader-runner/-/loader-runner-4.3.0.tgz", - "integrity": "sha512-3R/1M+yS3j5ou80Me59j7F9IMs4PXs3VqRrm0TU3AbKPxlmpoY1TNscJV/oGJXo8qCatFGTfDbY6W6ipGOYXfg==", - "dev": true, + "node_modules/lilconfig": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/lilconfig/-/lilconfig-2.1.0.tgz", + "integrity": "sha512-utWOt/GHzuUxnLKxB6dk81RoOeoNeHgbrXiuGk4yyF5qlRz+iIVWu56E2fqGHFrXz0QNUhLB/8nKqvRH66JKGQ==", "engines": { - "node": ">=6.11.5" + "node": ">=10" } }, - "node_modules/local-pkg": { - "version": "0.4.3", + "node_modules/lines-and-columns": { + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/lines-and-columns/-/lines-and-columns-1.2.4.tgz", + "integrity": "sha512-7ylylesZQ/PV29jhEDl3Ufjo6ZX7gCqJr5F7PKrqc93v7fzSymt1BpwEU8nAUXs8qzzvqhbjhK5QZg6Mt/HkBg==" + }, + "node_modules/load-tsconfig": { + "version": "0.2.5", + "resolved": "https://registry.npmjs.org/load-tsconfig/-/load-tsconfig-0.2.5.tgz", + "integrity": "sha512-IXO6OCs9yg8tMKzfPZ1YmheJbZCiEsnBdcB03l0OcfK9prKnJb96siuHCr5Fl37/yo9DnKU+TLpxzTUspw9shg==", + "dev": true, + "engines": { + "node": "^12.20.0 || ^14.13.1 || >=16.0.0" + } + }, + "node_modules/loader-runner": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/loader-runner/-/loader-runner-4.3.0.tgz", + "integrity": "sha512-3R/1M+yS3j5ou80Me59j7F9IMs4PXs3VqRrm0TU3AbKPxlmpoY1TNscJV/oGJXo8qCatFGTfDbY6W6ipGOYXfg==", + "dev": true, + "engines": { + "node": ">=6.11.5" + } + }, + "node_modules/local-pkg": { + "version": "0.4.3", "resolved": "https://registry.npmjs.org/local-pkg/-/local-pkg-0.4.3.tgz", "integrity": "sha512-SFppqq5p42fe2qcZQqqEOiVRXl+WCP1MdT6k7BDEW1j++sp5fIY+/fdRQitvKgB5BrBcmrs5m/L0v2FrU5MY1g==", "dev": true, @@ -4346,11 +4700,21 @@ "integrity": "sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ==", "dev": true }, + "node_modules/lodash.sortby": { + "version": "4.7.0", + "resolved": "https://registry.npmjs.org/lodash.sortby/-/lodash.sortby-4.7.0.tgz", + "integrity": "sha512-HDWXG8isMntAyRF5vZ7xKuEvOhT4AhlRt/3czTSjvGUxjYCBVRQY48ViDHyfYz9VIoBkW4TMGQNapx+l3RUwdA==", + "dev": true + }, + "node_modules/lodash.uniq": { + "version": "4.5.0", + "resolved": "https://registry.npmjs.org/lodash.uniq/-/lodash.uniq-4.5.0.tgz", + "integrity": "sha512-xfBaXQd9ryd9dlSDvnvI0lvxfLJlYAZzXomUYzLKtUeOQvOP5piqAWuGtrhWeqaXK9hhoM/iyJc5AV+XfsX3HQ==" + }, "node_modules/loose-envify": { "version": "1.4.0", "resolved": "https://registry.npmjs.org/loose-envify/-/loose-envify-1.4.0.tgz", "integrity": "sha512-lyuxPGr/Wfhrlem2CL/UcnUc1zcqKAImBDzukY7Y5F/yQiNdko6+fRLevlw1HgMySw7f611UIY408EtxRSoK3Q==", - "dev": true, "dependencies": { "js-tokens": "^3.0.0 || ^4.0.0" }, @@ -4361,8 +4725,7 @@ "node_modules/lottie-web": { "version": "5.12.2", "resolved": "https://registry.npmjs.org/lottie-web/-/lottie-web-5.12.2.tgz", - "integrity": "sha512-uvhvYPC8kGPjXT3MyKMrL3JitEAmDMp30lVkuq/590Mw9ok6pWcFCwXJveo0t5uqYw1UREQHofD+jVpdjBv8wg==", - "dev": true + "integrity": "sha512-uvhvYPC8kGPjXT3MyKMrL3JitEAmDMp30lVkuq/590Mw9ok6pWcFCwXJveo0t5uqYw1UREQHofD+jVpdjBv8wg==" }, "node_modules/loupe": { "version": "2.3.6", @@ -4451,6 +4814,26 @@ "integrity": "sha512-abv/qOcuPfk3URPfDzmZU1LKmuw8kT+0nIHvKrKgFrwifol/doWcdA4ZqsWQ8ENrFKkd67Mfpo/LovbIUsbt3w==", "dev": true }, + "node_modules/merge2": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/merge2/-/merge2-1.4.1.tgz", + "integrity": "sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==", + "engines": { + "node": ">= 8" + } + }, + "node_modules/micromatch": { + "version": "4.0.5", + "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.5.tgz", + "integrity": "sha512-DMy+ERcEW2q8Z2Po+WNXuw3c5YaUSFjAO5GsJqfEl7UjvtIuFKO6ZrKvcItdy98dwFI2N1tg3zNIdKaQT+aNdA==", + "dependencies": { + "braces": "^3.0.2", + "picomatch": "^2.3.1" + }, + "engines": { + "node": ">=8.6" + } + }, "node_modules/mime-db": { "version": "1.52.0", "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.52.0.tgz", @@ -4472,11 +4855,27 @@ "node": ">= 0.6" } }, + "node_modules/mimic-fn": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-2.1.0.tgz", + "integrity": "sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg==", + "dev": true, + "engines": { + "node": ">=6" + } + }, + "node_modules/mini-svg-data-uri": { + "version": "1.4.4", + "resolved": "https://registry.npmjs.org/mini-svg-data-uri/-/mini-svg-data-uri-1.4.4.tgz", + "integrity": "sha512-r9deDe9p5FJUPZAk3A59wGH7Ii9YrjjWw0jmw/liSbHl2CHiyXj6FcDXDu2K3TjVAXqiJdaw3xxwlZZr9E6nHg==", + "bin": { + "mini-svg-data-uri": "cli.js" + } + }, "node_modules/minimatch": { "version": "3.1.2", "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", - "dev": true, "dependencies": { "brace-expansion": "^1.1.7" }, @@ -4523,11 +4922,20 @@ "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", "dev": true }, + "node_modules/mz": { + "version": "2.7.0", + "resolved": "https://registry.npmjs.org/mz/-/mz-2.7.0.tgz", + "integrity": "sha512-z81GNO7nnYMEhrGh9LeymoE4+Yr0Wn5McHIZMK5cfQCl+NDX08sCZgUc9/6MHni9IWuFLm1Z3HTCXu2z9fN62Q==", + "dependencies": { + "any-promise": "^1.0.0", + "object-assign": "^4.0.1", + "thenify-all": "^1.0.0" + } + }, "node_modules/nanoid": { "version": "4.0.2", "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-4.0.2.tgz", "integrity": "sha512-7ZtY5KTCNheRGfEFxnedV5zFiORN1+Y1N6zvPTnHQd8ENUvfaDBeuJDZb2bN/oXwXxu3qkTXDzy57W5vAmDTBw==", - "dev": true, "funding": [ { "type": "github", @@ -4579,6 +4987,26 @@ "integrity": "sha512-QzsYKWhXTWx8h1kIvqfnC++o0pEmpRQA/aenALsL2F4pqNVr7YzcdMlDij5WBnwftRbJCNJL/O7zdKaxKPHqgQ==", "dev": true }, + "node_modules/normalize-path": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz", + "integrity": "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/npm-run-path": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/npm-run-path/-/npm-run-path-4.0.1.tgz", + "integrity": "sha512-S48WzZW777zhNIrn7gxOlISNAqi9ZC/uQFnRdbeIHhZhCA6UqpkOT8T1G7BvfdgP4Er8gF4sUbaS0i7QvIfCWw==", + "dev": true, + "dependencies": { + "path-key": "^3.0.0" + }, + "engines": { + "node": ">=8" + } + }, "node_modules/npmlog": { "version": "5.0.1", "resolved": "https://registry.npmjs.org/npmlog/-/npmlog-5.0.1.tgz", @@ -4595,11 +5023,18 @@ "version": "4.1.1", "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz", "integrity": "sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg==", - "dev": true, "engines": { "node": ">=0.10.0" } }, + "node_modules/object-hash": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/object-hash/-/object-hash-3.0.0.tgz", + "integrity": "sha512-RSn9F68PjH9HqtltsSnqYC1XXoWe9Bju5+213R98cNGttag9q9yAOTzdbsqvIa7aNm5WffBZFpWYr2aWrklWAw==", + "engines": { + "node": ">= 6" + } + }, "node_modules/object-inspect": { "version": "1.12.3", "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.12.3.tgz", @@ -4656,11 +5091,25 @@ "version": "1.4.0", "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", "integrity": "sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==", - "dev": true, "dependencies": { "wrappy": "1" } }, + "node_modules/onetime": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/onetime/-/onetime-5.1.2.tgz", + "integrity": "sha512-kbpaSSGJTWdAY5KPVeMOKXSrPtr8C8C7wodJbcsd51jRnmD+GZu8Y0VoU6Dm5Z4vWr0Ig/1NKuWRKf7j5aaYSg==", + "dev": true, + "dependencies": { + "mimic-fn": "^2.1.0" + }, + "engines": { + "node": ">=6" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/optionator": { "version": "0.8.3", "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.8.3.tgz", @@ -4767,7 +5216,6 @@ "version": "1.0.1", "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", "integrity": "sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg==", - "dev": true, "engines": { "node": ">=0.10.0" } @@ -4781,6 +5229,20 @@ "node": ">=8" } }, + "node_modules/path-parse": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.7.tgz", + "integrity": "sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==" + }, + "node_modules/path-type": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/path-type/-/path-type-4.0.0.tgz", + "integrity": "sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw==", + "dev": true, + "engines": { + "node": ">=8" + } + }, "node_modules/pathe": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/pathe/-/pathe-1.1.1.tgz", @@ -4799,14 +5261,12 @@ "node_modules/picocolors": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.0.0.tgz", - "integrity": "sha512-1fygroTLlHu66zi26VoTDv8yRgm0Fccecssto+MhsZ0D/DGW2sm8E8AjW7NU5VVTRt5GxbeZ5qBuJr+HyLYkjQ==", - "dev": true + "integrity": "sha512-1fygroTLlHu66zi26VoTDv8yRgm0Fccecssto+MhsZ0D/DGW2sm8E8AjW7NU5VVTRt5GxbeZ5qBuJr+HyLYkjQ==" }, "node_modules/picomatch": { "version": "2.3.1", "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz", "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==", - "dev": true, "engines": { "node": ">=8.6" }, @@ -4814,6 +5274,22 @@ "url": "https://github.com/sponsors/jonschlinkert" } }, + "node_modules/pify": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/pify/-/pify-2.3.0.tgz", + "integrity": "sha512-udgsAY+fTnvv7kI7aaxbqwWNb0AHiB0qBO89PZKPkoTmGOgdbrHDKD+0B2X4uTfJ/FT1R09r9gTsjUjNJotuog==", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/pirates": { + "version": "4.0.6", + "resolved": "https://registry.npmjs.org/pirates/-/pirates-4.0.6.tgz", + "integrity": "sha512-saLsH7WeYYPiD25LDuLRRY/i+6HaPYr6G1OUlN39otzkSTxKnubR9RTxS3/Kk50s1g2JTgFwWQDQyplC5/SHZg==", + "engines": { + "node": ">= 6" + } + }, "node_modules/pkg-dir": { "version": "5.0.0", "resolved": "https://registry.npmjs.org/pkg-dir/-/pkg-dir-5.0.0.tgz", @@ -4841,7 +5317,6 @@ "version": "8.4.24", "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.4.24.tgz", "integrity": "sha512-M0RzbcI0sO/XJNucsGjvWU9ERWxb/ytp1w6dKtxTKgixdtQDq4rmx/g8W1hnaheq9jgwL/oyEdH5Bc4WwJKMqg==", - "dev": true, "funding": [ { "type": "opencollective", @@ -4865,11 +5340,107 @@ "node": "^10 || ^12 || >=14" } }, + "node_modules/postcss-import": { + "version": "15.1.0", + "resolved": "https://registry.npmjs.org/postcss-import/-/postcss-import-15.1.0.tgz", + "integrity": "sha512-hpr+J05B2FVYUAXHeK1YyI267J/dDDhMU6B6civm8hSY1jYJnBXxzKDKDswzJmtLHryrjhnDjqqp/49t8FALew==", + "dependencies": { + "postcss-value-parser": "^4.0.0", + "read-cache": "^1.0.0", + "resolve": "^1.1.7" + }, + "engines": { + "node": ">=14.0.0" + }, + "peerDependencies": { + "postcss": "^8.0.0" + } + }, + "node_modules/postcss-js": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/postcss-js/-/postcss-js-4.0.1.tgz", + "integrity": "sha512-dDLF8pEO191hJMtlHFPRa8xsizHaM82MLfNkUHdUtVEV3tgTp5oj+8qbEqYM57SLfc74KSbw//4SeJma2LRVIw==", + "dependencies": { + "camelcase-css": "^2.0.1" + }, + "engines": { + "node": "^12 || ^14 || >= 16" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/postcss/" + }, + "peerDependencies": { + "postcss": "^8.4.21" + } + }, + "node_modules/postcss-load-config": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/postcss-load-config/-/postcss-load-config-4.0.1.tgz", + "integrity": "sha512-vEJIc8RdiBRu3oRAI0ymerOn+7rPuMvRXslTvZUKZonDHFIczxztIyJ1urxM1x9JXEikvpWWTUUqal5j/8QgvA==", + "dependencies": { + "lilconfig": "^2.0.5", + "yaml": "^2.1.1" + }, + "engines": { + "node": ">= 14" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/postcss/" + }, + "peerDependencies": { + "postcss": ">=8.0.9", + "ts-node": ">=9.0.0" + }, + "peerDependenciesMeta": { + "postcss": { + "optional": true + }, + "ts-node": { + "optional": true + } + } + }, + "node_modules/postcss-nested": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/postcss-nested/-/postcss-nested-6.0.1.tgz", + "integrity": "sha512-mEp4xPMi5bSWiMbsgoPfcP74lsWLHkQbZc3sY+jWYd65CUwXrUaTp0fmNpa01ZcETKlIgUdFN/MpS2xZtqL9dQ==", + "dependencies": { + "postcss-selector-parser": "^6.0.11" + }, + "engines": { + "node": ">=12.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/postcss/" + }, + "peerDependencies": { + "postcss": "^8.2.14" + } + }, + "node_modules/postcss-selector-parser": { + "version": "6.0.13", + "resolved": "https://registry.npmjs.org/postcss-selector-parser/-/postcss-selector-parser-6.0.13.tgz", + "integrity": "sha512-EaV1Gl4mUEV4ddhDnv/xtj7sxwrwxdetHdWUGnT4VJQf+4d05v6lHYZr8N573k5Z0BViss7BDhfWtKS3+sfAqQ==", + "dependencies": { + "cssesc": "^3.0.0", + "util-deprecate": "^1.0.2" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/postcss-value-parser": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/postcss-value-parser/-/postcss-value-parser-4.2.0.tgz", + "integrity": "sha512-1NNCs6uurfkVbeXG4S8JFT9t19m45ICnif8zWLd5oPSZ50QnwMfK+H3jv408d4jw/7Bttv5axS5IiHoLaVNHeQ==" + }, "node_modules/postcss/node_modules/nanoid": { "version": "3.3.6", "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.6.tgz", "integrity": "sha512-BGcqMMJuToF7i1rt+2PWSNVnWIkGCU78jBG3RxO/bZlnZPK2Cmi2QaffxGO/2RvWi9sL+FAiRiXMgsyxQ1DIDA==", - "dev": true, "funding": [ { "type": "github", @@ -4972,7 +5543,6 @@ "version": "1.2.3", "resolved": "https://registry.npmjs.org/queue-microtask/-/queue-microtask-1.2.3.tgz", "integrity": "sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==", - "dev": true, "funding": [ { "type": "github", @@ -5011,7 +5581,6 @@ "version": "18.2.0", "resolved": "https://registry.npmjs.org/react/-/react-18.2.0.tgz", "integrity": "sha512-/3IjMdb2L9QbBdWiW5e3P2/npwMBaU9mHCSCUzNln0ZCYbcfTsGbTJrU/kGemdH2IWmB2ioZ+zkxtmq6g09fGQ==", - "dev": true, "dependencies": { "loose-envify": "^1.1.0" }, @@ -5023,7 +5592,6 @@ "version": "18.2.0", "resolved": "https://registry.npmjs.org/react-dom/-/react-dom-18.2.0.tgz", "integrity": "sha512-6IMTriUmvsjHUjNtEDudZfuDQUoWXVxKHhlEGSk81n4YFS+r/Kl99wXiwlVXtPBtJenozv2P+hxDsw9eA7Xo6g==", - "dev": true, "dependencies": { "loose-envify": "^1.1.0", "scheduler": "^0.23.0" @@ -5056,8 +5624,7 @@ "node_modules/react-fast-compare": { "version": "3.2.2", "resolved": "https://registry.npmjs.org/react-fast-compare/-/react-fast-compare-3.2.2.tgz", - "integrity": "sha512-nsO+KSNgo1SbJqJEYRE9ERzo7YtYbou/OqjSQKxV7jcKox7+usiUVZOAC+XnDOABXggQTno0Y1CpVnuWEc1boQ==", - "dev": true + "integrity": "sha512-nsO+KSNgo1SbJqJEYRE9ERzo7YtYbou/OqjSQKxV7jcKox7+usiUVZOAC+XnDOABXggQTno0Y1CpVnuWEc1boQ==" }, "node_modules/react-is": { "version": "17.0.2", @@ -5069,7 +5636,6 @@ "version": "1.5.4", "resolved": "https://registry.npmjs.org/react-lottie-player/-/react-lottie-player-1.5.4.tgz", "integrity": "sha512-eM0g11bAc4EJJuDDfCoNloaAYphfXlIpYnriOt4nRU66PpVmvKhajvP2aif4YflGY2ArAFXhWxs418YzdebK9w==", - "dev": true, "dependencies": { "fast-deep-equal": "^3.1.3", "lottie-web": "^5.7.6", @@ -5086,7 +5652,6 @@ "version": "2.3.0", "resolved": "https://registry.npmjs.org/react-popper/-/react-popper-2.3.0.tgz", "integrity": "sha512-e1hj8lL3uM+sgSR4Lxzn5h1GxBlpa4CQz0XLF8kx4MDrDRWY0Ena4c97PUeSX9i5W3UAfDP0z0FXCTQkoXUl3Q==", - "dev": true, "dependencies": { "react-fast-compare": "^3.0.1", "warning": "^4.0.2" @@ -5106,6 +5671,14 @@ "node": ">=0.10.0" } }, + "node_modules/read-cache": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/read-cache/-/read-cache-1.0.0.tgz", + "integrity": "sha512-Owdv/Ft7IjOgm/i0xvNDZ1LrRANRfew4b2prF3OWMQLxLfu3bS8FVhCsrSCMK4lR56Y9ya+AThoTpDCTxCmpRA==", + "dependencies": { + "pify": "^2.3.0" + } + }, "node_modules/readable-stream": { "version": "3.6.2", "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.2.tgz", @@ -5120,6 +5693,17 @@ "node": ">= 6" } }, + "node_modules/readdirp": { + "version": "3.6.0", + "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-3.6.0.tgz", + "integrity": "sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA==", + "dependencies": { + "picomatch": "^2.2.1" + }, + "engines": { + "node": ">=8.10.0" + } + }, "node_modules/regenerator-runtime": { "version": "0.13.11", "resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.13.11.tgz", @@ -5152,13 +5736,20 @@ "node": ">=0.10.0" } }, - "node_modules/require-from-string": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/require-from-string/-/require-from-string-2.0.2.tgz", - "integrity": "sha512-Xf0nWe6RseziFMu+Ap9biiUbmplq6S9/p+7w7YXP/JBHhrUDDUhwa+vANyubuqfZWTveU//DYVGsDG7RKL/vEw==", - "dev": true, - "engines": { - "node": ">=0.10.0" + "node_modules/resolve": { + "version": "1.22.2", + "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.22.2.tgz", + "integrity": "sha512-Sb+mjNHOULsBv818T40qSPeRiuWLyaGMa5ewydRLFimneixmVy2zdivRl+AF6jaYPC8ERxGDmFSiqui6SfPd+g==", + "dependencies": { + "is-core-module": "^2.11.0", + "path-parse": "^1.0.7", + "supports-preserve-symlinks-flag": "^1.0.0" + }, + "bin": { + "resolve": "bin/resolve" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" } }, "node_modules/resolve-from": { @@ -5174,7 +5765,6 @@ "version": "1.0.4", "resolved": "https://registry.npmjs.org/reusify/-/reusify-1.0.4.tgz", "integrity": "sha512-U9nH88a3fc/ekCF1l0/UP1IosiuIjyTh7hBvXVMHYgVcfGvt897Xguj2UOLDeI5BG2m7/uwyaLVT6fbtCwTyzw==", - "dev": true, "engines": { "iojs": ">=1.0.0", "node": ">=0.10.0" @@ -5183,8 +5773,7 @@ "node_modules/rfdc": { "version": "1.3.0", "resolved": "https://registry.npmjs.org/rfdc/-/rfdc-1.3.0.tgz", - "integrity": "sha512-V2hovdzFbOi77/WajaSMXk2OLm+xNIeQdMMuB7icj7bk6zi2F8GGAxigcnDFpJHbNyNcgyJDiP+8nOrY5cZGrA==", - "dev": true + "integrity": "sha512-V2hovdzFbOi77/WajaSMXk2OLm+xNIeQdMMuB7icj7bk6zi2F8GGAxigcnDFpJHbNyNcgyJDiP+8nOrY5cZGrA==" }, "node_modules/rimraf": { "version": "3.0.2", @@ -5241,7 +5830,6 @@ "version": "1.2.0", "resolved": "https://registry.npmjs.org/run-parallel/-/run-parallel-1.2.0.tgz", "integrity": "sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA==", - "dev": true, "funding": [ { "type": "github", @@ -5290,7 +5878,6 @@ "version": "0.23.0", "resolved": "https://registry.npmjs.org/scheduler/-/scheduler-0.23.0.tgz", "integrity": "sha512-CtuThmgHNg7zIZWAXi3AsyIzA3n4xx7aNyjwC2VJldO2LMVDhFK+63xGqq6CsJH4rTAt6/M+N4GhZiDYPx9eUw==", - "dev": true, "dependencies": { "loose-envify": "^1.1.0" } @@ -5384,6 +5971,15 @@ "integrity": "sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ==", "dev": true }, + "node_modules/slash": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/slash/-/slash-3.0.0.tgz", + "integrity": "sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==", + "dev": true, + "engines": { + "node": ">=8" + } + }, "node_modules/source-map": { "version": "0.6.1", "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", @@ -5397,7 +5993,6 @@ "version": "1.0.2", "resolved": "https://registry.npmjs.org/source-map-js/-/source-map-js-1.0.2.tgz", "integrity": "sha512-R0XvVJ9WusLiqTCEiGCmICCMplcCkIwwR11mOSD9CR5u+IXYdiseeEuXCVAjS54zqwkLcPNnmU4OeJ6tUrWhDw==", - "dev": true, "engines": { "node": ">=0.10.0" } @@ -5471,6 +6066,15 @@ "node": ">=8" } }, + "node_modules/strip-final-newline": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/strip-final-newline/-/strip-final-newline-2.0.0.tgz", + "integrity": "sha512-BrpvfNAE3dcvq7ll3xVumzjKjZQ5tI1sEUIKr3Uoks0XUl45St3FlatVqef9prk4jRDzhW6WZg+3bk93y6pLjA==", + "dev": true, + "engines": { + "node": ">=6" + } + }, "node_modules/strip-json-comments": { "version": "3.1.1", "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-3.1.1.tgz", @@ -5507,6 +6111,54 @@ "node": ">=0.4.0" } }, + "node_modules/sucrase": { + "version": "3.32.0", + "resolved": "https://registry.npmjs.org/sucrase/-/sucrase-3.32.0.tgz", + "integrity": "sha512-ydQOU34rpSyj2TGyz4D2p8rbktIOZ8QY9s+DGLvFU1i5pWJE8vkpruCjGCMHsdXwnD7JDcS+noSwM/a7zyNFDQ==", + "dependencies": { + "@jridgewell/gen-mapping": "^0.3.2", + "commander": "^4.0.0", + "glob": "7.1.6", + "lines-and-columns": "^1.1.6", + "mz": "^2.7.0", + "pirates": "^4.0.1", + "ts-interface-checker": "^0.1.9" + }, + "bin": { + "sucrase": "bin/sucrase", + "sucrase-node": "bin/sucrase-node" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/sucrase/node_modules/commander": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/commander/-/commander-4.1.1.tgz", + "integrity": "sha512-NOKm8xhkzAjzFx8B2v5OAHT+u5pRQc2UCa2Vq9jYL/31o2wi9mxBA7LIFs3sV5VSC49z6pEhfbMULvShKj26WA==", + "engines": { + "node": ">= 6" + } + }, + "node_modules/sucrase/node_modules/glob": { + "version": "7.1.6", + "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.6.tgz", + "integrity": "sha512-LwaxwyZ72Lk7vZINtNNrywX0ZuLyStrdDtabefZKAY5ZGJhVtgdznluResxNmPitE0SAO+O26sWTHeKSI2wMBA==", + "dependencies": { + "fs.realpath": "^1.0.0", + "inflight": "^1.0.4", + "inherits": "2", + "minimatch": "^3.0.4", + "once": "^1.3.0", + "path-is-absolute": "^1.0.0" + }, + "engines": { + "node": "*" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, "node_modules/supports-color": { "version": "5.5.0", "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", @@ -5519,12 +6171,60 @@ "node": ">=4" } }, + "node_modules/supports-preserve-symlinks-flag": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/supports-preserve-symlinks-flag/-/supports-preserve-symlinks-flag-1.0.0.tgz", + "integrity": "sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==", + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, "node_modules/synchronous-promise": { "version": "2.0.17", "resolved": "https://registry.npmjs.org/synchronous-promise/-/synchronous-promise-2.0.17.tgz", "integrity": "sha512-AsS729u2RHUfEra9xJrE39peJcc2stq2+poBXX8bcM08Y6g9j/i/PUzwNQqkaJde7Ntg1TO7bSREbR5sdosQ+g==", "dev": true }, + "node_modules/tailwindcss": { + "version": "3.3.2", + "resolved": "https://registry.npmjs.org/tailwindcss/-/tailwindcss-3.3.2.tgz", + "integrity": "sha512-9jPkMiIBXvPc2KywkraqsUfbfj+dHDb+JPWtSJa9MLFdrPyazI7q6WX2sUrm7R9eVR7qqv3Pas7EvQFzxKnI6w==", + "dependencies": { + "@alloc/quick-lru": "^5.2.0", + "arg": "^5.0.2", + "chokidar": "^3.5.3", + "didyoumean": "^1.2.2", + "dlv": "^1.1.3", + "fast-glob": "^3.2.12", + "glob-parent": "^6.0.2", + "is-glob": "^4.0.3", + "jiti": "^1.18.2", + "lilconfig": "^2.1.0", + "micromatch": "^4.0.5", + "normalize-path": "^3.0.0", + "object-hash": "^3.0.0", + "picocolors": "^1.0.0", + "postcss": "^8.4.23", + "postcss-import": "^15.1.0", + "postcss-js": "^4.0.1", + "postcss-load-config": "^4.0.1", + "postcss-nested": "^6.0.1", + "postcss-selector-parser": "^6.0.11", + "postcss-value-parser": "^4.2.0", + "resolve": "^1.22.2", + "sucrase": "^3.32.0" + }, + "bin": { + "tailwind": "lib/cli.js", + "tailwindcss": "lib/cli.js" + }, + "engines": { + "node": ">=14.0.0" + } + }, "node_modules/tapable": { "version": "2.2.1", "resolved": "https://registry.npmjs.org/tapable/-/tapable-2.2.1.tgz", @@ -5647,6 +6347,25 @@ "integrity": "sha512-N+8UisAXDGk8PFXP4HAzVR9nbfmVJ3zYLAWiTIoqC5v5isinhr+r5uaO8+7r3BMfuNIufIsA7RdpVgacC2cSpw==", "dev": true }, + "node_modules/thenify": { + "version": "3.3.1", + "resolved": "https://registry.npmjs.org/thenify/-/thenify-3.3.1.tgz", + "integrity": "sha512-RVZSIV5IG10Hk3enotrhvz0T9em6cyHBLkH/YAZuKqd8hRkKhSfCGIcP2KUY0EPxndzANBmNllzWPwak+bheSw==", + "dependencies": { + "any-promise": "^1.0.0" + } + }, + "node_modules/thenify-all": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/thenify-all/-/thenify-all-1.6.0.tgz", + "integrity": "sha512-RNxQH/qI8/t3thXJDwcstUO4zeqo64+Uy/+sNVRBx4Xn2OX+OZ9oP+iJnNFqplFra2ZUVeKCSa2oVWi3T4uVmA==", + "dependencies": { + "thenify": ">= 3.1.0 < 4" + }, + "engines": { + "node": ">=0.8" + } + }, "node_modules/time-zone": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/time-zone/-/time-zone-1.0.0.tgz", @@ -5689,12 +6408,32 @@ "node": ">=4" } }, - "node_modules/tr46": { - "version": "0.0.3", - "resolved": "https://registry.npmjs.org/tr46/-/tr46-0.0.3.tgz", + "node_modules/to-regex-range": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz", + "integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==", + "dependencies": { + "is-number": "^7.0.0" + }, + "engines": { + "node": ">=8.0" + } + }, + "node_modules/tr46": { + "version": "0.0.3", + "resolved": "https://registry.npmjs.org/tr46/-/tr46-0.0.3.tgz", "integrity": "sha512-N3WMsuqV66lT30CrXNbEjx4GEwlow3v6rr4mCcv6prnfwhS01rkgyFdjPNBYd9br7LpXV1+Emh01fHnq2Gdgrw==", "dev": true }, + "node_modules/tree-kill": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/tree-kill/-/tree-kill-1.2.2.tgz", + "integrity": "sha512-L0Orpi8qGpRG//Nd+H90vFB+3iHnue1zSSGmNOOCh1GLJ7rUKVwV2HvijphGQS2UmhUZewS9VgvxYIdgr+fG1A==", + "dev": true, + "bin": { + "tree-kill": "cli.js" + } + }, "node_modules/ts-dedent": { "version": "2.2.0", "resolved": "https://registry.npmjs.org/ts-dedent/-/ts-dedent-2.2.0.tgz", @@ -5704,6 +6443,483 @@ "node": ">=6.10" } }, + "node_modules/ts-interface-checker": { + "version": "0.1.13", + "resolved": "https://registry.npmjs.org/ts-interface-checker/-/ts-interface-checker-0.1.13.tgz", + "integrity": "sha512-Y/arvbn+rrz3JCKl9C4kVNfTfSm2/mEp5FSz5EsZSANGPSlQrpRI5M4PKF+mJnE52jOO90PnPSc3Ur3bTQw0gA==" + }, + "node_modules/tsup": { + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/tsup/-/tsup-7.1.0.tgz", + "integrity": "sha512-mazl/GRAk70j8S43/AbSYXGgvRP54oQeX8Un4iZxzATHt0roW0t6HYDVZIXMw0ZQIpvr1nFMniIVnN5186lW7w==", + "dev": true, + "dependencies": { + "bundle-require": "^4.0.0", + "cac": "^6.7.12", + "chokidar": "^3.5.1", + "debug": "^4.3.1", + "esbuild": "^0.18.2", + "execa": "^5.0.0", + "globby": "^11.0.3", + "joycon": "^3.0.1", + "postcss-load-config": "^4.0.1", + "resolve-from": "^5.0.0", + "rollup": "^3.2.5", + "source-map": "0.8.0-beta.0", + "sucrase": "^3.20.3", + "tree-kill": "^1.2.2" + }, + "bin": { + "tsup": "dist/cli-default.js", + "tsup-node": "dist/cli-node.js" + }, + "engines": { + "node": ">=16.14" + }, + "peerDependencies": { + "@swc/core": "^1", + "postcss": "^8.4.12", + "typescript": ">=4.1.0" + }, + "peerDependenciesMeta": { + "@swc/core": { + "optional": true + }, + "postcss": { + "optional": true + }, + "typescript": { + "optional": true + } + } + }, + "node_modules/tsup/node_modules/@esbuild/android-arm": { + "version": "0.18.10", + "resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.18.10.tgz", + "integrity": "sha512-3KClmVNd+Fku82uZJz5C4Rx8m1PPmWUFz5Zkw8jkpZPOmsq+EG1TTOtw1OXkHuX3WczOFQigrtf60B1ijKwNsg==", + "cpu": [ + "arm" + ], + "dev": true, + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/tsup/node_modules/@esbuild/android-arm64": { + "version": "0.18.10", + "resolved": "https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.18.10.tgz", + "integrity": "sha512-ynm4naLbNbK0ajf9LUWtQB+6Vfg1Z/AplArqr4tGebC00Z6m9Y91OVIcjDa461wGcZwcaHYaZAab4yJxfhisTQ==", + "cpu": [ + "arm64" + ], + "dev": true, + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/tsup/node_modules/@esbuild/android-x64": { + "version": "0.18.10", + "resolved": "https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.18.10.tgz", + "integrity": "sha512-vFfXj8P9Yfjh54yqUDEHKzqzYuEfPyAOl3z7R9hjkwt+NCvbn9VMxX+IILnAfdImRBfYVItgSUsqGKhJFnBwZw==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/tsup/node_modules/@esbuild/darwin-arm64": { + "version": "0.18.10", + "resolved": "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.18.10.tgz", + "integrity": "sha512-k2OJQ7ZxE6sVc91+MQeZH9gFeDAH2uIYALPAwTjTCvcPy9Dzrf7V7gFUQPYkn09zloWhQ+nvxWHia2x2ZLR0sQ==", + "cpu": [ + "arm64" + ], + "dev": true, + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/tsup/node_modules/@esbuild/darwin-x64": { + "version": "0.18.10", + "resolved": "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.18.10.tgz", + "integrity": "sha512-tnz/mdZk1L1Z3WpGjin/L2bKTe8/AKZpI8fcCLtH+gq8WXWsCNJSxlesAObV4qbtTl6pG5vmqFXfWUQ5hV8PAQ==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/tsup/node_modules/@esbuild/freebsd-arm64": { + "version": "0.18.10", + "resolved": "https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.18.10.tgz", + "integrity": "sha512-QJluV0LwBrbHnYYwSKC+K8RGz0g/EyhpQH1IxdoFT0nM7PfgjE+aS8wxq/KFEsU0JkL7U/EEKd3O8xVBxXb2aA==", + "cpu": [ + "arm64" + ], + "dev": true, + "optional": true, + "os": [ + "freebsd" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/tsup/node_modules/@esbuild/freebsd-x64": { + "version": "0.18.10", + "resolved": "https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.18.10.tgz", + "integrity": "sha512-Hi/ycUkS6KTw+U9G5PK5NoK7CZboicaKUSVs0FSiPNtuCTzK6HNM4DIgniH7hFaeuszDS9T4dhAHWiLSt/Y5Ng==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "freebsd" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/tsup/node_modules/@esbuild/linux-arm": { + "version": "0.18.10", + "resolved": "https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.18.10.tgz", + "integrity": "sha512-HfFoxY172tVHPIvJy+FHxzB4l8xU7e5cxmNS11cQ2jt4JWAukn/7LXaPdZid41UyTweqa4P/1zs201gRGCTwHw==", + "cpu": [ + "arm" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/tsup/node_modules/@esbuild/linux-arm64": { + "version": "0.18.10", + "resolved": "https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.18.10.tgz", + "integrity": "sha512-Nz6XcfRBOO7jSrVpKAyEyFOPGhySPNlgumSDhWAspdQQ11ub/7/NZDMhWDFReE9QH/SsCOCLQbdj0atAk/HMOQ==", + "cpu": [ + "arm64" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/tsup/node_modules/@esbuild/linux-ia32": { + "version": "0.18.10", + "resolved": "https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.18.10.tgz", + "integrity": "sha512-otMdmSmkMe+pmiP/bZBjfphyAsTsngyT9RCYwoFzqrveAbux9nYitDTpdgToG0Z0U55+PnH654gCH2GQ1aB6Yw==", + "cpu": [ + "ia32" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/tsup/node_modules/@esbuild/linux-loong64": { + "version": "0.18.10", + "resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.18.10.tgz", + "integrity": "sha512-t8tjFuON1koxskzQ4VFoh0T5UDUMiLYjwf9Wktd0tx8AoK6xgU+5ubKOpWpcnhEQ2tESS5u0v6QuN8PX/ftwcQ==", + "cpu": [ + "loong64" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/tsup/node_modules/@esbuild/linux-mips64el": { + "version": "0.18.10", + "resolved": "https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.18.10.tgz", + "integrity": "sha512-+dUkcVzcfEJHz3HEnVpIJu8z8Wdn2n/nWMWdl6FVPFGJAVySO4g3+XPzNKFytVFwf8hPVDwYXzVcu8GMFqsqZw==", + "cpu": [ + "mips64el" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/tsup/node_modules/@esbuild/linux-ppc64": { + "version": "0.18.10", + "resolved": "https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.18.10.tgz", + "integrity": "sha512-sO3PjjxEGy+PY2qkGe2gwJbXdZN9wAYpVBZWFD0AwAoKuXRkWK0/zaMQ5ekUFJDRDCRm8x5U0Axaub7ynH/wVg==", + "cpu": [ + "ppc64" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/tsup/node_modules/@esbuild/linux-riscv64": { + "version": "0.18.10", + "resolved": "https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.18.10.tgz", + "integrity": "sha512-JDtdbJg3yjDeXLv4lZYE1kiTnxv73/8cbPHY9T/dUKi8rYOM/k5b3W4UJLMUksuQ6nTm5c89W1nADsql6FW75A==", + "cpu": [ + "riscv64" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/tsup/node_modules/@esbuild/linux-s390x": { + "version": "0.18.10", + "resolved": "https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.18.10.tgz", + "integrity": "sha512-NLuSKcp8WckjD2a7z5kzLiCywFwBTMlIxDNuud1AUGVuwBBJSkuubp6cNjJ0p5c6CZaA3QqUGwjHJBiG1SoOFw==", + "cpu": [ + "s390x" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/tsup/node_modules/@esbuild/linux-x64": { + "version": "0.18.10", + "resolved": "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.18.10.tgz", + "integrity": "sha512-wj2KRsCsFusli+6yFgNO/zmmLslislAWryJnodteRmGej7ZzinIbMdsyp13rVGde88zxJd5vercNYK9kuvlZaQ==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/tsup/node_modules/@esbuild/netbsd-x64": { + "version": "0.18.10", + "resolved": "https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.18.10.tgz", + "integrity": "sha512-pQ9QqxEPI3cVRZyUtCoZxhZK3If+7RzR8L2yz2+TDzdygofIPOJFaAPkEJ5rYIbUO101RaiYxfdOBahYexLk5A==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "netbsd" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/tsup/node_modules/@esbuild/openbsd-x64": { + "version": "0.18.10", + "resolved": "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.18.10.tgz", + "integrity": "sha512-k8GTIIW9I8pEEfoOUm32TpPMgSg06JhL5DO+ql66aLTkOQUs0TxCA67Wi7pv6z8iF8STCGcNbm3UWFHLuci+ag==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "openbsd" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/tsup/node_modules/@esbuild/sunos-x64": { + "version": "0.18.10", + "resolved": "https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.18.10.tgz", + "integrity": "sha512-vIGYJIdEI6d4JBucAx8py792G8J0GP40qSH+EvSt80A4zvGd6jph+5t1g+eEXcS2aRpgZw6CrssNCFZxTdEsxw==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "sunos" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/tsup/node_modules/@esbuild/win32-arm64": { + "version": "0.18.10", + "resolved": "https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.18.10.tgz", + "integrity": "sha512-kRhNcMZFGMW+ZHCarAM1ypr8OZs0k688ViUCetVCef9p3enFxzWeBg9h/575Y0nsFu0ZItluCVF5gMR2pwOEpA==", + "cpu": [ + "arm64" + ], + "dev": true, + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/tsup/node_modules/@esbuild/win32-ia32": { + "version": "0.18.10", + "resolved": "https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.18.10.tgz", + "integrity": "sha512-AR9PX1whYaYh9p0EOaKna0h48F/A101Mt/ag72+kMkkBZXPQ7cjbz2syXI/HI3OlBdUytSdHneljfjvUoqwqiQ==", + "cpu": [ + "ia32" + ], + "dev": true, + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/tsup/node_modules/@esbuild/win32-x64": { + "version": "0.18.10", + "resolved": "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.18.10.tgz", + "integrity": "sha512-5sTkYhAGHNRr6bVf4RM0PsscqVr6/DBYdrlMh168oph3usid3lKHcHEEHmr34iZ9GHeeg2juFOxtpl6XyC3tpw==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/tsup/node_modules/esbuild": { + "version": "0.18.10", + "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.18.10.tgz", + "integrity": "sha512-33WKo67auOXzZHBY/9DTJRo7kIvfU12S+D4sp2wIz39N88MDIaCGyCwbW01RR70pK6Iya0I74lHEpyLfFqOHPA==", + "dev": true, + "hasInstallScript": true, + "bin": { + "esbuild": "bin/esbuild" + }, + "engines": { + "node": ">=12" + }, + "optionalDependencies": { + "@esbuild/android-arm": "0.18.10", + "@esbuild/android-arm64": "0.18.10", + "@esbuild/android-x64": "0.18.10", + "@esbuild/darwin-arm64": "0.18.10", + "@esbuild/darwin-x64": "0.18.10", + "@esbuild/freebsd-arm64": "0.18.10", + "@esbuild/freebsd-x64": "0.18.10", + "@esbuild/linux-arm": "0.18.10", + "@esbuild/linux-arm64": "0.18.10", + "@esbuild/linux-ia32": "0.18.10", + "@esbuild/linux-loong64": "0.18.10", + "@esbuild/linux-mips64el": "0.18.10", + "@esbuild/linux-ppc64": "0.18.10", + "@esbuild/linux-riscv64": "0.18.10", + "@esbuild/linux-s390x": "0.18.10", + "@esbuild/linux-x64": "0.18.10", + "@esbuild/netbsd-x64": "0.18.10", + "@esbuild/openbsd-x64": "0.18.10", + "@esbuild/sunos-x64": "0.18.10", + "@esbuild/win32-arm64": "0.18.10", + "@esbuild/win32-ia32": "0.18.10", + "@esbuild/win32-x64": "0.18.10" + } + }, + "node_modules/tsup/node_modules/source-map": { + "version": "0.8.0-beta.0", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.8.0-beta.0.tgz", + "integrity": "sha512-2ymg6oRBpebeZi9UUNsgQ89bhx01TcTkmNTGnNO88imTmbSgy4nfujrgVEFKWpMTEGA11EDkTt7mqObTPdigIA==", + "dev": true, + "dependencies": { + "whatwg-url": "^7.0.0" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/tsup/node_modules/tr46": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/tr46/-/tr46-1.0.1.tgz", + "integrity": "sha512-dTpowEjclQ7Kgx5SdBkqRzVhERQXov8/l9Ft9dVM9fmg0W0KQSVaXX9T4i6twCPNtYiZM53lpSSUAwJbFPOHxA==", + "dev": true, + "dependencies": { + "punycode": "^2.1.0" + } + }, + "node_modules/tsup/node_modules/webidl-conversions": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-4.0.2.tgz", + "integrity": "sha512-YQ+BmxuTgd6UXZW3+ICGfyqRyHXVlD5GtQr5+qjiNW7bF0cqrzX500HVXPBOvgXb5YnzDd+h0zqyv61KUD7+Sg==", + "dev": true + }, + "node_modules/tsup/node_modules/whatwg-url": { + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-7.1.0.tgz", + "integrity": "sha512-WUu7Rg1DroM7oQvGWfOiAK21n74Gg+T4elXEQYkOhtyLeWiJFoOGLXPKI/9gzIie9CtwVLm8wtw6YJdKyxSjeg==", + "dev": true, + "dependencies": { + "lodash.sortby": "^4.7.0", + "tr46": "^1.0.1", + "webidl-conversions": "^4.0.2" + } + }, "node_modules/type-check": { "version": "0.4.0", "resolved": "https://registry.npmjs.org/type-check/-/type-check-0.4.0.tgz", @@ -5820,8 +7036,7 @@ "node_modules/util-deprecate": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", - "integrity": "sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==", - "dev": true + "integrity": "sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==" }, "node_modules/v8-to-istanbul": { "version": "9.1.0", @@ -6011,7 +7226,6 @@ "version": "4.0.3", "resolved": "https://registry.npmjs.org/warning/-/warning-4.0.3.tgz", "integrity": "sha512-rpJyN222KWIvHJ/F53XSZv0Zl/accqHR8et1kpaMTD/fLCRxtV8iX8czMzY7sVZupTI3zcUTg8eycS2kNF9l6w==", - "dev": true, "dependencies": { "loose-envify": "^1.0.0" } @@ -6348,8 +7562,7 @@ "node_modules/wrappy": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", - "integrity": "sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==", - "dev": true + "integrity": "sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==" }, "node_modules/y18n": { "version": "5.0.8", @@ -6366,6 +7579,14 @@ "integrity": "sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g==", "dev": true }, + "node_modules/yaml": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/yaml/-/yaml-2.3.1.tgz", + "integrity": "sha512-2eHWfjaoXgTBC2jNM1LRef62VQa0umtvRiDSk6HSzW7RvS5YtkabJrwYLLEKWBc8a5U2PTSCs+dJjUTJdlHsWQ==", + "engines": { + "node": ">= 14" + } + }, "node_modules/yargs": { "version": "16.2.0", "resolved": "https://registry.npmjs.org/yargs/-/yargs-16.2.0.tgz", diff --git a/apps/wing-console/console/design-system/package.json b/apps/wing-console/console/design-system/package.json index ba1c7b28ac3..fd827f60ae7 100644 --- a/apps/wing-console/console/design-system/package.json +++ b/apps/wing-console/console/design-system/package.json @@ -2,41 +2,56 @@ "name": "@wingconsole/design-system", "license": "SEE LICENSE IN LICENSE.md", "version": "0.0.0", - "private": true, - "exports": "./src/index.ts", + "type": "module", + "exports": { + ".": "./src/index.ts", + "./tailwind-plugin.cjs": "./tailwind-plugin.cjs" + }, "types": "./src/index.ts", - "files": [ - "dist" - ], + "publishConfig": { + "exports": "./dist/index.js", + "types": "./dist/index.d.ts", + "files": [ + "dist", + "tailwind-plugin.cjs" + ] + }, "scripts": { + "compile": "tsup", "tsc": "tsc --build", "eslint": "eslint --ext .js,.cjs,.ts,.cts,.mts,.tsx --no-error-on-unmatched-pattern . --fix", - "vitest": "vitest run --coverage --passWithNoTests" + "vitest": "vitest run --coverage --passWithNoTests", + "package": "bump-pack -b" }, - "devDependencies": { - "@babel/core": "^7.22.5", + "dependencies": { "@headlessui/react": "^1.7.15", "@heroicons/react": "^2.0.18", "@popperjs/core": "^2.11.8", + "@tailwindcss/forms": "^0.5.3", + "classnames": "^2.3.2", + "lodash.uniq": "^4.5.0", + "nanoid": "^4.0.2", + "react": "^18.2.0", + "react-dom": "^18.2.0", + "react-lottie-player": "^1.5.4", + "react-popper": "^2.3.0", + "tailwindcss": "^3.3.2" + }, + "devDependencies": { + "@babel/core": "^7.22.5", "@storybook/react": "^7.0.20", "@testing-library/react": "^14.0.0", - "@types/lodash": "^4.14.195", + "@types/lodash.uniq": "^4.5.7", "@types/react": "^18.2.12", "@types/react-dom": "^18.2.5", "@vitejs/plugin-react": "^4.0.0", "@vitest/coverage-c8": "^0.31.4", "@wingconsole/eslint-plugin": "file:../../tools/eslint-plugin", "@wingconsole/tsconfig": "file:../../tools/tsconfig", - "classnames": "^2.3.2", + "bump-pack": "file:../../../../tools/bump-pack", "eslint": "^8.42.0", "happy-dom": "^9.20.3", - "lodash": "^4.17.21", - "nanoid": "^4.0.2", - "react": "^18.2.0", - "react-dom": "^18.2.0", - "react-lottie-player": "^1.5.4", - "react-popper": "^2.3.0", - "require-from-string": "^2.0.2", + "tsup": "^7.1.0", "typescript": "^5.1.3", "vite": "^4.3.9", "vitest": "^0.31.4", diff --git a/apps/wing-console/console/design-system/project.json b/apps/wing-console/console/design-system/project.json new file mode 100644 index 00000000000..cd934857223 --- /dev/null +++ b/apps/wing-console/console/design-system/project.json @@ -0,0 +1,19 @@ +{ + "name": "console-design-system", + "$schema": "../../../../node_modules/nx/schemas/project-schema.json", + "implicitDependencies": [], + "targets": { + "build": { + "options": { + "command": "npm run compile", + "cwd": "apps/wing-console/console/design-system" + } + }, + "package": { + "options": { + "command": "npm run package", + "cwd": "apps/wing-console/console/design-system" + } + } + } +} diff --git a/apps/wing-console/console/design-system/src/tree.tsx b/apps/wing-console/console/design-system/src/tree.tsx index eaf4eea1ea3..aa7b8aaf1bf 100644 --- a/apps/wing-console/console/design-system/src/tree.tsx +++ b/apps/wing-console/console/design-system/src/tree.tsx @@ -1,5 +1,5 @@ import classNames from "classnames"; -import { uniq } from "lodash"; +import uniq from "lodash.uniq"; import { useState, KeyboardEvent, useEffect, Ref, useCallback } from "react"; import { useTheme } from "./theme-provider.js"; diff --git a/apps/wing-console/console/design-system/tailwind-plugin.cjs b/apps/wing-console/console/design-system/tailwind-plugin.cjs new file mode 100644 index 00000000000..0ac948f6427 --- /dev/null +++ b/apps/wing-console/console/design-system/tailwind-plugin.cjs @@ -0,0 +1,187 @@ +const colors = require("tailwindcss/colors"); +const defaultTheme = require("tailwindcss/defaultTheme"); +const flattenColorPalette = require("tailwindcss/lib/util/flattenColorPalette.js"); +const toColorValue = require("tailwindcss/lib/util/toColorValue.js"); +const plugin = require("tailwindcss/plugin"); + +const forms = require("@tailwindcss/forms"); + +/** + * Extracts the value of the RGB components an hexadecimal color. + * @param {string} color + * @returns {[number, number, number]} The decimal value of the RGB components + */ +const rgbFromColor = (color) => [ + Number.parseInt(color.slice(1, 3), 16), + Number.parseInt(color.slice(3, 5), 16), + Number.parseInt(color.slice(5, 7), 16), +]; + +/** + * Returns the value between two numbers. + * @param {number} value1 + * @param {number} value2 + * @returns + */ +const mixColorComponent = (value1, value2) => { + const max = Math.max(value1, value2); + const min = Math.min(value1, value2); + return Math.round(min + (max - min) / 2); +}; + +/** + * Mix two hexadecimal colors. + * @param {string} color1 + * @param {string} color2 + * @returns The mixed hexadecimal color. + * @example ```ts + * const color = mixColor("#666666", "#888888"); // "#777777" + * ``` + */ +const mixColor = (color1, color2) => { + const rgb1 = rgbFromColor(color1); + const rgb2 = rgbFromColor(color2); + const r = mixColorComponent(rgb1[0], rgb2[0]); + const g = mixColorComponent(rgb1[1], rgb2[1]); + const b = mixColorComponent(rgb1[2], rgb2[2]); + return `#${r.toString(16)}${g.toString(16)}${b.toString(16)}`; +}; + +const expandColor = (color) => { + return { + ...color, + 150: mixColor(color[100], color[200]), + 250: mixColor(color[200], color[300]), + 350: mixColor(color[300], color[400]), + 450: mixColor(color[400], color[500]), + 550: mixColor(color[500], color[600]), + 650: mixColor(color[600], color[700]), + 750: mixColor(color[700], color[800]), + 850: mixColor(color[800], color[900]), + }; +}; + +const scrollbarPlugin = + // Scrollbar plugin. + plugin(function ({ addUtilities, matchUtilities, addBase, theme }) { + addBase({ + ".scrollbar": { + "&": { + "border-color": "rgba(0, 0, 0, 0)", + }, + "&::-webkit-scrollbar, &::-webkit-scrollbar-thumb, &::-webkit-scrollbar-corner": + { + // add border to act as background-color + "border-right-style": "inset", + // sum viewport dimensions to guarantee border will fill scrollbar + "border-right-width": "calc(100vw + 100vh)", + // inherit border-color to inherit transitions + "border-color": "inherit", + }, + }, + }); + + const themeColors = flattenColorPalette.default(theme("colors")); + const colors = Object.fromEntries( + Object.entries(themeColors).map(([k, v]) => [k, toColorValue.default(v)]), + ); + matchUtilities( + { + "scrollbar-bg": (value) => ({ + "border-color": value, + }), + "scrollbar-thumb": (value) => ({ + "&::-webkit-scrollbar-thumb": { + "border-color": value, + }, + }), + "scrollbar-thumb-hover": (value) => ({ + "&::-webkit-scrollbar-thumb:hover, &:hover::-webkit-scrollbar-thumb:hover": + { + "border-color": value, + }, + }), + "scrollbar-thumb-active": (value) => ({ + "&::-webkit-scrollbar-thumb:active, &:hover::-webkit-scrollbar-thumb:active": + { + "border-color": value, + }, + }), + }, + { values: colors, type: "color" }, + ); + + const themeWidths = flattenColorPalette.default(theme("width")); + const widths = Object.entries(themeWidths).filter( + ([, size]) => size.endsWith("px") || size.endsWith("rem"), + ); + matchUtilities( + { + "scrollbar-w": (value) => ({ + "&::-webkit-scrollbar": { + width: Array.isArray(value) ? value[1] : value, + }, + }), + }, + { + values: widths, + type: ["absolute-size", "length"], + }, + ); + + const themeHeights = flattenColorPalette.default(theme("height")); + const heights = Object.entries(themeHeights).filter( + ([, size]) => size.endsWith("px") || size.endsWith("rem"), + ); + matchUtilities( + { + "scrollbar-h": (value) => ({ + "&::-webkit-scrollbar": { + height: Array.isArray(value) ? value[1] : value, + }, + }), + }, + { + values: heights, + type: ["absolute-size", "length"], + }, + ); + + addUtilities({ + ".overflow-overlay": { + overflow: ["scroll", "overlay"], + }, + ".overflow-x-overlay": { + "overflow-x": ["scroll", "overlay"], + }, + ".overflow-y-overlay": { + "overflow-y": ["scroll", "overlay"], + }, + }); + }); + +module.exports.plugins = [forms, scrollbarPlugin]; +module.exports.content = [ + `${__dirname}/src/**/*.{ts,tsx,js,jsx}`, + `${__dirname}/dist/index.js`, +]; +module.exports.theme = { + fontFamily: { + ...defaultTheme.fontFamily, + sans: ["IBM Plex Sans", ...defaultTheme.fontFamily.sans], + mono: ["IBM Plex Mono", ...defaultTheme.fontFamily.mono], + "share-tech": ["Share Tech Mono", ...defaultTheme.fontFamily.mono], + }, + extend: { + colors: { + gray: expandColor(colors.gray), + slate: expandColor(colors.slate), + "monada-light": "#AEF8EC", + "monada-dark": "#2ad5c1", + "monada-black": "#03120E", + }, + fontSize: { + "2xs": "0.7rem", + }, + }, +}; diff --git a/apps/wing-console/console/design-system/tsup.config.ts b/apps/wing-console/console/design-system/tsup.config.ts new file mode 100644 index 00000000000..7a3d66a9c8b --- /dev/null +++ b/apps/wing-console/console/design-system/tsup.config.ts @@ -0,0 +1,8 @@ +import { defineConfig } from "tsup"; + +export default defineConfig({ + entry: ["src/index.ts"], + format: ["esm"], + dts: true, + clean: true, +}); diff --git a/apps/wing-console/console/server/package-lock.json b/apps/wing-console/console/server/package-lock.json index c9c20a0ef01..484b7ddb5e8 100644 --- a/apps/wing-console/console/server/package-lock.json +++ b/apps/wing-console/console/server/package-lock.json @@ -152,7 +152,7 @@ "eslint-plugin-prettier": "^4.2.1", "eslint-plugin-sort-exports": "^0.8.0", "fs-extra": "^10.1.0", - "jsii": "~5.0.0", + "jsii": "5.0.11", "jsii-diff": "^1.73.0", "jsii-pacmak": "^1.73.0", "nanoid": "^3.3.4", diff --git a/apps/wing-console/console/server/package.json b/apps/wing-console/console/server/package.json index f4a58812d69..73014ea2e74 100644 --- a/apps/wing-console/console/server/package.json +++ b/apps/wing-console/console/server/package.json @@ -18,11 +18,11 @@ "package": "bump-pack -b" }, "dependencies": { - "@winglang/compiler": "file:../../../../libs/wingcompiler", - "@winglang/sdk": "file:../../../../libs/wingsdk", "codespan-wasm": "^0.4.0", "debug": "^4.3.4", - "ms": "^2.1.3" + "ms": "^2.1.3", + "@winglang/compiler": "file:../../../../libs/wingcompiler", + "@winglang/sdk": "file:../../../../libs/wingsdk" }, "devDependencies": { "@trpc/server": "^10.30.0", @@ -52,4 +52,4 @@ "ws": "^8.13.0", "zod": "^3.21.4" } -} +} \ No newline at end of file diff --git a/apps/wing-console/console/server/src/expressServer.ts b/apps/wing-console/console/server/src/expressServer.ts index df610920f5d..f00a8b5a68d 100644 --- a/apps/wing-console/console/server/src/expressServer.ts +++ b/apps/wing-console/console/server/src/expressServer.ts @@ -51,8 +51,6 @@ export const createExpressServer = async ({ const app = express(); app.use(cors()); - onExpressCreated?.(app); - const { router } = mergeAllRouters(); const createContext = (): RouterContext => { return { @@ -83,6 +81,10 @@ export const createExpressServer = async ({ createContext, }), ); + + // Allow extending the express app (after trpc is set up). + onExpressCreated?.(app); + log.info("Looking for an open port"); const port = await getPort({ port: requestedPort }); const server = app.listen(port); diff --git a/apps/wing-console/console/server/src/index.ts b/apps/wing-console/console/server/src/index.ts index 32f226ab8b6..d2a7f4db752 100644 --- a/apps/wing-console/console/server/src/index.ts +++ b/apps/wing-console/console/server/src/index.ts @@ -24,8 +24,13 @@ export type { Updater, UpdaterStatus } from "./updater.js"; export type { Config } from "./config.js"; export type { Router } from "./router/index.js"; export type { HostUtils } from "./hostUtils.js"; +export type { RouterContext } from "./utils/createRouter.js"; +export type { MapNode, MapEdge } from "./router/app.js"; +export type { InternalTestResult } from "./router/test.js"; +export type { Column } from "./router/table.js"; +export type { NodeDisplay } from "./utils/constructTreeNodeMap.js"; -type RouteNames = keyof inferRouterInputs | undefined; +export type RouteNames = keyof inferRouterInputs | undefined; export interface CreateConsoleServerOptions { wingfile: string; diff --git a/apps/wing-console/console/server/src/utils/compiler.ts b/apps/wing-console/console/server/src/utils/compiler.ts index 3421bd66c20..313de81aa17 100644 --- a/apps/wing-console/console/server/src/utils/compiler.ts +++ b/apps/wing-console/console/server/src/utils/compiler.ts @@ -21,14 +21,7 @@ export interface Compiler { ): void; } -const deduceSimfile = (wingfile: string): string => { - const dirname = path.dirname(wingfile); - const basename = path.basename(wingfile, ".w"); - return path.resolve(dirname, "target", `${basename}.wsim`); -}; - export const createCompiler = (wingfile: string): Compiler => { - const simfile = deduceSimfile(wingfile); const events = new Emittery(); let isCompiling = false; let shouldCompileAgain = false; @@ -41,7 +34,7 @@ export const createCompiler = (wingfile: string): Compiler => { try { isCompiling = true; await events.emit("compiling"); - const outdir = await wing.compile(wingfile, { + const simfile = await wing.compile(wingfile, { target: wing.Target.SIM, }); await events.emit("compiled", { simfile }); diff --git a/apps/wing-console/console/ui/package-lock.json b/apps/wing-console/console/ui/package-lock.json index 84132363189..e198b222e9d 100644 --- a/apps/wing-console/console/ui/package-lock.json +++ b/apps/wing-console/console/ui/package-lock.json @@ -8,11 +8,32 @@ "name": "@wingconsole/ui", "version": "0.0.0", "license": "SEE LICENSE IN LICENSE.md", - "devDependencies": { - "@babel/core": "^7.22.5", + "dependencies": { "@headlessui/react": "^1.7.15", "@heroicons/react": "^2.0.18", "@popperjs/core": "^2.11.8", + "@tanstack/react-query": "^4.29.12", + "@trpc/client": "^10.30.0", + "@trpc/react-query": "^10.30.0", + "@trpc/server": "^10.30.0", + "@wingconsole/design-system": "file:../design-system", + "classnames": "^2.3.2", + "d3-selection": "^3.0.0", + "d3-zoom": "^3.0.0", + "elkjs": "^0.8.2", + "framer-motion": "^10.12.16", + "jszip": "^3.10.1", + "lodash.debounce": "^4.0.8", + "lodash.throttle": "^4.1.1", + "lodash.uniqby": "^4.7.0", + "nanoid": "^4.0.2", + "react": "^18.2.0", + "react-dom": "^18.2.0", + "react-lottie-player": "^1.5.4", + "zod": "^3.21.4" + }, + "devDependencies": { + "@babel/core": "^7.22.5", "@storybook/addon-essentials": "^7.0.20", "@storybook/addon-interactions": "^7.0.20", "@storybook/addon-links": "^7.0.20", @@ -20,49 +41,47 @@ "@storybook/react": "^7.0.20", "@storybook/react-vite": "^7.0.20", "@storybook/testing-library": "^0.1.0", - "@tanstack/react-query": "^4.29.12", - "@trpc/client": "^10.30.0", - "@trpc/react-query": "^10.30.0", - "@trpc/server": "^10.30.0", "@types/cors": "^2.8.13", "@types/d3-selection": "^3.0.5", "@types/d3-zoom": "^3.0.3", - "@types/lodash": "^4.14.195", + "@types/lodash.debounce": "^4.0.7", "@types/lodash.throttle": "^4.1.7", "@types/lodash.uniqby": "^4.7.7", "@types/react": "^18.2.12", "@types/react-dom": "^18.2.5", "@vitejs/plugin-react-swc": "^3.3.2", - "@wingconsole/design-system": "file:../design-system", "@wingconsole/eslint-plugin": "file:../../tools/eslint-plugin", "@wingconsole/server": "file:../server", "@wingconsole/tsconfig": "file:../../tools/tsconfig", "@wingconsole/use-loading": "file:../../packages/use-loading", - "classnames": "^2.3.2", - "constructs": "^10.2.51", - "d3-selection": "^3.0.0", - "d3-zoom": "^3.0.0", - "elkjs": "^0.8.2", - "esbuild-plugin-external-global": "^1.0.1", + "autoprefixer": "^10.4.14", + "bump-pack": "file:../../../../tools/bump-pack", "eslint": "^8.42.0", - "framer-motion": "^10.12.16", - "jszip": "^3.10.1", - "lodash": "^4.17.21", - "lodash.throttle": "^4.1.1", - "lodash.uniqby": "^4.7.0", - "nanoid": "^4.0.2", - "react": "^18.2.0", - "react-dom": "^18.2.0", - "react-lottie-player": "^1.5.4", - "react-use": "^17.4.0", - "require-from-string": "^2.0.2", "storybook": "^7.0.20", + "tailwindcss": "^3.3.2", "tsup": "^6.7.0", "typescript": "^5.1.3", "vite": "^4.3.9", "vitest": "^0.31.4", - "webpack": "^5.86.0", - "zod": "^3.21.4" + "webpack": "^5.86.0" + } + }, + "../../../../tools/bump-pack": { + "version": "0.0.0", + "dev": true, + "dependencies": { + "changelogen": "^0.5.3", + "npm-which": "^3.0.1", + "semver": "^7.5.2", + "tsx": "^3.12.7" + }, + "bin": { + "bump-pack": "bin/bump-pack.cjs" + }, + "devDependencies": { + "@types/node": "^18.16.18", + "@types/semver": "^7.5.0", + "typescript": "^5.1.3" } }, "../../packages/use-loading": { @@ -119,32 +138,36 @@ "../design-system": { "name": "@wingconsole/design-system", "version": "0.0.0", - "dev": true, "license": "SEE LICENSE IN LICENSE.md", - "devDependencies": { - "@babel/core": "^7.22.5", + "dependencies": { "@headlessui/react": "^1.7.15", "@heroicons/react": "^2.0.18", "@popperjs/core": "^2.11.8", + "@tailwindcss/forms": "^0.5.3", + "classnames": "^2.3.2", + "lodash.uniq": "^4.5.0", + "nanoid": "^4.0.2", + "react": "^18.2.0", + "react-dom": "^18.2.0", + "react-lottie-player": "^1.5.4", + "react-popper": "^2.3.0", + "tailwindcss": "^3.3.2" + }, + "devDependencies": { + "@babel/core": "^7.22.5", "@storybook/react": "^7.0.20", "@testing-library/react": "^14.0.0", - "@types/lodash": "^4.14.195", + "@types/lodash.uniq": "^4.5.7", "@types/react": "^18.2.12", "@types/react-dom": "^18.2.5", "@vitejs/plugin-react": "^4.0.0", "@vitest/coverage-c8": "^0.31.4", "@wingconsole/eslint-plugin": "file:../../tools/eslint-plugin", "@wingconsole/tsconfig": "file:../../tools/tsconfig", - "classnames": "^2.3.2", + "bump-pack": "file:../../../../tools/bump-pack", "eslint": "^8.42.0", "happy-dom": "^9.20.3", - "lodash": "^4.17.21", - "nanoid": "^4.0.2", - "react": "^18.2.0", - "react-dom": "^18.2.0", - "react-lottie-player": "^1.5.4", - "react-popper": "^2.3.0", - "require-from-string": "^2.0.2", + "tsup": "^7.1.0", "typescript": "^5.1.3", "vite": "^4.3.9", "vitest": "^0.31.4", @@ -192,6 +215,18 @@ "zod": "^3.21.4" } }, + "node_modules/@alloc/quick-lru": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/@alloc/quick-lru/-/quick-lru-5.2.0.tgz", + "integrity": "sha512-UrcABB+4bUrFABwbluTIBErXwvbsU/V7TZWfmbgJfbkwiBuziS9gxdODUyuiecfdGQ85jglMW6juS3+z5TsKLw==", + "dev": true, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/@ampproject/remapping": { "version": "2.2.1", "resolved": "https://registry.npmjs.org/@ampproject/remapping/-/remapping-2.2.1.tgz", @@ -2420,7 +2455,6 @@ "version": "0.8.8", "resolved": "https://registry.npmjs.org/@emotion/is-prop-valid/-/is-prop-valid-0.8.8.tgz", "integrity": "sha512-u5WtneEAr5IDG2Wv65yhunPSMLIpuKsbuOktRojfrEiEvRyC85LgPMZI63cr7NUqT8ZIGdSVg8ZKGxIug4lXcA==", - "dev": true, "optional": true, "dependencies": { "@emotion/memoize": "0.7.4" @@ -2430,7 +2464,6 @@ "version": "0.7.4", "resolved": "https://registry.npmjs.org/@emotion/memoize/-/memoize-0.7.4.tgz", "integrity": "sha512-Ja/Vfqe3HpuzRsG1oBtWTHk2PGZ7GR+2Vz5iYGelAw8dx32K0y7PjVuxK6z1nMpZOqAFsRUPCkK1YjJ56qJlgw==", - "dev": true, "optional": true }, "node_modules/@emotion/use-insertion-effect-with-fallbacks": { @@ -2905,7 +2938,6 @@ "version": "1.7.15", "resolved": "https://registry.npmjs.org/@headlessui/react/-/react-1.7.15.tgz", "integrity": "sha512-OTO0XtoRQ6JPB1cKNFYBZv2Q0JMqMGNhYP1CjPvcJvjz8YGokz8oAj89HIYZGN0gZzn/4kk9iUpmMF4Q21Gsqw==", - "dev": true, "dependencies": { "client-only": "^0.0.1" }, @@ -2921,7 +2953,6 @@ "version": "2.0.18", "resolved": "https://registry.npmjs.org/@heroicons/react/-/react-2.0.18.tgz", "integrity": "sha512-7TyMjRrZZMBPa+/5Y8lN0iyvUU/01PeMGX2+RE7cQWpEUIcb4QotzUObFkJDejj/HUH4qjP/eQ0gzzKs2f+6Yw==", - "dev": true, "peerDependencies": { "react": ">= 16" } @@ -3408,7 +3439,6 @@ "version": "2.11.8", "resolved": "https://registry.npmjs.org/@popperjs/core/-/core-2.11.8.tgz", "integrity": "sha512-P1st0aksCrn9sGZhp8GMYwBnQsbvAWsZAX44oXNNvLHGqAOcoVxmjZiohstwQ7SqKnbR47akdNi+uleWD8+g6A==", - "dev": true, "funding": { "type": "opencollective", "url": "https://opencollective.com/popperjs" @@ -5455,7 +5485,6 @@ "version": "4.29.15", "resolved": "https://registry.npmjs.org/@tanstack/query-core/-/query-core-4.29.15.tgz", "integrity": "sha512-Recc1d5rjHesKhzlH3Aw66v+vQxtB9OHEXP/vxgEcEJ0DwEpfe3EQ4id20vuBJHY2XRjfgWGmUs6ZgK6PSsTXA==", - "dev": true, "funding": { "type": "github", "url": "https://github.com/sponsors/tannerlinsley" @@ -5465,7 +5494,6 @@ "version": "4.29.15", "resolved": "https://registry.npmjs.org/@tanstack/react-query/-/react-query-4.29.15.tgz", "integrity": "sha512-1zDkv95ljuJ623hhbYU8YIprPW2x6774kh3IQNEuZav62+S+Zr26uUOrE2zGRp9I1uO5Liw/0uYB3dWXQP5+3Q==", - "dev": true, "dependencies": { "@tanstack/query-core": "4.29.15", "use-sync-external-store": "^1.2.0" @@ -5579,7 +5607,6 @@ "version": "10.31.0", "resolved": "https://registry.npmjs.org/@trpc/client/-/client-10.31.0.tgz", "integrity": "sha512-VCqbJEvFJb8C4hQFw7AD+dkQTjgEdV/QAzO4D+/cX5e93u5NpfNXI+PKS0QFXwG/zqgwQwVV6OkYc/D/MFwA6g==", - "dev": true, "funding": [ "https://trpc.io/sponsor" ], @@ -5591,7 +5618,6 @@ "version": "10.31.0", "resolved": "https://registry.npmjs.org/@trpc/react-query/-/react-query-10.31.0.tgz", "integrity": "sha512-+M8sIsbf6e4H5XYvHlzDqhaf+ybfUigA/9OL3wXRp2vXhCedEiIERCnwNuHWFDRASl9vjOcM33AuJ4sbOOINEA==", - "dev": true, "funding": [ "https://trpc.io/sponsor" ], @@ -5607,7 +5633,6 @@ "version": "10.31.0", "resolved": "https://registry.npmjs.org/@trpc/server/-/server-10.31.0.tgz", "integrity": "sha512-9EnRTSDE9nF11LZsvSOqNKqkRYzHqFX4ch5AJ6VIu8uta2vxVTN4FxxsNRSOluTzVYZDeaCISbwmOJ5iihCCIg==", - "dev": true, "funding": [ "https://trpc.io/sponsor" ] @@ -5856,12 +5881,6 @@ "@types/istanbul-lib-report": "*" } }, - "node_modules/@types/js-cookie": { - "version": "2.2.7", - "resolved": "https://registry.npmjs.org/@types/js-cookie/-/js-cookie-2.2.7.tgz", - "integrity": "sha512-aLkWa0C0vO5b4Sr798E26QgOkss68Un0bLjs7u9qxzPT5CG+8DuNTffWES58YzJs3hrVAOs1wonycqEBqNJubA==", - "dev": true - }, "node_modules/@types/json-schema": { "version": "7.0.12", "resolved": "https://registry.npmjs.org/@types/json-schema/-/json-schema-7.0.12.tgz", @@ -5874,6 +5893,15 @@ "integrity": "sha512-Hwx9EUgdwf2GLarOjQp5ZH8ZmblzcbTBC2wtQWNKARBSxM9ezRIAUpeDTgoQRAFB0+8CNWXVA9+MaSOzOF3nPg==", "dev": true }, + "node_modules/@types/lodash.debounce": { + "version": "4.0.7", + "resolved": "https://registry.npmjs.org/@types/lodash.debounce/-/lodash.debounce-4.0.7.tgz", + "integrity": "sha512-X1T4wMZ+gT000M2/91SYj0d/7JfeNZ9PeeOldSNoE/lunLeQXKvkmIumI29IaKMotU/ln/McOIvgzZcQ/3TrSA==", + "dev": true, + "dependencies": { + "@types/lodash": "*" + } + }, "node_modules/@types/lodash.throttle": { "version": "4.1.7", "resolved": "https://registry.npmjs.org/@types/lodash.throttle/-/lodash.throttle-4.1.7.tgz", @@ -6346,12 +6374,6 @@ "resolved": "../../packages/use-loading", "link": true }, - "node_modules/@xobotyi/scrollbar-width": { - "version": "1.9.5", - "resolved": "https://registry.npmjs.org/@xobotyi/scrollbar-width/-/scrollbar-width-1.9.5.tgz", - "integrity": "sha512-N8tkAACJx2ww8vFMneJmaAgmjAG1tnVBZJRLRcx061tmsLRZHSEZSLuGWnwPtunsSLvSqXQ2wfp7Mgqg1I+2dQ==", - "dev": true - }, "node_modules/@xtuc/ieee754": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/@xtuc/ieee754/-/ieee754-1.2.0.tgz", @@ -6575,6 +6597,12 @@ "node": ">= 6" } }, + "node_modules/arg": { + "version": "5.0.2", + "resolved": "https://registry.npmjs.org/arg/-/arg-5.0.2.tgz", + "integrity": "sha512-PYjyFOLKQ9y57JvQ6QLo8dAgNqswh8M1RMJYdQduT6xbWSgK36P/Z/v+p888pM69jMMfS8Xd8F6I1kQ/I9HUGg==", + "dev": true + }, "node_modules/argparse": { "version": "1.0.10", "resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.10.tgz", @@ -6672,6 +6700,39 @@ "integrity": "sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q==", "dev": true }, + "node_modules/autoprefixer": { + "version": "10.4.14", + "resolved": "https://registry.npmjs.org/autoprefixer/-/autoprefixer-10.4.14.tgz", + "integrity": "sha512-FQzyfOsTlwVzjHxKEqRIAdJx9niO6VCBCoEwax/VLSoQF29ggECcPuBqUMZ+u8jCZOPSy8b8/8KnuFbp0SaFZQ==", + "dev": true, + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/postcss/" + }, + { + "type": "tidelift", + "url": "https://tidelift.com/funding/github/npm/autoprefixer" + } + ], + "dependencies": { + "browserslist": "^4.21.5", + "caniuse-lite": "^1.0.30001464", + "fraction.js": "^4.2.0", + "normalize-range": "^0.1.2", + "picocolors": "^1.0.0", + "postcss-value-parser": "^4.2.0" + }, + "bin": { + "autoprefixer": "bin/autoprefixer" + }, + "engines": { + "node": "^10 || ^12 || >=14" + }, + "peerDependencies": { + "postcss": "^8.1.0" + } + }, "node_modules/available-typed-arrays": { "version": "1.0.5", "resolved": "https://registry.npmjs.org/available-typed-arrays/-/available-typed-arrays-1.0.5.tgz", @@ -7040,6 +7101,10 @@ "integrity": "sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ==", "dev": true }, + "node_modules/bump-pack": { + "resolved": "../../../../tools/bump-pack", + "link": true + }, "node_modules/bundle-require": { "version": "4.0.1", "resolved": "https://registry.npmjs.org/bundle-require/-/bundle-require-4.0.1.tgz", @@ -7130,6 +7195,15 @@ "node": ">=6" } }, + "node_modules/camelcase-css": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/camelcase-css/-/camelcase-css-2.0.1.tgz", + "integrity": "sha512-QOSvevhslijgYwRx6Rv7zKdMF8lbRmx+uQGx2+vDc+KI/eBnsy9kit5aj23AgGu3pa4t9AgwbnXWqS+iOY+2aA==", + "dev": true, + "engines": { + "node": ">= 6" + } + }, "node_modules/caniuse-lite": { "version": "1.0.30001506", "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001506.tgz", @@ -7266,8 +7340,7 @@ "node_modules/classnames": { "version": "2.3.2", "resolved": "https://registry.npmjs.org/classnames/-/classnames-2.3.2.tgz", - "integrity": "sha512-CSbhY4cFEJRe6/GQzIk5qXZ4Jeg5pcsP7b5peFSDpffpe1cqjASH/n9UTjBwOp6XpMSTwQ8Za2K5V02ueA7Tmw==", - "dev": true + "integrity": "sha512-CSbhY4cFEJRe6/GQzIk5qXZ4Jeg5pcsP7b5peFSDpffpe1cqjASH/n9UTjBwOp6XpMSTwQ8Za2K5V02ueA7Tmw==" }, "node_modules/clean-stack": { "version": "2.2.0", @@ -7320,8 +7393,7 @@ "node_modules/client-only": { "version": "0.0.1", "resolved": "https://registry.npmjs.org/client-only/-/client-only-0.0.1.tgz", - "integrity": "sha512-IV3Ou0jSMzZrd3pZ48nLkT9DA7Ag1pnPzaiQhpW7c3RbcqqzvzzVu+L8gfqMp/8IM2MQtSiqaCxrrcfu8I8rMA==", - "dev": true + "integrity": "sha512-IV3Ou0jSMzZrd3pZ48nLkT9DA7Ag1pnPzaiQhpW7c3RbcqqzvzzVu+L8gfqMp/8IM2MQtSiqaCxrrcfu8I8rMA==" }, "node_modules/cliui": { "version": "7.0.4", @@ -7565,15 +7637,6 @@ "integrity": "sha512-ty/fTekppD2fIwRvnZAVdeOiGd1c7YXEixbgJTNzqcxJWKQnjJ/V1bNEEE6hygpM3WjwHFUVK6HTjWSzV4a8sQ==", "dev": true }, - "node_modules/constructs": { - "version": "10.2.55", - "resolved": "https://registry.npmjs.org/constructs/-/constructs-10.2.55.tgz", - "integrity": "sha512-TjH8BRN9qpmjZqq0ixH1NqgPHam0tQJcMQ6puffM0Sj0dRPXaJAzOtbHpn24rhjE+90vIQ8jBAUO8v8Sdp1uAQ==", - "dev": true, - "engines": { - "node": ">= 16.14.0" - } - }, "node_modules/content-disposition": { "version": "0.5.4", "resolved": "https://registry.npmjs.org/content-disposition/-/content-disposition-0.5.4.tgz", @@ -7616,15 +7679,6 @@ "integrity": "sha512-QADzlaHc8icV8I7vbaJXJwod9HWYp8uCqf1xa4OfNu1T7JVxQIrUgOWtHdNDtPiywmFbiS12VjotIXLrKM3orQ==", "dev": true }, - "node_modules/copy-to-clipboard": { - "version": "3.3.3", - "resolved": "https://registry.npmjs.org/copy-to-clipboard/-/copy-to-clipboard-3.3.3.tgz", - "integrity": "sha512-2KV8NhB5JqC3ky0r9PMCAZKbUHSwtEo4CwCs0KXgruG43gX5PMqDEBbVU4OUzw2MuAWUfsuFmWvEKG5QRfSnJA==", - "dev": true, - "dependencies": { - "toggle-selection": "^1.0.6" - } - }, "node_modules/core-js-compat": { "version": "3.31.0", "resolved": "https://registry.npmjs.org/core-js-compat/-/core-js-compat-3.31.0.tgz", @@ -7641,8 +7695,7 @@ "node_modules/core-util-is": { "version": "1.0.3", "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.3.tgz", - "integrity": "sha512-ZQBvi1DcpJ4GDqanjucZ2Hj3wEO5pZDS89BWbkcrvdxksJorwUDDZamX9ldFkp9aw2lmBDLgkObEA4DWNJ9FYQ==", - "dev": true + "integrity": "sha512-ZQBvi1DcpJ4GDqanjucZ2Hj3wEO5pZDS89BWbkcrvdxksJorwUDDZamX9ldFkp9aw2lmBDLgkObEA4DWNJ9FYQ==" }, "node_modules/cross-spawn": { "version": "7.0.3", @@ -7667,26 +7720,16 @@ "node": ">=8" } }, - "node_modules/css-in-js-utils": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/css-in-js-utils/-/css-in-js-utils-3.1.0.tgz", - "integrity": "sha512-fJAcud6B3rRu+KHYk+Bwf+WFL2MDCJJ1XG9x137tJQ0xYxor7XziQtuGFbWNdqrvF4Tk26O3H73nfVqXt/fW1A==", - "dev": true, - "dependencies": { - "hyphenate-style-name": "^1.0.3" - } - }, - "node_modules/css-tree": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/css-tree/-/css-tree-1.1.3.tgz", - "integrity": "sha512-tRpdppF7TRazZrjJ6v3stzv93qxRcSsFmW6cX0Zm2NVKpxE1WV1HblnghVv9TreireHkqI/VDEsfolRF1p6y7Q==", + "node_modules/cssesc": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/cssesc/-/cssesc-3.0.0.tgz", + "integrity": "sha512-/Tb/JcjK111nNScGob5MNtsntNM1aCNUDipB/TkwZFhyDrrE47SOx/18wF2bbjgc3ZzCSKW1T5nt5EbFoAz/Vg==", "dev": true, - "dependencies": { - "mdn-data": "2.0.14", - "source-map": "^0.6.1" + "bin": { + "cssesc": "bin/cssesc" }, "engines": { - "node": ">=8.0.0" + "node": ">=4" } }, "node_modules/csstype": { @@ -7699,7 +7742,6 @@ "version": "3.1.0", "resolved": "https://registry.npmjs.org/d3-color/-/d3-color-3.1.0.tgz", "integrity": "sha512-zg/chbXyeBtMQ1LbD/WSoW2DpC3I0mpmPdW+ynRTj/x2DAWYrIY7qeZIHidozwV24m4iavr15lNwIwLxRmOxhA==", - "dev": true, "engines": { "node": ">=12" } @@ -7708,7 +7750,6 @@ "version": "3.0.1", "resolved": "https://registry.npmjs.org/d3-dispatch/-/d3-dispatch-3.0.1.tgz", "integrity": "sha512-rzUyPU/S7rwUflMyLc1ETDeBj0NRuHKKAcvukozwhshr6g6c5d8zh4c2gQjY2bZ0dXeGLWc1PF174P2tVvKhfg==", - "dev": true, "engines": { "node": ">=12" } @@ -7717,7 +7758,6 @@ "version": "3.0.0", "resolved": "https://registry.npmjs.org/d3-drag/-/d3-drag-3.0.0.tgz", "integrity": "sha512-pWbUJLdETVA8lQNJecMxoXfH6x+mO2UQo8rSmZ+QqxcbyA3hfeprFgIT//HW2nlHChWeIIMwS2Fq+gEARkhTkg==", - "dev": true, "dependencies": { "d3-dispatch": "1 - 3", "d3-selection": "3" @@ -7730,7 +7770,6 @@ "version": "3.0.1", "resolved": "https://registry.npmjs.org/d3-ease/-/d3-ease-3.0.1.tgz", "integrity": "sha512-wR/XK3D3XcLIZwpbvQwQ5fK+8Ykds1ip7A2Txe0yxncXSdq1L9skcG7blcedkOX+ZcgxGAmLX1FrRGbADwzi0w==", - "dev": true, "engines": { "node": ">=12" } @@ -7739,7 +7778,6 @@ "version": "3.0.1", "resolved": "https://registry.npmjs.org/d3-interpolate/-/d3-interpolate-3.0.1.tgz", "integrity": "sha512-3bYs1rOD33uo8aqJfKP3JWPAibgw8Zm2+L9vBKEHJ2Rg+viTR7o5Mmv5mZcieN+FRYaAOWX5SJATX6k1PWz72g==", - "dev": true, "dependencies": { "d3-color": "1 - 3" }, @@ -7751,7 +7789,6 @@ "version": "3.0.0", "resolved": "https://registry.npmjs.org/d3-selection/-/d3-selection-3.0.0.tgz", "integrity": "sha512-fmTRWbNMmsmWq6xJV8D19U/gw/bwrHfNXxrIN+HfZgnzqTHp9jOmKMhsTUjXOJnZOdZY9Q28y4yebKzqDKlxlQ==", - "dev": true, "engines": { "node": ">=12" } @@ -7760,7 +7797,6 @@ "version": "3.0.1", "resolved": "https://registry.npmjs.org/d3-timer/-/d3-timer-3.0.1.tgz", "integrity": "sha512-ndfJ/JxxMd3nw31uyKoY2naivF+r29V+Lc0svZxe1JvvIRmi8hUsrMvdOwgS1o6uBHmiz91geQ0ylPP0aj1VUA==", - "dev": true, "engines": { "node": ">=12" } @@ -7769,7 +7805,6 @@ "version": "3.0.1", "resolved": "https://registry.npmjs.org/d3-transition/-/d3-transition-3.0.1.tgz", "integrity": "sha512-ApKvfjsSR6tg06xrL434C0WydLr7JewBB3V+/39RMHsaXTOG0zmt/OAXeng5M5LBm0ojmxJrpomQVZ1aPvBL4w==", - "dev": true, "dependencies": { "d3-color": "1 - 3", "d3-dispatch": "1 - 3", @@ -7788,7 +7823,6 @@ "version": "3.0.0", "resolved": "https://registry.npmjs.org/d3-zoom/-/d3-zoom-3.0.0.tgz", "integrity": "sha512-b8AmV3kfQaqWAuacbPuNbL6vahnOJflOhexLzMMNLga62+/nh0JzvJ0aO/5a5MVgUFGS7Hu1P9P03o3fJkDCyw==", - "dev": true, "dependencies": { "d3-dispatch": "1 - 3", "d3-drag": "2 - 3", @@ -8035,6 +8069,12 @@ "detect-port": "bin/detect-port.js" } }, + "node_modules/didyoumean": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/didyoumean/-/didyoumean-1.2.2.tgz", + "integrity": "sha512-gxtyfqMg7GKyhQmb056K7M3xszy/myH8w+B4RT+QXBQsvAOdc3XymqDDPHx1BgPgsdAA5SIifona89YtRATDzw==", + "dev": true + }, "node_modules/dir-glob": { "version": "3.0.1", "resolved": "https://registry.npmjs.org/dir-glob/-/dir-glob-3.0.1.tgz", @@ -8047,6 +8087,12 @@ "node": ">=8" } }, + "node_modules/dlv": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/dlv/-/dlv-1.1.3.tgz", + "integrity": "sha512-+HlytyjlPKnIG8XuRG8WvmBP8xs8P71y+SKKS6ZXWoEgLuePxtDoUEiH7WkdePWrQ5JBpE6aoVqfZfJUQkjXwA==", + "dev": true + }, "node_modules/doctrine": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-3.0.0.tgz", @@ -8128,8 +8174,7 @@ "node_modules/elkjs": { "version": "0.8.2", "resolved": "https://registry.npmjs.org/elkjs/-/elkjs-0.8.2.tgz", - "integrity": "sha512-L6uRgvZTH+4OF5NE/MBbzQx/WYpru1xCBE9respNj6qznEewGUIfhzmm7horWWxbNO2M0WckQypGctR8lH79xQ==", - "dev": true + "integrity": "sha512-L6uRgvZTH+4OF5NE/MBbzQx/WYpru1xCBE9respNj6qznEewGUIfhzmm7horWWxbNO2M0WckQypGctR8lH79xQ==" }, "node_modules/emoji-regex": { "version": "8.0.0", @@ -8189,15 +8234,6 @@ "is-arrayish": "^0.2.1" } }, - "node_modules/error-stack-parser": { - "version": "2.1.4", - "resolved": "https://registry.npmjs.org/error-stack-parser/-/error-stack-parser-2.1.4.tgz", - "integrity": "sha512-Sk5V6wVazPhq5MhpO+AUxJn5x7XSXGl1R93Vn7i+zS15KDVxQijejNCrz8340/2bgLBjR9GtEG8ZVKONDjcqGQ==", - "dev": true, - "dependencies": { - "stackframe": "^1.3.4" - } - }, "node_modules/es-get-iterator": { "version": "1.1.3", "resolved": "https://registry.npmjs.org/es-get-iterator/-/es-get-iterator-1.1.3.tgz", @@ -8273,12 +8309,6 @@ "integrity": "sha512-jyfL/pwPqaFXyKnj8lP8iLk6Z0m099uXR45aSN8Av1XD4vhvQutxxPzgA2bTcAwQpa1zCXDcWOlhFgyP3GKqhQ==", "dev": true }, - "node_modules/esbuild-plugin-external-global": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/esbuild-plugin-external-global/-/esbuild-plugin-external-global-1.0.1.tgz", - "integrity": "sha512-NDzYHRoShpvLqNcrgV8ZQh61sMIFAry5KLTQV83BPG5iTXCCu7h72SCfJ97bW0GqtuqDD/1aqLbKinI/rNgUsg==", - "dev": true - }, "node_modules/esbuild-register": { "version": "3.4.2", "resolved": "https://registry.npmjs.org/esbuild-register/-/esbuild-register-3.4.2.tgz", @@ -8803,8 +8833,7 @@ "node_modules/fast-deep-equal": { "version": "3.1.3", "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz", - "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==", - "dev": true + "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==" }, "node_modules/fast-diff": { "version": "1.3.0", @@ -8852,24 +8881,6 @@ "integrity": "sha512-DCXu6Ifhqcks7TZKY3Hxp3y6qphY5SJZmrWMDrKcERSOXWQdMhU9Ig/PYrzyw/ul9jOIyh0N4M0tbC5hodg8dw==", "dev": true }, - "node_modules/fast-loops": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/fast-loops/-/fast-loops-1.1.3.tgz", - "integrity": "sha512-8EZzEP0eKkEEVX+drtd9mtuQ+/QrlfW/5MlwcwK5Nds6EkZ/tRzEexkzUY2mIssnAyVLT+TKHuRXmFNNXYUd6g==", - "dev": true - }, - "node_modules/fast-shallow-equal": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/fast-shallow-equal/-/fast-shallow-equal-1.0.0.tgz", - "integrity": "sha512-HPtaa38cPgWvaCFmRNhlc6NG7pv6NUHqjPgVAkWGoB9mQMwYB27/K0CvOM5Czy+qpT3e8XJ6Q4aPAnzpNpzNaw==", - "dev": true - }, - "node_modules/fastest-stable-stringify": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/fastest-stable-stringify/-/fastest-stable-stringify-2.0.2.tgz", - "integrity": "sha512-bijHueCGd0LqqNK9b5oCMHc0MluJAx0cwqASgbWMvkO01lCYgIhacVRLcaDz3QnyYIRNJRDwMb41VuT6pHJ91Q==", - "dev": true - }, "node_modules/fastq": { "version": "1.15.0", "resolved": "https://registry.npmjs.org/fastq/-/fastq-1.15.0.tgz", @@ -9170,11 +9181,23 @@ "node": ">= 0.6" } }, + "node_modules/fraction.js": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/fraction.js/-/fraction.js-4.2.0.tgz", + "integrity": "sha512-MhLuK+2gUcnZe8ZHlaaINnQLl0xRIGRfcGk2yl8xoQAfHrSsL3rYu6FCmBdkdbhc9EPlwyGHewaRsvwRMJtAlA==", + "dev": true, + "engines": { + "node": "*" + }, + "funding": { + "type": "patreon", + "url": "https://www.patreon.com/infusion" + } + }, "node_modules/framer-motion": { "version": "10.12.16", "resolved": "https://registry.npmjs.org/framer-motion/-/framer-motion-10.12.16.tgz", "integrity": "sha512-w/SfWEIWJkYSgRHYBmln7EhcNo31ao8Xexol8lGXf1pR/tlnBtf1HcxoUmEiEh6pacB4/geku5ami53AAQWHMQ==", - "dev": true, "dependencies": { "tslib": "^2.4.0" }, @@ -9733,12 +9756,6 @@ "node": ">=10.17.0" } }, - "node_modules/hyphenate-style-name": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/hyphenate-style-name/-/hyphenate-style-name-1.0.4.tgz", - "integrity": "sha512-ygGZLjmXfPHj+ZWh6LwbC37l43MhfztxetbFCoYTM2VjkIUpeHgSNn7QIyVFj7YQ1Wl9Cbw5sholVJPzWvC2MQ==", - "dev": true - }, "node_modules/iconv-lite": { "version": "0.4.24", "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.24.tgz", @@ -9783,8 +9800,7 @@ "node_modules/immediate": { "version": "3.0.6", "resolved": "https://registry.npmjs.org/immediate/-/immediate-3.0.6.tgz", - "integrity": "sha512-XXOFtyqDjNDAQxVfYxuF7g9Il/IbWmmlQg2MYKOH8ExIT1qg6xc4zyS3HaEEATgs1btfzxq15ciUiY7gjSXRGQ==", - "dev": true + "integrity": "sha512-XXOFtyqDjNDAQxVfYxuF7g9Il/IbWmmlQg2MYKOH8ExIT1qg6xc4zyS3HaEEATgs1btfzxq15ciUiY7gjSXRGQ==" }, "node_modules/import-fresh": { "version": "3.3.0", @@ -9842,18 +9858,7 @@ "node_modules/inherits": { "version": "2.0.4", "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", - "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==", - "dev": true - }, - "node_modules/inline-style-prefixer": { - "version": "6.0.4", - "resolved": "https://registry.npmjs.org/inline-style-prefixer/-/inline-style-prefixer-6.0.4.tgz", - "integrity": "sha512-FwXmZC2zbeeS7NzGjJ6pAiqRhXR0ugUShSNb6GApMl6da0/XGc4MOJsoWAywia52EEWbXNSy0pzkwz/+Y+swSg==", - "dev": true, - "dependencies": { - "css-in-js-utils": "^3.1.0", - "fast-loops": "^1.1.3" - } + "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==" }, "node_modules/internal-slot": { "version": "1.0.5", @@ -10727,6 +10732,15 @@ "url": "https://github.com/chalk/supports-color?sponsor=1" } }, + "node_modules/jiti": { + "version": "1.18.2", + "resolved": "https://registry.npmjs.org/jiti/-/jiti-1.18.2.tgz", + "integrity": "sha512-QAdOptna2NYiSSpv0O/BwoHBSmz4YhpzJHyi+fnMRTXFjp7B8i/YG5Z8IfusxB1ufjcD2Sre1F3R+nX3fvy7gg==", + "dev": true, + "bin": { + "jiti": "bin/jiti.js" + } + }, "node_modules/joycon": { "version": "3.1.1", "resolved": "https://registry.npmjs.org/joycon/-/joycon-3.1.1.tgz", @@ -10736,12 +10750,6 @@ "node": ">=10" } }, - "node_modules/js-cookie": { - "version": "2.2.1", - "resolved": "https://registry.npmjs.org/js-cookie/-/js-cookie-2.2.1.tgz", - "integrity": "sha512-HvdH2LzI/EAZcUwA8+0nKNtWHqS+ZmijLA30RwZA0bo7ToCckjK5MkGhjED9KoRcXO6BaGI3I9UIzSA1FKFPOQ==", - "dev": true - }, "node_modules/js-string-escape": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/js-string-escape/-/js-string-escape-1.0.1.tgz", @@ -10754,8 +10762,7 @@ "node_modules/js-tokens": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz", - "integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==", - "dev": true + "integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==" }, "node_modules/js-yaml": { "version": "3.14.1", @@ -10957,7 +10964,6 @@ "version": "3.10.1", "resolved": "https://registry.npmjs.org/jszip/-/jszip-3.10.1.tgz", "integrity": "sha512-xXDvecyTpGLrqFrvkrUSoxxfJI5AH7U8zxxtVclpsUtMCq4JQ290LY8AW5c7Ggnr/Y/oK+bQMbqK2qmtk3pN4g==", - "dev": true, "dependencies": { "lie": "~3.3.0", "pako": "~1.0.2", @@ -11023,7 +11029,6 @@ "version": "3.3.0", "resolved": "https://registry.npmjs.org/lie/-/lie-3.3.0.tgz", "integrity": "sha512-UaiMJzeWRlEujzAuw5LokY1L5ecNQYZKfmyZ9L7wDHb/p5etKaxXhohBcrw0EYby+G/NA52vRSN4N39dxHAIwQ==", - "dev": true, "dependencies": { "immediate": "~3.0.5" } @@ -11097,8 +11102,7 @@ "node_modules/lodash.debounce": { "version": "4.0.8", "resolved": "https://registry.npmjs.org/lodash.debounce/-/lodash.debounce-4.0.8.tgz", - "integrity": "sha512-FT1yDzDYEoYWhnSGnpE/4Kj1fLZkDFyqRb7fNt6FdYOSxlUWAtp42Eh6Wb0rGIv/m9Bgo7x4GhQbm5Ys4SG5ow==", - "dev": true + "integrity": "sha512-FT1yDzDYEoYWhnSGnpE/4Kj1fLZkDFyqRb7fNt6FdYOSxlUWAtp42Eh6Wb0rGIv/m9Bgo7x4GhQbm5Ys4SG5ow==" }, "node_modules/lodash.merge": { "version": "4.6.2", @@ -11115,14 +11119,12 @@ "node_modules/lodash.throttle": { "version": "4.1.1", "resolved": "https://registry.npmjs.org/lodash.throttle/-/lodash.throttle-4.1.1.tgz", - "integrity": "sha512-wIkUCfVKpVsWo3JSZlc+8MB5it+2AN5W8J7YVMST30UrvcQNZ1Okbj+rbVniijTWE6FGYy4XJq/rHkas8qJMLQ==", - "dev": true + "integrity": "sha512-wIkUCfVKpVsWo3JSZlc+8MB5it+2AN5W8J7YVMST30UrvcQNZ1Okbj+rbVniijTWE6FGYy4XJq/rHkas8qJMLQ==" }, "node_modules/lodash.uniqby": { "version": "4.7.0", "resolved": "https://registry.npmjs.org/lodash.uniqby/-/lodash.uniqby-4.7.0.tgz", - "integrity": "sha512-e/zcLx6CSbmaEgFHCA7BnoQKyCtKMxnuWrJygbwPs/AIn+IMKl66L8/s+wBUn5LRw2pZx3bUHibiV1b6aTWIww==", - "dev": true + "integrity": "sha512-e/zcLx6CSbmaEgFHCA7BnoQKyCtKMxnuWrJygbwPs/AIn+IMKl66L8/s+wBUn5LRw2pZx3bUHibiV1b6aTWIww==" }, "node_modules/log-symbols": { "version": "4.1.0", @@ -11196,7 +11198,6 @@ "version": "1.4.0", "resolved": "https://registry.npmjs.org/loose-envify/-/loose-envify-1.4.0.tgz", "integrity": "sha512-lyuxPGr/Wfhrlem2CL/UcnUc1zcqKAImBDzukY7Y5F/yQiNdko6+fRLevlw1HgMySw7f611UIY408EtxRSoK3Q==", - "dev": true, "dependencies": { "js-tokens": "^3.0.0 || ^4.0.0" }, @@ -11207,8 +11208,7 @@ "node_modules/lottie-web": { "version": "5.12.2", "resolved": "https://registry.npmjs.org/lottie-web/-/lottie-web-5.12.2.tgz", - "integrity": "sha512-uvhvYPC8kGPjXT3MyKMrL3JitEAmDMp30lVkuq/590Mw9ok6pWcFCwXJveo0t5uqYw1UREQHofD+jVpdjBv8wg==", - "dev": true + "integrity": "sha512-uvhvYPC8kGPjXT3MyKMrL3JitEAmDMp30lVkuq/590Mw9ok6pWcFCwXJveo0t5uqYw1UREQHofD+jVpdjBv8wg==" }, "node_modules/loupe": { "version": "2.3.6", @@ -11326,12 +11326,6 @@ "url": "https://opencollective.com/unified" } }, - "node_modules/mdn-data": { - "version": "2.0.14", - "resolved": "https://registry.npmjs.org/mdn-data/-/mdn-data-2.0.14.tgz", - "integrity": "sha512-dn6wd0uw5GsdswPFfsgMp5NSB0/aDe6fK94YJV/AJDYXL6HVLWBsxeq7js7Ad+mU2K9LAlwpk6kN2D5mwCPVow==", - "dev": true - }, "node_modules/media-typer": { "version": "0.3.0", "resolved": "https://registry.npmjs.org/media-typer/-/media-typer-0.3.0.tgz", @@ -11573,31 +11567,10 @@ "thenify-all": "^1.0.0" } }, - "node_modules/nano-css": { - "version": "5.3.5", - "resolved": "https://registry.npmjs.org/nano-css/-/nano-css-5.3.5.tgz", - "integrity": "sha512-vSB9X12bbNu4ALBu7nigJgRViZ6ja3OU7CeuiV1zMIbXOdmkLahgtPmh3GBOlDxbKY0CitqlPdOReGlBLSp+yg==", - "dev": true, - "dependencies": { - "css-tree": "^1.1.2", - "csstype": "^3.0.6", - "fastest-stable-stringify": "^2.0.2", - "inline-style-prefixer": "^6.0.0", - "rtl-css-js": "^1.14.0", - "sourcemap-codec": "^1.4.8", - "stacktrace-js": "^2.0.2", - "stylis": "^4.0.6" - }, - "peerDependencies": { - "react": "*", - "react-dom": "*" - } - }, "node_modules/nanoid": { "version": "4.0.2", "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-4.0.2.tgz", "integrity": "sha512-7ZtY5KTCNheRGfEFxnedV5zFiORN1+Y1N6zvPTnHQd8ENUvfaDBeuJDZb2bN/oXwXxu3qkTXDzy57W5vAmDTBw==", - "dev": true, "funding": [ { "type": "github", @@ -11712,6 +11685,15 @@ "node": ">=0.10.0" } }, + "node_modules/normalize-range": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/normalize-range/-/normalize-range-0.1.2.tgz", + "integrity": "sha512-bdok/XvKII3nUpklnV6P2hxtMNrCboOjAcyBuQnWEhO665FwrSNRxU+AqpsyvO6LgGYPspN+lu5CLtw4jPRKNA==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, "node_modules/npm-run-path": { "version": "4.0.1", "resolved": "https://registry.npmjs.org/npm-run-path/-/npm-run-path-4.0.1.tgz", @@ -11745,6 +11727,15 @@ "node": ">=0.10.0" } }, + "node_modules/object-hash": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/object-hash/-/object-hash-3.0.0.tgz", + "integrity": "sha512-RSn9F68PjH9HqtltsSnqYC1XXoWe9Bju5+213R98cNGttag9q9yAOTzdbsqvIa7aNm5WffBZFpWYr2aWrklWAw==", + "dev": true, + "engines": { + "node": ">= 6" + } + }, "node_modules/object-inspect": { "version": "1.12.3", "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.12.3.tgz", @@ -12042,8 +12033,7 @@ "node_modules/pako": { "version": "1.0.11", "resolved": "https://registry.npmjs.org/pako/-/pako-1.0.11.tgz", - "integrity": "sha512-4hLB8Py4zZce5s4yd9XzopqwVv/yGNhV1Bl8NTmCq1763HeK2+EwVTv+leGeL13Dnh2wfbqowVPXCIO0z4taYw==", - "dev": true + "integrity": "sha512-4hLB8Py4zZce5s4yd9XzopqwVv/yGNhV1Bl8NTmCq1763HeK2+EwVTv+leGeL13Dnh2wfbqowVPXCIO0z4taYw==" }, "node_modules/parent-module": { "version": "1.0.1", @@ -12263,6 +12253,42 @@ "node": "^10 || ^12 || >=14" } }, + "node_modules/postcss-import": { + "version": "15.1.0", + "resolved": "https://registry.npmjs.org/postcss-import/-/postcss-import-15.1.0.tgz", + "integrity": "sha512-hpr+J05B2FVYUAXHeK1YyI267J/dDDhMU6B6civm8hSY1jYJnBXxzKDKDswzJmtLHryrjhnDjqqp/49t8FALew==", + "dev": true, + "dependencies": { + "postcss-value-parser": "^4.0.0", + "read-cache": "^1.0.0", + "resolve": "^1.1.7" + }, + "engines": { + "node": ">=14.0.0" + }, + "peerDependencies": { + "postcss": "^8.0.0" + } + }, + "node_modules/postcss-js": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/postcss-js/-/postcss-js-4.0.1.tgz", + "integrity": "sha512-dDLF8pEO191hJMtlHFPRa8xsizHaM82MLfNkUHdUtVEV3tgTp5oj+8qbEqYM57SLfc74KSbw//4SeJma2LRVIw==", + "dev": true, + "dependencies": { + "camelcase-css": "^2.0.1" + }, + "engines": { + "node": "^12 || ^14 || >= 16" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/postcss/" + }, + "peerDependencies": { + "postcss": "^8.4.21" + } + }, "node_modules/postcss-load-config": { "version": "3.1.4", "resolved": "https://registry.npmjs.org/postcss-load-config/-/postcss-load-config-3.1.4.tgz", @@ -12292,6 +12318,44 @@ } } }, + "node_modules/postcss-nested": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/postcss-nested/-/postcss-nested-6.0.1.tgz", + "integrity": "sha512-mEp4xPMi5bSWiMbsgoPfcP74lsWLHkQbZc3sY+jWYd65CUwXrUaTp0fmNpa01ZcETKlIgUdFN/MpS2xZtqL9dQ==", + "dev": true, + "dependencies": { + "postcss-selector-parser": "^6.0.11" + }, + "engines": { + "node": ">=12.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/postcss/" + }, + "peerDependencies": { + "postcss": "^8.2.14" + } + }, + "node_modules/postcss-selector-parser": { + "version": "6.0.13", + "resolved": "https://registry.npmjs.org/postcss-selector-parser/-/postcss-selector-parser-6.0.13.tgz", + "integrity": "sha512-EaV1Gl4mUEV4ddhDnv/xtj7sxwrwxdetHdWUGnT4VJQf+4d05v6lHYZr8N573k5Z0BViss7BDhfWtKS3+sfAqQ==", + "dev": true, + "dependencies": { + "cssesc": "^3.0.0", + "util-deprecate": "^1.0.2" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/postcss-value-parser": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/postcss-value-parser/-/postcss-value-parser-4.2.0.tgz", + "integrity": "sha512-1NNCs6uurfkVbeXG4S8JFT9t19m45ICnif8zWLd5oPSZ50QnwMfK+H3jv408d4jw/7Bttv5axS5IiHoLaVNHeQ==", + "dev": true + }, "node_modules/postcss/node_modules/nanoid": { "version": "3.3.6", "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.6.tgz", @@ -12381,8 +12445,7 @@ "node_modules/process-nextick-args": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-2.0.1.tgz", - "integrity": "sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag==", - "dev": true + "integrity": "sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag==" }, "node_modules/progress": { "version": "2.0.3", @@ -12660,7 +12723,6 @@ "version": "18.2.0", "resolved": "https://registry.npmjs.org/react/-/react-18.2.0.tgz", "integrity": "sha512-/3IjMdb2L9QbBdWiW5e3P2/npwMBaU9mHCSCUzNln0ZCYbcfTsGbTJrU/kGemdH2IWmB2ioZ+zkxtmq6g09fGQ==", - "dev": true, "dependencies": { "loose-envify": "^1.1.0" }, @@ -12715,7 +12777,6 @@ "version": "18.2.0", "resolved": "https://registry.npmjs.org/react-dom/-/react-dom-18.2.0.tgz", "integrity": "sha512-6IMTriUmvsjHUjNtEDudZfuDQUoWXVxKHhlEGSk81n4YFS+r/Kl99wXiwlVXtPBtJenozv2P+hxDsw9eA7Xo6g==", - "dev": true, "dependencies": { "loose-envify": "^1.1.0", "scheduler": "^0.23.0" @@ -12764,7 +12825,6 @@ "version": "1.5.4", "resolved": "https://registry.npmjs.org/react-lottie-player/-/react-lottie-player-1.5.4.tgz", "integrity": "sha512-eM0g11bAc4EJJuDDfCoNloaAYphfXlIpYnriOt4nRU66PpVmvKhajvP2aif4YflGY2ArAFXhWxs418YzdebK9w==", - "dev": true, "dependencies": { "fast-deep-equal": "^3.1.3", "lottie-web": "^5.7.6", @@ -12786,40 +12846,22 @@ "node": ">=0.10.0" } }, - "node_modules/react-universal-interface": { - "version": "0.6.2", - "resolved": "https://registry.npmjs.org/react-universal-interface/-/react-universal-interface-0.6.2.tgz", - "integrity": "sha512-dg8yXdcQmvgR13RIlZbTRQOoUrDciFVoSBZILwjE2LFISxZZ8loVJKAkuzswl5js8BHda79bIb2b84ehU8IjXw==", + "node_modules/read-cache": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/read-cache/-/read-cache-1.0.0.tgz", + "integrity": "sha512-Owdv/Ft7IjOgm/i0xvNDZ1LrRANRfew4b2prF3OWMQLxLfu3bS8FVhCsrSCMK4lR56Y9ya+AThoTpDCTxCmpRA==", "dev": true, - "peerDependencies": { - "react": "*", - "tslib": "*" + "dependencies": { + "pify": "^2.3.0" } }, - "node_modules/react-use": { - "version": "17.4.0", - "resolved": "https://registry.npmjs.org/react-use/-/react-use-17.4.0.tgz", - "integrity": "sha512-TgbNTCA33Wl7xzIJegn1HndB4qTS9u03QUwyNycUnXaweZkE4Kq2SB+Yoxx8qbshkZGYBDvUXbXWRUmQDcZZ/Q==", + "node_modules/read-cache/node_modules/pify": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/pify/-/pify-2.3.0.tgz", + "integrity": "sha512-udgsAY+fTnvv7kI7aaxbqwWNb0AHiB0qBO89PZKPkoTmGOgdbrHDKD+0B2X4uTfJ/FT1R09r9gTsjUjNJotuog==", "dev": true, - "dependencies": { - "@types/js-cookie": "^2.2.6", - "@xobotyi/scrollbar-width": "^1.9.5", - "copy-to-clipboard": "^3.3.1", - "fast-deep-equal": "^3.1.3", - "fast-shallow-equal": "^1.0.0", - "js-cookie": "^2.2.1", - "nano-css": "^5.3.1", - "react-universal-interface": "^0.6.2", - "resize-observer-polyfill": "^1.5.1", - "screenfull": "^5.1.0", - "set-harmonic-interval": "^1.0.1", - "throttle-debounce": "^3.0.1", - "ts-easing": "^0.2.0", - "tslib": "^2.1.0" - }, - "peerDependencies": { - "react": "^16.8.0 || ^17.0.0 || ^18.0.0", - "react-dom": "^16.8.0 || ^17.0.0 || ^18.0.0" + "engines": { + "node": ">=0.10.0" } }, "node_modules/read-pkg": { @@ -12928,7 +12970,6 @@ "version": "2.3.8", "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.8.tgz", "integrity": "sha512-8p0AUk4XODgIewSi0l8Epjs+EVnWiK7NoDIEGU0HhE7+ZyY8D1IMY7odu5lRrFXGg71L15KG8QrPmum45RTtdA==", - "dev": true, "dependencies": { "core-util-is": "~1.0.0", "inherits": "~2.0.3", @@ -12942,14 +12983,12 @@ "node_modules/readable-stream/node_modules/isarray": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", - "integrity": "sha512-VLghIWNM6ELQzo7zwmcg0NmTVyWKYjvIeM83yjp0wRDTmUnrM678fQbcKBo6n2CJEF0szoG//ytg+TKla89ALQ==", - "dev": true + "integrity": "sha512-VLghIWNM6ELQzo7zwmcg0NmTVyWKYjvIeM83yjp0wRDTmUnrM678fQbcKBo6n2CJEF0szoG//ytg+TKla89ALQ==" }, "node_modules/readable-stream/node_modules/safe-buffer": { "version": "5.1.2", "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", - "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", - "dev": true + "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==" }, "node_modules/readdirp": { "version": "3.6.0", @@ -13132,21 +13171,6 @@ "node": ">=0.10.0" } }, - "node_modules/require-from-string": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/require-from-string/-/require-from-string-2.0.2.tgz", - "integrity": "sha512-Xf0nWe6RseziFMu+Ap9biiUbmplq6S9/p+7w7YXP/JBHhrUDDUhwa+vANyubuqfZWTveU//DYVGsDG7RKL/vEw==", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/resize-observer-polyfill": { - "version": "1.5.1", - "resolved": "https://registry.npmjs.org/resize-observer-polyfill/-/resize-observer-polyfill-1.5.1.tgz", - "integrity": "sha512-LwZrotdHOo12nQuZlHEmtuXdqGoOD0OhaxopaNFxWzInpEgaLWoVuAMbTzixuosCx2nEG58ngzW3vxdWoxIgdg==", - "dev": true - }, "node_modules/resolve": { "version": "1.22.2", "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.22.2.tgz", @@ -13199,8 +13223,7 @@ "node_modules/rfdc": { "version": "1.3.0", "resolved": "https://registry.npmjs.org/rfdc/-/rfdc-1.3.0.tgz", - "integrity": "sha512-V2hovdzFbOi77/WajaSMXk2OLm+xNIeQdMMuB7icj7bk6zi2F8GGAxigcnDFpJHbNyNcgyJDiP+8nOrY5cZGrA==", - "dev": true + "integrity": "sha512-V2hovdzFbOi77/WajaSMXk2OLm+xNIeQdMMuB7icj7bk6zi2F8GGAxigcnDFpJHbNyNcgyJDiP+8nOrY5cZGrA==" }, "node_modules/rimraf": { "version": "3.0.2", @@ -13253,15 +13276,6 @@ "fsevents": "~2.3.2" } }, - "node_modules/rtl-css-js": { - "version": "1.16.1", - "resolved": "https://registry.npmjs.org/rtl-css-js/-/rtl-css-js-1.16.1.tgz", - "integrity": "sha512-lRQgou1mu19e+Ya0LsTvKrVJ5TYUbqCVPAiImX3UfLTenarvPUl1QFdvu5Z3PYmHT9RCcwIfbjRQBntExyj3Zg==", - "dev": true, - "dependencies": { - "@babel/runtime": "^7.1.2" - } - }, "node_modules/run-parallel": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/run-parallel/-/run-parallel-1.2.0.tgz", @@ -13315,7 +13329,6 @@ "version": "0.23.0", "resolved": "https://registry.npmjs.org/scheduler/-/scheduler-0.23.0.tgz", "integrity": "sha512-CtuThmgHNg7zIZWAXi3AsyIzA3n4xx7aNyjwC2VJldO2LMVDhFK+63xGqq6CsJH4rTAt6/M+N4GhZiDYPx9eUw==", - "dev": true, "dependencies": { "loose-envify": "^1.1.0" } @@ -13338,18 +13351,6 @@ "url": "https://opencollective.com/webpack" } }, - "node_modules/screenfull": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/screenfull/-/screenfull-5.2.0.tgz", - "integrity": "sha512-9BakfsO2aUQN2K9Fdbj87RJIEZ82Q9IGim7FqM5OsebfoFC6ZHXgDq/KvniuLTPdeM8wY2o6Dj3WQ7KeQCj3cA==", - "dev": true, - "engines": { - "node": ">=0.10.0" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, "node_modules/semver": { "version": "6.3.0", "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", @@ -13462,20 +13463,10 @@ "integrity": "sha512-KiKBS8AnWGEyLzofFfmvKwpdPzqiy16LvQfK3yv/fVH7Bj13/wl3JSR1J+rfgRE9q7xUJK4qvgS8raSOeLUehw==", "dev": true }, - "node_modules/set-harmonic-interval": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/set-harmonic-interval/-/set-harmonic-interval-1.0.1.tgz", - "integrity": "sha512-AhICkFV84tBP1aWqPwLZqFvAwqEoVA9kxNMniGEUvzOlm4vLmOFLiTT3UZ6bziJTy4bOVpzWGTfSCbmaayGx8g==", - "dev": true, - "engines": { - "node": ">=6.9" - } - }, "node_modules/setimmediate": { "version": "1.0.5", "resolved": "https://registry.npmjs.org/setimmediate/-/setimmediate-1.0.5.tgz", - "integrity": "sha512-MATJdZp8sLqDl/68LfQmbP8zKPLQNV6BIZoIgrscFDQ+RsvK/BxeDQOgyxKKoh0y/8h3BqVFnCqQ/gd+reiIXA==", - "dev": true + "integrity": "sha512-MATJdZp8sLqDl/68LfQmbP8zKPLQNV6BIZoIgrscFDQ+RsvK/BxeDQOgyxKKoh0y/8h3BqVFnCqQ/gd+reiIXA==" }, "node_modules/setprototypeof": { "version": "1.2.0", @@ -13643,13 +13634,6 @@ "source-map": "^0.6.0" } }, - "node_modules/sourcemap-codec": { - "version": "1.4.8", - "resolved": "https://registry.npmjs.org/sourcemap-codec/-/sourcemap-codec-1.4.8.tgz", - "integrity": "sha512-9NykojV5Uih4lgo5So5dtw+f0JgJX30KCNI8gwhz2J9A15wD0Ml6tjHKwf6fTSa6fAdVBdZeNOs9eJ71qCk8vA==", - "deprecated": "Please use @jridgewell/sourcemap-codec instead", - "dev": true - }, "node_modules/space-separated-tokens": { "version": "1.1.5", "resolved": "https://registry.npmjs.org/space-separated-tokens/-/space-separated-tokens-1.1.5.tgz", @@ -13698,57 +13682,12 @@ "integrity": "sha512-D9cPgkvLlV3t3IzL0D0YLvGA9Ahk4PcvVwUbN0dSGr1aP0Nrt4AEnTUbuGvquEC0mA64Gqt1fzirlRs5ibXx8g==", "dev": true }, - "node_modules/stack-generator": { - "version": "2.0.10", - "resolved": "https://registry.npmjs.org/stack-generator/-/stack-generator-2.0.10.tgz", - "integrity": "sha512-mwnua/hkqM6pF4k8SnmZ2zfETsRUpWXREfA/goT8SLCV4iOFa4bzOX2nDipWAZFPTjLvQB82f5yaodMVhK0yJQ==", - "dev": true, - "dependencies": { - "stackframe": "^1.3.4" - } - }, "node_modules/stackback": { "version": "0.0.2", "resolved": "https://registry.npmjs.org/stackback/-/stackback-0.0.2.tgz", "integrity": "sha512-1XMJE5fQo1jGH6Y/7ebnwPOBEkIEnT4QF32d5R1+VXdXveM0IBMJt8zfaxX1P3QhVwrYe+576+jkANtSS2mBbw==", "dev": true }, - "node_modules/stackframe": { - "version": "1.3.4", - "resolved": "https://registry.npmjs.org/stackframe/-/stackframe-1.3.4.tgz", - "integrity": "sha512-oeVtt7eWQS+Na6F//S4kJ2K2VbRlS9D43mAlMyVpVWovy9o+jfgH8O9agzANzaiLjclA0oYzUXEM4PurhSUChw==", - "dev": true - }, - "node_modules/stacktrace-gps": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/stacktrace-gps/-/stacktrace-gps-3.1.2.tgz", - "integrity": "sha512-GcUgbO4Jsqqg6RxfyTHFiPxdPqF+3LFmQhm7MgCuYQOYuWyqxo5pwRPz5d/u6/WYJdEnWfK4r+jGbyD8TSggXQ==", - "dev": true, - "dependencies": { - "source-map": "0.5.6", - "stackframe": "^1.3.4" - } - }, - "node_modules/stacktrace-gps/node_modules/source-map": { - "version": "0.5.6", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.6.tgz", - "integrity": "sha512-MjZkVp0NHr5+TPihLcadqnlVoGIoWo4IBHptutGh9wI3ttUYvCG26HkSuDi+K6lsZ25syXJXcctwgyVCt//xqA==", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/stacktrace-js": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/stacktrace-js/-/stacktrace-js-2.0.2.tgz", - "integrity": "sha512-Je5vBeY4S1r/RnLydLl0TBTi3F2qdfWmYsGvtfZgEI+SCprPppaIhQf5nGcal4gI4cGpCV/duLcAzT1np6sQqg==", - "dev": true, - "dependencies": { - "error-stack-parser": "^2.0.6", - "stack-generator": "^2.0.5", - "stacktrace-gps": "^3.0.4" - } - }, "node_modules/statuses": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/statuses/-/statuses-2.0.1.tgz", @@ -13809,7 +13748,6 @@ "version": "1.1.1", "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", - "dev": true, "dependencies": { "safe-buffer": "~5.1.0" } @@ -13817,8 +13755,7 @@ "node_modules/string_decoder/node_modules/safe-buffer": { "version": "5.1.2", "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", - "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", - "dev": true + "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==" }, "node_modules/string-width": { "version": "4.2.3", @@ -13903,12 +13840,6 @@ "node": ">=0.4.0" } }, - "node_modules/stylis": { - "version": "4.2.0", - "resolved": "https://registry.npmjs.org/stylis/-/stylis-4.2.0.tgz", - "integrity": "sha512-Orov6g6BB1sDfYgzWfTHDOxamtX1bE/zo104Dh9e6fqJ3PooipYyfJ0pUmrZO2wAvO8YbEyeFrkV91XTsGMSrw==", - "dev": true - }, "node_modules/sucrase": { "version": "3.32.0", "resolved": "https://registry.npmjs.org/sucrase/-/sucrase-3.32.0.tgz", @@ -13990,6 +13921,82 @@ "integrity": "sha512-AsS729u2RHUfEra9xJrE39peJcc2stq2+poBXX8bcM08Y6g9j/i/PUzwNQqkaJde7Ntg1TO7bSREbR5sdosQ+g==", "dev": true }, + "node_modules/tailwindcss": { + "version": "3.3.2", + "resolved": "https://registry.npmjs.org/tailwindcss/-/tailwindcss-3.3.2.tgz", + "integrity": "sha512-9jPkMiIBXvPc2KywkraqsUfbfj+dHDb+JPWtSJa9MLFdrPyazI7q6WX2sUrm7R9eVR7qqv3Pas7EvQFzxKnI6w==", + "dev": true, + "dependencies": { + "@alloc/quick-lru": "^5.2.0", + "arg": "^5.0.2", + "chokidar": "^3.5.3", + "didyoumean": "^1.2.2", + "dlv": "^1.1.3", + "fast-glob": "^3.2.12", + "glob-parent": "^6.0.2", + "is-glob": "^4.0.3", + "jiti": "^1.18.2", + "lilconfig": "^2.1.0", + "micromatch": "^4.0.5", + "normalize-path": "^3.0.0", + "object-hash": "^3.0.0", + "picocolors": "^1.0.0", + "postcss": "^8.4.23", + "postcss-import": "^15.1.0", + "postcss-js": "^4.0.1", + "postcss-load-config": "^4.0.1", + "postcss-nested": "^6.0.1", + "postcss-selector-parser": "^6.0.11", + "postcss-value-parser": "^4.2.0", + "resolve": "^1.22.2", + "sucrase": "^3.32.0" + }, + "bin": { + "tailwind": "lib/cli.js", + "tailwindcss": "lib/cli.js" + }, + "engines": { + "node": ">=14.0.0" + } + }, + "node_modules/tailwindcss/node_modules/postcss-load-config": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/postcss-load-config/-/postcss-load-config-4.0.1.tgz", + "integrity": "sha512-vEJIc8RdiBRu3oRAI0ymerOn+7rPuMvRXslTvZUKZonDHFIczxztIyJ1urxM1x9JXEikvpWWTUUqal5j/8QgvA==", + "dev": true, + "dependencies": { + "lilconfig": "^2.0.5", + "yaml": "^2.1.1" + }, + "engines": { + "node": ">= 14" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/postcss/" + }, + "peerDependencies": { + "postcss": ">=8.0.9", + "ts-node": ">=9.0.0" + }, + "peerDependenciesMeta": { + "postcss": { + "optional": true + }, + "ts-node": { + "optional": true + } + } + }, + "node_modules/tailwindcss/node_modules/yaml": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/yaml/-/yaml-2.3.1.tgz", + "integrity": "sha512-2eHWfjaoXgTBC2jNM1LRef62VQa0umtvRiDSk6HSzW7RvS5YtkabJrwYLLEKWBc8a5U2PTSCs+dJjUTJdlHsWQ==", + "dev": true, + "engines": { + "node": ">= 14" + } + }, "node_modules/tapable": { "version": "2.2.1", "resolved": "https://registry.npmjs.org/tapable/-/tapable-2.2.1.tgz", @@ -14338,15 +14345,6 @@ "node": ">=0.8" } }, - "node_modules/throttle-debounce": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/throttle-debounce/-/throttle-debounce-3.0.1.tgz", - "integrity": "sha512-dTEWWNu6JmeVXY0ZYoPuH5cRIwc0MeGbJwah9KUNYSJwommQpCzTySTpEe8Gs1J23aeWEuAobe4Ag7EHVt/LOg==", - "dev": true, - "engines": { - "node": ">=10" - } - }, "node_modules/through2": { "version": "2.0.5", "resolved": "https://registry.npmjs.org/through2/-/through2-2.0.5.tgz", @@ -14417,12 +14415,6 @@ "node": ">=8.0" } }, - "node_modules/toggle-selection": { - "version": "1.0.6", - "resolved": "https://registry.npmjs.org/toggle-selection/-/toggle-selection-1.0.6.tgz", - "integrity": "sha512-BiZS+C1OS8g/q2RRbJmy59xpyghNBqrr6k5L/uKBGRsTfxmu3ffiRnd8mlGPUVayg8pvfi5urfnu8TU7DVOkLQ==", - "dev": true - }, "node_modules/toidentifier": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/toidentifier/-/toidentifier-1.0.1.tgz", @@ -14456,12 +14448,6 @@ "node": ">=6.10" } }, - "node_modules/ts-easing": { - "version": "0.2.0", - "resolved": "https://registry.npmjs.org/ts-easing/-/ts-easing-0.2.0.tgz", - "integrity": "sha512-Z86EW+fFFh/IFB1fqQ3/+7Zpf9t2ebOAxNI/V6Wo7r5gqiqtxmgTlQ1qbqQcjLKYeSHPTsEmvlJUDg/EuL0uHQ==", - "dev": true - }, "node_modules/ts-interface-checker": { "version": "0.1.13", "resolved": "https://registry.npmjs.org/ts-interface-checker/-/ts-interface-checker-0.1.13.tgz", @@ -14471,8 +14457,7 @@ "node_modules/tslib": { "version": "2.5.3", "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.5.3.tgz", - "integrity": "sha512-mSxlJJwl3BMEQCUNnxXBU9jP4JBktcEGhURcPR6VQVlnP0FdDEsIaz0C35dXNGLyRfrATNofF0F5p2KPxQgB+w==", - "dev": true + "integrity": "sha512-mSxlJJwl3BMEQCUNnxXBU9jP4JBktcEGhURcPR6VQVlnP0FdDEsIaz0C35dXNGLyRfrATNofF0F5p2KPxQgB+w==" }, "node_modules/tsup": { "version": "6.7.0", @@ -14845,7 +14830,6 @@ "version": "1.2.0", "resolved": "https://registry.npmjs.org/use-sync-external-store/-/use-sync-external-store-1.2.0.tgz", "integrity": "sha512-eEgnFxGQ1Ife9bzYs6VLi8/4X6CObHMw9Qr9tPY43iKwsPw8xE8+EFsf/2cFZ5S3esXgpWgtSCtLNS41F+sKPA==", - "dev": true, "peerDependencies": { "react": "^16.8.0 || ^17.0.0 || ^18.0.0" } @@ -14866,8 +14850,7 @@ "node_modules/util-deprecate": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", - "integrity": "sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==", - "dev": true + "integrity": "sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==" }, "node_modules/utils-merge": { "version": "1.0.1", @@ -15539,7 +15522,6 @@ "version": "3.21.4", "resolved": "https://registry.npmjs.org/zod/-/zod-3.21.4.tgz", "integrity": "sha512-m46AKbrzKVzOzs/DZgVnG5H55N1sv1M8qZU3A8RIKbs3mrACDNeIOeilDymVb2HdmP8uwshOCF4uJ8uM9rCqJw==", - "dev": true, "funding": { "url": "https://github.com/sponsors/colinhacks" } diff --git a/apps/wing-console/console/ui/package.json b/apps/wing-console/console/ui/package.json index 4722e485120..fbb9d6cd337 100644 --- a/apps/wing-console/console/ui/package.json +++ b/apps/wing-console/console/ui/package.json @@ -2,21 +2,53 @@ "name": "@wingconsole/ui", "license": "SEE LICENSE IN LICENSE.md", "version": "0.0.0", - "private": true, - "exports": "./src/index.ts", + "exports": { + ".": "./src/index.ts", + "./tailwind-plugin.cjs": "./tailwind-plugin.cjs" + }, "types": "./src/index.ts", + "publishConfig": { + "exports": "./dist/index.js", + "types": "./dist/index.d.ts", + "files": [ + "dist", + "tailwind-plugin.cjs" + ] + }, "scripts": { "compile": "tsup", "tsc": "tsc --build", "eslint": "eslint --ext .js,.cjs,.ts,.cts,.mts,.tsx --no-error-on-unmatched-pattern . --fix", "storybook": "storybook dev -p 6006", - "build-storybook": "storybook build" + "build-storybook": "storybook build", + "package": "bump-pack -b" }, - "devDependencies": { - "@babel/core": "^7.22.5", + "dependencies": { "@headlessui/react": "^1.7.15", "@heroicons/react": "^2.0.18", "@popperjs/core": "^2.11.8", + "@tanstack/react-query": "^4.29.12", + "@trpc/client": "^10.30.0", + "@trpc/react-query": "^10.30.0", + "@trpc/server": "^10.30.0", + "@wingconsole/design-system": "file:../design-system", + "classnames": "^2.3.2", + "d3-selection": "^3.0.0", + "d3-zoom": "^3.0.0", + "elkjs": "^0.8.2", + "framer-motion": "^10.12.16", + "jszip": "^3.10.1", + "lodash.debounce": "^4.0.8", + "lodash.throttle": "^4.1.1", + "lodash.uniqby": "^4.7.0", + "nanoid": "^4.0.2", + "react": "^18.2.0", + "react-dom": "^18.2.0", + "react-lottie-player": "^1.5.4", + "zod": "^3.21.4" + }, + "devDependencies": { + "@babel/core": "^7.22.5", "@storybook/addon-essentials": "^7.0.20", "@storybook/addon-interactions": "^7.0.20", "@storybook/addon-links": "^7.0.20", @@ -24,48 +56,28 @@ "@storybook/react": "^7.0.20", "@storybook/react-vite": "^7.0.20", "@storybook/testing-library": "^0.1.0", - "@tanstack/react-query": "^4.29.12", - "@trpc/client": "^10.30.0", - "@trpc/react-query": "^10.30.0", - "@trpc/server": "^10.30.0", "@types/cors": "^2.8.13", "@types/d3-selection": "^3.0.5", "@types/d3-zoom": "^3.0.3", - "@types/lodash": "^4.14.195", + "@types/lodash.debounce": "^4.0.7", "@types/lodash.throttle": "^4.1.7", "@types/lodash.uniqby": "^4.7.7", "@types/react": "^18.2.12", "@types/react-dom": "^18.2.5", "@vitejs/plugin-react-swc": "^3.3.2", - "@wingconsole/design-system": "file:../design-system", "@wingconsole/eslint-plugin": "file:../../tools/eslint-plugin", "@wingconsole/server": "file:../server", "@wingconsole/tsconfig": "file:../../tools/tsconfig", "@wingconsole/use-loading": "file:../../packages/use-loading", - "classnames": "^2.3.2", - "constructs": "^10.2.51", - "d3-selection": "^3.0.0", - "d3-zoom": "^3.0.0", - "elkjs": "^0.8.2", - "esbuild-plugin-external-global": "^1.0.1", + "autoprefixer": "^10.4.14", + "bump-pack": "file:../../../../tools/bump-pack", "eslint": "^8.42.0", - "framer-motion": "^10.12.16", - "jszip": "^3.10.1", - "lodash": "^4.17.21", - "lodash.throttle": "^4.1.1", - "lodash.uniqby": "^4.7.0", - "nanoid": "^4.0.2", - "react": "^18.2.0", - "react-dom": "^18.2.0", - "react-lottie-player": "^1.5.4", - "react-use": "^17.4.0", - "require-from-string": "^2.0.2", "storybook": "^7.0.20", + "tailwindcss": "^3.3.2", "tsup": "^6.7.0", "typescript": "^5.1.3", "vite": "^4.3.9", "vitest": "^0.31.4", - "webpack": "^5.86.0", - "zod": "^3.21.4" + "webpack": "^5.86.0" } } diff --git a/apps/wing-console/console/ui/project.json b/apps/wing-console/console/ui/project.json index 8039c7330e2..8b5061d1a2a 100644 --- a/apps/wing-console/console/ui/project.json +++ b/apps/wing-console/console/ui/project.json @@ -1,13 +1,24 @@ { "name": "console-ui", "$schema": "../../../../node_modules/nx/schemas/project-schema.json", - "implicitDependencies": ["compiler", "sdk"], + "implicitDependencies": [ + "compiler", + "sdk", + "console-server", + "console-design-system" + ], "targets": { "build": { "options": { "command": "npm run compile", "cwd": "apps/wing-console/console/ui" } + }, + "package": { + "options": { + "command": "npm run package", + "cwd": "apps/wing-console/console/ui" + } } } } diff --git a/apps/wing-console/console/ui/readme.md b/apps/wing-console/console/ui/readme.md index c1708bc7e54..5007748e26f 100644 --- a/apps/wing-console/console/ui/readme.md +++ b/apps/wing-console/console/ui/readme.md @@ -1,5 +1,37 @@ # @wingconsole/ui +> โš ๏ธ This package is meant to be used internally by the Wing Console. + +## Usage + +The Console react component: + +```tsx +import { Console } from "@wingconsole/ui"; +import React from "react"; +import ReactDOM from "react-dom/client"; + +ReactDOM.createRoot(document.querySelector("#root")!).render( + + + , +); +``` + +The Tailwindcss config: + +```js +const ui = require("@wingconsole/ui/tailwind-plugin.cjs"); + +/** @type {import('tailwindcss').Config} */ +module.exports = { + darkMode: "class", + content: [...ui.content, "./index.html", "./src/**/*.{vue,js,ts,jsx,tsx}"], + plugins: [...ui.plugins], + theme: { ...ui.theme }, +}; +``` + ## License This code is distributed under the [Monada Console License](./LICENSE.md). diff --git a/apps/wing-console/console/ui/src/AppContext.ts b/apps/wing-console/console/ui/src/AppContext.ts index d61b560f0e3..899bbfb0efe 100644 --- a/apps/wing-console/console/ui/src/AppContext.ts +++ b/apps/wing-console/console/ui/src/AppContext.ts @@ -1,6 +1,6 @@ import React from "react"; -export type AppMode = "webapp" | "electron"; +export type AppMode = "remote" | "local"; export interface AppContextValue { appMode: AppMode; @@ -8,6 +8,6 @@ export interface AppContextValue { } export const AppContext = React.createContext({ - appMode: "electron", + appMode: "local", title: "Wing Console", }); diff --git a/apps/wing-console/console/ui/src/Console.tsx b/apps/wing-console/console/ui/src/Console.tsx index 7d835d5596d..460a7e5a8e3 100644 --- a/apps/wing-console/console/ui/src/Console.tsx +++ b/apps/wing-console/console/ui/src/Console.tsx @@ -56,8 +56,7 @@ export const Console = ({ let windowTitle = title ?? "Wing Console"; - const appMode = layout === LayoutType.Vscode ? "electron" : "webapp"; - + const appMode = layout === LayoutType.Vscode ? "local" : "remote"; return ( diff --git a/apps/wing-console/console/ui/src/features/console-logs-filters.tsx b/apps/wing-console/console/ui/src/features/console-logs-filters.tsx index 547b574cfd8..f3aeb985e4d 100644 --- a/apps/wing-console/console/ui/src/features/console-logs-filters.tsx +++ b/apps/wing-console/console/ui/src/features/console-logs-filters.tsx @@ -1,7 +1,7 @@ import { MagnifyingGlassIcon, NoSymbolIcon } from "@heroicons/react/24/outline"; import { Button, Input, Listbox } from "@wingconsole/design-system"; import { LogLevel } from "@wingconsole/server"; -import debounce from "lodash/debounce"; +import debounce from "lodash.debounce"; import { useCallback, useEffect, useState } from "react"; export interface ConsoleLogsFiltersProps { diff --git a/apps/wing-console/console/ui/src/index.ts b/apps/wing-console/console/ui/src/index.ts index ab311c0c8c8..cdaee3c6d5e 100644 --- a/apps/wing-console/console/ui/src/index.ts +++ b/apps/wing-console/console/ui/src/index.ts @@ -1 +1,3 @@ export * from "./Console.js"; + +export type { RouterContext } from "@wingconsole/server"; diff --git a/apps/wing-console/console/ui/src/services/trpc.ts b/apps/wing-console/console/ui/src/services/trpc.ts index 1b586dbc47f..793de09293d 100644 --- a/apps/wing-console/console/ui/src/services/trpc.ts +++ b/apps/wing-console/console/ui/src/services/trpc.ts @@ -1,6 +1,8 @@ import { createTRPCReact } from "@trpc/react-query"; import type { Router } from "@wingconsole/server"; +export type { Router } from "@wingconsole/server"; + export const trpc = createTRPCReact({ unstable_overrides: { useMutation: { diff --git a/apps/wing-console/console/ui/src/ui/api-interaction.tsx b/apps/wing-console/console/ui/src/ui/api-interaction.tsx index e431c7305bb..ab0474f7524 100644 --- a/apps/wing-console/console/ui/src/ui/api-interaction.tsx +++ b/apps/wing-console/console/ui/src/ui/api-interaction.tsx @@ -196,7 +196,7 @@ export const ApiInteraction = ({ return (
- {appMode !== "webapp" && ( + {appMode === "local" && ( )}
diff --git a/apps/wing-console/console/ui/tailwind-plugin.cjs b/apps/wing-console/console/ui/tailwind-plugin.cjs new file mode 100644 index 00000000000..e0f4377476b --- /dev/null +++ b/apps/wing-console/console/ui/tailwind-plugin.cjs @@ -0,0 +1,9 @@ +const designSystem = require("@wingconsole/design-system/tailwind-plugin.cjs"); + +module.exports.plugins = [...designSystem.plugins]; +module.exports.content = [ + ...designSystem.content, + `${__dirname}/src/**/*.{ts,tsx,js,jsx}`, + `${__dirname}/dist/index.js`, +]; +module.exports.theme = designSystem.theme; diff --git a/apps/wing-console/console/ui/tailwind.config.cjs b/apps/wing-console/console/ui/tailwind.config.cjs index 7d68379da28..cfcc1f17971 100644 --- a/apps/wing-console/console/ui/tailwind.config.cjs +++ b/apps/wing-console/console/ui/tailwind.config.cjs @@ -1,8 +1,9 @@ +const { content, plugins, theme } = require("./tailwind-plugin.cjs"); + /** @type {import('tailwindcss').Config} */ module.exports = { - content: [ - "./src/**/*.{js,ts,jsx,tsx}", - "../design-system/src/**/*.{js,ts,jsx,tsx}", - ], - plugins: [require("@tailwindcss/forms")], + darkMode: "class", + content: [...content, "./index.html", "./src/**/*.{js,ts,jsx,tsx}"], + plugins: [...plugins], + theme: { ...theme }, }; diff --git a/apps/wing-console/console/ui/tsup.config.ts b/apps/wing-console/console/ui/tsup.config.ts index e4749db3b9b..7a3d66a9c8b 100644 --- a/apps/wing-console/console/ui/tsup.config.ts +++ b/apps/wing-console/console/ui/tsup.config.ts @@ -1,16 +1,8 @@ -import externalGlobalPlugin from "esbuild-plugin-external-global"; import { defineConfig } from "tsup"; export default defineConfig({ entry: ["src/index.ts"], - platform: "browser", - globalName: "WingConsole", - external: ["react", "react-dom"], - format: ["cjs", "esm", "iife"], - esbuildPlugins: [ - externalGlobalPlugin.externalGlobalPlugin({ - react: "window.React", - "react-dom": "window.ReactDOM", - }), - ], + format: ["esm"], + dts: true, + clean: true, }); diff --git a/apps/wing-playground/package-lock.json b/apps/wing-playground/package-lock.json index 9cc41103b68..dc36022b52a 100644 --- a/apps/wing-playground/package-lock.json +++ b/apps/wing-playground/package-lock.json @@ -127,7 +127,7 @@ "eslint-plugin-prettier": "^4.2.1", "eslint-plugin-sort-exports": "^0.8.0", "fs-extra": "^10.1.0", - "jsii": "~5.0.0", + "jsii": "5.0.11", "jsii-diff": "^1.73.0", "jsii-pacmak": "^1.73.0", "nanoid": "^3.3.4", @@ -152,6 +152,7 @@ "version": "0.0.0", "license": "MIT", "dependencies": { + "@wingconsole/app": "file:../wing-console/console/app", "@winglang/compiler": "file:../../libs/wingcompiler", "@winglang/sdk": "file:../../libs/wingsdk", "chalk": "^4.1.2", @@ -2343,7 +2344,7 @@ "express": "^4.18.2", "fs-extra": "^10.1.0", "ioredis": "^5.3.1", - "jsii": "~5.0.0", + "jsii": "5.0.11", "jsii-diff": "^1.73.0", "jsii-pacmak": "^1.73.0", "mime-types": "^2.1.35", @@ -3477,6 +3478,7 @@ "@types/node-persist": "^3.1.3", "@types/semver-utils": "^1.1.1", "@types/update-notifier": "^6.0.1", + "@wingconsole/app": "file:../wing-console/console/app", "@winglang/compiler": "file:../../libs/wingcompiler", "@winglang/sdk": "file:../../libs/wingsdk", "bump-pack": "file:../../tools/bump-pack", diff --git a/apps/wing/package-lock.json b/apps/wing/package-lock.json index a8bfabc76b5..00076cf1fc3 100644 --- a/apps/wing/package-lock.json +++ b/apps/wing/package-lock.json @@ -9,6 +9,7 @@ "version": "0.0.0", "license": "MIT", "dependencies": { + "@wingconsole/app": "file:../wing-console/console/app", "@winglang/compiler": "file:../../libs/wingcompiler", "@winglang/sdk": "file:../../libs/wingsdk", "chalk": "^4.1.2", @@ -147,7 +148,7 @@ "eslint-plugin-prettier": "^4.2.1", "eslint-plugin-sort-exports": "^0.8.0", "fs-extra": "^10.1.0", - "jsii": "~5.0.0", + "jsii": "5.0.11", "jsii-diff": "^1.73.0", "jsii-pacmak": "^1.73.0", "nanoid": "^3.3.4", @@ -185,6 +186,42 @@ "typescript": "^5.1.3" } }, + "../wing-console/console/app": { + "name": "@wingconsole/app", + "version": "0.0.0", + "license": "SEE LICENSE IN LICENSE.md", + "dependencies": { + "@wingconsole/server": "file:../server", + "analytics-node": "^6.2.0", + "express": "^4.18.2" + }, + "devDependencies": { + "@tailwindcss/forms": "^0.5.3", + "@types/analytics-node": "^3.1.11", + "@types/express": "^4.17.17", + "@types/react": "^18.2.12", + "@types/react-dom": "^18.2.5", + "@vitejs/plugin-react": "^4.0.0", + "@vitest/coverage-c8": "^0.31.4", + "@wingconsole/eslint-plugin": "file:../../tools/eslint-plugin", + "@wingconsole/tsconfig": "file:../../tools/tsconfig", + "@wingconsole/ui": "file:../ui", + "autoprefixer": "^10.4.14", + "bump-pack": "file:../../../../tools/bump-pack", + "conf": "^11.0.1", + "eslint": "^8.42.0", + "nanoid": "^4.0.2", + "open": "^9.1.0", + "react": "^18.2.0", + "react-dom": "^18.2.0", + "tailwindcss": "^3.3.2", + "tsup": "^6.7.0", + "tsx": "^3.12.7", + "typescript": "^5.1.3", + "vite": "^4.3.9", + "vitest": "^0.31.4" + } + }, "node_modules/@esbuild/android-arm": { "version": "0.17.19", "resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.17.19.tgz", @@ -728,6 +765,10 @@ "pretty-format": "^27.5.1" } }, + "node_modules/@wingconsole/app": { + "resolved": "../wing-console/console/app", + "link": true + }, "node_modules/@winglang/compiler": { "resolved": "../../libs/wingcompiler", "link": true @@ -3126,6 +3167,38 @@ "pretty-format": "^27.5.1" } }, + "@wingconsole/app": { + "version": "file:../wing-console/console/app", + "requires": { + "@tailwindcss/forms": "^0.5.3", + "@types/analytics-node": "^3.1.11", + "@types/express": "^4.17.17", + "@types/react": "^18.2.12", + "@types/react-dom": "^18.2.5", + "@vitejs/plugin-react": "^4.0.0", + "@vitest/coverage-c8": "^0.31.4", + "@wingconsole/eslint-plugin": "file:../../tools/eslint-plugin", + "@wingconsole/server": "file:../server", + "@wingconsole/tsconfig": "file:../../tools/tsconfig", + "@wingconsole/ui": "file:../ui", + "analytics-node": "^6.2.0", + "autoprefixer": "^10.4.14", + "bump-pack": "file:../../../../tools/bump-pack", + "conf": "^11.0.1", + "eslint": "^8.42.0", + "express": "^4.18.2", + "nanoid": "^4.0.2", + "open": "^9.1.0", + "react": "^18.2.0", + "react-dom": "^18.2.0", + "tailwindcss": "^3.3.2", + "tsup": "^6.7.0", + "tsx": "^3.12.7", + "typescript": "^5.1.3", + "vite": "^4.3.9", + "vitest": "^0.31.4" + } + }, "@winglang/compiler": { "version": "file:../../libs/wingcompiler", "requires": { @@ -3189,7 +3262,7 @@ "express": "^4.18.2", "fs-extra": "^10.1.0", "ioredis": "^5.3.1", - "jsii": "~5.0.0", + "jsii": "5.0.11", "jsii-diff": "^1.73.0", "jsii-pacmak": "^1.73.0", "mime-types": "^2.1.35", diff --git a/apps/wing/package.json b/apps/wing/package.json index 83c70f01eea..2b521deae99 100644 --- a/apps/wing/package.json +++ b/apps/wing/package.json @@ -36,8 +36,9 @@ "ora": "^5.4.1", "update-notifier": "^6.0.2", "vscode-languageserver": "^8.0.2", - "@winglang/sdk": "file:../../libs/wingsdk", - "@winglang/compiler": "file:../../libs/wingcompiler" + "@wingconsole/app": "file:../wing-console/console/app", + "@winglang/compiler": "file:../../libs/wingcompiler", + "@winglang/sdk": "file:../../libs/wingsdk" }, "devDependencies": { "@types/debug": "^4.1.7", @@ -45,10 +46,10 @@ "@types/node-persist": "^3.1.3", "@types/semver-utils": "^1.1.1", "@types/update-notifier": "^6.0.1", + "bump-pack": "file:../../tools/bump-pack", "esbuild": "^0.17.19", "typescript": "^4.9.4", - "vitest": "^0.30.1", - "bump-pack": "file:../../tools/bump-pack" + "vitest": "^0.30.1" }, "volta": { "node": "18.16.0", diff --git a/apps/wing/project.json b/apps/wing/project.json index 01cde51ef44..dc27b732f55 100644 --- a/apps/wing/project.json +++ b/apps/wing/project.json @@ -1,7 +1,7 @@ { "name": "winglang", "$schema": "../../node_modules/nx/schemas/project-schema.json", - "implicitDependencies": ["wingc", "sdk", "compiler"], + "implicitDependencies": ["wingc", "sdk", "compiler", "console-app"], "targets": { "build": { "dependsOn": ["^build"], diff --git a/apps/wing/src/cli.ts b/apps/wing/src/cli.ts index 6d588c329b0..3915272b9cd 100644 --- a/apps/wing/src/cli.ts +++ b/apps/wing/src/cli.ts @@ -58,8 +58,9 @@ async function main() { program .command("run") .alias("it") - .description("Runs a Wing simulator file in the Wing Console") - .argument("[simfile]", ".wsim simulator file") + .description("Runs a Wing program in the Wing Console") + .argument("[entrypoint]", "program .w entrypoint") + .option("-p, --port ", "specify port") .action(run); program.command("lsp").description("Run the Wing language server on stdio").action(run_server); diff --git a/apps/wing/src/commands/run.test.ts b/apps/wing/src/commands/run.test.ts index e6180526015..95b3cd5f6ac 100644 --- a/apps/wing/src/commands/run.test.ts +++ b/apps/wing/src/commands/run.test.ts @@ -1,4 +1,5 @@ import open from "open"; +import { createConsoleApp } from "@wingconsole/app"; import { run } from "./run"; import { mkdtemp } from "fs/promises"; import { join } from "path"; @@ -9,6 +10,16 @@ import { vi, test, expect } from "vitest"; vi.mock("open"); +vi.mock("@wingconsole/app", () => { + return { + createConsoleApp: vi.fn((options?: { requestedPort?: number }) => { + return { + port: options?.requestedPort ?? 3000, + }; + }), + }; +}); + test("wing it runs the only .w file", async () => { const workdir = await mkdtemp(join(tmpdir(), "-wing-it-test")); const prevdir = process.cwd(); @@ -18,7 +29,12 @@ test("wing it runs the only .w file", async () => { writeFileSync("foo.w", "bring cloud;"); await run(); - expect(open).toBeCalledWith("wing-console://" + resolve("foo.w")); + expect(createConsoleApp).toBeCalledWith({ + wingfile: resolve("foo.w"), + requestedPort: undefined, + hostUtils: expect.anything(), + }); + expect(open).toBeCalledWith("http://localhost:3000/"); } finally { process.chdir(prevdir); } @@ -48,7 +64,12 @@ test("wing it with a file runs", async () => { writeFileSync("foo.w", "bring cloud;"); await run("foo.w"); - expect(open).toBeCalledWith("wing-console://" + resolve("foo.w")); + expect(createConsoleApp).toBeCalledWith({ + wingfile: resolve("foo.w"), + requestedPort: undefined, + hostUtils: expect.anything(), + }); + expect(open).toBeCalledWith("http://localhost:3000/"); } finally { process.chdir(prevdir); } @@ -66,7 +87,12 @@ test("wing it with a nested file runs", async () => { writeFileSync(filePath, "bring cloud;"); await run(filePath); - expect(open).toBeCalledWith("wing-console://" + resolve(filePath)); + expect(createConsoleApp).toBeCalledWith({ + wingfile: resolve(filePath), + requestedPort: undefined, + hostUtils: expect.anything(), + }); + expect(open).toBeCalledWith("http://localhost:3000/"); } finally { process.chdir(prevdir); } @@ -85,3 +111,39 @@ test("wing it with an invalid file throws exception", async () => { process.chdir(prevdir); } }); + +test("wing it with a custom port runs", async () => { + const workdir = await mkdtemp(join(tmpdir(), "-wing-it-test")); + const prevdir = process.cwd(); + try { + process.chdir(workdir); + + writeFileSync("foo.w", "bring cloud;"); + + await run("foo.w", { port: "5000" }); + expect(createConsoleApp).toBeCalledWith({ + wingfile: resolve("foo.w"), + requestedPort: 5000, + hostUtils: expect.anything(), + }); + expect(open).toBeCalledWith("http://localhost:5000/"); + } finally { + process.chdir(prevdir); + } +}); + +test("wing it throws when invalid port number is used", async () => { + const workdir = await mkdtemp(join(tmpdir(), "-wing-it-test")); + const prevdir = process.cwd(); + try { + process.chdir(workdir); + + writeFileSync("foo.w", "bring cloud;"); + + await expect(async () => { + await run("foo.w", { port: "not a number" }); + }).rejects.toThrowError('"not a number" is not a number'); + } finally { + process.chdir(prevdir); + } +}); diff --git a/apps/wing/src/commands/run.ts b/apps/wing/src/commands/run.ts index 4240ecc1f61..f4e2135226e 100644 --- a/apps/wing/src/commands/run.ts +++ b/apps/wing/src/commands/run.ts @@ -2,21 +2,53 @@ import { readdirSync, existsSync } from "fs"; import { debug } from "debug"; import { resolve } from "path"; import open from "open"; +import { createConsoleApp } from "@wingconsole/app"; +import { parseNumericString } from "../util"; -export async function run(simfile?: string) { - if (!simfile) { +/** + * Options for the `run` command. + * This is passed from Commander to the `run` function. + */ +export interface RunOptions { + /** + * Preferred port number. + * + * Falls back to a random port number if necessary. + */ + readonly port?: string; +} + +/** + * Runs a Wing program in the Console. + * @param entrypoint The program .w entrypoint. Looks for a .w file in the current directory if not specified. + * @param options Run options. + */ +export async function run(entrypoint?: string, options?: RunOptions) { + if (!entrypoint) { const wingFiles = readdirSync(".").filter((item) => item.endsWith(".w")); if (wingFiles.length !== 1) { throw new Error("Please specify which file you want to run"); } - simfile = wingFiles[0]; + entrypoint = wingFiles[0]; } - if (!existsSync(simfile)) { - throw new Error(simfile + " doesn't exist"); + if (!existsSync(entrypoint)) { + throw new Error(entrypoint + " doesn't exist"); } - simfile = resolve(simfile); - debug("calling wing console protocol with:" + simfile); - await open("wing-console://" + simfile); + entrypoint = resolve(entrypoint); + debug("opening the wing console with:" + entrypoint); + + const { port } = await createConsoleApp({ + wingfile: entrypoint, + requestedPort: parseNumericString(options?.port), + hostUtils: { + async openExternal(url) { + await open(url); + }, + }, + }); + const url = `http://localhost:${port}/`; + await open(url); + console.log(`The Wing Console is running at ${url}`); } diff --git a/apps/wing/src/commands/test.ts b/apps/wing/src/commands/test.ts index acd5dda459f..ae0be9aaf65 100644 --- a/apps/wing/src/commands/test.ts +++ b/apps/wing/src/commands/test.ts @@ -25,73 +25,96 @@ const generateTestName = (path: string) => path.split(sep).slice(-2).join("/"); /** * Options for the `test` command. */ -export interface TestOptions extends CompileOptions { } +export interface TestOptions extends CompileOptions {} export async function test(entrypoints: string[], options: TestOptions) { const startTime = Date.now(); - const passing: string[] = []; - const failing: { testName: string; error: Error }[] = []; + const results: { testName: string; results: sdk.cloud.TestResult[] }[] = []; for (const entrypoint of entrypoints) { + const testName = generateTestName(entrypoint); try { - const results: sdk.cloud.TestResult[] | void = await testOne(entrypoint, options); - if (results?.some(({ pass }) => !pass)) { - failing.push( - ...results - ?.filter(({ pass }) => !pass) - .map((item) => ({ - testName: generateTestName(entrypoint), - error: new Error(item.error), - })) - ); - } else { - passing.push(generateTestName(entrypoint)); - } + const singleTestResults: sdk.cloud.TestResult[] | void = await testOne(entrypoint, options); + results.push({ testName, results: singleTestResults ?? [] }); } catch (error) { console.log((error as Error).message); - failing.push({ testName: generateTestName(entrypoint), error: error as Error }); + results.push({ + testName: generateTestName(entrypoint), + results: [{ pass: false, path: "", error: (error as Error).message, traces: [] }], + }); } } - printResults(passing, failing, Date.now() - startTime); + printResults(results, Date.now() - startTime); } function printResults( - passing: string[], - failing: { testName: string; error: Error }[], + testResults: { testName: string; results: sdk.cloud.TestResult[] }[], duration: number ) { const durationInSeconds = duration / 1000; - const totalSum = failing.length + passing.length; + const totalSum = testResults.length; + const failing = testResults.filter(({ results }) => results.some(({ pass }) => !pass)); + const passing = testResults.filter(({ results }) => results.every(({ pass }) => !!pass)); + const failingTestsNumber = failing.reduce( + (acc, { results }) => acc + results.filter(({ pass }) => !pass).length, + 0 + ); + const passingTestsNumber = testResults.reduce( + (acc, { results }) => acc + results.filter(({ pass }) => !!pass).length, + 0 + ); console.log(" "); // for getting a new line- \n does't seem to work :( - console.log(` -${totalSum > 1 - ? `Tests Results: -${passing.map((testName) => ` ${chalk.green("โœ“")} ${testName}`).join("\n")} -${failing.map(({ testName }) => ` ${chalk.red("ร—")} ${testName}`).join("\n")} -${" "} -` - : "" - } -${failing.length && totalSum > 1 - ? ` -${" "} -Errors:` + - failing - .map( - ({ testName, error }) => ` - -At ${testName}\n ${chalk.red(error.message)} - ` - ) - .join("\n\n") - : "" - } + const areErrors = failing.length > 0 && totalSum > 1; + const showTitle = totalSum > 1; + + const results = []; -${chalk.dim("Tests")}${failing.length ? chalk.red(` ${failing.length} failed`) : ""}${failing.length && passing.length ? chalk.dim(" |") : "" - }${passing.length ? chalk.green(` ${passing.length} passed`) : ""} ${chalk.dim(`(${totalSum})`)} -${chalk.dim("Duration")} ${Math.floor(durationInSeconds / 60)}m${(durationInSeconds % 60).toFixed( - 2 - )}s -`); + if (showTitle) { + // prints a list of the tests names with an icon + results.push(`Results:`); + results.push(...passing.map(({ testName }) => ` ${chalk.green("โœ“")} ${testName}`)); + results.push(...failing.map(({ testName }) => ` ${chalk.red("ร—")} ${testName}`)); + } + + if (areErrors) { + // prints error messages form failed tests + results.push(" "); + results.push("Errors:"); + results.push( + ...failing.map(({ testName, results }) => + [ + `At ${testName}`, + results.filter(({ pass }) => !pass).map(({ error }) => chalk.red(error)), + ].join("\n") + ) + ); + } + + // prints a summary of how many tests passed and failed + results.push(" "); + results.push( + `${chalk.dim("Tests")}${failingTestsNumber ? chalk.red(` ${failingTestsNumber} failed`) : ""}${ + failingTestsNumber && passingTestsNumber ? chalk.dim(" |") : "" + }${passingTestsNumber ? chalk.green(` ${passingTestsNumber} passed`) : ""} ${chalk.dim( + `(${failingTestsNumber + passingTestsNumber})` + )}` + ); + // prints a summary of how many tests files passed and failed + results.push( + `${chalk.dim("Test Files")}${failing.length ? chalk.red(` ${failing.length} failed`) : ""}${ + failing.length && passing.length ? chalk.dim(" |") : "" + }${passing.length ? chalk.green(` ${passing.length} passed`) : ""} ${chalk.dim( + `(${totalSum})` + )}` + ); + + // prints the test duration + results.push( + `${chalk.dim("Duration")} ${Math.floor(durationInSeconds / 60)}m${( + durationInSeconds % 60 + ).toFixed(2)}s` + ); + + console.log(results.filter((value) => !!value).join("\n")); } async function testOne(entrypoint: string, options: TestOptions) { @@ -224,9 +247,7 @@ async function testSimulator(synthDir: string) { rmSync(synthDir, { recursive: true, force: true }); - if (testResultsContainsFailure(results)) { - throw Error(results.map(({ error }) => error).join("\n")); - } + return results; } async function testAwsCdk(synthDir: string): Promise { @@ -236,7 +257,11 @@ async function testAwsCdk(synthDir: string): Promise { await withSpinner("cdk deploy", () => awsCdkDeploy(synthDir)); const [testRunner, tests] = await withSpinner("Setting up test runner...", async () => { - const testArns = await awsCdkOutput(synthDir, ENV_WING_TEST_RUNNER_FUNCTION_ARNS_AWSCDK, process.env.CDK_STACK_NAME!); + const testArns = await awsCdkOutput( + synthDir, + ENV_WING_TEST_RUNNER_FUNCTION_ARNS_AWSCDK, + process.env.CDK_STACK_NAME! + ); const testRunner = new TestRunnerClient(testArns); const tests = await testRunner.listTests(); @@ -283,7 +308,9 @@ async function isAwsCdkInstalled(synthDir: string) { } export async function awsCdkDeploy(synthDir: string) { - await execCapture("cdk deploy --require-approval never --ci true -O ./output.json --app . ", { cwd: synthDir }); + await execCapture("cdk deploy --require-approval never --ci true -O ./output.json --app . ", { + cwd: synthDir, + }); } export async function awsCdkDestroy(synthDir: string) { diff --git a/apps/wing/src/util.ts b/apps/wing/src/util.ts index 31575c3ca3b..c16b33d43fb 100644 --- a/apps/wing/src/util.ts +++ b/apps/wing/src/util.ts @@ -73,3 +73,23 @@ export async function generateTmpDir(sourcePath: string, ...additionalFiles: str return tempWingFile; } + +/** + * Casts a numeric string to a number. + * + * Returns `undefined` if the string is empty. + * + * @throws If the string is not a number. + */ +export function parseNumericString(text?: string) { + if (!text) { + return undefined; + } + + const number = Number(text); + if (isNaN(number)) { + throw new Error(`"${text}" is not a number`); + } + + return number; +} diff --git a/docs/01-start-here/06-learn-more.md b/docs/01-start-here/06-learn-more.md deleted file mode 100644 index f47491d31a6..00000000000 --- a/docs/01-start-here/06-learn-more.md +++ /dev/null @@ -1,10 +0,0 @@ ---- -title: Learn more -id: learn-more -description: Tutorials and Workshopts -keywords: [Wing] ---- - -links to tutorials, workshops, examples repos, etc - -TODO diff --git a/docs/02-concepts/03-simulator.md b/docs/02-concepts/03-simulator.md deleted file mode 100644 index 5b358b0c5f2..00000000000 --- a/docs/02-concepts/03-simulator.md +++ /dev/null @@ -1,92 +0,0 @@ ---- -title: Simulator -id: simulator -description: A facility for executing Wing applications on the local machine for development and testing -keywords: [Wing simulator, simulator] ---- - -The simulator is a set of APIs in the standard library that can be used to test Wing -applications without having to deploy the application to a cloud provider. The -simulator works with any Wing application made with the standard library's `cloud` APIs. - -## Quick start guide - -### Create a Wing simulator file - -To use the simulator, you will need to provide a Wing simulator file -- this is -a file with a `.wsim` extension that is output when you compile your Wing program -with the `--target sim` option. Check out the [Wing Getting Started -Guide](/) for more information on how to write your -first Wing program. - -## Using the simulator API (in Wing) - -๐Ÿšง Coming soon! ๐Ÿšง - -## Using the simulator API (in TypeScript) - -Now, let's try starting the simulator and creating some resource clients to -interact with the resources. - -First, create an empty directory and add your `.wsim` file. -Next, run `npm install @winglang/sdk`. - -Let's create a file in the directory named `main.ts`: - -```typescript -import { testing } from '@winglang/sdk'; - -async function main() { - const mySim = new testing.Simulator({ simfile: "hello.wsim" }); - await mySim.start(); - - // (1) - - await mySim.stop(); -} - -void main(); -``` - -Here, we create a new `Simulator` object, passing in the path to our simulator -file, and then start the simulator. Inside (1) we can invoke methods on the -simulator to get more information about the resources in our application. When -we are done, we call `sim.stop()` to stop the simulator and clean up all -resources (files, ports, etc.) that were created on your machine. - -To print out a JSON tree view of the application, add the following line: - -```typescript -console.log(JSON.stringify(sim.tree, null, 2)); -``` - -The tree contains the IDs of all the resources in the application, as well as -details about dependencies between resources. - -Now let's perform operations using a resource client. To obtain a resource's -client, get the resource's path (from the JSON tree or elsewhere) and query the -simulator with the `getResource` method. For example: - -```typescript -import { cloud } from '@winglang/sdk'; - -const fn = mySim.getResource("root/my_function") as cloud.IFunctionClient; -const response = await fn.invoke("hello!"); -console.log(response); -``` - -Finally, when you want to understand how Wing resources are working, you may -want to debug your application using traces and logs. Simulated resources -automatically generate traces that you can inspect by calling `listTraces()` on -your simulator instance. - -```typescript -console.log(JSON.stringify(mySim.listTraces(), null, 2)); -``` - - - -Congratulations, you now know the ins and outs of using the Wing simulator! ๐Ÿง‘โ€๐ŸŽ“ - -Check the API reference for more details about what methods are available on -different resources and their inflight clients. diff --git a/docs/03-language-guide/01-basic-syntax.md b/docs/03-language-guide/01-basic-syntax.md deleted file mode 100644 index 3714d81a768..00000000000 --- a/docs/03-language-guide/01-basic-syntax.md +++ /dev/null @@ -1,6 +0,0 @@ ---- -title: Basic syntax -id: basic-syntax ---- - -TODO (for now, see the [language spec RFC](../999-contributors/999-rfcs/2023-06-12-language-spec.md)) diff --git a/docs/03-language-guide/02-basic-types.md b/docs/03-language-guide/02-basic-types.md deleted file mode 100644 index d01ade083a1..00000000000 --- a/docs/03-language-guide/02-basic-types.md +++ /dev/null @@ -1,6 +0,0 @@ ---- -title: Basic types -id: basic-types ---- - -TODO (for now, see the [language spec RFC](../999-contributors/999-rfcs/2023-06-12-language-spec.md)) diff --git a/docs/03-language-guide/03-control-flow.md b/docs/03-language-guide/03-control-flow.md deleted file mode 100644 index 87147a2b804..00000000000 --- a/docs/03-language-guide/03-control-flow.md +++ /dev/null @@ -1,6 +0,0 @@ ---- -title: Control flow -id: control-flow ---- - -TODO (for now, see the [language spec RFC](../999-contributors/999-rfcs/2023-06-12-language-spec.md)) diff --git a/docs/03-language-guide/04-immutability.md b/docs/03-language-guide/04-immutability.md deleted file mode 100644 index 25dbf2b9eeb..00000000000 --- a/docs/03-language-guide/04-immutability.md +++ /dev/null @@ -1,6 +0,0 @@ ---- -title: Immutability -id: immutability ---- - -TODO (for now, see the [language spec RFC](../999-contributors/999-rfcs/2023-06-12-language-spec.md)) diff --git a/docs/03-language-guide/05-null-safety.md b/docs/03-language-guide/05-null-safety.md deleted file mode 100644 index aa1db869102..00000000000 --- a/docs/03-language-guide/05-null-safety.md +++ /dev/null @@ -1,6 +0,0 @@ ---- -title: Null safety -id: null-safety ---- - -TODO (for now, see the [language spec RFC](../999-contributors/999-rfcs/2023-06-12-language-spec.md)) diff --git a/docs/03-language-guide/06-modules.md b/docs/03-language-guide/06-modules.md deleted file mode 100644 index 78316617a14..00000000000 --- a/docs/03-language-guide/06-modules.md +++ /dev/null @@ -1,6 +0,0 @@ ---- -title: Modules -id: modules ---- - -TODO (for now, see the [language spec RFC](../999-contributors/999-rfcs/2023-06-12-language-spec.md)) diff --git a/docs/03-language-guide/07-functions.md b/docs/03-language-guide/07-functions.md deleted file mode 100644 index 9d2f7bf6385..00000000000 --- a/docs/03-language-guide/07-functions.md +++ /dev/null @@ -1,6 +0,0 @@ ---- -title: Functions -id: functions ---- - -TODO (for now, see the [language spec RFC](../999-contributors/999-rfcs/2023-06-12-language-spec.md)) diff --git a/docs/03-language-guide/08-classes-and-interfaces.md b/docs/03-language-guide/08-classes-and-interfaces.md deleted file mode 100644 index bd7ec2394a7..00000000000 --- a/docs/03-language-guide/08-classes-and-interfaces.md +++ /dev/null @@ -1,6 +0,0 @@ ---- -title: Classes and interfaces -id: classes-and-interfaces ---- - -TODO (for now, see the [language spec RFC](../999-contributors/999-rfcs/2023-06-12-language-spec.md)) diff --git a/docs/03-language-guide/09-preflight-inflight.md b/docs/03-language-guide/09-preflight-inflight.md deleted file mode 100644 index 79e23a078b6..00000000000 --- a/docs/03-language-guide/09-preflight-inflight.md +++ /dev/null @@ -1,6 +0,0 @@ ---- -title: Preflight and Inflight -id: preflight-inflight ---- - -TODO (for now, see the [language spec RFC](../999-contributors/999-rfcs/2023-06-12-language-spec.md)) diff --git a/docs/03-language-guide/10-enums.md b/docs/03-language-guide/10-enums.md deleted file mode 100644 index e15ece4c54c..00000000000 --- a/docs/03-language-guide/10-enums.md +++ /dev/null @@ -1,6 +0,0 @@ ---- -title: Enums -id: enums ---- - -TODO (for now, see the [language spec RFC](../999-contributors/999-rfcs/2023-06-12-language-spec.md)) diff --git a/docs/03-language-guide/11-structs.md b/docs/03-language-guide/11-structs.md deleted file mode 100644 index fa7e53d6f12..00000000000 --- a/docs/03-language-guide/11-structs.md +++ /dev/null @@ -1,6 +0,0 @@ ---- -title: Structs -id: structs ---- - -TODO (for now, see the [language spec RFC](../999-contributors/999-rfcs/2023-06-12-language-spec.md)) diff --git a/docs/03-language-guide/12-javascript.md b/docs/03-language-guide/12-javascript.md deleted file mode 100644 index f223de7e077..00000000000 --- a/docs/03-language-guide/12-javascript.md +++ /dev/null @@ -1,6 +0,0 @@ ---- -title: JavaScript interoperability -id: javascript-interop ---- - -TODO (for now, see the [language spec RFC](../999-contributors/999-rfcs/2023-06-12-language-spec.md)) diff --git a/docs/03-language-guide/13-testing.md b/docs/03-language-guide/13-testing.md deleted file mode 100644 index 60085b6de74..00000000000 --- a/docs/03-language-guide/13-testing.md +++ /dev/null @@ -1,6 +0,0 @@ ---- -title: Testing -id: testing ---- - -TODO (for now, see the [language spec RFC](../999-contributors/999-rfcs/2023-06-12-language-spec.md)) diff --git a/docs/03-language-guide/50-reference/01-keywords.md b/docs/03-language-guide/50-reference/01-keywords.md deleted file mode 100644 index deb0bcc5546..00000000000 --- a/docs/03-language-guide/50-reference/01-keywords.md +++ /dev/null @@ -1,7 +0,0 @@ ---- -title: Keywords -id: keywords -description: A list of all reserved keywords in Wing. ---- - -TODO diff --git a/docs/03-language-guide/50-reference/02-operators.md b/docs/03-language-guide/50-reference/02-operators.md deleted file mode 100644 index 9ab34f566cd..00000000000 --- a/docs/03-language-guide/50-reference/02-operators.md +++ /dev/null @@ -1,7 +0,0 @@ ---- -title: Operators -id: operators -description: A list of all built-in operators in Wing. ---- - -TODO diff --git a/docs/03-language-guide/50-reference/03-grammar.md b/docs/03-language-guide/50-reference/03-grammar.md deleted file mode 100644 index f8efd90118d..00000000000 --- a/docs/03-language-guide/50-reference/03-grammar.md +++ /dev/null @@ -1,7 +0,0 @@ ---- -title: Grammar -id: grammar -description: A specification of Wing's grammar. ---- - -TODO diff --git a/docs/03-language-guide/50-reference/_category_.yml b/docs/03-language-guide/50-reference/_category_.yml deleted file mode 100644 index 41ffe266dd7..00000000000 --- a/docs/03-language-guide/50-reference/_category_.yml +++ /dev/null @@ -1,3 +0,0 @@ -label: Reference material -collapsible: true -collapsed: false diff --git a/docs/04-standard-library/02-basic-types/_category_.yml b/docs/04-standard-library/02-basic-types/_category_.yml deleted file mode 100644 index 2a88555606a..00000000000 --- a/docs/04-standard-library/02-basic-types/_category_.yml +++ /dev/null @@ -1,3 +0,0 @@ -label: Built-in types -collapsible: true -collapsed: false diff --git a/docs/04-standard-library/04-api-reference.md b/docs/04-standard-library/04-api-reference.md deleted file mode 100644 index 86c4e8dac53..00000000000 --- a/docs/04-standard-library/04-api-reference.md +++ /dev/null @@ -1,6922 +0,0 @@ ---- -title: API reference -id: sdk -description: Wing standard library API reference -keywords: [Wing sdk, sdk, Wing API Reference] ---- - -# API Reference - -## Resources - -### Api - -Functionality shared between all `Api` implementations. - -#### Initializers - -```wing -bring cloud; - -new cloud.Api(props?: ApiProps) -``` - -| **Name** | **Type** | **Description** | -| --- | --- | --- | -| props | ApiProps | *No description.* | - ---- - -##### `props`Optional - -- *Type:* ApiProps - ---- - -#### Methods - -| **Name** | **Description** | -| --- | --- | -| connect | Add a inflight handler to the api for CONNECT requests on the given path. | -| delete | Add a inflight handler to the api for DELETE requests on the given path. | -| get | Add a inflight handler to the api for GET requests on the given path. | -| head | Add a inflight handler to the api for HEAD requests on the given path. | -| options | Add a inflight handler to the api for OPTIONS requests on the given path. | -| patch | Add a inflight handler to the api for PATCH requests on the given path. | -| post | Add a inflight handler to the api for POST requests on the given path. | -| put | Add a inflight handler to the api for PUT requests on the given path. | - ---- - -##### `connect` - -```wing -connect(path: str, inflight: IApiEndpointHandler, props?: ApiConnectProps): void -``` - -Add a inflight handler to the api for CONNECT requests on the given path. - -###### `path`Required - -- *Type:* str - -The path to handle CONNECT requests for. - ---- - -###### `inflight`Required - -- *Type:* IApiEndpointHandler - -The function to handle the request. - ---- - -###### `props`Optional - -- *Type:* ApiConnectProps - -Options for the route. - ---- - -##### `delete` - -```wing -delete(path: str, inflight: IApiEndpointHandler, props?: ApiDeleteProps): void -``` - -Add a inflight handler to the api for DELETE requests on the given path. - -###### `path`Required - -- *Type:* str - -The path to handle DELETE requests for. - ---- - -###### `inflight`Required - -- *Type:* IApiEndpointHandler - -The function to handle the request. - ---- - -###### `props`Optional - -- *Type:* ApiDeleteProps - -Options for the route. - ---- - -##### `get` - -```wing -get(path: str, inflight: IApiEndpointHandler, props?: ApiGetProps): void -``` - -Add a inflight handler to the api for GET requests on the given path. - -###### `path`Required - -- *Type:* str - -The path to handle GET requests for. - ---- - -###### `inflight`Required - -- *Type:* IApiEndpointHandler - -The function to handle the request. - ---- - -###### `props`Optional - -- *Type:* ApiGetProps - -Options for the route. - ---- - -##### `head` - -```wing -head(path: str, inflight: IApiEndpointHandler, props?: ApiHeadProps): void -``` - -Add a inflight handler to the api for HEAD requests on the given path. - -###### `path`Required - -- *Type:* str - -The path to handle HEAD requests for. - ---- - -###### `inflight`Required - -- *Type:* IApiEndpointHandler - -The function to handle the request. - ---- - -###### `props`Optional - -- *Type:* ApiHeadProps - -Options for the route. - ---- - -##### `options` - -```wing -options(path: str, inflight: IApiEndpointHandler, props?: ApiOptionsProps): void -``` - -Add a inflight handler to the api for OPTIONS requests on the given path. - -###### `path`Required - -- *Type:* str - -The path to handle OPTIONS requests for. - ---- - -###### `inflight`Required - -- *Type:* IApiEndpointHandler - -The function to handle the request. - ---- - -###### `props`Optional - -- *Type:* ApiOptionsProps - -Options for the route. - ---- - -##### `patch` - -```wing -patch(path: str, inflight: IApiEndpointHandler, props?: ApiPatchProps): void -``` - -Add a inflight handler to the api for PATCH requests on the given path. - -###### `path`Required - -- *Type:* str - -The path to handle PATCH requests for. - ---- - -###### `inflight`Required - -- *Type:* IApiEndpointHandler - -The function to handle the request. - ---- - -###### `props`Optional - -- *Type:* ApiPatchProps - -Options for the route. - ---- - -##### `post` - -```wing -post(path: str, inflight: IApiEndpointHandler, props?: ApiPostProps): void -``` - -Add a inflight handler to the api for POST requests on the given path. - -###### `path`Required - -- *Type:* str - -The path to handle POST requests for. - ---- - -###### `inflight`Required - -- *Type:* IApiEndpointHandler - -The function to handle the request. - ---- - -###### `props`Optional - -- *Type:* ApiPostProps - -Options for the route. - ---- - -##### `put` - -```wing -put(path: str, inflight: IApiEndpointHandler, props?: ApiPutProps): void -``` - -Add a inflight handler to the api for PUT requests on the given path. - -###### `path`Required - -- *Type:* str - -The path to handle PUT requests for. - ---- - -###### `inflight`Required - -- *Type:* IApiEndpointHandler - -The function to handle the request. - ---- - -###### `props`Optional - -- *Type:* ApiPutProps - -Options for the route. - ---- - - -#### Properties - -| **Name** | **Type** | **Description** | -| --- | --- | --- | -| node | constructs.Node | The tree node. | -| display | Display | Information on how to display a resource in the UI. | -| url | str | The base URL of the API endpoint. | - ---- - -##### `node`Required - -```wing -node: Node; -``` - -- *Type:* constructs.Node - -The tree node. - ---- - -##### `display`Required - -```wing -display: Display; -``` - -- *Type:* Display - -Information on how to display a resource in the UI. - ---- - -##### `url`Required - -```wing -url: str; -``` - -- *Type:* str - -The base URL of the API endpoint. - ---- - - -### Bucket - -**Inflight client:** [@winglang/sdk.cloud.IBucketClient](#@winglang/sdk.cloud.IBucketClient) - -Represents a cloud object store. - -#### Initializers - -```wing -bring cloud; - -new cloud.Bucket(props?: BucketProps) -``` - -| **Name** | **Type** | **Description** | -| --- | --- | --- | -| props | BucketProps | *No description.* | - ---- - -##### `props`Optional - -- *Type:* BucketProps - ---- - -#### Methods - -| **Name** | **Description** | -| --- | --- | -| addObject | Add a file to the bucket that is uploaded when the app is deployed. | -| onCreate | Run an inflight whenever a file is uploaded to the bucket. | -| onDelete | Run an inflight whenever a file is deleted from the bucket. | -| onEvent | Run an inflight whenever a file is uploaded, modified, or deleted from the bucket. | -| onUpdate | Run an inflight whenever a file is updated in the bucket. | - ---- - -##### `addObject` - -```wing -addObject(key: str, body: str): void -``` - -Add a file to the bucket that is uploaded when the app is deployed. - -TODO: In the future this will support uploading any `Blob` type or -referencing a file from the local filesystem. - -###### `key`Required - -- *Type:* str - ---- - -###### `body`Required - -- *Type:* str - ---- - -##### `onCreate` - -```wing -onCreate(fn: IBucketEventHandler, opts?: BucketOnCreateProps): void -``` - -Run an inflight whenever a file is uploaded to the bucket. - -###### `fn`Required - -- *Type:* IBucketEventHandler - ---- - -###### `opts`Optional - -- *Type:* BucketOnCreateProps - ---- - -##### `onDelete` - -```wing -onDelete(fn: IBucketEventHandler, opts?: BucketOnDeleteProps): void -``` - -Run an inflight whenever a file is deleted from the bucket. - -###### `fn`Required - -- *Type:* IBucketEventHandler - ---- - -###### `opts`Optional - -- *Type:* BucketOnDeleteProps - ---- - -##### `onEvent` - -```wing -onEvent(fn: IBucketEventHandler, opts?: BucketOnEventProps): void -``` - -Run an inflight whenever a file is uploaded, modified, or deleted from the bucket. - -###### `fn`Required - -- *Type:* IBucketEventHandler - ---- - -###### `opts`Optional - -- *Type:* BucketOnEventProps - ---- - -##### `onUpdate` - -```wing -onUpdate(fn: IBucketEventHandler, opts?: BucketOnUpdateProps): void -``` - -Run an inflight whenever a file is updated in the bucket. - -###### `fn`Required - -- *Type:* IBucketEventHandler - ---- - -###### `opts`Optional - -- *Type:* BucketOnUpdateProps - ---- - - -#### Properties - -| **Name** | **Type** | **Description** | -| --- | --- | --- | -| node | constructs.Node | The tree node. | -| display | Display | Information on how to display a resource in the UI. | - ---- - -##### `node`Required - -```wing -node: Node; -``` - -- *Type:* constructs.Node - -The tree node. - ---- - -##### `display`Required - -```wing -display: Display; -``` - -- *Type:* Display - -Information on how to display a resource in the UI. - ---- - - -### Counter - -**Inflight client:** [@winglang/sdk.cloud.ICounterClient](#@winglang/sdk.cloud.ICounterClient) - -Represents a distributed atomic counter. - -#### Initializers - -```wing -bring cloud; - -new cloud.Counter(props?: CounterProps) -``` - -| **Name** | **Type** | **Description** | -| --- | --- | --- | -| props | CounterProps | *No description.* | - ---- - -##### `props`Optional - -- *Type:* CounterProps - ---- - - - -#### Properties - -| **Name** | **Type** | **Description** | -| --- | --- | --- | -| node | constructs.Node | The tree node. | -| display | Display | Information on how to display a resource in the UI. | -| initial | num | The initial value of the counter. | - ---- - -##### `node`Required - -```wing -node: Node; -``` - -- *Type:* constructs.Node - -The tree node. - ---- - -##### `display`Required - -```wing -display: Display; -``` - -- *Type:* Display - -Information on how to display a resource in the UI. - ---- - -##### `initial`Required - -```wing -initial: num; -``` - -- *Type:* num - -The initial value of the counter. - ---- - - -### Function - -- *Implements:* IInflightHost - -**Inflight client:** [@winglang/sdk.cloud.IFunctionClient](#@winglang/sdk.cloud.IFunctionClient) - -Represents a function. - -#### Initializers - -```wing -bring cloud; - -new cloud.Function(inflight: IFunctionHandler, props?: FunctionProps) -``` - -| **Name** | **Type** | **Description** | -| --- | --- | --- | -| inflight | IFunctionHandler | *No description.* | -| props | FunctionProps | *No description.* | - ---- - -##### `inflight`Required - -- *Type:* IFunctionHandler - ---- - -##### `props`Optional - -- *Type:* FunctionProps - ---- - -#### Methods - -| **Name** | **Description** | -| --- | --- | -| addEnvironment | Add an environment variable to the function. | - ---- - -##### `addEnvironment` - -```wing -addEnvironment(name: str, value: str): void -``` - -Add an environment variable to the function. - -###### `name`Required - -- *Type:* str - ---- - -###### `value`Required - -- *Type:* str - ---- - - -#### Properties - -| **Name** | **Type** | **Description** | -| --- | --- | --- | -| node | constructs.Node | The tree node. | -| display | Display | Information on how to display a resource in the UI. | -| env | MutMap<str> | Returns the set of environment variables for this function. | - ---- - -##### `node`Required - -```wing -node: Node; -``` - -- *Type:* constructs.Node - -The tree node. - ---- - -##### `display`Required - -```wing -display: Display; -``` - -- *Type:* Display - -Information on how to display a resource in the UI. - ---- - -##### `env`Required - -```wing -env: MutMap; -``` - -- *Type:* MutMap<str> - -Returns the set of environment variables for this function. - ---- - - -### Queue - -**Inflight client:** [@winglang/sdk.cloud.IQueueClient](#@winglang/sdk.cloud.IQueueClient) - -Represents a queue. - -#### Initializers - -```wing -bring cloud; - -new cloud.Queue(props?: QueueProps) -``` - -| **Name** | **Type** | **Description** | -| --- | --- | --- | -| props | QueueProps | *No description.* | - ---- - -##### `props`Optional - -- *Type:* QueueProps - ---- - -#### Methods - -| **Name** | **Description** | -| --- | --- | -| setConsumer | Create a function to consume messages from this queue. | - ---- - -##### `setConsumer` - -```wing -setConsumer(handler: IQueueSetConsumerHandler, props?: QueueSetConsumerProps): Function -``` - -Create a function to consume messages from this queue. - -###### `handler`Required - -- *Type:* IQueueSetConsumerHandler - ---- - -###### `props`Optional - -- *Type:* QueueSetConsumerProps - ---- - - -#### Properties - -| **Name** | **Type** | **Description** | -| --- | --- | --- | -| node | constructs.Node | The tree node. | -| display | Display | Information on how to display a resource in the UI. | - ---- - -##### `node`Required - -```wing -node: Node; -``` - -- *Type:* constructs.Node - -The tree node. - ---- - -##### `display`Required - -```wing -display: Display; -``` - -- *Type:* Display - -Information on how to display a resource in the UI. - ---- - - -### Resource - -- *Implements:* IResource - -Shared behavior between all Wing SDK resources. - -#### Initializers - -```wing -bring std; - -new std.Resource() -``` - -| **Name** | **Type** | **Description** | -| --- | --- | --- | - ---- - - - -#### Properties - -| **Name** | **Type** | **Description** | -| --- | --- | --- | -| node | constructs.Node | The tree node. | -| display | Display | Information on how to display a resource in the UI. | - ---- - -##### `node`Required - -```wing -node: Node; -``` - -- *Type:* constructs.Node - -The tree node. - ---- - -##### `display`Required - -```wing -display: Display; -``` - -- *Type:* Display - -Information on how to display a resource in the UI. - ---- - - -### Schedule - -**Inflight client:** [@winglang/sdk.cloud.IScheduleClient](#@winglang/sdk.cloud.IScheduleClient) - -Represents a schedule. - -#### Initializers - -```wing -bring cloud; - -new cloud.Schedule(props?: ScheduleProps) -``` - -| **Name** | **Type** | **Description** | -| --- | --- | --- | -| props | ScheduleProps | *No description.* | - ---- - -##### `props`Optional - -- *Type:* ScheduleProps - ---- - -#### Methods - -| **Name** | **Description** | -| --- | --- | -| onTick | Create a function that runs when receiving the scheduled event. | - ---- - -##### `onTick` - -```wing -onTick(inflight: IScheduleOnTickHandler, props?: ScheduleOnTickProps): Function -``` - -Create a function that runs when receiving the scheduled event. - -###### `inflight`Required - -- *Type:* IScheduleOnTickHandler - ---- - -###### `props`Optional - -- *Type:* ScheduleOnTickProps - ---- - - -#### Properties - -| **Name** | **Type** | **Description** | -| --- | --- | --- | -| node | constructs.Node | The tree node. | -| display | Display | Information on how to display a resource in the UI. | - ---- - -##### `node`Required - -```wing -node: Node; -``` - -- *Type:* constructs.Node - -The tree node. - ---- - -##### `display`Required - -```wing -display: Display; -``` - -- *Type:* Display - -Information on how to display a resource in the UI. - ---- - - -### Secret - -**Inflight client:** [@winglang/sdk.cloud.ISecretClient](#@winglang/sdk.cloud.ISecretClient) - -Represents a cloud secret. - -#### Initializers - -```wing -bring cloud; - -new cloud.Secret(props?: SecretProps) -``` - -| **Name** | **Type** | **Description** | -| --- | --- | --- | -| props | SecretProps | *No description.* | - ---- - -##### `props`Optional - -- *Type:* SecretProps - ---- - - - -#### Properties - -| **Name** | **Type** | **Description** | -| --- | --- | --- | -| node | constructs.Node | The tree node. | -| display | Display | Information on how to display a resource in the UI. | - ---- - -##### `node`Required - -```wing -node: Node; -``` - -- *Type:* constructs.Node - -The tree node. - ---- - -##### `display`Required - -```wing -display: Display; -``` - -- *Type:* Display - -Information on how to display a resource in the UI. - ---- - - -### Service - -**Inflight client:** [@winglang/sdk.cloud.IServiceClient](#@winglang/sdk.cloud.IServiceClient) - -Represents a service. - -#### Initializers - -```wing -bring cloud; - -new cloud.Service(props: ServiceProps) -``` - -| **Name** | **Type** | **Description** | -| --- | --- | --- | -| props | ServiceProps | *No description.* | - ---- - -##### `props`Required - -- *Type:* ServiceProps - ---- - - - -#### Properties - -| **Name** | **Type** | **Description** | -| --- | --- | --- | -| node | constructs.Node | The tree node. | -| display | Display | Information on how to display a resource in the UI. | - ---- - -##### `node`Required - -```wing -node: Node; -``` - -- *Type:* constructs.Node - -The tree node. - ---- - -##### `display`Required - -```wing -display: Display; -``` - -- *Type:* Display - -Information on how to display a resource in the UI. - ---- - - -### Table - -**Inflight client:** [@winglang/sdk.cloud.ITableClient](#@winglang/sdk.cloud.ITableClient) - -Represents a NoSQL database table that can be used to store and query data. - -#### Initializers - -```wing -bring cloud; - -new cloud.Table(props: TableProps) -``` - -| **Name** | **Type** | **Description** | -| --- | --- | --- | -| props | TableProps | *No description.* | - ---- - -##### `props`Required - -- *Type:* TableProps - ---- - - - -#### Properties - -| **Name** | **Type** | **Description** | -| --- | --- | --- | -| node | constructs.Node | The tree node. | -| display | Display | Information on how to display a resource in the UI. | -| columns | MutMap<ColumnType> | Table columns. | -| name | str | Table name. | -| primaryKey | str | Table primary key name. | - ---- - -##### `node`Required - -```wing -node: Node; -``` - -- *Type:* constructs.Node - -The tree node. - ---- - -##### `display`Required - -```wing -display: Display; -``` - -- *Type:* Display - -Information on how to display a resource in the UI. - ---- - -##### `columns`Required - -```wing -columns: MutMap; -``` - -- *Type:* MutMap<ColumnType> - -Table columns. - ---- - -##### `name`Required - -```wing -name: str; -``` - -- *Type:* str - -Table name. - ---- - -##### `primaryKey`Required - -```wing -primaryKey: str; -``` - -- *Type:* str - -Table primary key name. - ---- - - -### Test - -- *Implements:* IInflightHost - -**Inflight client:** [@winglang/sdk.cloud.ITestClient](#@winglang/sdk.cloud.ITestClient) - -Represents a unit test. - -#### Initializers - -```wing -bring std; - -new std.Test(inflight: ITestHandler, props?: TestProps) -``` - -| **Name** | **Type** | **Description** | -| --- | --- | --- | -| inflight | ITestHandler | *No description.* | -| props | TestProps | *No description.* | - ---- - -##### `inflight`Required - -- *Type:* ITestHandler - ---- - -##### `props`Optional - -- *Type:* TestProps - ---- - - - -#### Properties - -| **Name** | **Type** | **Description** | -| --- | --- | --- | -| node | constructs.Node | The tree node. | -| display | Display | Information on how to display a resource in the UI. | - ---- - -##### `node`Required - -```wing -node: Node; -``` - -- *Type:* constructs.Node - -The tree node. - ---- - -##### `display`Required - -```wing -display: Display; -``` - -- *Type:* Display - -Information on how to display a resource in the UI. - ---- - - -### TestRunner - -**Inflight client:** [@winglang/sdk.cloud.ITestRunnerClient](#@winglang/sdk.cloud.ITestRunnerClient) - -Represents a test engine. - -#### Initializers - -```wing -bring cloud; - -new cloud.TestRunner(props?: TestRunnerProps) -``` - -| **Name** | **Type** | **Description** | -| --- | --- | --- | -| props | TestRunnerProps | *No description.* | - ---- - -##### `props`Optional - -- *Type:* TestRunnerProps - ---- - -#### Methods - -| **Name** | **Description** | -| --- | --- | -| findTests | Find all tests in the construct tree. | - ---- - -##### `findTests` - -```wing -findTests(): MutArray -``` - -Find all tests in the construct tree. - - -#### Properties - -| **Name** | **Type** | **Description** | -| --- | --- | --- | -| node | constructs.Node | The tree node. | -| display | Display | Information on how to display a resource in the UI. | - ---- - -##### `node`Required - -```wing -node: Node; -``` - -- *Type:* constructs.Node - -The tree node. - ---- - -##### `display`Required - -```wing -display: Display; -``` - -- *Type:* Display - -Information on how to display a resource in the UI. - ---- - - -### Topic - -**Inflight client:** [@winglang/sdk.cloud.ITopicClient](#@winglang/sdk.cloud.ITopicClient) - -Represents a topic. - -#### Initializers - -```wing -bring cloud; - -new cloud.Topic(props?: TopicProps) -``` - -| **Name** | **Type** | **Description** | -| --- | --- | --- | -| props | TopicProps | *No description.* | - ---- - -##### `props`Optional - -- *Type:* TopicProps - ---- - -#### Methods - -| **Name** | **Description** | -| --- | --- | -| onMessage | Run an inflight whenever an message is published to the topic. | - ---- - -##### `onMessage` - -```wing -onMessage(inflight: ITopicOnMessageHandler, props?: TopicOnMessageProps): Function -``` - -Run an inflight whenever an message is published to the topic. - -###### `inflight`Required - -- *Type:* ITopicOnMessageHandler - ---- - -###### `props`Optional - -- *Type:* TopicOnMessageProps - ---- - - -#### Properties - -| **Name** | **Type** | **Description** | -| --- | --- | --- | -| node | constructs.Node | The tree node. | -| display | Display | Information on how to display a resource in the UI. | - ---- - -##### `node`Required - -```wing -node: Node; -``` - -- *Type:* constructs.Node - -The tree node. - ---- - -##### `display`Required - -```wing -display: Display; -``` - -- *Type:* Display - -Information on how to display a resource in the UI. - ---- - - -### Website - -**Inflight client:** [@winglang/sdk.cloud.IWebsiteClient](#@winglang/sdk.cloud.IWebsiteClient) - -Represents a cloud static website. - -#### Initializers - -```wing -bring cloud; - -new cloud.Website(props: WebsiteProps) -``` - -| **Name** | **Type** | **Description** | -| --- | --- | --- | -| props | WebsiteProps | *No description.* | - ---- - -##### `props`Required - -- *Type:* WebsiteProps - ---- - -#### Methods - -| **Name** | **Description** | -| --- | --- | -| addJson | Add a JSON file with custom values during the website's deployment. | - ---- - -##### `addJson` - -```wing -addJson(path: str, data: Json): str -``` - -Add a JSON file with custom values during the website's deployment. - -If the path conflicts with file path from the website's static assets, an error will be thrown. - -###### `path`Required - -- *Type:* str - -the file path it will be uploaded as. - ---- - -###### `data`Required - -- *Type:* Json - -the data to write to the file. - ---- - - -#### Properties - -| **Name** | **Type** | **Description** | -| --- | --- | --- | -| node | constructs.Node | The tree node. | -| display | Display | Information on how to display a resource in the UI. | -| path | str | Absolute local path to the website's static files. | -| url | str | The website's url. | - ---- - -##### `node`Required - -```wing -node: Node; -``` - -- *Type:* constructs.Node - -The tree node. - ---- - -##### `display`Required - -```wing -display: Display; -``` - -- *Type:* Display - -Information on how to display a resource in the UI. - ---- - -##### `path`Required - -```wing -path: str; -``` - -- *Type:* str - -Absolute local path to the website's static files. - ---- - -##### `url`Required - -```wing -url: str; -``` - -- *Type:* str - -The website's url. - ---- - - -## Structs - -### AddConnectionProps - -Props for `Resource.addConnection`. - -#### Initializer - -```wing -bring std; - -let AddConnectionProps = std.AddConnectionProps{ ... } -``` - -#### Properties - -| **Name** | **Type** | **Description** | -| --- | --- | --- | -| from | IResource | The resource creating the connection to `to`. | -| relationship | str | The type of relationship between the resources. | -| to | IResource | The resource `from` is connecting to. | -| implicit | bool | Whether the relationship is implicit, i.e. it is not explicitly defined by the user. | - ---- - -##### `from`Required - -```wing -from: IResource; -``` - -- *Type:* IResource - -The resource creating the connection to `to`. - ---- - -##### `relationship`Required - -```wing -relationship: str; -``` - -- *Type:* str - -The type of relationship between the resources. - ---- - -##### `to`Required - -```wing -to: IResource; -``` - -- *Type:* IResource - -The resource `from` is connecting to. - ---- - -##### `implicit`Optional - -```wing -implicit: bool; -``` - -- *Type:* bool -- *Default:* false - -Whether the relationship is implicit, i.e. it is not explicitly defined by the user. - ---- - -### ApiConnectProps - -Options for Api patch endpoint. - -#### Initializer - -```wing -bring cloud; - -let ApiConnectProps = cloud.ApiConnectProps{ ... } -``` - - -### ApiDeleteProps - -Options for Api put endpoint. - -#### Initializer - -```wing -bring cloud; - -let ApiDeleteProps = cloud.ApiDeleteProps{ ... } -``` - - -### ApiGetProps - -Options for Api get endpoint. - -#### Initializer - -```wing -bring cloud; - -let ApiGetProps = cloud.ApiGetProps{ ... } -``` - - -### ApiHeadProps - -Options for Api patch endpoint. - -#### Initializer - -```wing -bring cloud; - -let ApiHeadProps = cloud.ApiHeadProps{ ... } -``` - - -### ApiOptionsProps - -Options for Api patch endpoint. - -#### Initializer - -```wing -bring cloud; - -let ApiOptionsProps = cloud.ApiOptionsProps{ ... } -``` - - -### ApiPatchProps - -Options for Api patch endpoint. - -#### Initializer - -```wing -bring cloud; - -let ApiPatchProps = cloud.ApiPatchProps{ ... } -``` - - -### ApiPostProps - -Options for Api post endpoint. - -#### Initializer - -```wing -bring cloud; - -let ApiPostProps = cloud.ApiPostProps{ ... } -``` - - -### ApiProps - -Properties for `Api`. - -#### Initializer - -```wing -bring cloud; - -let ApiProps = cloud.ApiProps{ ... } -``` - - -### ApiPutProps - -Options for Api put endpoint. - -#### Initializer - -```wing -bring cloud; - -let ApiPutProps = cloud.ApiPutProps{ ... } -``` - - -### ApiRequest - -Shape of a request to an inflight handler. - -#### Initializer - -```wing -bring cloud; - -let ApiRequest = cloud.ApiRequest{ ... } -``` - -#### Properties - -| **Name** | **Type** | **Description** | -| --- | --- | --- | -| method | HttpMethod | The request's HTTP method. | -| path | str | The request's path. | -| query | MutMap<str> | The request's query string values. | -| vars | MutMap<str> | The path variables. | -| body | str | The request's body. | -| headers | MutMap<str> | The request's headers. | - ---- - -##### `method`Required - -```wing -method: HttpMethod; -``` - -- *Type:* HttpMethod - -The request's HTTP method. - ---- - -##### `path`Required - -```wing -path: str; -``` - -- *Type:* str - -The request's path. - ---- - -##### `query`Required - -```wing -query: MutMap; -``` - -- *Type:* MutMap<str> - -The request's query string values. - ---- - -##### `vars`Required - -```wing -vars: MutMap; -``` - -- *Type:* MutMap<str> - -The path variables. - ---- - -##### `body`Optional - -```wing -body: str; -``` - -- *Type:* str - -The request's body. - ---- - -##### `headers`Optional - -```wing -headers: MutMap; -``` - -- *Type:* MutMap<str> - -The request's headers. - ---- - -### ApiResponse - -Shape of a response from a inflight handler. - -#### Initializer - -```wing -bring cloud; - -let ApiResponse = cloud.ApiResponse{ ... } -``` - -#### Properties - -| **Name** | **Type** | **Description** | -| --- | --- | --- | -| status | num | The response's status code. | -| body | str | The response's body. | -| headers | MutMap<str> | The response's headers. | - ---- - -##### `status`Required - -```wing -status: num; -``` - -- *Type:* num - -The response's status code. - ---- - -##### `body`Optional - -```wing -body: str; -``` - -- *Type:* str - -The response's body. - ---- - -##### `headers`Optional - -```wing -headers: MutMap; -``` - -- *Type:* MutMap<str> - -The response's headers. - ---- - -### BucketDeleteOptions - -Interface for delete method inside `Bucket`. - -#### Initializer - -```wing -bring cloud; - -let BucketDeleteOptions = cloud.BucketDeleteOptions{ ... } -``` - -#### Properties - -| **Name** | **Type** | **Description** | -| --- | --- | --- | -| mustExist | bool | Check failures on the method and retrieve errors if any. | - ---- - -##### `mustExist`Optional - -```wing -mustExist: bool; -``` - -- *Type:* bool -- *Default:* false - -Check failures on the method and retrieve errors if any. - ---- - -### BucketEvent - -on_event notification payload- will be in use after solving issue: https://github.com/winglang/wing/issues/1927. - -#### Initializer - -```wing -bring cloud; - -let BucketEvent = cloud.BucketEvent{ ... } -``` - -#### Properties - -| **Name** | **Type** | **Description** | -| --- | --- | --- | -| key | str | the bucket key that triggered the event. | -| type | BucketEventType | type of event. | - ---- - -##### `key`Required - -```wing -key: str; -``` - -- *Type:* str - -the bucket key that triggered the event. - ---- - -##### `type`Required - -```wing -type: BucketEventType; -``` - -- *Type:* BucketEventType - -type of event. - ---- - -### BucketOnCreateProps - -on create event options. - -#### Initializer - -```wing -bring cloud; - -let BucketOnCreateProps = cloud.BucketOnCreateProps{ ... } -``` - - -### BucketOnDeleteProps - -on delete event options. - -#### Initializer - -```wing -bring cloud; - -let BucketOnDeleteProps = cloud.BucketOnDeleteProps{ ... } -``` - - -### BucketOnEventProps - -on any event options. - -#### Initializer - -```wing -bring cloud; - -let BucketOnEventProps = cloud.BucketOnEventProps{ ... } -``` - - -### BucketOnUpdateProps - -on update event options. - -#### Initializer - -```wing -bring cloud; - -let BucketOnUpdateProps = cloud.BucketOnUpdateProps{ ... } -``` - - -### BucketProps - -Properties for `Bucket`. - -#### Initializer - -```wing -bring cloud; - -let BucketProps = cloud.BucketProps{ ... } -``` - -#### Properties - -| **Name** | **Type** | **Description** | -| --- | --- | --- | -| public | bool | Whether the bucket's objects should be publicly accessible. | - ---- - -##### `public`Optional - -```wing -public: bool; -``` - -- *Type:* bool -- *Default:* false - -Whether the bucket's objects should be publicly accessible. - ---- - -### Connection - -A connection between two resources. - -#### Initializer - -```wing -bring std; - -let Connection = std.Connection{ ... } -``` - -#### Properties - -| **Name** | **Type** | **Description** | -| --- | --- | --- | -| direction | Direction | The direction of the connection. | -| implicit | bool | Whether the relationship is implicit, i.e. it is not explicitly defined by the user. | -| relationship | str | The type of relationship with the resource. | -| resource | IResource | The resource this connection is to. | - ---- - -##### `direction`Required - -```wing -direction: Direction; -``` - -- *Type:* Direction - -The direction of the connection. - ---- - -##### `implicit`Required - -```wing -implicit: bool; -``` - -- *Type:* bool - -Whether the relationship is implicit, i.e. it is not explicitly defined by the user. - ---- - -##### `relationship`Required - -```wing -relationship: str; -``` - -- *Type:* str - -The type of relationship with the resource. - ---- - -##### `resource`Required - -```wing -resource: IResource; -``` - -- *Type:* IResource - -The resource this connection is to. - ---- - -### CounterProps - -Properties for `Counter`. - -#### Initializer - -```wing -bring cloud; - -let CounterProps = cloud.CounterProps{ ... } -``` - -#### Properties - -| **Name** | **Type** | **Description** | -| --- | --- | --- | -| initial | num | The initial value of the counter. | - ---- - -##### `initial`Optional - -```wing -initial: num; -``` - -- *Type:* num -- *Default:* 0 - -The initial value of the counter. - ---- - -### DisplayProps - -Properties for the Display class. - -#### Initializer - -```wing -bring std; - -let DisplayProps = std.DisplayProps{ ... } -``` - -#### Properties - -| **Name** | **Type** | **Description** | -| --- | --- | --- | -| description | str | Description of the resource. | -| hidden | bool | Whether the resource should be hidden from the UI. | -| title | str | Title of the resource. | - ---- - -##### `description`Optional - -```wing -description: str; -``` - -- *Type:* str -- *Default:* No description. - -Description of the resource. - ---- - -##### `hidden`Optional - -```wing -hidden: bool; -``` - -- *Type:* bool -- *Default:* Undefined - -Whether the resource should be hidden from the UI. - ---- - -##### `title`Optional - -```wing -title: str; -``` - -- *Type:* str -- *Default:* No title. - -Title of the resource. - ---- - -### FunctionProps - -Properties for `Function`. - -This is the type users see when constructing a cloud.Function instance. - -#### Initializer - -```wing -bring cloud; - -let FunctionProps = cloud.FunctionProps{ ... } -``` - -#### Properties - -| **Name** | **Type** | **Description** | -| --- | --- | --- | -| env | MutMap<str> | Environment variables to pass to the function. | -| memory | num | The amount of memory to allocate to the function, in MB. | -| timeout | Duration | The maximum amount of time the function can run. | - ---- - -##### `env`Optional - -```wing -env: MutMap; -``` - -- *Type:* MutMap<str> -- *Default:* No environment variables. - -Environment variables to pass to the function. - ---- - -##### `memory`Optional - -```wing -memory: num; -``` - -- *Type:* num -- *Default:* 128 - -The amount of memory to allocate to the function, in MB. - ---- - -##### `timeout`Optional - -```wing -timeout: Duration; -``` - -- *Type:* Duration -- *Default:* 1m - -The maximum amount of time the function can run. - ---- - -### GetSecretValueOptions - -Options when getting a secret value. - -#### Initializer - -```wing -bring cloud; - -let GetSecretValueOptions = cloud.GetSecretValueOptions{ ... } -``` - -#### Properties - -| **Name** | **Type** | **Description** | -| --- | --- | --- | -| cache | bool | Whether to cache the value. | - ---- - -##### `cache`Optional - -```wing -cache: bool; -``` - -- *Type:* bool -- *Default:* true - -Whether to cache the value. - ---- - -### QueueProps - -Properties for `Queue`. - -#### Initializer - -```wing -bring cloud; - -let QueueProps = cloud.QueueProps{ ... } -``` - -#### Properties - -| **Name** | **Type** | **Description** | -| --- | --- | --- | -| initialMessages | MutArray<str> | Initialize the queue with a set of messages. | -| retentionPeriod | Duration | How long a queue retains a message. | -| timeout | Duration | How long a queue's consumers have to process a message. | - ---- - -##### `initialMessages`Optional - -```wing -initialMessages: MutArray; -``` - -- *Type:* MutArray<str> -- *Default:* [] - -Initialize the queue with a set of messages. - ---- - -##### `retentionPeriod`Optional - -```wing -retentionPeriod: Duration; -``` - -- *Type:* Duration -- *Default:* undefined - -How long a queue retains a message. - ---- - -##### `timeout`Optional - -```wing -timeout: Duration; -``` - -- *Type:* Duration -- *Default:* undefined - -How long a queue's consumers have to process a message. - ---- - -### QueueSetConsumerProps - -Options for Queue.setConsumer. - -#### Initializer - -```wing -bring cloud; - -let QueueSetConsumerProps = cloud.QueueSetConsumerProps{ ... } -``` - -#### Properties - -| **Name** | **Type** | **Description** | -| --- | --- | --- | -| env | MutMap<str> | Environment variables to pass to the function. | -| memory | num | The amount of memory to allocate to the function, in MB. | -| timeout | Duration | The maximum amount of time the function can run. | -| batchSize | num | The maximum number of messages to send to subscribers at once. | - ---- - -##### `env`Optional - -```wing -env: MutMap; -``` - -- *Type:* MutMap<str> -- *Default:* No environment variables. - -Environment variables to pass to the function. - ---- - -##### `memory`Optional - -```wing -memory: num; -``` - -- *Type:* num -- *Default:* 128 - -The amount of memory to allocate to the function, in MB. - ---- - -##### `timeout`Optional - -```wing -timeout: Duration; -``` - -- *Type:* Duration -- *Default:* 1m - -The maximum amount of time the function can run. - ---- - -##### `batchSize`Optional - -```wing -batchSize: num; -``` - -- *Type:* num -- *Default:* 1 - -The maximum number of messages to send to subscribers at once. - ---- - -### ScheduleOnTickProps - -Options for Schedule.onTick. - -#### Initializer - -```wing -bring cloud; - -let ScheduleOnTickProps = cloud.ScheduleOnTickProps{ ... } -``` - -#### Properties - -| **Name** | **Type** | **Description** | -| --- | --- | --- | -| env | MutMap<str> | Environment variables to pass to the function. | -| memory | num | The amount of memory to allocate to the function, in MB. | -| timeout | Duration | The maximum amount of time the function can run. | - ---- - -##### `env`Optional - -```wing -env: MutMap; -``` - -- *Type:* MutMap<str> -- *Default:* No environment variables. - -Environment variables to pass to the function. - ---- - -##### `memory`Optional - -```wing -memory: num; -``` - -- *Type:* num -- *Default:* 128 - -The amount of memory to allocate to the function, in MB. - ---- - -##### `timeout`Optional - -```wing -timeout: Duration; -``` - -- *Type:* Duration -- *Default:* 1m - -The maximum amount of time the function can run. - ---- - -### ScheduleProps - -Properties for `Schedule`. - -#### Initializer - -```wing -bring cloud; - -let ScheduleProps = cloud.ScheduleProps{ ... } -``` - -#### Properties - -| **Name** | **Type** | **Description** | -| --- | --- | --- | -| cron | str | Trigger events according to a cron schedule using the UNIX cron format. | -| rate | Duration | Trigger events at a periodic rate. | - ---- - -##### `cron`Optional - -```wing -cron: str; -``` - -- *Type:* str -- *Default:* undefined - -Trigger events according to a cron schedule using the UNIX cron format. - -[minute] [hour] [day of month] [month] [day of week] - ---- - -*Example* - -```wing -"0/1 * ? * *" -``` - - -##### `rate`Optional - -```wing -rate: Duration; -``` - -- *Type:* Duration -- *Default:* undefined - -Trigger events at a periodic rate. - ---- - -*Example* - -```wing -1m -``` - - -### SecretProps - -Properties for `Secret`. - -#### Initializer - -```wing -bring cloud; - -let SecretProps = cloud.SecretProps{ ... } -``` - -#### Properties - -| **Name** | **Type** | **Description** | -| --- | --- | --- | -| name | str | The secret's name. | - ---- - -##### `name`Optional - -```wing -name: str; -``` - -- *Type:* str -- *Default:* a new secret is provisioned with a generated name - -The secret's name. - -If no name is provided then a new secret is provisioned in the target. -If a name is provided then the resource will reference an existing -secret in the target. - ---- - -### ServiceOnStartProps - -Options for Service.onStart. - -#### Initializer - -```wing -bring cloud; - -let ServiceOnStartProps = cloud.ServiceOnStartProps{ ... } -``` - -#### Properties - -| **Name** | **Type** | **Description** | -| --- | --- | --- | -| env | MutMap<str> | Environment variables to pass to the function. | -| memory | num | The amount of memory to allocate to the function, in MB. | -| timeout | Duration | The maximum amount of time the function can run. | - ---- - -##### `env`Optional - -```wing -env: MutMap; -``` - -- *Type:* MutMap<str> -- *Default:* No environment variables. - -Environment variables to pass to the function. - ---- - -##### `memory`Optional - -```wing -memory: num; -``` - -- *Type:* num -- *Default:* 128 - -The amount of memory to allocate to the function, in MB. - ---- - -##### `timeout`Optional - -```wing -timeout: Duration; -``` - -- *Type:* Duration -- *Default:* 1m - -The maximum amount of time the function can run. - ---- - -### ServiceProps - -Properties for `Service`. - -#### Initializer - -```wing -bring cloud; - -let ServiceProps = cloud.ServiceProps{ ... } -``` - -#### Properties - -| **Name** | **Type** | **Description** | -| --- | --- | --- | -| onStart | IServiceOnEventHandler | Handler to run with the service starts. | -| autoStart | bool | Whether the service should start automatically. | -| onStop | IServiceOnEventHandler | Handler to run with the service stops. | - ---- - -##### `onStart`Required - -```wing -onStart: IServiceOnEventHandler; -``` - -- *Type:* IServiceOnEventHandler - -Handler to run with the service starts. - ---- - -##### `autoStart`Optional - -```wing -autoStart: bool; -``` - -- *Type:* bool -- *Default:* true - -Whether the service should start automatically. - ---- - -##### `onStop`Optional - -```wing -onStop: IServiceOnEventHandler; -``` - -- *Type:* IServiceOnEventHandler -- *Default:* no special activity at shutdown - -Handler to run with the service stops. - ---- - -### TableProps - -Properties for `Table`. - -#### Initializer - -```wing -bring cloud; - -let TableProps = cloud.TableProps{ ... } -``` - -#### Properties - -| **Name** | **Type** | **Description** | -| --- | --- | --- | -| columns | MutMap<ColumnType> | The table's columns. | -| name | str | The table's name. | -| primaryKey | str | The table's primary key. | - ---- - -##### `columns`Optional - -```wing -columns: MutMap; -``` - -- *Type:* MutMap<ColumnType> -- *Default:* undefined - -The table's columns. - ---- - -##### `name`Optional - -```wing -name: str; -``` - -- *Type:* str -- *Default:* undefined - -The table's name. - ---- - -##### `primaryKey`Optional - -```wing -primaryKey: str; -``` - -- *Type:* str -- *Default:* undefined - -The table's primary key. - -No two rows can have the same value for the -primary key. - ---- - -### TestProps - -Properties for `Test`. - -This is the type users see when constructing a std.Test instance. - -#### Initializer - -```wing -bring std; - -let TestProps = std.TestProps{ ... } -``` - -#### Properties - -| **Name** | **Type** | **Description** | -| --- | --- | --- | -| env | MutMap<str> | Environment variables to pass to the function. | -| memory | num | The amount of memory to allocate to the function, in MB. | -| timeout | Duration | The maximum amount of time the function can run. | - ---- - -##### `env`Optional - -```wing -env: MutMap; -``` - -- *Type:* MutMap<str> -- *Default:* No environment variables. - -Environment variables to pass to the function. - ---- - -##### `memory`Optional - -```wing -memory: num; -``` - -- *Type:* num -- *Default:* 128 - -The amount of memory to allocate to the function, in MB. - ---- - -##### `timeout`Optional - -```wing -timeout: Duration; -``` - -- *Type:* Duration -- *Default:* 1m - -The maximum amount of time the function can run. - ---- - -### TestResult - -A result of a single test. - -#### Initializer - -```wing -bring cloud; - -let TestResult = cloud.TestResult{ ... } -``` - -#### Properties - -| **Name** | **Type** | **Description** | -| --- | --- | --- | -| pass | bool | Whether the test passed. | -| path | str | The path of the test. | -| traces | MutArray<Trace> | List of traces emitted during the test. | -| error | str | The error message if the test failed. | - ---- - -##### `pass`Required - -```wing -pass: bool; -``` - -- *Type:* bool - -Whether the test passed. - ---- - -##### `path`Required - -```wing -path: str; -``` - -- *Type:* str - -The path of the test. - ---- - -##### `traces`Required - -```wing -traces: MutArray; -``` - -- *Type:* MutArray<Trace> - -List of traces emitted during the test. - ---- - -##### `error`Optional - -```wing -error: str; -``` - -- *Type:* str - -The error message if the test failed. - ---- - -### TestRunnerProps - -Properties for `TestRunner`. - -#### Initializer - -```wing -bring cloud; - -let TestRunnerProps = cloud.TestRunnerProps{ ... } -``` - - -### TopicOnMessageProps - -Options for `Topic.onMessage`. - -#### Initializer - -```wing -bring cloud; - -let TopicOnMessageProps = cloud.TopicOnMessageProps{ ... } -``` - -#### Properties - -| **Name** | **Type** | **Description** | -| --- | --- | --- | -| env | MutMap<str> | Environment variables to pass to the function. | -| memory | num | The amount of memory to allocate to the function, in MB. | -| timeout | Duration | The maximum amount of time the function can run. | - ---- - -##### `env`Optional - -```wing -env: MutMap; -``` - -- *Type:* MutMap<str> -- *Default:* No environment variables. - -Environment variables to pass to the function. - ---- - -##### `memory`Optional - -```wing -memory: num; -``` - -- *Type:* num -- *Default:* 128 - -The amount of memory to allocate to the function, in MB. - ---- - -##### `timeout`Optional - -```wing -timeout: Duration; -``` - -- *Type:* Duration -- *Default:* 1m - -The maximum amount of time the function can run. - ---- - -### TopicProps - -Properties for `Topic`. - -#### Initializer - -```wing -bring cloud; - -let TopicProps = cloud.TopicProps{ ... } -``` - - -### Trace - -Represents an trace emitted during simulation. - -#### Initializer - -```wing -bring cloud; - -let Trace = cloud.Trace{ ... } -``` - -#### Properties - -| **Name** | **Type** | **Description** | -| --- | --- | --- | -| data | any | A JSON blob with structured data. | -| sourcePath | str | The path of the resource that emitted the trace. | -| sourceType | str | The type of the source that emitted the trace. | -| timestamp | str | The timestamp of the event, in ISO 8601 format. | -| type | TraceType | The type of a trace. | - ---- - -##### `data`Required - -```wing -data: any; -``` - -- *Type:* any - -A JSON blob with structured data. - ---- - -##### `sourcePath`Required - -```wing -sourcePath: str; -``` - -- *Type:* str - -The path of the resource that emitted the trace. - ---- - -##### `sourceType`Required - -```wing -sourceType: str; -``` - -- *Type:* str - -The type of the source that emitted the trace. - ---- - -##### `timestamp`Required - -```wing -timestamp: str; -``` - -- *Type:* str - -The timestamp of the event, in ISO 8601 format. - ---- - -*Example* - -```wing -2020-01-01T00:00:00.000Z -``` - - -##### `type`Required - -```wing -type: TraceType; -``` - -- *Type:* TraceType - -The type of a trace. - ---- - -### WaitUntilProps - -Properties for `util.waitUntil`. - -#### Initializer - -```wing -bring util; - -let WaitUntilProps = util.WaitUntilProps{ ... } -``` - -#### Properties - -| **Name** | **Type** | **Description** | -| --- | --- | --- | -| interval | Duration | Interval between predicate retries. | -| timeout | Duration | The timeout for keep trying predicate. | - ---- - -##### `interval`Optional - -```wing -interval: Duration; -``` - -- *Type:* Duration -- *Default:* 0.1s - -Interval between predicate retries. - ---- - -##### `timeout`Optional - -```wing -timeout: Duration; -``` - -- *Type:* Duration -- *Default:* 1m - -The timeout for keep trying predicate. - ---- - -### WebsiteProps - -website props. - -#### Initializer - -```wing -bring cloud; - -let WebsiteProps = cloud.WebsiteProps{ ... } -``` - -#### Properties - -| **Name** | **Type** | **Description** | -| --- | --- | --- | -| path | str | Local path to the website's static files, relative to the Wing source file or absolute. | -| domain | str | The website's custom domain name. | - ---- - -##### `path`Required - -```wing -path: str; -``` - -- *Type:* str - -Local path to the website's static files, relative to the Wing source file or absolute. - ---- - -*Example* - -```wing -"./dist" -``` - - -##### `domain`Optional - -```wing -domain: str; -``` - -- *Type:* str -- *Default:* a domain is generated by the cloud provider - -The website's custom domain name. - ---- - -*Example* - -```wing -"example.com" -``` - - -## Classes - -### Boolean - -Boolean. - -#### Initializers - -```wing -bring std; - -new std.Boolean() -``` - -| **Name** | **Type** | **Description** | -| --- | --- | --- | - ---- - - -#### Static Functions - -| **Name** | **Description** | -| --- | --- | -| fromJson | Parse a boolean from Json. | - ---- - -##### `fromJson` - -```wing -bring std; - -std.Boolean.fromJson(json: Json) -``` - -Parse a boolean from Json. - -###### `json`Required - -- *Type:* Json - -to parse boolean from. - ---- - - - -### Display - -Information on how to display a resource in the UI. - -#### Initializers - -```wing -bring std; - -new std.Display(props?: DisplayProps) -``` - -| **Name** | **Type** | **Description** | -| --- | --- | --- | -| props | DisplayProps | *No description.* | - ---- - -##### `props`Optional - -- *Type:* DisplayProps - ---- - - - -#### Properties - -| **Name** | **Type** | **Description** | -| --- | --- | --- | -| description | str | Description of the resource. | -| hidden | bool | Whether the resource should be hidden from the UI. | -| title | str | Title of the resource. | - ---- - -##### `description`Optional - -```wing -description: str; -``` - -- *Type:* str - -Description of the resource. - ---- - -##### `hidden`Optional - -```wing -hidden: bool; -``` - -- *Type:* bool - -Whether the resource should be hidden from the UI. - ---- - -##### `title`Optional - -```wing -title: str; -``` - -- *Type:* str - -Title of the resource. - ---- - - -### Duration - -Represents a length of time. - - -#### Static Functions - -| **Name** | **Description** | -| --- | --- | -| fromDays | Create a Duration representing an amount of days. | -| fromHours | Create a Duration representing an amount of hours. | -| fromMilliseconds | Create a Duration representing an amount of milliseconds. | -| fromMinutes | Create a Duration representing an amount of minutes. | -| fromMonths | Create a Duration representing an amount of months. | -| fromSeconds | Create a Duration representing an amount of seconds. | -| fromYears | Create a Duration representing an amount of years. | - ---- - -##### `fromDays` - -```wing -bring std; - -std.Duration.fromDays(amount: num) -``` - -Create a Duration representing an amount of days. - -###### `amount`Required - -- *Type:* num - -the amount of Days the `Duration` will represent. - ---- - -##### `fromHours` - -```wing -bring std; - -std.Duration.fromHours(amount: num) -``` - -Create a Duration representing an amount of hours. - -###### `amount`Required - -- *Type:* num - -the amount of Hours the `Duration` will represent. - ---- - -##### `fromMilliseconds` - -```wing -bring std; - -std.Duration.fromMilliseconds(amount: num) -``` - -Create a Duration representing an amount of milliseconds. - -###### `amount`Required - -- *Type:* num - -the amount of Milliseconds the `Duration` will represent. - ---- - -##### `fromMinutes` - -```wing -bring std; - -std.Duration.fromMinutes(amount: num) -``` - -Create a Duration representing an amount of minutes. - -###### `amount`Required - -- *Type:* num - -the amount of Minutes the `Duration` will represent. - ---- - -##### `fromMonths` - -```wing -bring std; - -std.Duration.fromMonths(amount: num) -``` - -Create a Duration representing an amount of months. - -###### `amount`Required - -- *Type:* num - -the amount of Months the `Duration` will represent. - ---- - -##### `fromSeconds` - -```wing -bring std; - -std.Duration.fromSeconds(amount: num) -``` - -Create a Duration representing an amount of seconds. - -###### `amount`Required - -- *Type:* num - -the amount of Seconds the `Duration` will represent. - ---- - -##### `fromYears` - -```wing -bring std; - -std.Duration.fromYears(amount: num) -``` - -Create a Duration representing an amount of years. - -###### `amount`Required - -- *Type:* num - -the amount of Years the `Duration` will represent. - ---- - -#### Properties - -| **Name** | **Type** | **Description** | -| --- | --- | --- | -| days | num | Return the total number of days in this Duration. | -| hours | num | Return the total number of hours in this Duration. | -| milliseconds | num | Return the total number of milliseconds in this Duration. | -| minutes | num | Return the total number of minutes in this Duration. | -| months | num | Return the total number of months in this Duration. | -| seconds | num | Return the total number of seconds in this Duration. | -| years | num | Return the total number of years in this Duration. | - ---- - -##### `days`Required - -```wing -days: num; -``` - -- *Type:* num - -Return the total number of days in this Duration. - ---- - -##### `hours`Required - -```wing -hours: num; -``` - -- *Type:* num - -Return the total number of hours in this Duration. - ---- - -##### `milliseconds`Required - -```wing -milliseconds: num; -``` - -- *Type:* num - -Return the total number of milliseconds in this Duration. - ---- - -##### `minutes`Required - -```wing -minutes: num; -``` - -- *Type:* num - -Return the total number of minutes in this Duration. - ---- - -##### `months`Required - -```wing -months: num; -``` - -- *Type:* num - -Return the total number of months in this Duration. - ---- - -##### `seconds`Required - -```wing -seconds: num; -``` - -- *Type:* num - -Return the total number of seconds in this Duration. - ---- - -##### `years`Required - -```wing -years: num; -``` - -- *Type:* num - -Return the total number of years in this Duration. - ---- - - -### ImmutableArray - -Immutable Array. - -#### Initializers - -```wing -bring std; - -new std.ImmutableArray() -``` - -| **Name** | **Type** | **Description** | -| --- | --- | --- | - ---- - -#### Methods - -| **Name** | **Description** | -| --- | --- | -| at | Get the value at the given index. | -| concat | Merge arr to the end of this array. | -| contains | Checks if this array includes searchElement. | -| copyMut | Create a mutable shallow copy of this array. | -| indexOf | Returns the index of the first occurrence of searchElement found. | -| join | Returns a new string containing the concatenated values in this array, separated by commas or a specified separator string. | -| lastIndexOf | Returns the index of the last occurrence of searchElement found. | - ---- - -##### `at` - -```wing -at(index: num): T1 -``` - -Get the value at the given index. - -###### `index`Required - -- *Type:* num - -index of the value to get. - ---- - -##### `concat` - -```wing -concat(arr: ImmutableArray): ImmutableArray -``` - -Merge arr to the end of this array. - -###### `arr`Required - -- *Type:* ImmutableArray - -array to merge. - ---- - -##### `contains` - -```wing -contains(searchElement: T1): bool -``` - -Checks if this array includes searchElement. - -###### `searchElement`Required - -- *Type:* T1 - -to search for. - ---- - -##### `copyMut` - -```wing -copyMut(): MutableArray -``` - -Create a mutable shallow copy of this array. - -##### `indexOf` - -```wing -indexOf(searchElement: T1): num -``` - -Returns the index of the first occurrence of searchElement found. - -###### `searchElement`Required - -- *Type:* T1 - -to search for. - ---- - -##### `join` - -```wing -join(separator?: str): str -``` - -Returns a new string containing the concatenated values in this array, separated by commas or a specified separator string. - -If the array has only -one item, then that item will be returned without using the separator. - -###### `separator`Optional - -- *Type:* str - ---- - -##### `lastIndexOf` - -```wing -lastIndexOf(searchElement: T1): num -``` - -Returns the index of the last occurrence of searchElement found. - -###### `searchElement`Required - -- *Type:* T1 - -to search for. - ---- - - -#### Properties - -| **Name** | **Type** | **Description** | -| --- | --- | --- | -| length | num | The length of the array. | - ---- - -##### `length`Required - -```wing -length: num; -``` - -- *Type:* num - -The length of the array. - ---- - - -### ImmutableMap - -Immutable Map. - -#### Initializers - -```wing -bring std; - -new std.ImmutableMap() -``` - -| **Name** | **Type** | **Description** | -| --- | --- | --- | - ---- - -#### Methods - -| **Name** | **Description** | -| --- | --- | -| copyMut | Create a mutable shallow copy of this map. | -| get | Returns a specified element from the map. | -| has | Returns a boolean indicating whether an element with the specified key exists or not. | -| keys | Returns the keys of this map. | -| size | Returns the number of elements in the map. | -| values | Returns the values of this map. | - ---- - -##### `copyMut` - -```wing -copyMut(): MutableMap -``` - -Create a mutable shallow copy of this map. - -##### `get` - -```wing -get(key: str): T1 -``` - -Returns a specified element from the map. - -If the value that is associated to the provided key is an object, then you will get a reference -to that object and any change made to that object will effectively modify it inside the map. - -###### `key`Required - -- *Type:* str - -The key of the element to return. - ---- - -##### `has` - -```wing -has(key: str): bool -``` - -Returns a boolean indicating whether an element with the specified key exists or not. - -###### `key`Required - -- *Type:* str - -The key of the element to test for presence. - ---- - -##### `keys` - -```wing -keys(): MutArray -``` - -Returns the keys of this map. - -##### `size` - -```wing -size(): num -``` - -Returns the number of elements in the map. - -TODO: For now this has to be a method rather than a getter as macros only work on methods https://github.com/winglang/wing/issues/1658 - -##### `values` - -```wing -values(): ImmutableArray -``` - -Returns the values of this map. - - - - -### ImmutableSet - -Immutable Set. - -#### Initializers - -```wing -bring std; - -new std.ImmutableSet() -``` - -| **Name** | **Type** | **Description** | -| --- | --- | --- | - ---- - -#### Methods - -| **Name** | **Description** | -| --- | --- | -| copyMut | Create a mutable shallow copy of this set. | -| has | Returns a boolean indicating whether an element with the specified value exists in the set. | - ---- - -##### `copyMut` - -```wing -copyMut(): MutableSet -``` - -Create a mutable shallow copy of this set. - -##### `has` - -```wing -has(value: T1): bool -``` - -Returns a boolean indicating whether an element with the specified value exists in the set. - -###### `value`Required - -- *Type:* T1 - -The value to test for presence in the Set object. - ---- - - -#### Properties - -| **Name** | **Type** | **Description** | -| --- | --- | --- | -| size | num | The length of the set. | - ---- - -##### `size`Required - -```wing -size: num; -``` - -- *Type:* num - -The length of the set. - ---- - - -### Json - -Immutable Json. - -#### Initializers - -```wing -bring std; - -new std.Json() -``` - -| **Name** | **Type** | **Description** | -| --- | --- | --- | - ---- - -#### Methods - -| **Name** | **Description** | -| --- | --- | -| get | Returns a specified element from the Json. | -| getAt | Returns a specified element at a given index from Json Array. | - ---- - -##### `get` - -```wing -get(key: str): Json -``` - -Returns a specified element from the Json. - -###### `key`Required - -- *Type:* str - -The key of the element to return. - ---- - -##### `getAt` - -```wing -getAt(index: num): Json -``` - -Returns a specified element at a given index from Json Array. - -###### `index`Required - -- *Type:* num - -The index of the element in the Json Array to return. - ---- - -#### Static Functions - -| **Name** | **Description** | -| --- | --- | -| deepCopyMut | Creates a mutable deep copy of the Json. | -| delete | Deletes a key in a given Json. | -| has | Checks if a Json object has a given key. | -| keys | Returns the keys from the Json object. | -| parse | Parse a string into a Json. | -| stringify | Formats Json as string. | -| tryParse | Try to parse a string into a Json. | -| values | Returns the values from the Json. | - ---- - -##### `deepCopyMut` - -```wing -bring std; - -std.Json.deepCopyMut(json: Json) -``` - -Creates a mutable deep copy of the Json. - -###### `json`Required - -- *Type:* Json - -to copy. - ---- - -##### `delete` - -```wing -bring std; - -std.Json.delete(json: Json, key: str) -``` - -Deletes a key in a given Json. - -###### `json`Required - -- *Type:* Json - -to delete key from. - ---- - -###### `key`Required - -- *Type:* str - -the key to delete. - ---- - -##### `has` - -```wing -bring std; - -std.Json.has(json: Json, key: str) -``` - -Checks if a Json object has a given key. - -###### `json`Required - -- *Type:* Json - -The json object to inspect. - ---- - -###### `key`Required - -- *Type:* str - -The key to check. - ---- - -##### `keys` - -```wing -bring std; - -std.Json.keys(json: Json) -``` - -Returns the keys from the Json object. - -###### `json`Required - -- *Type:* Json - -to get keys from. - ---- - -##### `parse` - -```wing -bring std; - -std.Json.parse(str: str) -``` - -Parse a string into a Json. - -###### `str`Required - -- *Type:* str - -to parse as Json. - ---- - -##### `stringify` - -```wing -bring std; - -std.Json.stringify(json: Json, indent?: num) -``` - -Formats Json as string. - -(JSON.stringify($args$)) - -###### `json`Required - -- *Type:* Json - -to format as string. - ---- - -###### `indent`Optional - -- *Type:* num - ---- - -##### `tryParse` - -```wing -bring std; - -std.Json.tryParse(str: str) -``` - -Try to parse a string into a Json. - -###### `str`Required - -- *Type:* str - -to parse as Json. - ---- - -##### `values` - -```wing -bring std; - -std.Json.values(json: Json) -``` - -Returns the values from the Json. - -###### `json`Required - -- *Type:* Json - -to get values from. - ---- - - - -### MutableArray - -Mutable Array. - -#### Initializers - -```wing -bring std; - -new std.MutableArray() -``` - -| **Name** | **Type** | **Description** | -| --- | --- | --- | - ---- - -#### Methods - -| **Name** | **Description** | -| --- | --- | -| at | Get the value at the given index. | -| concat | Merge arr to the end of this array. | -| contains | Checks if this array includes searchElement. | -| copy | Create an immutable shallow copy of this array. | -| indexOf | Returns the index of the first occurrence of searchElement found. | -| join | Returns a new string containing the concatenated values in this array, separated by commas or a specified separator string. | -| lastIndexOf | Returns the index of the last occurrence of searchElement found. | -| pop | Remove value from end of array. | -| push | Add value to end of array. | - ---- - -##### `at` - -```wing -at(index: num): T1 -``` - -Get the value at the given index. - -###### `index`Required - -- *Type:* num - -index of the value to get. - ---- - -##### `concat` - -```wing -concat(arr: MutableArray): MutableArray -``` - -Merge arr to the end of this array. - -###### `arr`Required - -- *Type:* MutableArray - -array to merge. - ---- - -##### `contains` - -```wing -contains(searchElement: T1): bool -``` - -Checks if this array includes searchElement. - -###### `searchElement`Required - -- *Type:* T1 - -to search for. - ---- - -##### `copy` - -```wing -copy(): ImmutableArray -``` - -Create an immutable shallow copy of this array. - -##### `indexOf` - -```wing -indexOf(searchElement: T1): num -``` - -Returns the index of the first occurrence of searchElement found. - -###### `searchElement`Required - -- *Type:* T1 - -to search for. - ---- - -##### `join` - -```wing -join(separator?: str): str -``` - -Returns a new string containing the concatenated values in this array, separated by commas or a specified separator string. - -If the array has only -one item, then that item will be returned without using the separator. - -###### `separator`Optional - -- *Type:* str - ---- - -##### `lastIndexOf` - -```wing -lastIndexOf(searchElement: T1): num -``` - -Returns the index of the last occurrence of searchElement found. - -###### `searchElement`Required - -- *Type:* T1 - -to search for. - ---- - -##### `pop` - -```wing -pop(): T1 -``` - -Remove value from end of array. - -##### `push` - -```wing -push(value: T1): void -``` - -Add value to end of array. - -###### `value`Required - -- *Type:* T1 - -value to add. - ---- - - -#### Properties - -| **Name** | **Type** | **Description** | -| --- | --- | --- | -| length | num | The length of the array. | - ---- - -##### `length`Required - -```wing -length: num; -``` - -- *Type:* num - -The length of the array. - ---- - - -### MutableMap - -Mutable Map. - -#### Initializers - -```wing -bring std; - -new std.MutableMap() -``` - -| **Name** | **Type** | **Description** | -| --- | --- | --- | - ---- - -#### Methods - -| **Name** | **Description** | -| --- | --- | -| clear | Removes all elements. | -| copy | Create an immutable shallow copy of this map. | -| delete | Removes the specified element from a map. | -| get | Returns a specified element from the map. | -| has | Returns a boolean indicating whether an element with the specified key exists or not. | -| keys | Returns the keys of this map. | -| set | Adds or updates an entry in a Map object with a specified key and a value. | -| size | Returns the number of elements in the map. | -| values | Returns the values of this map. | - ---- - -##### `clear` - -```wing -clear(): void -``` - -Removes all elements. - -##### `copy` - -```wing -copy(): ImmutableMap -``` - -Create an immutable shallow copy of this map. - -##### `delete` - -```wing -delete(key: str): bool -``` - -Removes the specified element from a map. - -###### `key`Required - -- *Type:* str - -The key. - ---- - -##### `get` - -```wing -get(key: str): T1 -``` - -Returns a specified element from the map. - -If the value that is associated to the provided key is an object, then you will get a reference -to that object and any change made to that object will effectively modify it inside the map. - -###### `key`Required - -- *Type:* str - -The key of the element to return. - ---- - -##### `has` - -```wing -has(key: str): bool -``` - -Returns a boolean indicating whether an element with the specified key exists or not. - -###### `key`Required - -- *Type:* str - -The key of the element to test for presence. - ---- - -##### `keys` - -```wing -keys(): MutArray -``` - -Returns the keys of this map. - -##### `set` - -```wing -set(key: str, value: T1): void -``` - -Adds or updates an entry in a Map object with a specified key and a value. - -TODO: revisit this macro after we support indexed args https://github.com/winglang/wing/issues/1659 - -###### `key`Required - -- *Type:* str - -The key of the element to add. - ---- - -###### `value`Required - -- *Type:* T1 - -The value of the element to add. - ---- - -##### `size` - -```wing -size(): num -``` - -Returns the number of elements in the map. - -TODO: For now this has to be a method rather than a getter as macros only work on methods https://github.com/winglang/wing/issues/1658 - -##### `values` - -```wing -values(): ImmutableArray -``` - -Returns the values of this map. - - - - -### MutableSet - -Mutable Set. - -#### Initializers - -```wing -bring std; - -new std.MutableSet() -``` - -| **Name** | **Type** | **Description** | -| --- | --- | --- | - ---- - -#### Methods - -| **Name** | **Description** | -| --- | --- | -| add | Add value to set. | -| clear | The clear() method removes all elements from a set. | -| copy | Create an immutable shallow copy of this set. | -| delete | Removes a specified value from a set, if it is in the set. | -| has | Returns a boolean indicating whether an element with the specified value exists in the set. | - ---- - -##### `add` - -```wing -add(value: T1): MutableSet -``` - -Add value to set. - -###### `value`Required - -- *Type:* T1 - -value to add. - ---- - -##### `clear` - -```wing -clear(): void -``` - -The clear() method removes all elements from a set. - -##### `copy` - -```wing -copy(): ImmutableSet -``` - -Create an immutable shallow copy of this set. - -##### `delete` - -```wing -delete(value: T1): bool -``` - -Removes a specified value from a set, if it is in the set. - -###### `value`Required - -- *Type:* T1 - -The value to remove from the set. - ---- - -##### `has` - -```wing -has(value: T1): bool -``` - -Returns a boolean indicating whether an element with the specified value exists in the set. - -###### `value`Required - -- *Type:* T1 - -The value to test for presence in the Set object. - ---- - - -#### Properties - -| **Name** | **Type** | **Description** | -| --- | --- | --- | -| size | num | The length of the set. | - ---- - -##### `size`Required - -```wing -size: num; -``` - -- *Type:* num - -The length of the set. - ---- - - -### MutJson - -Mutable Json. - -#### Initializers - -```wing -bring std; - -new std.MutJson() -``` - -| **Name** | **Type** | **Description** | -| --- | --- | --- | - ---- - -#### Methods - -| **Name** | **Description** | -| --- | --- | -| get | Returns a specified element from the Json. | -| getAt | Returns a specified element at a given index from MutJson Array. | -| set | Adds or updates an element in MutJson with a specific key and value. | -| setAt | Set element in MutJson Array with a specific key and value. | - ---- - -##### `get` - -```wing -get(key: str): MutJson -``` - -Returns a specified element from the Json. - -###### `key`Required - -- *Type:* str - -The key of the element to return. - ---- - -##### `getAt` - -```wing -getAt(index: num): MutJson -``` - -Returns a specified element at a given index from MutJson Array. - -###### `index`Required - -- *Type:* num - -The index of the element in the MutJson Array to return. - ---- - -##### `set` - -```wing -set(key: str, value: MutJson): void -``` - -Adds or updates an element in MutJson with a specific key and value. - -###### `key`Required - -- *Type:* str - -The key of the element to add. - ---- - -###### `value`Required - -- *Type:* MutJson - -The value of the element to add. - ---- - -##### `setAt` - -```wing -setAt(index: num, value: MutJson): void -``` - -Set element in MutJson Array with a specific key and value. - -###### `index`Required - -- *Type:* num - ---- - -###### `value`Required - -- *Type:* MutJson - -The value of the element to set. - ---- - -#### Static Functions - -| **Name** | **Description** | -| --- | --- | -| deepCopy | Creates an immutable deep copy of the Json. | - ---- - -##### `deepCopy` - -```wing -bring std; - -std.MutJson.deepCopy(json: MutJson) -``` - -Creates an immutable deep copy of the Json. - -###### `json`Required - -- *Type:* MutJson - -to copy. - ---- - - - -### Number - -Number. - -#### Initializers - -```wing -bring std; - -new std.Number() -``` - -| **Name** | **Type** | **Description** | -| --- | --- | --- | - ---- - - -#### Static Functions - -| **Name** | **Description** | -| --- | --- | -| fromJson | Parse a number from Json. | -| fromStr | Parse a number from string. | - ---- - -##### `fromJson` - -```wing -bring std; - -std.Number.fromJson(json: Json) -``` - -Parse a number from Json. - -###### `json`Required - -- *Type:* Json - -to parse number from. - ---- - -##### `fromStr` - -```wing -bring std; - -std.Number.fromStr(str: str) -``` - -Parse a number from string. - -###### `str`Required - -- *Type:* str - -to parse number from. - ---- - - - -### Range - -Range. - -#### Initializers - -```wing -bring std; - -new std.Range() -``` - -| **Name** | **Type** | **Description** | -| --- | --- | --- | - ---- - - - - - -### String - -String. - -#### Initializers - -```wing -bring std; - -new std.String() -``` - -| **Name** | **Type** | **Description** | -| --- | --- | --- | - ---- - -#### Methods - -| **Name** | **Description** | -| --- | --- | -| at | Returns the character at the specified index. | -| concat | Combines the text of two (or more) strings and returns a new string. | -| contains | Checks if string includes substring. | -| endsWith | Does this string end with the given searchString? | -| indexOf | Returns the index of the first occurrence of searchString found. | -| lowercase | Returns this string in lower case. | -| split | Splits string by separator. | -| startsWith | Does this string start with the given searchString? | -| substring | Returns a string between indexStart, indexEnd. | -| trim | Removes white spaces from start and end of this string. | -| uppercase | Returns this string in upper case. | - ---- - -##### `at` - -```wing -at(index: num): str -``` - -Returns the character at the specified index. - -###### `index`Required - -- *Type:* num - -position of the character. - ---- - -##### `concat` - -```wing -concat(strN: str): str -``` - -Combines the text of two (or more) strings and returns a new string. - -###### `strN`Required - -- *Type:* str - -one or more strings to concatenate to this string. - ---- - -##### `contains` - -```wing -contains(searchString: str): bool -``` - -Checks if string includes substring. - -###### `searchString`Required - -- *Type:* str - -substring to search for. - ---- - -##### `endsWith` - -```wing -endsWith(searchString: str): bool -``` - -Does this string end with the given searchString? - -###### `searchString`Required - -- *Type:* str - -substring to search for. - ---- - -##### `indexOf` - -```wing -indexOf(searchString: str): num -``` - -Returns the index of the first occurrence of searchString found. - -###### `searchString`Required - -- *Type:* str - -substring to search for. - ---- - -##### `lowercase` - -```wing -lowercase(): str -``` - -Returns this string in lower case. - -##### `split` - -```wing -split(separator: str): MutArray -``` - -Splits string by separator. - -###### `separator`Required - -- *Type:* str - -separator to split by. - ---- - -##### `startsWith` - -```wing -startsWith(searchString: str): bool -``` - -Does this string start with the given searchString? - -###### `searchString`Required - -- *Type:* str - -substring to search for. - ---- - -##### `substring` - -```wing -substring(indexStart: num, indexEnd?: num): str -``` - -Returns a string between indexStart, indexEnd. - -###### `indexStart`Required - -- *Type:* num - -index of the character we slice at. - ---- - -###### `indexEnd`Optional - -- *Type:* num - -optional - index of the character we end slicing at. - ---- - -##### `trim` - -```wing -trim(): str -``` - -Removes white spaces from start and end of this string. - -##### `uppercase` - -```wing -uppercase(): str -``` - -Returns this string in upper case. - -#### Static Functions - -| **Name** | **Description** | -| --- | --- | -| fromJson | Parse string from Json. | - ---- - -##### `fromJson` - -```wing -bring std; - -std.String.fromJson(json: Json) -``` - -Parse string from Json. - -###### `json`Required - -- *Type:* Json - -to create string from. - ---- - -#### Properties - -| **Name** | **Type** | **Description** | -| --- | --- | --- | -| length | num | The length of the string. | - ---- - -##### `length`Required - -```wing -length: num; -``` - -- *Type:* num - -The length of the string. - ---- - - -### T1 - -Generic type argument. - -This type is replaced at compile time. - -#### Initializers - -```wing -bring std; - -new std.T1() -``` - -| **Name** | **Type** | **Description** | -| --- | --- | --- | - ---- - - - - - -### Util - -Utility functions. - -#### Initializers - -```wing -bring util; - -new util.Util() -``` - -| **Name** | **Type** | **Description** | -| --- | --- | --- | - ---- - - -#### Static Functions - -| **Name** | **Description** | -| --- | --- | -| env | Returns the value of an environment variable. | -| sleep | Suspends execution for a given duration. | -| tryEnv | Returns the value of an environment variable. | -| waitUntil | Run a predicate repeatedly, waiting until it returns true or until the timeout elapses. | - ---- - -##### `env` - -```wing -bring util; - -util.Util.env(name: str) -``` - -Returns the value of an environment variable. - -Throws if not found or empty. - -###### `name`Required - -- *Type:* str - -The name of the environment variable. - ---- - -##### `sleep` - -```wing -bring util; - -util.Util.sleep(delay: Duration) -``` - -**Inflight client:** [true](#true) - -Suspends execution for a given duration. - -###### `delay`Required - -- *Type:* Duration - -The time to suspend execution. - ---- - -##### `tryEnv` - -```wing -bring util; - -util.Util.tryEnv(name: str) -``` - -Returns the value of an environment variable. - -Returns `nil` if not found or empty. - -###### `name`Required - -- *Type:* str - -The name of the environment variable. - ---- - -##### `waitUntil` - -```wing -bring util; - -util.Util.waitUntil(predicate: IPredicateHandler, props?: WaitUntilProps) -``` - -**Inflight client:** [true](#true) - -Run a predicate repeatedly, waiting until it returns true or until the timeout elapses. - -###### `predicate`Required - -- *Type:* IPredicateHandler - -The function that will be evaluated. - ---- - -###### `props`Optional - -- *Type:* WaitUntilProps - -Timeout and interval values, default to one 1m timeout and 0.1sec interval. - ---- - - - -## Protocols - -### IApiClient - -- *Implemented By:* IApiClient - -Inflight methods and members of `cloud.Api`. - - - -### IApiEndpointHandler - -- *Extends:* IResource - -- *Implemented By:* IApiEndpointHandler - -**Inflight client:** [@winglang/sdk.cloud.IApiEndpointHandlerClient](#@winglang/sdk.cloud.IApiEndpointHandlerClient) - -Represents a resource with an inflight "handle" method that can be passed to one of the `Api` request preflight methods. - - -#### Properties - -| **Name** | **Type** | **Description** | -| --- | --- | --- | -| node | constructs.Node | The tree node. | -| display | Display | Information on how to display a resource in the UI. | - ---- - -##### `node`Required - -```wing -node: Node; -``` - -- *Type:* constructs.Node - -The tree node. - ---- - -##### `display`Required - -```wing -display: Display; -``` - -- *Type:* Display - -Information on how to display a resource in the UI. - ---- - -### IApiEndpointHandlerClient - -- *Implemented By:* IApiEndpointHandlerClient - -Inflight client for `IApiEndpointHandler`. - -#### Methods - -| **Name** | **Description** | -| --- | --- | -| handle | Inflight that will be called when a request is made to the endpoint. | - ---- - -##### `handle` - -```wing -handle(request: ApiRequest): ApiResponse -``` - -**Inflight client:** [true](#true) - -Inflight that will be called when a request is made to the endpoint. - -###### `request`Required - -- *Type:* ApiRequest - ---- - - -### IBucketClient - -- *Implemented By:* IBucketClient - -Inflight interface for `Bucket`. - -#### Methods - -| **Name** | **Description** | -| --- | --- | -| delete | Delete an existing object using a key from the bucket. | -| exists | Check if an object exists in the bucket. | -| get | Retrieve an object from the bucket. | -| getJson | Retrieve a Json object from the bucket. | -| list | Retrieve existing objects keys from the bucket. | -| publicUrl | Returns a url to the given file. | -| put | Put an object in the bucket. | -| putJson | Put a Json object in the bucket. | -| tryDelete | Delete an object from the bucket if it exists. | -| tryGet | Get an object from the bucket if it exists. | -| tryGetJson | Gets an object from the bucket if it exists, parsing it as Json. | - ---- - -##### `delete` - -```wing -delete(key: str, opts?: BucketDeleteOptions): void -``` - -**Inflight client:** [true](#true) - -Delete an existing object using a key from the bucket. - -###### `key`Required - -- *Type:* str - -Key of the object. - ---- - -###### `opts`Optional - -- *Type:* BucketDeleteOptions - -Options available for delete an item from a bucket. - ---- - -##### `exists` - -```wing -exists(key: str): bool -``` - -**Inflight client:** [true](#true) - -Check if an object exists in the bucket. - -###### `key`Required - -- *Type:* str - -Key of the object. - ---- - -##### `get` - -```wing -get(key: str): str -``` - -**Inflight client:** [true](#true) - -Retrieve an object from the bucket. - -###### `key`Required - -- *Type:* str - -Key of the object. - ---- - -##### `getJson` - -```wing -getJson(key: str): Json -``` - -**Inflight client:** [true](#true) - -Retrieve a Json object from the bucket. - -###### `key`Required - -- *Type:* str - -Key of the object. - ---- - -##### `list` - -```wing -list(prefix?: str): MutArray -``` - -**Inflight client:** [true](#true) - -Retrieve existing objects keys from the bucket. - -###### `prefix`Optional - -- *Type:* str - -Limits the response to keys that begin with the specified prefix. - ---- - -##### `publicUrl` - -```wing -publicUrl(key: str): str -``` - -**Inflight client:** [true](#true) - -Returns a url to the given file. - -###### `key`Required - -- *Type:* str - ---- - -##### `put` - -```wing -put(key: str, body: str): void -``` - -**Inflight client:** [true](#true) - -Put an object in the bucket. - -###### `key`Required - -- *Type:* str - -Key of the object. - ---- - -###### `body`Required - -- *Type:* str - -Content of the object we want to store into the bucket. - ---- - -##### `putJson` - -```wing -putJson(key: str, body: Json): void -``` - -**Inflight client:** [true](#true) - -Put a Json object in the bucket. - -###### `key`Required - -- *Type:* str - -Key of the object. - ---- - -###### `body`Required - -- *Type:* Json - -Json object that we want to store into the bucket. - ---- - -##### `tryDelete` - -```wing -tryDelete(key: str): bool -``` - -**Inflight client:** [true](#true) - -Delete an object from the bucket if it exists. - -###### `key`Required - -- *Type:* str - -Key of the object. - ---- - -##### `tryGet` - -```wing -tryGet(key: str): str -``` - -**Inflight client:** [true](#true) - -Get an object from the bucket if it exists. - -###### `key`Required - -- *Type:* str - -Key of the object. - ---- - -##### `tryGetJson` - -```wing -tryGetJson(key: str): Json -``` - -**Inflight client:** [true](#true) - -Gets an object from the bucket if it exists, parsing it as Json. - -###### `key`Required - -- *Type:* str - -Key of the object. - ---- - - -### IBucketEventHandler - -- *Extends:* IResource - -- *Implemented By:* IBucketEventHandler - -**Inflight client:** [@winglang/sdk.cloud.IBucketEventHandlerClient](#@winglang/sdk.cloud.IBucketEventHandlerClient) - -Represents a resource with an inflight "handle" method that can be passed to the bucket events. - - -#### Properties - -| **Name** | **Type** | **Description** | -| --- | --- | --- | -| node | constructs.Node | The tree node. | -| display | Display | Information on how to display a resource in the UI. | - ---- - -##### `node`Required - -```wing -node: Node; -``` - -- *Type:* constructs.Node - -The tree node. - ---- - -##### `display`Required - -```wing -display: Display; -``` - -- *Type:* Display - -Information on how to display a resource in the UI. - ---- - -### IBucketEventHandlerClient - -- *Implemented By:* IBucketEventHandlerClient - -Represents a resource with an inflight "handle" method that can be passed to the bucket events. - -#### Methods - -| **Name** | **Description** | -| --- | --- | -| handle | Function that will be called when an event notification is fired. | - ---- - -##### `handle` - -```wing -handle(key: str, type: BucketEventType): void -``` - -**Inflight client:** [true](#true) - -Function that will be called when an event notification is fired. - -###### `key`Required - -- *Type:* str - ---- - -###### `type`Required - -- *Type:* BucketEventType - ---- - - -### ICounterClient - -- *Implemented By:* ICounterClient - -Inflight interface for `Counter`. - -#### Methods - -| **Name** | **Description** | -| --- | --- | -| dec | Decrement the counter, returning the previous value. | -| inc | Increments the counter atomically by a certain amount and returns the previous value. | -| peek | Get the current value of the counter. | -| set | Set a counter to a given value. | - ---- - -##### `dec` - -```wing -dec(amount?: num, key?: str): num -``` - -**Inflight client:** [true](#true) - -Decrement the counter, returning the previous value. - -###### `amount`Optional - -- *Type:* num - -amount to decrement (default is 1). - ---- - -###### `key`Optional - -- *Type:* str - -specify the key to be decremented. - ---- - -##### `inc` - -```wing -inc(amount?: num, key?: str): num -``` - -**Inflight client:** [true](#true) - -Increments the counter atomically by a certain amount and returns the previous value. - -###### `amount`Optional - -- *Type:* num - -amount to increment (default is 1). - ---- - -###### `key`Optional - -- *Type:* str - -specify the key to be incremented. - ---- - -##### `peek` - -```wing -peek(key?: str): num -``` - -**Inflight client:** [true](#true) - -Get the current value of the counter. - -Using this API may introduce race conditions since the value can change between -the time it is read and the time it is used in your code. - -###### `key`Optional - -- *Type:* str - -specify the key to be retrieved. - ---- - -##### `set` - -```wing -set(value: num, key?: str): void -``` - -**Inflight client:** [true](#true) - -Set a counter to a given value. - -###### `value`Required - -- *Type:* num - -new value. - ---- - -###### `key`Optional - -- *Type:* str - -specify the key to be set. - ---- - - -### IFunctionClient - -- *Implemented By:* IFunctionClient - -Inflight interface for `Function`. - -#### Methods - -| **Name** | **Description** | -| --- | --- | -| invoke | Invoke the function asynchronously with a given payload. | - ---- - -##### `invoke` - -```wing -invoke(payload: str): str -``` - -**Inflight client:** [true](#true) - -Invoke the function asynchronously with a given payload. - -###### `payload`Required - -- *Type:* str - ---- - - -### IFunctionHandler - -- *Extends:* IResource - -- *Implemented By:* IFunctionHandler - -**Inflight client:** [@winglang/sdk.cloud.IFunctionHandlerClient](#@winglang/sdk.cloud.IFunctionHandlerClient) - -Represents a resource with an inflight "handle" method that can be used to create a `cloud.Function`. - - -#### Properties - -| **Name** | **Type** | **Description** | -| --- | --- | --- | -| node | constructs.Node | The tree node. | -| display | Display | Information on how to display a resource in the UI. | - ---- - -##### `node`Required - -```wing -node: Node; -``` - -- *Type:* constructs.Node - -The tree node. - ---- - -##### `display`Required - -```wing -display: Display; -``` - -- *Type:* Display - -Information on how to display a resource in the UI. - ---- - -### IFunctionHandlerClient - -- *Implemented By:* IFunctionHandlerClient - -Inflight client for `IFunctionHandler`. - -#### Methods - -| **Name** | **Description** | -| --- | --- | -| handle | Entrypoint function that will be called when the cloud function is invoked. | - ---- - -##### `handle` - -```wing -handle(event: str): void -``` - -**Inflight client:** [true](#true) - -Entrypoint function that will be called when the cloud function is invoked. - -###### `event`Required - -- *Type:* str - ---- - - -### IInflightHost - -- *Extends:* IResource - -- *Implemented By:* Function, Test, IInflightHost - -A resource that can run inflight code. - - -#### Properties - -| **Name** | **Type** | **Description** | -| --- | --- | --- | -| node | constructs.Node | The tree node. | -| display | Display | Information on how to display a resource in the UI. | - ---- - -##### `node`Required - -```wing -node: Node; -``` - -- *Type:* constructs.Node - -The tree node. - ---- - -##### `display`Required - -```wing -display: Display; -``` - -- *Type:* Display - -Information on how to display a resource in the UI. - ---- - -### IPredicateHandler - -- *Extends:* IResource - -- *Implemented By:* IPredicateHandler - -**Inflight client:** [@winglang/sdk.util.IPredicateHandlerClient](#@winglang/sdk.util.IPredicateHandlerClient) - -Represents a predicate with an inflight "handle" method that can be passed to `util.busyWait`. - - -#### Properties - -| **Name** | **Type** | **Description** | -| --- | --- | --- | -| node | constructs.Node | The tree node. | -| display | Display | Information on how to display a resource in the UI. | - ---- - -##### `node`Required - -```wing -node: Node; -``` - -- *Type:* constructs.Node - -The tree node. - ---- - -##### `display`Required - -```wing -display: Display; -``` - -- *Type:* Display - -Information on how to display a resource in the UI. - ---- - -### IPredicateHandlerClient - -- *Implemented By:* IPredicateHandlerClient - -Inflight client for `IPredicateHandler`. - -#### Methods - -| **Name** | **Description** | -| --- | --- | -| handle | The Predicate function that is called. | - ---- - -##### `handle` - -```wing -handle(): bool -``` - -**Inflight client:** [true](#true) - -The Predicate function that is called. - - -### IQueueClient - -- *Implemented By:* IQueueClient - -Inflight interface for `Queue`. - -#### Methods - -| **Name** | **Description** | -| --- | --- | -| approxSize | Retrieve the approximate number of messages in the queue. | -| pop | Pop a message from the queue. | -| purge | Purge all of the messages in the queue. | -| push | Push a message to the queue. | - ---- - -##### `approxSize` - -```wing -approxSize(): num -``` - -**Inflight client:** [true](#true) - -Retrieve the approximate number of messages in the queue. - -##### `pop` - -```wing -pop(): str -``` - -**Inflight client:** [true](#true) - -Pop a message from the queue. - -##### `purge` - -```wing -purge(): void -``` - -**Inflight client:** [true](#true) - -Purge all of the messages in the queue. - -##### `push` - -```wing -push(message: str): void -``` - -**Inflight client:** [true](#true) - -Push a message to the queue. - -###### `message`Required - -- *Type:* str - -Payload to send to the queue. - ---- - - -### IQueueSetConsumerHandler - -- *Extends:* IResource - -- *Implemented By:* IQueueSetConsumerHandler - -**Inflight client:** [@winglang/sdk.cloud.IQueueSetConsumerHandlerClient](#@winglang/sdk.cloud.IQueueSetConsumerHandlerClient) - -Represents a resource with an inflight "handle" method that can be passed to `Queue.setConsumer`. - - -#### Properties - -| **Name** | **Type** | **Description** | -| --- | --- | --- | -| node | constructs.Node | The tree node. | -| display | Display | Information on how to display a resource in the UI. | - ---- - -##### `node`Required - -```wing -node: Node; -``` - -- *Type:* constructs.Node - -The tree node. - ---- - -##### `display`Required - -```wing -display: Display; -``` - -- *Type:* Display - -Information on how to display a resource in the UI. - ---- - -### IQueueSetConsumerHandlerClient - -- *Implemented By:* IQueueSetConsumerHandlerClient - -Inflight client for `IQueueSetConsumerHandler`. - -#### Methods - -| **Name** | **Description** | -| --- | --- | -| handle | Function that will be called when a message is received from the queue. | - ---- - -##### `handle` - -```wing -handle(message: str): void -``` - -**Inflight client:** [true](#true) - -Function that will be called when a message is received from the queue. - -###### `message`Required - -- *Type:* str - ---- - - -### IResource - -- *Extends:* IInspectable, constructs.IConstruct - -- *Implemented By:* Api, Bucket, Counter, Function, Queue, Schedule, Secret, Service, Table, TestRunner, Topic, Website, Redis, Resource, Test, IApiEndpointHandler, IBucketEventHandler, IFunctionHandler, IQueueSetConsumerHandler, IScheduleOnTickHandler, IServiceOnEventHandler, ITopicOnMessageHandler, IInflightHost, IResource, ITestHandler, IPredicateHandler - -Abstract interface for `Resource`. - - -#### Properties - -| **Name** | **Type** | **Description** | -| --- | --- | --- | -| node | constructs.Node | The tree node. | -| display | Display | Information on how to display a resource in the UI. | - ---- - -##### `node`Required - -```wing -node: Node; -``` - -- *Type:* constructs.Node - -The tree node. - ---- - -##### `display`Required - -```wing -display: Display; -``` - -- *Type:* Display - -Information on how to display a resource in the UI. - ---- - -### IScheduleClient - -- *Implemented By:* IScheduleClient - -Inflight interface for `Schedule`. - - - -### IScheduleOnTickHandler - -- *Extends:* IResource - -- *Implemented By:* IScheduleOnTickHandler - -**Inflight client:** [@winglang/sdk.cloud.IScheduleOnTickHandlerClient](#@winglang/sdk.cloud.IScheduleOnTickHandlerClient) - -Represents a resource with an inflight "handle" method that can be passed to `Schedule.on_tick`. - - -#### Properties - -| **Name** | **Type** | **Description** | -| --- | --- | --- | -| node | constructs.Node | The tree node. | -| display | Display | Information on how to display a resource in the UI. | - ---- - -##### `node`Required - -```wing -node: Node; -``` - -- *Type:* constructs.Node - -The tree node. - ---- - -##### `display`Required - -```wing -display: Display; -``` - -- *Type:* Display - -Information on how to display a resource in the UI. - ---- - -### IScheduleOnTickHandlerClient - -- *Implemented By:* IScheduleOnTickHandlerClient - -Inflight client for `IScheduleOnTickHandler`. - -#### Methods - -| **Name** | **Description** | -| --- | --- | -| handle | Function that will be called when a message is received from the schedule. | - ---- - -##### `handle` - -```wing -handle(): void -``` - -**Inflight client:** [true](#true) - -Function that will be called when a message is received from the schedule. - - -### ISecretClient - -- *Implemented By:* ISecretClient - -Inflight interface for `Secret`. - -#### Methods - -| **Name** | **Description** | -| --- | --- | -| value | Retrieve the value of the secret. | -| valueJson | Retrieve the Json value of the secret. | - ---- - -##### `value` - -```wing -value(options?: GetSecretValueOptions): str -``` - -**Inflight client:** [true](#true) - -Retrieve the value of the secret. - -###### `options`Optional - -- *Type:* GetSecretValueOptions - ---- - -##### `valueJson` - -```wing -valueJson(options?: GetSecretValueOptions): Json -``` - -**Inflight client:** [true](#true) - -Retrieve the Json value of the secret. - -###### `options`Optional - -- *Type:* GetSecretValueOptions - ---- - - -### IServiceClient - -- *Implemented By:* IServiceClient - -Inflight interface for `Service`. - -#### Methods - -| **Name** | **Description** | -| --- | --- | -| start | Start the service. | -| stop | Stop the service. | - ---- - -##### `start` - -```wing -start(): void -``` - -**Inflight client:** [true](#true) - -Start the service. - -##### `stop` - -```wing -stop(): void -``` - -**Inflight client:** [true](#true) - -Stop the service. - - -### IServiceOnEventClient - -- *Implemented By:* IServiceOnEventClient - -Inflight client for `IServiceOnEventHandler`. - -#### Methods - -| **Name** | **Description** | -| --- | --- | -| handle | Function that will be called for service events. | - ---- - -##### `handle` - -```wing -handle(): void -``` - -**Inflight client:** [true](#true) - -Function that will be called for service events. - - -### IServiceOnEventHandler - -- *Extends:* IResource - -- *Implemented By:* IServiceOnEventHandler - -**Inflight client:** [@winglang/sdk.cloud.IServiceOnEventClient](#@winglang/sdk.cloud.IServiceOnEventClient) - -Represents a resource with an inflight "handle" method that can be passed to `ServiceProps.on_start` || `ServiceProps.on_stop`. - - -#### Properties - -| **Name** | **Type** | **Description** | -| --- | --- | --- | -| node | constructs.Node | The tree node. | -| display | Display | Information on how to display a resource in the UI. | - ---- - -##### `node`Required - -```wing -node: Node; -``` - -- *Type:* constructs.Node - -The tree node. - ---- - -##### `display`Required - -```wing -display: Display; -``` - -- *Type:* Display - -Information on how to display a resource in the UI. - ---- - -### ITableClient - -- *Implemented By:* ITableClient - -Inflight interface for `Table`. - -#### Methods - -| **Name** | **Description** | -| --- | --- | -| delete | Delete a row from the table, by primary key. | -| get | Get a row from the table, by primary key. | -| insert | Insert a row into the table. | -| list | List all rows in the table. | -| update | Update a row in the table. | - ---- - -##### `delete` - -```wing -delete(key: str): void -``` - -**Inflight client:** [true](#true) - -Delete a row from the table, by primary key. - -###### `key`Required - -- *Type:* str - -primary key to delete the row. - ---- - -##### `get` - -```wing -get(key: str): Json -``` - -**Inflight client:** [true](#true) - -Get a row from the table, by primary key. - -###### `key`Required - -- *Type:* str - -primary key to search. - ---- - -##### `insert` - -```wing -insert(key: str, row: Json): void -``` - -**Inflight client:** [true](#true) - -Insert a row into the table. - -###### `key`Required - -- *Type:* str - -primary key to insert the row. - ---- - -###### `row`Required - -- *Type:* Json - -data to be inserted. - ---- - -##### `list` - -```wing -list(): MutArray -``` - -**Inflight client:** [true](#true) - -List all rows in the table. - -##### `update` - -```wing -update(key: str, row: Json): void -``` - -**Inflight client:** [true](#true) - -Update a row in the table. - -###### `key`Required - -- *Type:* str - -primary key to update the row. - ---- - -###### `row`Required - -- *Type:* Json - -data to be updated. - ---- - - -### ITestHandler - -- *Extends:* IResource - -- *Implemented By:* ITestHandler - -**Inflight client:** [@winglang/sdk.std.ITestHandlerClient](#@winglang/sdk.std.ITestHandlerClient) - -Interface with an inflight "handle" method that can be used to construct a `std.Test`. - - -#### Properties - -| **Name** | **Type** | **Description** | -| --- | --- | --- | -| node | constructs.Node | The tree node. | -| display | Display | Information on how to display a resource in the UI. | - ---- - -##### `node`Required - -```wing -node: Node; -``` - -- *Type:* constructs.Node - -The tree node. - ---- - -##### `display`Required - -```wing -display: Display; -``` - -- *Type:* Display - -Information on how to display a resource in the UI. - ---- - -### ITestHandlerClient - -- *Implemented By:* ITestHandlerClient - -Inflight client for `ITestHandler`. - -#### Methods - -| **Name** | **Description** | -| --- | --- | -| handle | Inflight function that will be called when the test is run. | - ---- - -##### `handle` - -```wing -handle(): void -``` - -**Inflight client:** [true](#true) - -Inflight function that will be called when the test is run. - - -### ITestRunnerClient - -- *Implemented By:* ITestRunnerClient - -Inflight interface for `TestRunner`. - -#### Methods - -| **Name** | **Description** | -| --- | --- | -| listTests | List all tests available for this test engine. | -| runTest | Run a test with a given path and return the result. | - ---- - -##### `listTests` - -```wing -listTests(): MutArray -``` - -**Inflight client:** [true](#true) - -List all tests available for this test engine. - -##### `runTest` - -```wing -runTest(path: str): TestResult -``` - -**Inflight client:** [true](#true) - -Run a test with a given path and return the result. - -###### `path`Required - -- *Type:* str - ---- - - -### ITopicClient - -- *Implemented By:* ITopicClient - -Inflight interface for `Topic`. - -#### Methods - -| **Name** | **Description** | -| --- | --- | -| publish | Publish message to topic. | - ---- - -##### `publish` - -```wing -publish(message: str): void -``` - -**Inflight client:** [true](#true) - -Publish message to topic. - -###### `message`Required - -- *Type:* str - -Payload to publish to Topic. - ---- - - -### ITopicOnMessageHandler - -- *Extends:* IResource - -- *Implemented By:* ITopicOnMessageHandler - -**Inflight client:** [@winglang/sdk.cloud.ITopicOnMessageHandlerClient](#@winglang/sdk.cloud.ITopicOnMessageHandlerClient) - -Represents a resource with an inflight "handle" method that can be passed to `Topic.on_message`. - - -#### Properties - -| **Name** | **Type** | **Description** | -| --- | --- | --- | -| node | constructs.Node | The tree node. | -| display | Display | Information on how to display a resource in the UI. | - ---- - -##### `node`Required - -```wing -node: Node; -``` - -- *Type:* constructs.Node - -The tree node. - ---- - -##### `display`Required - -```wing -display: Display; -``` - -- *Type:* Display - -Information on how to display a resource in the UI. - ---- - -### ITopicOnMessageHandlerClient - -- *Implemented By:* ITopicOnMessageHandlerClient - -Inflight client for `ITopicOnMessageHandler`. - -#### Methods - -| **Name** | **Description** | -| --- | --- | -| handle | Function that will be called when a message is received from the topic. | - ---- - -##### `handle` - -```wing -handle(event: str): void -``` - -**Inflight client:** [true](#true) - -Function that will be called when a message is received from the topic. - -###### `event`Required - -- *Type:* str - ---- - - -### IWebsiteClient - -- *Implemented By:* IWebsiteClient - -Inflight methods and members of `cloud.Website`. - - - -## Enums - -### BucketEventType - -bucket events to subscribe to. - -#### Members - -| **Name** | **Description** | -| --- | --- | -| CREATE | create. | -| DELETE | delete. | -| UPDATE | update. | - ---- - -##### `CREATE` - -create. - ---- - - -##### `DELETE` - -delete. - ---- - - -##### `UPDATE` - -update. - ---- - - -### ColumnType - -Table column types. - -#### Members - -| **Name** | **Description** | -| --- | --- | -| STRING | string type. | -| NUMBER | number type. | -| BOOLEAN | bool type. | -| DATE | date type. | -| JSON | json type. | - ---- - -##### `STRING` - -string type. - ---- - - -##### `NUMBER` - -number type. - ---- - - -##### `BOOLEAN` - -bool type. - ---- - - -##### `DATE` - -date type. - ---- - - -##### `JSON` - -json type. - ---- - - -### Direction - -The direction of a connection. - -Visually speaking, if a resource A has an outbound connection with resource B, -the arrow would point from A to B, and vice versa for inbound connections. - -#### Members - -| **Name** | **Description** | -| --- | --- | -| OUTBOUND | Indicates that this resource calls, triggers, or references the resource it is connected to. | -| INBOUND | Indicates that this resource is called, triggered, or referenced by the resource it is connected to. | - ---- - -##### `OUTBOUND` - -Indicates that this resource calls, triggers, or references the resource it is connected to. - ---- - - -##### `INBOUND` - -Indicates that this resource is called, triggered, or referenced by the resource it is connected to. - ---- - - -### HttpMethod - -Allowed HTTP methods for a endpoint. - -#### Members - -| **Name** | **Description** | -| --- | --- | -| GET | Get. | -| HEAD | Head. | -| POST | Post. | -| PUT | Put. | -| DELETE | Delete. | -| CONNECT | Connect. | -| OPTIONS | Options. | -| PATCH | Patch. | - ---- - -##### `GET` - -Get. - ---- - - -##### `HEAD` - -Head. - ---- - - -##### `POST` - -Post. - ---- - - -##### `PUT` - -Put. - ---- - - -##### `DELETE` - -Delete. - ---- - - -##### `CONNECT` - -Connect. - ---- - - -##### `OPTIONS` - -Options. - ---- - - -##### `PATCH` - -Patch. - ---- - - -### TraceType - -The type of a trace. - -#### Members - -| **Name** | **Description** | -| --- | --- | -| RESOURCE | A trace representing a resource activity. | -| LOG | A trace representing a message emitted by the logger. | - ---- - -##### `RESOURCE` - -A trace representing a resource activity. - ---- - - -##### `LOG` - -A trace representing a message emitted by the logger. - ---- - diff --git a/docs/06-reference/02-simulator.md b/docs/06-reference/02-simulator.md deleted file mode 100644 index bed25d5b2e2..00000000000 --- a/docs/06-reference/02-simulator.md +++ /dev/null @@ -1,8 +0,0 @@ ---- -title: Simulator -id: simulator -description: Wing simulator reference -keywords: [Wing simulator, simulator, Wing simulator Reference] ---- - -TODO diff --git a/docs/06-reference/_category_.yml b/docs/06-reference/_category_.yml deleted file mode 100644 index 1334f8b0341..00000000000 --- a/docs/06-reference/_category_.yml +++ /dev/null @@ -1,3 +0,0 @@ -label: CLI, plugins, and tools -collapsible: true -collapsed: false diff --git a/docs/07-examples/01-hello-world.md b/docs/07-examples/01-hello-world.md deleted file mode 100644 index e54bd3b7de4..00000000000 --- a/docs/07-examples/01-hello-world.md +++ /dev/null @@ -1,7 +0,0 @@ ---- -title: Hello world -id: hello-world -keywords: [Wing example, simulator, Wing simulator Reference] ---- - -TODO diff --git a/docs/07-examples/02-file-tranformation.md b/docs/07-examples/02-file-tranformation.md deleted file mode 100644 index 49824fcc861..00000000000 --- a/docs/07-examples/02-file-tranformation.md +++ /dev/null @@ -1,7 +0,0 @@ ---- -title: File transformation -id: file-tranformation -keywords: [Wing exmaple] ---- - -TODO diff --git a/docs/07-examples/03-web-application.md b/docs/07-examples/03-web-application.md deleted file mode 100644 index 3ab5f926274..00000000000 --- a/docs/07-examples/03-web-application.md +++ /dev/null @@ -1,7 +0,0 @@ ---- -title: Web application -id: web-application -keywords: [Wing example] ---- - -TODO diff --git a/docs/07-examples/04-aggregate-github-issue-to-slack.md b/docs/07-examples/04-aggregate-github-issue-to-slack.md deleted file mode 100644 index 46c300d0b86..00000000000 --- a/docs/07-examples/04-aggregate-github-issue-to-slack.md +++ /dev/null @@ -1,7 +0,0 @@ ---- -title: Scheduled task -id: scheduled-task -keywords: [Wing examples] ---- - -TODO diff --git a/docs/08-guides/01-json-optionality.md b/docs/08-guides/01-json-optionality.md deleted file mode 100644 index a2a2514a5db..00000000000 --- a/docs/08-guides/01-json-optionality.md +++ /dev/null @@ -1,7 +0,0 @@ ---- -title: JSON & optionality -id: json-optionality -keywords: [Wing exmaple] ---- - -TODO diff --git a/docs/08-guides/02-ci-cd.md b/docs/08-guides/02-ci-cd.md deleted file mode 100644 index 621843fde84..00000000000 --- a/docs/08-guides/02-ci-cd.md +++ /dev/null @@ -1,7 +0,0 @@ ---- -title: CI/CD -id: ci-cd -keywords: [Wing exmaple] ---- - -TODO diff --git a/docs/08-guides/03-using-javascript.md b/docs/08-guides/03-using-javascript.md deleted file mode 100644 index 3869233996d..00000000000 --- a/docs/08-guides/03-using-javascript.md +++ /dev/null @@ -1,7 +0,0 @@ ---- -title: Using JavaScript -id: using-javascript -keywords: [Wing exmaple] ---- - -TODO diff --git a/docs/08-guides/04-bring-cdktf.md b/docs/08-guides/04-bring-cdktf.md deleted file mode 100644 index 3df39cc7b1e..00000000000 --- a/docs/08-guides/04-bring-cdktf.md +++ /dev/null @@ -1,7 +0,0 @@ ---- -title: CDTKTF -id: bring cdktf -keywords: [Wing exmaple] ---- - -TODO diff --git a/docs/08-guides/05-using-tfsec.md b/docs/08-guides/05-using-tfsec.md deleted file mode 100644 index 00d414e8786..00000000000 --- a/docs/08-guides/05-using-tfsec.md +++ /dev/null @@ -1,7 +0,0 @@ ---- -title: Preventing public buckets -id: tfsec -keywords: [Wing exmaple] ---- - -TODO diff --git a/docs/08-guides/06-multi-region-bucket-duplication.md b/docs/08-guides/06-multi-region-bucket-duplication.md deleted file mode 100644 index e903271bc13..00000000000 --- a/docs/08-guides/06-multi-region-bucket-duplication.md +++ /dev/null @@ -1,7 +0,0 @@ ---- -title: Multi-region bucket -id: multi-region-bucket -keywords: [Wing exmaple] ---- - -TODO diff --git a/docs/08-guides/07-using-typescript.md b/docs/08-guides/07-using-typescript.md deleted file mode 100644 index 1283b95362a..00000000000 --- a/docs/08-guides/07-using-typescript.md +++ /dev/null @@ -1,7 +0,0 @@ ---- -title: Using TypeScript -id: bring-typescript -keywords: [Wing exmaple] ---- - -TODO diff --git a/docs/999-contributors/_category_.yml b/docs/999-contributors/_category_.yml deleted file mode 100644 index 6ec37f323c3..00000000000 --- a/docs/999-contributors/_category_.yml +++ /dev/null @@ -1,6 +0,0 @@ -label: Contributing -collapsible: true -collapsed: true -link: - type: doc - id: index diff --git a/docs/999-contributors/index.md b/docs/contributing/01-start-here/01-contributing-to-wing.md similarity index 96% rename from docs/999-contributors/index.md rename to docs/contributing/01-start-here/01-contributing-to-wing.md index 60669fde9a3..10d1073ed7a 100644 --- a/docs/999-contributors/index.md +++ b/docs/contributing/01-start-here/01-contributing-to-wing.md @@ -1,6 +1,7 @@ --- title: Contributing to Wing id: index +slug: / keywords: [Wing contributors, contributors] --- @@ -10,7 +11,7 @@ to know to help out with the Wing project. There are many ways to contribute to Wing: * Reporting bugs through a [GitHub issue](https://github.com/winglang/wing/issues) -* Writing [documentation and guides](https://github.com/winglang/wing/issues?q=is:issue+is:open+sort:updated-desc+label:documentation) or adding [examples](./docs) +* Writing [documentation and guides](https://github.com/winglang/wing/issues?q=is:issue+is:open+sort:updated-desc+label:documentation) or adding [examples](docs) * Setting up your [development environment](./development) and working on the code * Submitting [pull requests](./pull_requests) for new features or helping with [reviews](https://github.com/winglang/wing/pulls) * Picking up a [good first issue](https://github.com/winglang/wing/issues?q=is%3Aissue+is%3Aopen+label%3A%22good+first+issue%22+no%3Aassignee+sort%3Aupdated-desc+) to work on diff --git a/docs/999-contributors/005-help.md b/docs/contributing/01-start-here/02-help.md similarity index 100% rename from docs/999-contributors/005-help.md rename to docs/contributing/01-start-here/02-help.md diff --git a/docs/999-contributors/08-status.md b/docs/contributing/01-start-here/03-status.md similarity index 63% rename from docs/999-contributors/08-status.md rename to docs/contributing/01-start-here/03-status.md index 087a4506a3b..0deedd02f71 100644 --- a/docs/999-contributors/08-status.md +++ b/docs/contributing/01-start-here/03-status.md @@ -5,23 +5,23 @@ keywords: [Wing project status, wing status, project status] slug: /status --- -:::caution Maturity: Alpha - -Under active development. - -::: +## ๐Ÿงช This is a pre-release **Wing is very young, naive, and currently under active development**. This means that we still don't think it's a very useful tool at the moment, and -definitely not ready for production use. Many of the APIs and language features +probably not ready for production use. Many of the APIs and language features will likely change in the coming months. However, it's definitely ready for those brave of hearts who would like to be involved at this early stage, influence our roadmap and join us for the ride. -We are hard at work to get it to a state where it is ready to be used for real -world projects (let's call it **Beta**). To that end, we need to cover -sufficient surface area across the various components. +We are working hard to make this a great tool, but there's still a pretty good +chance you'll encounter missing pieces, rough edges, performance issues and even, +god forbid, bugs ๐Ÿž. + +Please don't hesitate to ping us on [Slack](https://t.winglang.io/slack) or +[file an issue](https://github.com/winglang/wing). We promise to do our best to +respond quickly and help out. ## Roadmap diff --git a/docs/999-contributors/010-bugs.md b/docs/contributing/01-start-here/04-bugs.md similarity index 100% rename from docs/999-contributors/010-bugs.md rename to docs/contributing/01-start-here/04-bugs.md diff --git a/docs/999-contributors/020-development.md b/docs/contributing/01-start-here/05-development.md similarity index 100% rename from docs/999-contributors/020-development.md rename to docs/contributing/01-start-here/05-development.md diff --git a/docs/999-contributors/030-pull-requests.md b/docs/contributing/01-start-here/06-pull-requests.md similarity index 90% rename from docs/999-contributors/030-pull-requests.md rename to docs/contributing/01-start-here/06-pull-requests.md index b6b8ed14ce1..2d79770fed0 100644 --- a/docs/999-contributors/030-pull-requests.md +++ b/docs/contributing/01-start-here/06-pull-requests.md @@ -66,3 +66,8 @@ In pull requests, by default we only run tests for the same operating system and If you want to run tests for all operating systems, you can add the `๐Ÿงช pr/e2e-full` label to your PR. This label must be present before the build job starts, so if you add it after the build job has started, you will need to re-trigger the build by pushing a new commit to your PR. + +## ๐Ÿงช How do I set up my PRs to update snapshots? + +When PR checks run they may mutate the PR branch with updates to the snapshots or other things you may have missed. +This behavior has to be enabled manually on forks. Create a repository secret called `MUTATION_TOKEN` with a personal access token that is able to read/write your repo. diff --git a/docs/999-contributors/040-wingsdk.md b/docs/contributing/01-start-here/07-wingsdk.md similarity index 97% rename from docs/999-contributors/040-wingsdk.md rename to docs/contributing/01-start-here/07-wingsdk.md index 691783ce87c..6029b1403b8 100644 --- a/docs/999-contributors/040-wingsdk.md +++ b/docs/contributing/01-start-here/07-wingsdk.md @@ -237,8 +237,3 @@ These classes are then bundled together with esbuild, and can be used by the inf In the case of AWS for example, a `cloud.Function` will create an AWS Lambda function referencing a Terraform asset with a zipfile of the inflight code. For the simulator, the inflight code is bundled into the `.wsim` file produced by the compiler. - -## ๐Ÿงช How do I set up my PRs to update snapshots? - -When PR checks run they may mutate the PR branch with updates to the snapshots or other things you may have missed. -This behavior has to be enabled manually on forks. Create a repository secret called `MUTATION_TOKEN` with a personal access token that is able to read/write your repo. diff --git a/docs/999-contributors/050-docs.md b/docs/contributing/01-start-here/08-docs.md similarity index 100% rename from docs/999-contributors/050-docs.md rename to docs/contributing/01-start-here/08-docs.md diff --git a/docs/999-contributors/090-troubleshooting.md b/docs/contributing/01-start-here/09-troubleshooting.md similarity index 100% rename from docs/999-contributors/090-troubleshooting.md rename to docs/contributing/01-start-here/09-troubleshooting.md diff --git a/docs/999-contributors/100-code-of-conduct.md b/docs/contributing/01-start-here/10-code-of-conduct.md similarity index 100% rename from docs/999-contributors/100-code-of-conduct.md rename to docs/contributing/01-start-here/10-code-of-conduct.md diff --git a/docs/01-start-here/_category_.yml b/docs/contributing/01-start-here/_category_.yml similarity index 68% rename from docs/01-start-here/_category_.yml rename to docs/contributing/01-start-here/_category_.yml index 571e0735b7e..66e204e9b20 100644 --- a/docs/01-start-here/_category_.yml +++ b/docs/contributing/01-start-here/_category_.yml @@ -1,3 +1,3 @@ label: Start here collapsible: true -collapsed: false +collapsed: true diff --git a/docs/999-contributors/giphy.webp b/docs/contributing/01-start-here/giphy.webp similarity index 100% rename from docs/999-contributors/giphy.webp rename to docs/contributing/01-start-here/giphy.webp diff --git a/docs/999-contributors/99-maintainers/050-operations.md b/docs/contributing/02-maintainers/050-operations.md similarity index 100% rename from docs/999-contributors/99-maintainers/050-operations.md rename to docs/contributing/02-maintainers/050-operations.md diff --git a/docs/999-contributors/99-maintainers/10-runbooks/000-runbook-template.md b/docs/contributing/02-maintainers/10-runbooks/000-runbook-template.md similarity index 100% rename from docs/999-contributors/99-maintainers/10-runbooks/000-runbook-template.md rename to docs/contributing/02-maintainers/10-runbooks/000-runbook-template.md diff --git a/docs/999-contributors/99-maintainers/10-runbooks/_category_.yml b/docs/contributing/02-maintainers/10-runbooks/_category_.yml similarity index 100% rename from docs/999-contributors/99-maintainers/10-runbooks/_category_.yml rename to docs/contributing/02-maintainers/10-runbooks/_category_.yml diff --git a/docs/999-contributors/99-maintainers/index.md b/docs/contributing/02-maintainers/index.md similarity index 100% rename from docs/999-contributors/99-maintainers/index.md rename to docs/contributing/02-maintainers/index.md diff --git a/docs/999-contributors/99-maintainers/notification-configuration.png b/docs/contributing/02-maintainers/notification-configuration.png similarity index 100% rename from docs/999-contributors/99-maintainers/notification-configuration.png rename to docs/contributing/02-maintainers/notification-configuration.png diff --git a/docs/999-contributors/999-rfcs/000-stories/_category_.yml b/docs/contributing/03-stories/_category_.yml similarity index 100% rename from docs/999-contributors/999-rfcs/000-stories/_category_.yml rename to docs/contributing/03-stories/_category_.yml diff --git a/docs/999-contributors/999-rfcs/000-stories/story-04.md b/docs/contributing/03-stories/story-04.md similarity index 98% rename from docs/999-contributors/999-rfcs/000-stories/story-04.md rename to docs/contributing/03-stories/story-04.md index e77d642717a..3e67ee57b91 100644 --- a/docs/999-contributors/999-rfcs/000-stories/story-04.md +++ b/docs/contributing/03-stories/story-04.md @@ -177,8 +177,8 @@ the log message `Hello, cloud!`. Now that you've written your first Wing program, what's next? Here are some resources to help you get started: -- [Wing Language Specification](https://docs.winglang.io/contributors/rfcs/language-spec) -- [Wing SDK Reference](https://docs.winglang.io/contributors/rfcs/2023-01-20-wingsdk-spec) +- [Wing Language Specification](https://docs.winglang.io/contributing/rfcs/language-spec) +- [Wing SDK Reference](https://docs.winglang.io/contributing/rfcs/2023-01-20-wingsdk-spec) ## Staying up to date @@ -222,7 +222,7 @@ As such, our focus for this sprint is: - Consolidate everything related to Wing into the [monadahq/winglang](https://github.com/monadahq/winglang/) GitHub repo. This includes: - The [Wing SDK](https://github.com/monadahq/wingsdk) - The [language spec](https://github.com/monadahq/winglang-spec) - should go under `docs/winglang-spec.md` - - The [language requirements RFC](https://docs.winglang.io/contributors/rfcs/2022-05-28-winglang-reqs) - + - The [language requirements RFC](https://docs.winglang.io/contributing/rfcs/2022-05-28-winglang-reqs) - should go under `rfcs/winglang-reqs.md` - All issues should also be transfered into this repository. - Updating the main README file to match this RFC as close as possible. diff --git a/docs/999-contributors/999-rfcs/000-stories/story-06.md b/docs/contributing/03-stories/story-06.md similarity index 100% rename from docs/999-contributors/999-rfcs/000-stories/story-06.md rename to docs/contributing/03-stories/story-06.md diff --git a/docs/999-contributors/999-rfcs/000-stories/story-07.md b/docs/contributing/03-stories/story-07.md similarity index 100% rename from docs/999-contributors/999-rfcs/000-stories/story-07.md rename to docs/contributing/03-stories/story-07.md diff --git a/docs/999-contributors/999-rfcs/000-stories/story-10.md b/docs/contributing/03-stories/story-10.md similarity index 100% rename from docs/999-contributors/999-rfcs/000-stories/story-10.md rename to docs/contributing/03-stories/story-10.md diff --git a/docs/999-contributors/999-rfcs/000-stories/story-12a.md b/docs/contributing/03-stories/story-12a.md similarity index 100% rename from docs/999-contributors/999-rfcs/000-stories/story-12a.md rename to docs/contributing/03-stories/story-12a.md diff --git a/docs/999-contributors/999-rfcs/000-stories/story-12b.md b/docs/contributing/03-stories/story-12b.md similarity index 100% rename from docs/999-contributors/999-rfcs/000-stories/story-12b.md rename to docs/contributing/03-stories/story-12b.md diff --git a/docs/999-contributors/999-rfcs/000-stories/story-13.md b/docs/contributing/03-stories/story-13.md similarity index 100% rename from docs/999-contributors/999-rfcs/000-stories/story-13.md rename to docs/contributing/03-stories/story-13.md diff --git a/docs/999-contributors/999-rfcs/000-stories/story-14b.md b/docs/contributing/03-stories/story-14b.md similarity index 100% rename from docs/999-contributors/999-rfcs/000-stories/story-14b.md rename to docs/contributing/03-stories/story-14b.md diff --git a/docs/999-contributors/999-rfcs/000-stories/story-15.md b/docs/contributing/03-stories/story-15.md similarity index 100% rename from docs/999-contributors/999-rfcs/000-stories/story-15.md rename to docs/contributing/03-stories/story-15.md diff --git a/docs/999-contributors/999-rfcs/2022-05-28-winglang-reqs.md b/docs/contributing/999-rfcs/2022-05-28-winglang-reqs.md similarity index 99% rename from docs/999-contributors/999-rfcs/2022-05-28-winglang-reqs.md rename to docs/contributing/999-rfcs/2022-05-28-winglang-reqs.md index 38d9145c510..9afc26a5eb8 100644 --- a/docs/999-contributors/999-rfcs/2022-05-28-winglang-reqs.md +++ b/docs/contributing/999-rfcs/2022-05-28-winglang-reqs.md @@ -6,7 +6,7 @@ description: The original requirements documents for the wing language experienc - **Author(s):**: @eladb - **Submission Date**: {2022-05-28} - **Stage**: Approved -- **Implementation**: [Language Specification](https://docs.winglang.io/contributors/rfcs/language-spec) +- **Implementation**: [Language Specification](https://docs.winglang.io/contributing/rfcs/language-spec) ## About this Document diff --git a/docs/999-contributors/999-rfcs/2022-06-14-polycons.md b/docs/contributing/999-rfcs/2022-06-14-polycons.md similarity index 99% rename from docs/999-contributors/999-rfcs/2022-06-14-polycons.md rename to docs/contributing/999-rfcs/2022-06-14-polycons.md index e2f6b2c3fd8..23b327cea37 100644 --- a/docs/999-contributors/999-rfcs/2022-06-14-polycons.md +++ b/docs/contributing/999-rfcs/2022-06-14-polycons.md @@ -4,7 +4,7 @@ description: This document describes a dependency injection meta-framework for p --- > Note: the design of polycons has changed significantly since this was first written! -> Please check out the polycons [README](https://github.com/winglang/polycons) for details about how the current Polycons API works, and check the [SDK Architecture](/contributors/wingsdk#sdk-architecture) to see where many ideas from this RFC were adopted! +> Please check out the polycons [README](https://github.com/winglang/polycons) for details about how the current Polycons API works, and check the [SDK Architecture](/wingsdk#sdk-architecture) to see where many ideas from this RFC were adopted! * **Author(s):**: @MarkMcCulloh * **Submission Date**: 2022-06-14 diff --git a/docs/999-contributors/999-rfcs/2022-08-22-resource-naming.md b/docs/contributing/999-rfcs/2022-08-22-resource-naming.md similarity index 100% rename from docs/999-contributors/999-rfcs/2022-08-22-resource-naming.md rename to docs/contributing/999-rfcs/2022-08-22-resource-naming.md diff --git a/docs/999-contributors/999-rfcs/2023-01-20-wingsdk-spec.md b/docs/contributing/999-rfcs/2023-01-20-wingsdk-spec.md similarity index 100% rename from docs/999-contributors/999-rfcs/2023-01-20-wingsdk-spec.md rename to docs/contributing/999-rfcs/2023-01-20-wingsdk-spec.md diff --git a/docs/999-contributors/999-rfcs/2023-01-21-wing-plugins.md b/docs/contributing/999-rfcs/2023-01-21-wing-plugins.md similarity index 100% rename from docs/999-contributors/999-rfcs/2023-01-21-wing-plugins.md rename to docs/contributing/999-rfcs/2023-01-21-wing-plugins.md diff --git a/docs/999-contributors/999-rfcs/2023-04-16-website-resource.md b/docs/contributing/999-rfcs/2023-04-16-website-resource.md similarity index 98% rename from docs/999-contributors/999-rfcs/2023-04-16-website-resource.md rename to docs/contributing/999-rfcs/2023-04-16-website-resource.md index b75d4f94117..6991f7d20d5 100644 --- a/docs/999-contributors/999-rfcs/2023-04-16-website-resource.md +++ b/docs/contributing/999-rfcs/2023-04-16-website-resource.md @@ -19,7 +19,7 @@ Stage: Fill in with current stage in the RFC lifecycle Stage Date: Fill in with date of last stage change --> -> Implementing the website resource following the [SDK spec](https://docs.winglang.io/contributors/rfcs/2023-01-20-wingsdk-spec#website). +> Implementing the website resource following the [SDK spec](https://docs.winglang.io/contributing/rfcs/2023-01-20-wingsdk-spec#website). <----- str? ------> <-- str ---> +``` + +The last element in a `??` chain must be a non-optional type `T`. + +#### 1.7.5 Optional chaining using `?.` + +The `?.` syntax can be used for optional chaining. Optional chaining returns a value of type `T?` +which must be unwrapped in order to be used. + +```js +let ipAddress: str? = options.networking?.ipAddress; + +if let ip = ipAddress { + print("the ip address is defined and it is: ${ip}"); +} +``` + +#### 1.7.6 Roadmap + +In the future we will consider the following additional sugar syntax: + +* `x ?? throw("message")` to unwrap `x` or throw if `x` is not defined. +* `x ??= value` returns `x` or assigns a value to it and returns it to support lazy + evaluation/memoization (inspired by [Nullish coalescing + assignment](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Nullish_coalescing_assignment)). +* Support `??` for different types if they have a common ancestor (and also think of interfaces). + +[`โ–ฒ top`][top] + +--- + +### 1.8 Type Inference + +Type can optionally be put between name and the equal sign, using a colon. +Partial type inference is allowed while using the `?` keyword immediately after +the variable name. + +When type annotation is missing, type will be inferred from r-value type. +r-value refers to the right hand side of an assignment here. + +All defined symbols are immutable (constant) by default. +Type casting is generally not allowed unless otherwise specified. + +Function arguments and their return type is always required. Function argument +type is inferred iff a default value is provided. + +> ```TS +> let i = 5; +> let m = i; +> let arrOpt? = MutArray[]; +> let arr = Array[]; +> let copy = arr; +> let i1? = nil; +> let i2: num? = i; +> ``` + +
Equivalent TypeScript Code + +> ```TS +> const i: number = 5; +> const m: number = i; +> const arrOpt: number[]? = []; +> const arr: number[] = Object.freeze([]); +> const copy: number[] = Object.freeze([...arr]); +> const i1: any = undefined; +> const i2: number? = i; +> ``` + +
+ +[`โ–ฒ top`][top] + +--- + +### 1.9 Error Handling + +Exceptions and `try/catch/finally` are the error mechanism. Mechanics directly +translate to JavaScript. You can create a new exception with a `throw` call. + +In the presence of `try`, both `catch` and `finally` are optional but at least one of them must be present. +In the presence of `catch` the variable holding the exception (`e` in the example below) is optional. + +`panic` is meant to be fatal error handling. +`throw` is meant to be recoverable error handling. + +An uncaught exception is considered user error but a panic call is not. Compiler +must guarantee exception safety by throwing a compile error if an exception is +expected from a call and it is not being caught. + +> ```TS +> try { +> let x: num? = 1; +> throw("hello exception"); +> } catch e { +> log(e); +> } finally { +> log("done"); +> } +> ``` + +
Equivalent TypeScript Code + +> ```TS +> try { +> let x: number? = 1; +> throw new Error("hello exception"); +> } catch (e) { +> console.log(e); +> } finally { +> console.log("done"); +> } +> ``` + +
+ +[`โ–ฒ top`][top] + +--- + +### 1.10 Recommended Formatting + +Wing recommends the following formatting and naming conventions: + +- Interface names should start with capital letter "I". +- Class, struct, and interface names should be TitleCased. +- Members of classes, and interfaces cannot share the same TitleCased + representation as the declaring expression itself. +- Parentheses are optional in expressions. Any Wing expression can be surrounded + by parentheses to enforce precedence, which implies that the expression inside + an if/for/while statement may be surrounded by parentheses. + +[`โ–ฒ top`][top] + +--- + +### 1.11 Memory Management + +There is no implicit memory de-allocation function, dynamic memory is managed by +Wing and is garbage collected (relying on JSII target GC for the meantime). + +[`โ–ฒ top`][top] + +--- + +### 1.12 Execution Model + +Execution model currently is delegated to the JSII target. This means if you are +targeting JSII with Node, Wing will use the event based loop that Node offers. + +In Wing, writing and executing at root block scope level is forbidden except for +the entrypoint of the program. Root block scope is considered special and +compiler generates special instructions to properly assign all preflight classes to +their respective scopes recursively down the constructs tree based on entry. + +Entrypoint is always a Wing source with an extension of `.w`. Within this entry +point, a root preflight class is made available for all subsequent preflight classes that are +initialized and instantiated. Type of the root class is determined by the +target being used by the compiler. The root class might be of type `App` in +AWS CDK or `TerraformApp` in case of CDK for Terraform target. + +> Following "shimming" is only done for the entrypoint file and nowhere else. +> Type of the "shim" changes from `cdk.Stack` to `TerraformStack` for cdk-tf. + +> ```TS +> // Wing Entrypoint Code: +> let a = MyResource(); +> let b = MyResource() be "my-resource"; +> ``` + +
Equivalent TypeScript Code + +> ```TS +> (new class extends cdk.Stack { +> constructor(scope: constructs.Construct, id: string) { +> const a = new MyResource(this, "MyResource"); +> const b = new MyResource(this, "my-resource"); +> } +> })(new cdk.App(), "WingEntry"); +> ``` + +
+ +[`โ–ฒ top`][top] + +--- + +### 1.13 Asynchronous Model + +Wing builds upon the asynchronous model of JavaScript currently and expands upon +it with new keywords and concepts. The `async` keyword of JavaScript is replaced +with `inflight` in Wing deliberately to indicate extended functionality. + +Main concepts to understand: + +- `preflight` implies synchronous execution. +- `inflight` implies asynchronous execution. + +Contrary to JavaScript, any call to an async function is implicitly awaited in Wing. As +a result, `await` in Wing is a rarely used keyword, since its use is implied by +the `inflight` keyword. `await` is only used when you want a `defer`ed `Promise` +to be fulfilled before execution flow continues. + +The Wing compiler emits `await`s when encountering `Promise` types as r-values +in expressions. Use the `defer` keyword to defer the resolution of a promise and +obtain a `Promise` type instead (a.k.a un`await` what the compiler does). + +The `Promise` type is not allowed to hold nested promises in `T`. + +## 2. Statements + +### 2.1 bring + +**bring** statement can be used to import and reuse code from other Wing files or +other JSII supported languages. The statement is detailed in its own section in +this document: [Module System](#4-module-system). + +[`โ–ฒ top`][top] + +--- + +### 2.2 break + +**break** statement allows to end execution of a cycle. This includes for and +while loops currently. + +> ```TS +> for let i in 1..10 { +> if i > 5 { +> break; +> } +> log(i); +> } +> ``` + +
Equivalent TypeScript Code + +> ```TS +> for (let i = 1; i < 10; i++) { +> if (i > 5) { +> break; +> } +> console.log(i); +> } +> ``` + +
+ +[`โ–ฒ top`][top] + +--- + +### 2.3 continue + +**continue** statement allows to skip to the next iteration of a cycle. This +includes for and while loops currently. + +> ```TS +> for let i in 1..10 { +> if i > 5 { +> continue; +> } +> log(i); +> } +> ``` + +
Equivalent TypeScript Code + +> ```TS +> for (let i = 1; i < 10; i++) { +> if (i > 5) { +> continue; +> } +> console.log(i); +> } +> ``` + +
+ +[`โ–ฒ top`][top] + +--- + +### 2.4 return + +**return** statement allows to return a value or exit from a called context. + +> ```TS +> class MyClass { +> public myPublicMethod() {} +> private _myPrivateMethod(): void {} +> protected myProtectedMethod(): nil { return nil; } +> internal _myInternalMethod(): str { return "hi!"; } +> } +> ``` + +
Equivalent TypeScript Code + +> ```TS +> class MyClass { +> public myPublicMethod(): void {} +> private myPrivateMethod(): undefined {} +> protected myProtectedMethod(): undefined { return undefined; } +> // specific compiled instruction is up to implementation of the compiler +> public __wing_InternalMyInternalMethod(): string { return "hi!"; } +> } +> ``` + +
+ +[`โ–ฒ top`][top] + +--- + +### 2.5 defer/await + +> Read [Asynchronous Model](#114-asynchronous-model) section as a prerequisite. + +You mostly do not need to use **defer** and **await** keywords in Wing. +"defer" prevents the compiler from awaiting a promise and grabs a reference. +"await" and "Promise" are semantically similar to JavaScript's promises. +"await" statement is only valid in `inflight` function declarations. +Awaiting non promises in Wing is a no-op just like in JavaScript. + +> ```TS +> // Wing program: +> class MyClass { +> inflight foo(): num { +> let w = defer somePromise(); +> let x = await w; +> return x; +> } +> inflight boo(): num { +> let x = somePromise(); +> return x; +> } +> } +> ``` + +
Equivalent TypeScript Code + +> ```TS +> class MyClass { +> async foo(): Promise { +> const w = somePromise(); +> const x = Object.freeze(await w); +> return x; +> } +> async boo(): Promise { +> const x = Object.freeze(await somePromise()); +> return x; +> } +> } +> ``` + +
+ +[`โ–ฒ top`][top] + +--- + +### 2.6 if + +Flow control can be done with `if/elif/else` statements. +The **if** statement is optionally followed by **elif** and **else**. + +> ```TS +> // Wing program: +> let x = 1; +> let y = "sample"; +> if x == 2 { +> log("x is 2"); +> } elif y != "sample" { +> log("y is not sample"); +> } else { +> log("x is 1 and y is sample"); +> } +> ``` + +
Equivalent TypeScript Code + +> ```TS +> const x: number = 1; +> const y: string = "sample"; +> if (x === 2) { +> console.log("x is 2"); +> } else if (y !== "sample") { +> console.log("y is not sample"); +> } else { +> console.log("x is 1 and y is sample"); +> } +> ``` + +
+ +[`โ–ฒ top`][top] + +--- + +### 2.7 for + +`for..in` statement is used to iterate over an array or a set. +Type annotation after an iteratee (left hand side of **in**) is optional. +The loop invariant in for loops is implicitly re-assignable (`var`). + +> ```TS +> // Wing program: +> let arr = [1, 2, 3]; +> let set = {1, 2, 3}; +> for item in arr { +> log(item); +> } +> for item: num in set { +> log(item); +> } +> for item in 0..100 { +> log(item); +> } +> ``` + +
Equivalent TypeScript Code + +> ```TS +> const arr: number[] = Object.freeze([1, 2, 3]); +> const set: Set = Object.freeze(new Set([1, 2, 3])); +> for (const item of arr) { +> console.log(item); +> } +> for (const item of set) { +> console.log(item); +> } +> // calling 0..100 does not allocate, just returns an iterator +> function* iterator(start, end) { +> let i = start; +> while (i < end) yield i++; +> while (i > end) yield i--; +> } +> const iter = iterator(0, 100); +> for (const val of iter) { +> console.log(val); +> } +> ``` + +
+ +[`โ–ฒ top`][top] + +--- + +### 2.8 while + +**while** statement is used to execute a block of code while a condition is true. + +> ```TS +> // Wing program: +> while callSomeFunction() { +> log("hello"); +> } +> ``` + +
Equivalent TypeScript Code + +> ```TS +> while (callSomeFunction()) { +> console.log("hello"); +> } +> ``` + +
+ +[`โ–ฒ top`][top] + +--- + +## 3. Declarations + +### 3.1 Structs + +Structs are loosely modeled after typed JSON literals in JavaScript. +Structs are defined with the `struct` keyword. +Structs are "bags" of immutable data. + +Structs can only have fields of primitive types, preflight classes, and other structs. +Array, set, and map of above types is also allowed in struct field definition. +Visibility, storage and phase modifiers are not allowed in struct fields. + +Structs can inherit from multiple other structs. + +> ```Rust +> // Wing program: +> struct MyDataModel1 { +> field1: num; +> field2: str; +> }; +> struct MyDataModel2 { +> field3: num; +> field4: bool?; +> }; +> struct MyDataModel3 extends MyDataModel1, MyDataModel2 { +> field5: str; +> } +> let s1 = MyDataModel1 { field1: 1, field2: "sample" }; +> let s2 = MyDataModel2 { field3: 1, field4: true }; +> let s3 = MyDataModel2 { field3: 1 }; +> let s4 = MyDataModel3 { +> field1: 12, +> field2: "sample", +> field3: 11, +> field4: false, +> field5: "sample" +> }; +> ``` + +
Equivalent TypeScript Code + +> ```TS +> interface MyDataModel1 { +> public readonly field1: number; +> public readonly field2: string; +> } +> interface MyDataModel2 { +> public readonly field3: number; +> public readonly field4?: boolean; +> } +> interface MyDataModel3 extends MyDataModel1, MyDataModel2 { +> public readonly field5: string; +> public readonly field6: number; +> } +> const s1: MyDataModel1 = { field1: 1, field2: "sample" }; +> const s2: MyDataModel2 = { field3: 1, field4: true }; +> const s3: MyDataModel2 = { field3: 1, field4: undefined }; +> const s4: MyDataModel3 = { +> field1: 12, +> field2: "sample", +> field3: 11, +> field4: false, +> field5: "sample", +> field6: 11 +> }; +> ``` + +
+ +[`โ–ฒ top`][top] + +--- + +### 3.2 Classes + +Similar to other object-oriented programming languages, Wing uses classes as its first-class +composition pattern. + +Classes consist of fields and methods in any order. +The class system is a single-dispatch class based object-orientated system. +Classes are instantiated with the `new` keyword. + +Classes are associated with a specific execution phase (preflight or inflight). The phase indicates +in which scope objects can be instantiated from this class. + +If a [phase modifier](#13-phase-modifiers) is not specified, the class inherits the phase from the +scope in which it is declared. This implies that, if a class is declared at the root scope (e.g. the +program's entrypoint), it will be a *preflight class*. If a class is declared within an inflight +scope, it will be implicitly an inflight class. + +A method that has the name **init** is considered to be a class +constructor (or initializer, or allocator). + +```TS +inflight class Name extends Base impl IMyInterface1, IMyInterface2 { + init() { + // constructor implementation + // order is up to user + this._field1 = 1; + this._field2 = "sample"; + } + + // class fields (private by due to having leading underscore) + _field1: num; + _field2: str; + + // static method (access with Name.staticMethod(...)) + public static staticMethod(arg: type, arg: type, ...) { /* impl */ } + // private method + private _privateMethod(arg: type, arg: type, ...): type { /* impl */ } + // visible to outside the instance + public publicMethod(arg:type, arg:type, ...) { /* impl */ } + // visible to children only + protected protectedMethod(type:arg, type:arg, ...) { /* impl */ } + // public in current compilation unit only + internal _internalMethod3(type:arg, type:arg, ...): type { /* impl */ } +} +``` + +Default initialization does not exist in Wing. All member fields must be +initialized in the constructor. Absent initialization is a compile error. All +field types, including the optional types must be initialized. Optionals are +initialized to `nil` if omitted, unless the type is `nil?`, which in that case, +absent initialization is a compile error. + +Member function and field access in constructor with the "this" keyword before +all fields are initialized is invalid and would throw a compile error. + +In other words, the `this` keyword is immutable to its field access operator `.` +before all the member fields are properly initialized. The behavior is similar +to JavaScript and TypeScript in their "strict" mode. + +```TS +class Foo { + x: num; + init() { this.x = 1; } +} +class Bar { + y: num; + z: Foo; + init() { + // this.log() // is compile error here + this.y = 1; + // this.log() // is also compile error here + this.z = new Foo(); + this.log(); // OK to call here + } + public log() { + log(this.y); + } +} +let a = new Bar(); +a.log(); // logs 20. +``` + +Overloading methods is allowed. This means functions can be overloaded with many +signatures only varying in the number of arguments and their unique type order. +Overloading the constructor is also allowed. +Inheritance is allowed with the `extends` keyword. `super` can be used to access +the base class, immediately up the inheritance chain (parent class). + +Calling using the member access operator `.` before calling `super` in inherited +classes is forbidden. The behavior is similar to JavaScript and TypeScript in +their "strict" mode. + +```TS +class Foo { + x: num; + init() { this.x = 0; } + public method() { } +} +class Boo extends Foo { + init() { + // this.x = 10; // compile error + super(); + this.x = 10; // OK + } + public override method() { + // override implementation + } +} +``` + +Classes can inherit and extend other classes using the `extends` keyword. +Classes can implement interfaces iff the interfaces do not contain `inflight`. +You can use the keyword `final` to stop the inheritance chain. + +```TS +class Foo { + x: num; + init() { this.x = 0; } + public method() { } +} +final class Boo extends Foo { + init() { super(); this.x = 10; } + public override method() { + // override implementation + } +} +// compile error +// class FinalBoo extends Boo {} +``` + +By default all methods are virtual. But if you are about to override a method, +you need to explicitly provide the keyword **override**. +Static, private, and internal methods cannot be and are not virtual. + +Statics are not inherited. As a result, statics can be overridden mid hierarchy +chain. Access to statics is through the class name that originally defined it: +`.Foo`. + +Child class must not introduce additional signatures (overloads) for overridden +(virtual) methods. + +Multiple inheritance is invalid and forbidden. +Multiple implementations of various interfaces is allowed. +Multiple implementations of the same interface is invalid and forbidden. + +In methods if return type is missing, `: void` is assumed. + +[`โ–ฒ top`][top] + +--- + +### 3.3 Preflight Classes + +Classes declared within a preflight scope (the root scope) are implicitly bound to the preflight +phase. These classes can have specific `inflight` members. + +For example: + +```TS +// Wing Code: +class Foo { + init() { /* initialize preflight fields */ } // preflight constructor + inflight init() {} // optional client initializer + + // inflight members + inflight foo(arg: num): num { return arg; } + inflight boo(): num { return 32; } + + // inflight fields + inflight field1: num; + inflight field2: str; + inflight field3: bool; + + // preflight members + foo(arg: num): num { return arg; } + boo(): num { return 32; } + + // preflight fields + field4: num; + field5: str; + field6: bool; + + // re-assignable class fields, read about them in the mutability section + var field4: num; + var field5: str; +} +``` + +Preflight objects all have a scope and a unique ID. Compiler provides an implicit scope +and ID for each object, both overrideable by user-defined ones in constructor. + +The default for scope is `this`, which means the scope in which the object was +defined (instantiated). The implicit ID is the type name of the class iff the type +is the only preflight object of this type being used in the current scope. In other words, if +there are multiple preflight objects of the same type defined in the same scope, they +must all have an explicit id. + +Preflight objects instantiated at block scope root level of entrypoint are assigned the +root app as their default implicit scope. + +Preflight object instantiation syntax uses the `let` keyword the same way variables are declared in +Wing. The `as` and `in` keywords can be used to customize the scope and identifier assigned to this +preflight object. + +```pre +let [: ] = new () [as ] [in ]; +``` + +```TS +// Wing Code: +let a = Foo(); // with default scope and id +let a = Foo() in scope; // with user-defined scope +let a = new Foo() as "custom-id" in scope; // with user-defined scope and id +let a = new Foo(...) as "custom-id2" in scope; // with constructor arguments +``` + +"id" must be of type string. It can also be a string literal with substitution +support (normal strings as well as shell strings). +"scope" must be an expression that resolves to a preflight object. + +Preflight objects can be captured into inflight scopes and once that happens, inside +the capture block only the inflight members are available. + +Preflight classes can extend other preflight classes (but not [structs](#31-structs)) and implement +[interfaces](#34-interfaces). If a class implements an interface marked `inflight interface`, then +all of the implemented methods must be `inflight`. + +Declaration of fields of the same name with different phases is not allowed due to requirement of +having inflight fields of same name being implicitly initialized by the compiler. But declaration +of methods with different phases is allowed. + +[`โ–ฒ top`][top] + +--- + +### 3.4 Interfaces + +Interfaces represent a contract that a class must fulfill. +Interfaces are defined with the `interface` keyword. +Both preflight and inflight signatures are allowed. +If the `inflight` modifier is used in the interface declaration, all methods will be automatically considered inflight methods. `impl` keyword is used to implement an interface or multiple interfaces that are +separated with commas. + +All methods of an interface are implicitly public and cannot be of any other +type of visibility (private, protected, etc.). + +Interface fields are not supported. + +> ```TS +> // Wing program: +> interface IMyInterface1 { +> method1(x: num): str; +> inflight method3(): void; +> }; +> +> inflight interface IMyInterface2 { +> method2(): str; // <-- "inflight" is implied +> }; +> +> class MyResource impl IMyInterface1, IMyInterface2 { +> field1: num; +> field2: str; +> +> inflight init(x: num) { +> // inflight client initialization +> this.field1 = x; +> this.field2 = "sample"; +> } +> method1(x: num): str { +> return "sample: ${x}"; +> } +> inflight method3(): void { } +> inflight method2(): str { +> return this.field2; +> } +> }; +> ``` + +
Equivalent TypeScript Code + +> ```TS +> interface IMyInterface1 { +> public readonly field1: number; +> public method1(x: number): string; +> } +> interface IMyInterface2 { +> public readonly __inflight__field2: string; +> public __inflight__method2(): string; +> } +> // this is only shown as a hypothetical sample +> class MyResource extends constructs.Construct +> implements IMyInterface1, IMyInterface2 { +> public readonly field1: number; +> public readonly __inflight__field2: string; +> public __inflight__constructor() { +> // inflight client initialization +> this.field1 = x; +> this.__inflight__field2 = "sample"; +> } +> public __inflight__method2(): string { +> return this.__inflight__field2; +> } +> public method1(x: number): string { +> return `sample: ${x}`; +> } +> } +> ``` + +
+ +[`โ–ฒ top`][top] + +--- + +### 3.5 Variables + +> Let let be let. (Elad B. 2022) + +```pre +let [: ] = ; +``` + +Assignment operator is `=`. +Assignment declaration keyword is `let`. +Type annotation is optional if a default value is given. + +> ```TS +> let n = 10; +> let s: str = "hello"; +> ``` + +
Equivalent TypeScript Code + +> ```TS +> const n: number = 10; +> const s: string = "hello"; +> ``` + +
+ +[`โ–ฒ top`][top] + +--- + +### 3.6 Functions + +#### 3.6.1 Closures + +It is possible to create closures. +It is not possible to create named closures. +However, it is possible to create anonymous closures and assign to variables +(function literals). Inflight closures are also supported. + +> ```TS +> // preflight closure: +> let f1 = (a: num, b: num) => { log(a + b); } +> // inflight closure: +> let f2 = inflight (a: num, b: num) => { log(a + b); } +> // OR: +> // preflight closure: +> let f4 = (a: num, b: num): void => { log(a + b); } +> // inflight closure: +> let f5 = inflight (a: num, b: num): void => { log(a + b); } +> ``` + +[`โ–ฒ top`][top] + +--- + +#### 3.6.2 Promises + +Promises in Wing are defined with `Promise` syntax. +All `inflight` functions implicitly wrap their return type in `Promise`. + +> ```TS +> let schema = inflight (): Struct => { +> return someCallForSchema(); +> } +> ``` + +
Equivalent TypeScript Code + +> ```TS +> const schema = async (): Promise => { +> return await someCallForSchema(); +> } +> ``` + +
+ +[`โ–ฒ top`][top] + +--- + +#### 3.6.3 Struct Expansion + +If the last argument of a function call is a struct, then the struct in the call +is "expandable" with a special `:` syntax. +In this calling signature, order of struct members do not matter. +Partial struct expansion in terms of supplying less number of arguments than the +number of fields on type of the struct expected is not allowed. Omitting `nil`s +is allowed with the same rules as explicit initialization in class constructors. + +This style of expansion can be thought of as having positional arguments passed +in before the final positional argument, which if happens to be a struct, it can +be passed as named arguments. As a result of named arguments being passed in, it +is safe to omit optional struct fields, or have order of arguments mixed. + +```TS +struct MyStruct { + field1: num; + field2: num; +}; +let f = (x: num, y: num, z: MyStruct) => { + log(x + y + z.field1 + z.field2); +} +// last arguments are expanded into their struct +f(1, 2, field1: 3, field2: 4); +// f(1, 2, field1: 3); // can't do this, partial expansion is not allowed +``` + +[`โ–ฒ top`][top] + +--- + +#### 3.6.4 Variadic Arguments + +If the last argument of a function type is the `...args` keyword followed by an +`Array` type, then the function accepts typed variadic arguments. Expansion of +variadic arguments is not supported currently and the container of variadic +arguments is accessible with the `args` key like a normal array instance. + +```TS +let f = (x: num, ...args: Array) => { + log(x + y + args.len); +} +// last arguments are expanded into their array +f(1, 2, 3, 4, 5, 6, 34..100); +``` + +[`โ–ฒ top`][top] + +--- + +### 3.7 Arrays + +`Array`s are dynamically sized in Wing and are defined with the `[]` syntax. +Individual array items are also accessed with the `[]` syntax. +Arrays are similar to dynamically sized arrays or vectors in other languages. + +> ```TS +> let arr1 = [1, 2, 3]; +> let arr2 = ["a", "b", "c"]; +> let arr3 = MutArray["a1", "b2", "c3"]; +> let l = arr1.len + arr2.len + arr3.len + arr1[0]; +> ``` + +
Equivalent TypeScript Code + +> ```TS +> const arr1: number[] = Object.freeze([1, 2, 3]); +> const arr2: string[] = Object.freeze(["a", "b", "c"]); +> const arr3: string[] = ["a1", "b2", "c3"]; +> const l = arr1.length + arr2.length + arr3.length + arr1[0]; +> ``` + +
+ +[`โ–ฒ top`][top] + +--- + +### 3.8 Enumeration + +Enumeration type (`enum`) is a type that groups a list of named constant members. +Enumeration is defined by writing **enum**, followed by enumeration name and a +list of comma-separated constants in a {}. Last comma is optional in single line +definitions but required in multi line definitions. +Naming convention for enums is to use "TitleCase" for name and ALL_CAPS for members. + +> ```TS +> enum SomeEnum { ONE, TWO, THREE }; +> enum MyFoo { +> A, +> B, +> C, +> }; +> let x = MyFoo.B; +> let y = x; // type is MyFoo +> ``` + +
Equivalent TypeScript Code + +> ```TS +> enum SomeEnum { ONE, TWO, THREE }; +> enum MyFoo { +> A, +> B, +> C, +> }; +> const x: MyFoo = MyFoo.B; +> const y: MyFoo = x; +> ``` + +
+ +`nameof` operator is used to get the name of a constant member at compile time. +For example `nameof(MyEnum.MEMBER)` resolves to `"MEMBER"` at compile time. + +This allows painless conditionals when enums are serialized and deserialized +over the wire without littering the source with strings everywhere. Compare: + +```TS +// Wing Code: +enum SomeEnum { ONE, TWO, THREE }; +let someVal: str = "ONE"; +if someVal == nameof(SomeEnum.ONE) { + // whatever1 +} elif someVal == nameof(SomeEnum.TWO) { + // whatever2 +} +``` + +Which is functionally equivalent to: + +```TS +// Wing Code: +enum SomeEnum { ONE, TWO, THREE }; +let someVal: str = getEnumSerializedFromNetwork(); +if someVal == "ONE" { + // whatever1 +} elif someVal == "TWO" { + // whatever2 +} +``` + +[`โ–ฒ top`][top] + +--- + +### 3.9 Computed Properties + +You may use the following syntax to define computed properties. +Computed properties are syntactic sugar for getters and setters which themselves +are syntactic sugar for methods, therefore omitting either one is acceptable. + +"Read block" must always return a value of the same type as the property. + +Keyword `new` can be used inside the write block to access the incoming r-value +of the assignment (write) operation. `new` is always the same type as the type +of the property itself. + +Both preflight and inflight computed properties are allowed. +Keyword `var` behind computed properties is not allowed. +`inflight` computed properties are also allowed. + +```TS +// Wing Code: +struct Vec2 { + x: num; + y: num; +} + +class Rect { + var size: Vec2; + var origin: Vec2; + + center: Vec2 { + read { + let centerX = origin.x + (size.width / 2); + let centerY = origin.y + (size.height / 2); + return Vec2(x: centerX, y: centerY); + } + write { + origin.x = new.x - (size.width / 2); + origin.y = new.y - (size.height / 2); + } + }; + + inflight prop: num { /* ... */ } +} +``` + +
Equivalent TypeScript Code + +```TS +interface Vec2 { x: number; y: number; } +class Rect { + size: Vec2; + origin: Vec2; + // computed property with a getter and setter block + get center(): Vec2 { + let centerX = origin.x + (size.width / 2); + let centerY = origin.y + (size.height / 2); + return Vec2(x: centerX, y: centerY); + } + set center(_new: Vec2) { + origin.x = _new.x - (size.width / 2); + origin.y = _new.y - (size.height / 2); + } +} +``` + +
+ +[`โ–ฒ top`][top] + +### 3.10 Unit tests + +Unit tests can be defined in Wing using the built-in test statement. +A test statement expects a name and a block of inflight code to execute. + +```js +let b = new cloud.Bucket(); + +test "can add objects" { + b.put("key", "value"); + assert(b.get("key") == "value"); +} +``` + +The behavior of running tests with `wing test` CLI command is determined by the `cloud.TestRunner` resource in the Wing SDK, which can be implemented for any compiler target. + +See the [CLI User Manual](https://docs.winglang.io/reference/cli#test-wing-test) for more details on running tests. + +[`โ–ฒ top`][top] + +--- + +## 4. Module System + +The module system in Wing uses the `bring` expression to reuse code. +**bring** expression allows code to "import" functions, classes, and variables +from other files, to allow reusability. +**bring** expression is only allowed at the top of the file before any other +code. Comments before the first bring expression are valid. + +### 4.1 Imports + +To import a JSII / Wing package under a named import, you may use the following +syntax: + +```TS +bring std; // from std bring * as std; +bring cloud; // from cloud bring * as cloud; +bring "path/to/what.js" as what; // from "path/to/what.js" bring * as what; +``` + +Currently, "bringing" other Wing files is treated as a preprocessor step and it +acts like C `#include`s. Symbols collision is fatal in this style of imports. + +[`โ–ฒ top`][top] + +--- + +### 4.2 Exports + +In preflight, anything with `public` at block scope level is importable. +This includes functions, classes, structs and interfaces. +In inflight, all of the above excluding preflight classes are importable. +Variables are not exportable. + +Preflight classes cannot be instantiated in inflight functions. There is no synthesizer inside +and no deployment system in the inflight body to provision. + +"Bringing" other Wing files currently ignores exports, but bringing JSII modules +respect the visibility of JSII module exports. + +[`โ–ฒ top`][top] + +--- + +## 5. Interoperability + +## 5.1 JSII Interoperability + +### 5.1.1 External Libraries + +You may import JSII modules in Wing and they are considered preflight classes if their +JSII type manifest shows that the JSII module is a construct. Wing is a consumer +of JSII modules currently. + +```ts +bring "aws-cdk-lib" as cdk; +let bucket = cdk.awsS3.Bucket( + publicAccess: true, +); +``` + +### 5.1.2 Internal Libraries + +Wing libraries themselves are JSII modules. They can be used in all other JSII +supported languages. + +## 5.2 JavaScript + +The `extern ""` modifier can be used on method declarations in classes to indicate that a method is backed by an implementation imported from a JavaScript module. The module can either be a relative path or a name and will be loaded via [require()](https://nodejs.org/api/modules.html#requireid). + +In the following example, the static inflight method `makeId` is implemented +in `helper.js`: + +```js +// task-list.w +class TaskList { + // ... + + inflight addTask(title: str) { + let id = TaskList.makeId(); // or TaskList.v6(); + this.bucket.put(id, title); + } + + extern "./helpers.js" static inflight makeId(): str; + + // Alternatively, you can use a module name + extern "uuid" static inflight v6(): str; +} + +// helpers.js +const uuid = require("uuid"); + +exports.makeId = function() { + return uuid.v6(); +}; +``` + +Given a method of name X, the compiler will map the method to the JavaScript export with the +matching name (without any case conversion). + +Initially we only support specifying `extern` for static methods (either inflight or preflight), +but we will consider adding support for instance methods in the future. In those cases the first +argument to the method will implicitly be `this`. + +### 5.2.1 TypeScript + +It is possible to use TypeScript to write helpers, but at the moment this will not be +directly supported by Wing. This means that you will need to setup the TypeScript toolchain +to compile your code to JavaScript and then use `extern` against the JavaScript file. + +In the future we will consider adding direct support for `extern "./helpers.ts"`. + +### 5.2.2 Type model + +The table below shows the mapping between Wing types and JavaScript types, represented with TypeScript syntax. +When calling **extern** function, the arguments are checked against these declared types and the return type is **assumed** to be satisfied by the called function. + +If [frozen](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/freeze#description), the value is expected to be immutable and will throw an error if any attempt is made to modify it. + +| Built-In Wing Type | JavaScript Type | Frozen? | +|------------------------|-----------------------------------------------------------------------|---------| +| `void` | `undefined` | | +| `nil` | `null` | | +| `any` | `any` | | +| `num` | `number` | | +| `str` | `string` | | +| `bool` | `boolean` | | +| `Set` | `Set` | Yes | +| `Map` | `{ [key: string]: T }` | Yes | +| `Array` | `T[]` | Yes | +| `MutSet` | `Set` | | +| `MutMap` | `{ [key: string]: T }` | | +| `MutArray` | `T[]` | | +| `Promise` | `Promise` | | +| `Json` | `string โ number โ boolean โ null โ json[] โ { [key: string]: json }` | Yes | +| `MutJson` | `string โ number โ boolean โ null โ json[] โ { [key: string]: json }` | | + +| User-Defined Wing Types | JavaScript Type | Frozen? | +|-------------------------|----------------------------------------------------------------------------------------|---------| +| `class` | `class`, only with members whose phase is compatible with the function signature | | +| `interface` | `interface`, only with members whose phase is compatible with the function signature | | +| `struct` | `interface` | Yes | +| `enum` | `string`-based enum-like `Object` | Yes | + +[`โ–ฒ top`][top] + +--- + +## 6. Miscellaneous + +### 6.1 Strings + +String reference doc is available [here](https://docs.winglang.io/standard-library/sdk#string-). +Type of string is UTF-16 internally. +All string declaration variants are multi-line. + +[`โ–ฒ top`][top] + +--- + +#### 6.1.1 Normal strings "..." + +The string inside the double quotes is processed, and all notations of form +`${}` are substituted from their respective scopes. The behavior is +similar to `` `text ${sub.prop}` `` notation in JavaScript. +Processing unicode escape sequences happens in these strings. +`"` and `$` can be escaped with backslash `\` inside string substitutions. + +> ```TS +> let name = "World"; +> let s = "Hello, ${name}!"; +> let l = s.len; +> ``` + +
Equivalent TypeScript Code + +> ```TS +> const name = "World"; +> const s = `Hello, ${name}!`; // with substitution +> const l = s.length; // length of string +> ``` + +
+ +[`โ–ฒ top`][top] + +--- + +#### 6.1.2 Shell strings \`...\` + +If string is enclosed with backticks, the contents of that string will be +interpreted as a shell command and its output will be used as a string. `` `echo +"Hello"` `` is equal to `"Hello"` for example. + +Shell strings are invalid in the bring expression. + +> ```TS +> let name = `echo "World"`; +> let s = "Hello, ${name}!"; +> ``` + +Shell strings are executed in an instance of the BusyBox shell, compiled to run +in WebAssembly to guarantee portability, in runtime. The stdout is returned as a +string, interleaved with stderr. If BusyBox exits with a non-zero exit code, the +stderr is thrown as an exception. + +[`โ–ฒ top`][top] + +--- + +### 6.2 Comments + +Single line comments start with a `//` and continue to the end of the line. +Multi-line comments are supported with the `/* ... */` syntax. +Commenting in Wing has a style that's described earlier in this document. + +> ```TS +> // comment +> /* comment */ +> /* +> multi line comment +> */ +> ``` + +[`โ–ฒ top`][top] + +--- + +### 6.3 Operators + +Unary operators are not supported except outline below. +Arithmetic assignment operators are not supported. +Ternary or conditional operators are not supported. + +#### 6.3.1 Relational Operators + +| Operator | Description | Example | +| -------- | ------------------------------------------------ | -------- | +| `==` | Checks for equality | `a == b` | +| `!=` | Checks for inequality | `a != b` | +| `>` | Checks if left is greater than right | `a > b` | +| `<` | Checks if left less than right | `a < b` | +| `>=` | Checks if left is greater than or equal to right | `a >= b` | +| `<=` | Checks if left is less than or equal to right | `a <= b` | + +[`โ–ฒ top`][top] + +--- + +#### 6.3.2 Logical Operators + +| Operator | Description | Example | +| -------- | -------------------- | ---------- | +| `&&` | Logical AND operator | `a && b` | +| `\|\|` | Logical OR operator | `a \|\| b` | +| `!` | Logical NOT operator | `!a` | + +[`โ–ฒ top`][top] + +--- + +#### 6.3.3 Mathematics Operators + +| Operator | Description | Example | +| -------- | -------------- | -------- | +| `*` | Multiplication | `a * b` | +| `/` | Division | `a / b` | +| `\` | Floor Division | `a \ b` | +| `%` | Modulus | `a % b` | +| `+` | Addition | `a + b` | +| `-` | Subtraction | `a - b` | +| `**` | Power | `a ** b` | + +[`โ–ฒ top`][top] + +--- + +#### 6.3.4 Operator Precedence + +| Operator | Notes | +| -------------------- | ------------------------------------------------- | +| () | Parentheses | +| ** | Power | +| -x | Unary minus | +| \*, /, \\, % | Multiplication, Division, Floor division, Modulus | +| +, - | Addition, Subtraction | +| ==, !=, >, >=, <, <= | Comparisons, Identity, operators | +| ! | Logical NOT | +| && | Logical AND | +| \|\| | Logical OR | + +Table above is in descending order of precedence. +`=` operator in Wing does not return a value so you cannot do `let x = y = 1`. +Operators of the same row in the table above have precedence from left to right +in the expression they appear in (e.g. `4 * 2 \ 3`). In other words, order is +determined by associativity. + +[`โ–ฒ top`][top] + +--- + +#### 6.3.5 Short Circuiting + +For the built-in logical NOT operators, the result is `true` if the operand is +`false`. Otherwise, the result is `false`. + +For the built-in logical AND operators, the result is `true` if both operands +are `true`. Otherwise, the result is `false`. This operator is short-circuiting +if the first operand is `false`, and the second operand is not evaluated. + +For the built-in logical OR operators, the result is `true` if either the first +or the second operand (or both) is `true`. This operator is short-circuiting if +the first operand is `true`, and the second operand is not evaluated. + +Note that bitwise logic operators do not perform short-circuiting. + +In conditionals, if an optional type is used as the only r-value expression of +the condition statement, it's equivalent to checking it against `nil`. Note that +using a `bool?` type in this short-circuit is a compile error due to ambiguity. +Using a `nil?` type is also ambiguous and results in a compile error. + +```TS +let x: num? = 1; +if x { + // ... +} +``` + +Which is equivalent to: + +```TS +let x: num? = 1; +if x != nil { + // ... +} +``` + +[`โ–ฒ top`][top] + +--- + +#### 6.3.6 Equality + +Of the operators supported, the following can be used with non-numeric operands: + +- `==`: can be used to check for equality of types and values in operands. +- `!=`: can be used to check for inequality of types and values in operands. + +When these operators are used on immutable data, values are checked for equality +as well as types. When these operators are used on mutable data, types and refs +are checked for equality. Concept of "refs" is loosely defined as "any object" +that's instantiated through a class currently and then gets reassigned to other +names until a mutable method is called on it, which then turns into a new "ref". + +This behavior is the same as JavaScript with the addition of structural equality +for immutable data (on top of nominal typing). + +[`โ–ฒ top`][top] + +--- + +### 6.4 Kitchen Sink + +This is an example with almost every feature of the Wing, showing you a whole +picture of what the syntax feels like. + +```TS +bring cloud; +bring fs; + +struct DenyListRule { + packageName: str; + version: str?; + reason: str; +} + +struct DenyListProps { + rules: MutArray[]; +} + +class DenyList { + _bucket: cloud.Bucket; + _objectKey: str; + + init(props: DenyListProps) { + this._bucket = cloud.Bucket(); + this._objectKey = "deny-list.json"; + + let rulesDir = this._writeToFile(props.rules, this._objectKey); + this._bucket.upload("${rulesDir}/*/**", prune: true, retainOnDelete: true); + } + + _writeToFile(list: MutArray[], filename: str): str { + let tmpdir = fs.mkdtemp(); + let filepath = "${tmpdir}/${filename}"; + let map = MutMap{}; + for rule in list { + let suffix = DenyList._maybeSuffix(rule.version); + let path = "${rule.packageName}${suffix}"; + map[path] = rule; + } + fs.writeJson(filepath, map); + return tmpdir; + } + + inflight rules: MutMap{}?; + + inflight init() { + // this._bucket is already initialized by the capture mechanic! + this.rules = this._bucket.get(this._objectKey) ?? MutMap{}; + } + + public inflight lookup(name: str, version: str): DenyListRule? { + return this.rules[name] ?? this.rules["${name}/v${version}"]; + } + + static _maybeSuffix(version: str?): str { + if version { + return "/v${version}"; + } else { + return ""; + } + } +} + +let denyList = DenyList(); +let filterFn = inflight (event: cloud.QueueEvent) => { + let packageName = event.data["packageName"]; + let version = event.data["version"]; + let reason = event.data["reason"]; + if denyList.lookup(packageName, version) { + log("Package rejected: ${packageName}"); + } else { + log("Package accepted: ${packageName}"); + } +}; + +queue = cloud.Queue(); +filter = cloud.Function(filterFn); +queue.setConsumer(filter); +``` + +[`โ–ฒ top`][top] + +--- + +### 6.5 Roadmap + +- [ ] Asynchronous Execution Safety Model. +- [ ] Make the language `async` by default. +- [x] Make inflight functions `async` by default. +- [ ] First class support for `regx`, `glob`, and `cron` types. +- [ ] Support of math operations over `date` and `duration` types. +- [x] Add `time`, `date`, and `durations` as first class types with syntax. +- [ ] More useful enums: Support for Enum Classes and Swift style enums. +- [ ] Reflection: add an extended `typeof` operator to get type information. +- [ ] Advanced OOP: Support for `abstract` and `private` implementations. +- [ ] Enforce naming conventions on public APIs (required by JSII). +- [ ] Develop a conformance test suite for ISO certification. +- [ ] Launch a formal spec site with ECMA standards. +- [ ] Built-in automatic formatter and linter. +- [ ] Distributed concurrency primitives. +- [ ] Distributed data structures. + +[`โ–ฒ top`][top] + +--- + +### 6.6 Credits + +* **Contributors (A-Z):** + * Chris R. ([@Chriscbr](https://github.com/Chriscbr)) + * Elad B. ([@eladb](https://github.com/eladb)) + * Eyal K. ([@ekeren](https://github.com/ekeren)) + * Mark MC. ([@MarkMcCulloh](https://github.com/MarkMcCulloh)) + * Sepehr L. ([@3p3r](https://github.com/3p3r)) + * Shai B. ([@ShaiBer](https://github.com/ShaiBer)) + * Uri B. ([@staycoolcall911](https://github.com/staycoolcall911)) + * Yoav S. ([@yoav-steinberg](https://github.com/yoav-steinberg)) + +Inspiration: + +- +- +- +- +- +- + +[top]: #0-preface diff --git a/docs/03-language-guide/_category_.yml b/docs/docs/03-language-guide/_category_.yml similarity index 70% rename from docs/03-language-guide/_category_.yml rename to docs/docs/03-language-guide/_category_.yml index c69b9186f1a..610f925fed8 100644 --- a/docs/03-language-guide/_category_.yml +++ b/docs/docs/03-language-guide/_category_.yml @@ -1,3 +1,3 @@ label: Language guide collapsible: true -collapsed: false +collapsed: true diff --git a/docs/04-standard-library/01-cloud/_category_.yml b/docs/docs/04-standard-library/01-cloud/_category_.yml similarity index 70% rename from docs/04-standard-library/01-cloud/_category_.yml rename to docs/docs/04-standard-library/01-cloud/_category_.yml index eda117183bf..e0105be4944 100644 --- a/docs/04-standard-library/01-cloud/_category_.yml +++ b/docs/docs/04-standard-library/01-cloud/_category_.yml @@ -1,3 +1,3 @@ label: Cloud resources collapsible: true -collapsed: false +collapsed: true diff --git a/libs/wingsdk/API.md b/docs/docs/04-standard-library/01-cloud/api-reference.md similarity index 62% rename from libs/wingsdk/API.md rename to docs/docs/04-standard-library/01-cloud/api-reference.md index 83d59d1076c..de4c76a225c 100644 --- a/libs/wingsdk/API.md +++ b/docs/docs/04-standard-library/01-cloud/api-reference.md @@ -1,3 +1,14 @@ +--- +title: API reference +id: api-reference +description: Wing standard library API reference for the cloud module +keywords: [Wing sdk, sdk, Wing API Reference] +hide_title: true +sidebar_position: 100 +--- + + + # API Reference ## Resources @@ -796,61 +807,6 @@ Information on how to display a resource in the UI. --- -### Resource - -- *Implements:* IResource - -Shared behavior between all Wing SDK resources. - -#### Initializers - -```wing -bring std; - -new std.Resource() -``` - -| **Name** | **Type** | **Description** | -| --- | --- | --- | - ---- - - - -#### Properties - -| **Name** | **Type** | **Description** | -| --- | --- | --- | -| node | constructs.Node | The tree node. | -| display | Display | Information on how to display a resource in the UI. | - ---- - -##### `node`Required - -```wing -node: Node; -``` - -- *Type:* constructs.Node - -The tree node. - ---- - -##### `display`Required - -```wing -display: Display; -``` - -- *Type:* Display - -Information on how to display a resource in the UI. - ---- - - ### Schedule **Inflight client:** [@winglang/sdk.cloud.IScheduleClient](#@winglang/sdk.cloud.IScheduleClient) @@ -1090,6 +1046,33 @@ new cloud.Table(props: TableProps) --- +#### Methods + +| **Name** | **Description** | +| --- | --- | +| addRow | Add a row to the table that is created when the app is deployed. | + +--- + +##### `addRow` + +```wing +addRow(key: str, row: Json): void +``` + +Add a row to the table that is created when the app is deployed. + +###### `key`Required + +- *Type:* str + +--- + +###### `row`Required + +- *Type:* Json + +--- #### Properties @@ -1165,77 +1148,6 @@ Table primary key name. --- -### Test - -- *Implements:* IInflightHost - -**Inflight client:** [@winglang/sdk.cloud.ITestClient](#@winglang/sdk.cloud.ITestClient) - -Represents a unit test. - -#### Initializers - -```wing -bring std; - -new std.Test(inflight: ITestHandler, props?: TestProps) -``` - -| **Name** | **Type** | **Description** | -| --- | --- | --- | -| inflight | ITestHandler | *No description.* | -| props | TestProps | *No description.* | - ---- - -##### `inflight`Required - -- *Type:* ITestHandler - ---- - -##### `props`Optional - -- *Type:* TestProps - ---- - - - -#### Properties - -| **Name** | **Type** | **Description** | -| --- | --- | --- | -| node | constructs.Node | The tree node. | -| display | Display | Information on how to display a resource in the UI. | - ---- - -##### `node`Required - -```wing -node: Node; -``` - -- *Type:* constructs.Node - -The tree node. - ---- - -##### `display`Required - -```wing -display: Display; -``` - -- *Type:* Display - -Information on how to display a resource in the UI. - ---- - - ### TestRunner **Inflight client:** [@winglang/sdk.cloud.ITestRunnerClient](#@winglang/sdk.cloud.ITestRunnerClient) @@ -1525,78 +1437,6 @@ The website's url. ## Structs -### AddConnectionProps - -Props for `Resource.addConnection`. - -#### Initializer - -```wing -bring std; - -let AddConnectionProps = std.AddConnectionProps{ ... } -``` - -#### Properties - -| **Name** | **Type** | **Description** | -| --- | --- | --- | -| from | IResource | The resource creating the connection to `to`. | -| relationship | str | The type of relationship between the resources. | -| to | IResource | The resource `from` is connecting to. | -| implicit | bool | Whether the relationship is implicit, i.e. it is not explicitly defined by the user. | - ---- - -##### `from`Required - -```wing -from: IResource; -``` - -- *Type:* IResource - -The resource creating the connection to `to`. - ---- - -##### `relationship`Required - -```wing -relationship: str; -``` - -- *Type:* str - -The type of relationship between the resources. - ---- - -##### `to`Required - -```wing -to: IResource; -``` - -- *Type:* IResource - -The resource `from` is connecting to. - ---- - -##### `implicit`Optional - -```wing -implicit: bool; -``` - -- *Type:* bool -- *Default:* false - -Whether the relationship is implicit, i.e. it is not explicitly defined by the user. - ---- - ### ApiConnectProps Options for Api patch endpoint. @@ -2032,293 +1872,161 @@ Whether the bucket's objects should be publicly accessible. --- -### Connection +### CounterProps -A connection between two resources. +Properties for `Counter`. -#### Initializer +#### Initializer ```wing -bring std; +bring cloud; -let Connection = std.Connection{ ... } +let CounterProps = cloud.CounterProps{ ... } ``` #### Properties | **Name** | **Type** | **Description** | | --- | --- | --- | -| direction | Direction | The direction of the connection. | -| implicit | bool | Whether the relationship is implicit, i.e. it is not explicitly defined by the user. | -| relationship | str | The type of relationship with the resource. | -| resource | IResource | The resource this connection is to. | +| initial | num | The initial value of the counter. | + +--- + +##### `initial`Optional + +```wing +initial: num; +``` + +- *Type:* num +- *Default:* 0 + +The initial value of the counter. --- -##### `direction`Required +### FunctionProps + +Properties for `Function`. + +This is the type users see when constructing a cloud.Function instance. + +#### Initializer ```wing -direction: Direction; +bring cloud; + +let FunctionProps = cloud.FunctionProps{ ... } ``` -- *Type:* Direction +#### Properties -The direction of the connection. +| **Name** | **Type** | **Description** | +| --- | --- | --- | +| env | MutMap<str> | Environment variables to pass to the function. | +| memory | num | The amount of memory to allocate to the function, in MB. | +| timeout | Duration | The maximum amount of time the function can run. | --- -##### `implicit`Required +##### `env`Optional ```wing -implicit: bool; +env: MutMap; ``` -- *Type:* bool +- *Type:* MutMap<str> +- *Default:* No environment variables. -Whether the relationship is implicit, i.e. it is not explicitly defined by the user. +Environment variables to pass to the function. --- -##### `relationship`Required +##### `memory`Optional ```wing -relationship: str; +memory: num; ``` -- *Type:* str +- *Type:* num +- *Default:* 128 -The type of relationship with the resource. +The amount of memory to allocate to the function, in MB. --- -##### `resource`Required +##### `timeout`Optional ```wing -resource: IResource; +timeout: Duration; ``` -- *Type:* IResource +- *Type:* Duration +- *Default:* 1m -The resource this connection is to. +The maximum amount of time the function can run. --- -### CounterProps +### GetSecretValueOptions -Properties for `Counter`. +Options when getting a secret value. -#### Initializer +#### Initializer ```wing bring cloud; -let CounterProps = cloud.CounterProps{ ... } +let GetSecretValueOptions = cloud.GetSecretValueOptions{ ... } ``` #### Properties | **Name** | **Type** | **Description** | | --- | --- | --- | -| initial | num | The initial value of the counter. | +| cache | bool | Whether to cache the value. | --- -##### `initial`Optional +##### `cache`Optional ```wing -initial: num; +cache: bool; ``` -- *Type:* num -- *Default:* 0 +- *Type:* bool +- *Default:* true -The initial value of the counter. +Whether to cache the value. --- -### DisplayProps +### QueueProps -Properties for the Display class. +Properties for `Queue`. -#### Initializer +#### Initializer ```wing -bring std; +bring cloud; -let DisplayProps = std.DisplayProps{ ... } +let QueueProps = cloud.QueueProps{ ... } ``` #### Properties | **Name** | **Type** | **Description** | | --- | --- | --- | -| description | str | Description of the resource. | -| hidden | bool | Whether the resource should be hidden from the UI. | -| title | str | Title of the resource. | +| initialMessages | MutArray<str> | Initialize the queue with a set of messages. | +| retentionPeriod | Duration | How long a queue retains a message. | +| timeout | Duration | How long a queue's consumers have to process a message. | --- -##### `description`Optional +##### `initialMessages`Optional ```wing -description: str; -``` - -- *Type:* str -- *Default:* No description. - -Description of the resource. - ---- - -##### `hidden`Optional - -```wing -hidden: bool; -``` - -- *Type:* bool -- *Default:* Undefined - -Whether the resource should be hidden from the UI. - ---- - -##### `title`Optional - -```wing -title: str; -``` - -- *Type:* str -- *Default:* No title. - -Title of the resource. - ---- - -### FunctionProps - -Properties for `Function`. - -This is the type users see when constructing a cloud.Function instance. - -#### Initializer - -```wing -bring cloud; - -let FunctionProps = cloud.FunctionProps{ ... } -``` - -#### Properties - -| **Name** | **Type** | **Description** | -| --- | --- | --- | -| env | MutMap<str> | Environment variables to pass to the function. | -| memory | num | The amount of memory to allocate to the function, in MB. | -| timeout | Duration | The maximum amount of time the function can run. | - ---- - -##### `env`Optional - -```wing -env: MutMap; -``` - -- *Type:* MutMap<str> -- *Default:* No environment variables. - -Environment variables to pass to the function. - ---- - -##### `memory`Optional - -```wing -memory: num; -``` - -- *Type:* num -- *Default:* 128 - -The amount of memory to allocate to the function, in MB. - ---- - -##### `timeout`Optional - -```wing -timeout: Duration; -``` - -- *Type:* Duration -- *Default:* 1m - -The maximum amount of time the function can run. - ---- - -### GetSecretValueOptions - -Options when getting a secret value. - -#### Initializer - -```wing -bring cloud; - -let GetSecretValueOptions = cloud.GetSecretValueOptions{ ... } -``` - -#### Properties - -| **Name** | **Type** | **Description** | -| --- | --- | --- | -| cache | bool | Whether to cache the value. | - ---- - -##### `cache`Optional - -```wing -cache: bool; -``` - -- *Type:* bool -- *Default:* true - -Whether to cache the value. - ---- - -### QueueProps - -Properties for `Queue`. - -#### Initializer - -```wing -bring cloud; - -let QueueProps = cloud.QueueProps{ ... } -``` - -#### Properties - -| **Name** | **Type** | **Description** | -| --- | --- | --- | -| initialMessages | MutArray<str> | Initialize the queue with a set of messages. | -| retentionPeriod | Duration | How long a queue retains a message. | -| timeout | Duration | How long a queue's consumers have to process a message. | - ---- - -##### `initialMessages`Optional - -```wing -initialMessages: MutArray; +initialMessages: MutArray; ``` - *Type:* MutArray<str> @@ -2728,6 +2436,7 @@ let TableProps = cloud.TableProps{ ... } | **Name** | **Type** | **Description** | | --- | --- | --- | | columns | MutMap<ColumnType> | The table's columns. | +| initialRows | MutMap<Json> | The table's initial rows. | | name | str | The table's name. | | primaryKey | str | The table's primary key. | @@ -2746,6 +2455,19 @@ The table's columns. --- +##### `initialRows`Optional + +```wing +initialRows: MutMap; +``` + +- *Type:* MutMap<Json> +- *Default:* undefined + +The table's initial rows. + +--- + ##### `name`Optional ```wing @@ -2775,69 +2497,6 @@ primary key. --- -### TestProps - -Properties for `Test`. - -This is the type users see when constructing a std.Test instance. - -#### Initializer - -```wing -bring std; - -let TestProps = std.TestProps{ ... } -``` - -#### Properties - -| **Name** | **Type** | **Description** | -| --- | --- | --- | -| env | MutMap<str> | Environment variables to pass to the function. | -| memory | num | The amount of memory to allocate to the function, in MB. | -| timeout | Duration | The maximum amount of time the function can run. | - ---- - -##### `env`Optional - -```wing -env: MutMap; -``` - -- *Type:* MutMap<str> -- *Default:* No environment variables. - -Environment variables to pass to the function. - ---- - -##### `memory`Optional - -```wing -memory: num; -``` - -- *Type:* num -- *Default:* 128 - -The amount of memory to allocate to the function, in MB. - ---- - -##### `timeout`Optional - -```wing -timeout: Duration; -``` - -- *Type:* Duration -- *Default:* 1m - -The maximum amount of time the function can run. - ---- - ### TestResult A result of a single test. @@ -3052,2143 +2711,99 @@ sourceType: str; - *Type:* str -The type of the source that emitted the trace. - ---- - -##### `timestamp`Required - -```wing -timestamp: str; -``` - -- *Type:* str - -The timestamp of the event, in ISO 8601 format. - ---- - -*Example* - -```wing -2020-01-01T00:00:00.000Z -``` - - -##### `type`Required - -```wing -type: TraceType; -``` - -- *Type:* TraceType - -The type of a trace. - ---- - -### WaitUntilProps - -Properties for `util.waitUntil`. - -#### Initializer - -```wing -bring util; - -let WaitUntilProps = util.WaitUntilProps{ ... } -``` - -#### Properties - -| **Name** | **Type** | **Description** | -| --- | --- | --- | -| interval | Duration | Interval between predicate retries. | -| timeout | Duration | The timeout for keep trying predicate. | - ---- - -##### `interval`Optional - -```wing -interval: Duration; -``` - -- *Type:* Duration -- *Default:* 0.1s - -Interval between predicate retries. - ---- - -##### `timeout`Optional - -```wing -timeout: Duration; -``` - -- *Type:* Duration -- *Default:* 1m - -The timeout for keep trying predicate. - ---- - -### WebsiteProps - -website props. - -#### Initializer - -```wing -bring cloud; - -let WebsiteProps = cloud.WebsiteProps{ ... } -``` - -#### Properties - -| **Name** | **Type** | **Description** | -| --- | --- | --- | -| path | str | Local path to the website's static files, relative to the Wing source file or absolute. | -| domain | str | The website's custom domain name. | - ---- - -##### `path`Required - -```wing -path: str; -``` - -- *Type:* str - -Local path to the website's static files, relative to the Wing source file or absolute. - ---- - -*Example* - -```wing -"./dist" -``` - - -##### `domain`Optional - -```wing -domain: str; -``` - -- *Type:* str -- *Default:* a domain is generated by the cloud provider - -The website's custom domain name. - ---- - -*Example* - -```wing -"example.com" -``` - - -## Classes - -### Boolean - -Boolean. - -#### Initializers - -```wing -bring std; - -new std.Boolean() -``` - -| **Name** | **Type** | **Description** | -| --- | --- | --- | - ---- - - -#### Static Functions - -| **Name** | **Description** | -| --- | --- | -| fromJson | Parse a boolean from Json. | - ---- - -##### `fromJson` - -```wing -bring std; - -std.Boolean.fromJson(json: Json) -``` - -Parse a boolean from Json. - -###### `json`Required - -- *Type:* Json - -to parse boolean from. - ---- - - - -### Display - -Information on how to display a resource in the UI. - -#### Initializers - -```wing -bring std; - -new std.Display(props?: DisplayProps) -``` - -| **Name** | **Type** | **Description** | -| --- | --- | --- | -| props | DisplayProps | *No description.* | - ---- - -##### `props`Optional - -- *Type:* DisplayProps - ---- - - - -#### Properties - -| **Name** | **Type** | **Description** | -| --- | --- | --- | -| description | str | Description of the resource. | -| hidden | bool | Whether the resource should be hidden from the UI. | -| title | str | Title of the resource. | - ---- - -##### `description`Optional - -```wing -description: str; -``` - -- *Type:* str - -Description of the resource. - ---- - -##### `hidden`Optional - -```wing -hidden: bool; -``` - -- *Type:* bool - -Whether the resource should be hidden from the UI. - ---- - -##### `title`Optional - -```wing -title: str; -``` - -- *Type:* str - -Title of the resource. - ---- - - -### Duration - -Represents a length of time. - - -#### Static Functions - -| **Name** | **Description** | -| --- | --- | -| fromDays | Create a Duration representing an amount of days. | -| fromHours | Create a Duration representing an amount of hours. | -| fromMilliseconds | Create a Duration representing an amount of milliseconds. | -| fromMinutes | Create a Duration representing an amount of minutes. | -| fromMonths | Create a Duration representing an amount of months. | -| fromSeconds | Create a Duration representing an amount of seconds. | -| fromYears | Create a Duration representing an amount of years. | - ---- - -##### `fromDays` - -```wing -bring std; - -std.Duration.fromDays(amount: num) -``` - -Create a Duration representing an amount of days. - -###### `amount`Required - -- *Type:* num - -the amount of Days the `Duration` will represent. - ---- - -##### `fromHours` - -```wing -bring std; - -std.Duration.fromHours(amount: num) -``` - -Create a Duration representing an amount of hours. - -###### `amount`Required - -- *Type:* num - -the amount of Hours the `Duration` will represent. - ---- - -##### `fromMilliseconds` - -```wing -bring std; - -std.Duration.fromMilliseconds(amount: num) -``` - -Create a Duration representing an amount of milliseconds. - -###### `amount`Required - -- *Type:* num - -the amount of Milliseconds the `Duration` will represent. - ---- - -##### `fromMinutes` - -```wing -bring std; - -std.Duration.fromMinutes(amount: num) -``` - -Create a Duration representing an amount of minutes. - -###### `amount`Required - -- *Type:* num - -the amount of Minutes the `Duration` will represent. - ---- - -##### `fromMonths` - -```wing -bring std; - -std.Duration.fromMonths(amount: num) -``` - -Create a Duration representing an amount of months. - -###### `amount`Required - -- *Type:* num - -the amount of Months the `Duration` will represent. - ---- - -##### `fromSeconds` - -```wing -bring std; - -std.Duration.fromSeconds(amount: num) -``` - -Create a Duration representing an amount of seconds. - -###### `amount`Required - -- *Type:* num - -the amount of Seconds the `Duration` will represent. - ---- - -##### `fromYears` - -```wing -bring std; - -std.Duration.fromYears(amount: num) -``` - -Create a Duration representing an amount of years. - -###### `amount`Required - -- *Type:* num - -the amount of Years the `Duration` will represent. - ---- - -#### Properties - -| **Name** | **Type** | **Description** | -| --- | --- | --- | -| days | num | Return the total number of days in this Duration. | -| hours | num | Return the total number of hours in this Duration. | -| milliseconds | num | Return the total number of milliseconds in this Duration. | -| minutes | num | Return the total number of minutes in this Duration. | -| months | num | Return the total number of months in this Duration. | -| seconds | num | Return the total number of seconds in this Duration. | -| years | num | Return the total number of years in this Duration. | - ---- - -##### `days`Required - -```wing -days: num; -``` - -- *Type:* num - -Return the total number of days in this Duration. - ---- - -##### `hours`Required - -```wing -hours: num; -``` - -- *Type:* num - -Return the total number of hours in this Duration. - ---- - -##### `milliseconds`Required - -```wing -milliseconds: num; -``` - -- *Type:* num - -Return the total number of milliseconds in this Duration. - ---- - -##### `minutes`Required - -```wing -minutes: num; -``` - -- *Type:* num - -Return the total number of minutes in this Duration. - ---- - -##### `months`Required - -```wing -months: num; -``` - -- *Type:* num - -Return the total number of months in this Duration. - ---- - -##### `seconds`Required - -```wing -seconds: num; -``` - -- *Type:* num - -Return the total number of seconds in this Duration. - ---- - -##### `years`Required - -```wing -years: num; -``` - -- *Type:* num - -Return the total number of years in this Duration. - ---- - - -### ImmutableArray - -Immutable Array. - -#### Initializers - -```wing -bring std; - -new std.ImmutableArray() -``` - -| **Name** | **Type** | **Description** | -| --- | --- | --- | - ---- - -#### Methods - -| **Name** | **Description** | -| --- | --- | -| at | Get the value at the given index. | -| concat | Merge arr to the end of this array. | -| contains | Checks if this array includes searchElement. | -| copyMut | Create a mutable shallow copy of this array. | -| indexOf | Returns the index of the first occurrence of searchElement found. | -| join | Returns a new string containing the concatenated values in this array, separated by commas or a specified separator string. | -| lastIndexOf | Returns the index of the last occurrence of searchElement found. | - ---- - -##### `at` - -```wing -at(index: num): T1 -``` - -Get the value at the given index. - -###### `index`Required - -- *Type:* num - -index of the value to get. - ---- - -##### `concat` - -```wing -concat(arr: ImmutableArray): ImmutableArray -``` - -Merge arr to the end of this array. - -###### `arr`Required - -- *Type:* ImmutableArray - -array to merge. - ---- - -##### `contains` - -```wing -contains(searchElement: T1): bool -``` - -Checks if this array includes searchElement. - -###### `searchElement`Required - -- *Type:* T1 - -to search for. - ---- - -##### `copyMut` - -```wing -copyMut(): MutableArray -``` - -Create a mutable shallow copy of this array. - -##### `indexOf` - -```wing -indexOf(searchElement: T1): num -``` - -Returns the index of the first occurrence of searchElement found. - -###### `searchElement`Required - -- *Type:* T1 - -to search for. - ---- - -##### `join` - -```wing -join(separator?: str): str -``` - -Returns a new string containing the concatenated values in this array, separated by commas or a specified separator string. - -If the array has only -one item, then that item will be returned without using the separator. - -###### `separator`Optional - -- *Type:* str - ---- - -##### `lastIndexOf` - -```wing -lastIndexOf(searchElement: T1): num -``` - -Returns the index of the last occurrence of searchElement found. - -###### `searchElement`Required - -- *Type:* T1 - -to search for. - ---- - - -#### Properties - -| **Name** | **Type** | **Description** | -| --- | --- | --- | -| length | num | The length of the array. | - ---- - -##### `length`Required - -```wing -length: num; -``` - -- *Type:* num - -The length of the array. - ---- - - -### ImmutableMap - -Immutable Map. - -#### Initializers - -```wing -bring std; - -new std.ImmutableMap() -``` - -| **Name** | **Type** | **Description** | -| --- | --- | --- | - ---- - -#### Methods - -| **Name** | **Description** | -| --- | --- | -| copyMut | Create a mutable shallow copy of this map. | -| get | Returns a specified element from the map. | -| has | Returns a boolean indicating whether an element with the specified key exists or not. | -| keys | Returns the keys of this map. | -| size | Returns the number of elements in the map. | -| values | Returns the values of this map. | - ---- - -##### `copyMut` - -```wing -copyMut(): MutableMap -``` - -Create a mutable shallow copy of this map. - -##### `get` - -```wing -get(key: str): T1 -``` - -Returns a specified element from the map. - -If the value that is associated to the provided key is an object, then you will get a reference -to that object and any change made to that object will effectively modify it inside the map. - -###### `key`Required - -- *Type:* str - -The key of the element to return. - ---- - -##### `has` - -```wing -has(key: str): bool -``` - -Returns a boolean indicating whether an element with the specified key exists or not. - -###### `key`Required - -- *Type:* str - -The key of the element to test for presence. - ---- - -##### `keys` - -```wing -keys(): MutArray -``` - -Returns the keys of this map. - -##### `size` - -```wing -size(): num -``` - -Returns the number of elements in the map. - -TODO: For now this has to be a method rather than a getter as macros only work on methods https://github.com/winglang/wing/issues/1658 - -##### `values` - -```wing -values(): ImmutableArray -``` - -Returns the values of this map. - - - - -### ImmutableSet - -Immutable Set. - -#### Initializers - -```wing -bring std; - -new std.ImmutableSet() -``` - -| **Name** | **Type** | **Description** | -| --- | --- | --- | - ---- - -#### Methods - -| **Name** | **Description** | -| --- | --- | -| copyMut | Create a mutable shallow copy of this set. | -| has | Returns a boolean indicating whether an element with the specified value exists in the set. | - ---- - -##### `copyMut` - -```wing -copyMut(): MutableSet -``` - -Create a mutable shallow copy of this set. - -##### `has` - -```wing -has(value: T1): bool -``` - -Returns a boolean indicating whether an element with the specified value exists in the set. - -###### `value`Required - -- *Type:* T1 - -The value to test for presence in the Set object. - ---- - - -#### Properties - -| **Name** | **Type** | **Description** | -| --- | --- | --- | -| size | num | The length of the set. | - ---- - -##### `size`Required - -```wing -size: num; -``` - -- *Type:* num - -The length of the set. - ---- - - -### Json - -Immutable Json. - -#### Initializers - -```wing -bring std; - -new std.Json() -``` - -| **Name** | **Type** | **Description** | -| --- | --- | --- | - ---- - -#### Methods - -| **Name** | **Description** | -| --- | --- | -| get | Returns a specified element from the Json. | -| getAt | Returns a specified element at a given index from Json Array. | - ---- - -##### `get` - -```wing -get(key: str): Json -``` - -Returns a specified element from the Json. - -###### `key`Required - -- *Type:* str - -The key of the element to return. - ---- - -##### `getAt` - -```wing -getAt(index: num): Json -``` - -Returns a specified element at a given index from Json Array. - -###### `index`Required - -- *Type:* num - -The index of the element in the Json Array to return. - ---- - -#### Static Functions - -| **Name** | **Description** | -| --- | --- | -| deepCopyMut | Creates a mutable deep copy of the Json. | -| delete | Deletes a key in a given Json. | -| has | Checks if a Json object has a given key. | -| keys | Returns the keys from the Json object. | -| parse | Parse a string into a Json. | -| stringify | Formats Json as string. | -| tryParse | Try to parse a string into a Json. | -| values | Returns the values from the Json. | - ---- - -##### `deepCopyMut` - -```wing -bring std; - -std.Json.deepCopyMut(json: Json) -``` - -Creates a mutable deep copy of the Json. - -###### `json`Required - -- *Type:* Json - -to copy. - ---- - -##### `delete` - -```wing -bring std; - -std.Json.delete(json: Json, key: str) -``` - -Deletes a key in a given Json. - -###### `json`Required - -- *Type:* Json - -to delete key from. - ---- - -###### `key`Required - -- *Type:* str - -the key to delete. - ---- - -##### `has` - -```wing -bring std; - -std.Json.has(json: Json, key: str) -``` - -Checks if a Json object has a given key. - -###### `json`Required - -- *Type:* Json - -The json object to inspect. - ---- - -###### `key`Required - -- *Type:* str - -The key to check. - ---- - -##### `keys` - -```wing -bring std; - -std.Json.keys(json: Json) -``` - -Returns the keys from the Json object. - -###### `json`Required - -- *Type:* Json - -to get keys from. - ---- - -##### `parse` - -```wing -bring std; - -std.Json.parse(str: str) -``` - -Parse a string into a Json. - -###### `str`Required - -- *Type:* str - -to parse as Json. - ---- - -##### `stringify` - -```wing -bring std; - -std.Json.stringify(json: Json, indent?: num) -``` - -Formats Json as string. - -(JSON.stringify($args$)) - -###### `json`Required - -- *Type:* Json - -to format as string. - ---- - -###### `indent`Optional - -- *Type:* num - ---- - -##### `tryParse` - -```wing -bring std; - -std.Json.tryParse(str: str) -``` - -Try to parse a string into a Json. - -###### `str`Required - -- *Type:* str - -to parse as Json. - ---- - -##### `values` - -```wing -bring std; - -std.Json.values(json: Json) -``` - -Returns the values from the Json. - -###### `json`Required - -- *Type:* Json - -to get values from. - ---- - - - -### MutableArray - -Mutable Array. - -#### Initializers - -```wing -bring std; - -new std.MutableArray() -``` - -| **Name** | **Type** | **Description** | -| --- | --- | --- | - ---- - -#### Methods - -| **Name** | **Description** | -| --- | --- | -| at | Get the value at the given index. | -| concat | Merge arr to the end of this array. | -| contains | Checks if this array includes searchElement. | -| copy | Create an immutable shallow copy of this array. | -| indexOf | Returns the index of the first occurrence of searchElement found. | -| join | Returns a new string containing the concatenated values in this array, separated by commas or a specified separator string. | -| lastIndexOf | Returns the index of the last occurrence of searchElement found. | -| pop | Remove value from end of array. | -| push | Add value to end of array. | - ---- - -##### `at` - -```wing -at(index: num): T1 -``` - -Get the value at the given index. - -###### `index`Required - -- *Type:* num - -index of the value to get. - ---- - -##### `concat` - -```wing -concat(arr: MutableArray): MutableArray -``` - -Merge arr to the end of this array. - -###### `arr`Required - -- *Type:* MutableArray - -array to merge. - ---- - -##### `contains` - -```wing -contains(searchElement: T1): bool -``` - -Checks if this array includes searchElement. - -###### `searchElement`Required - -- *Type:* T1 - -to search for. - ---- - -##### `copy` - -```wing -copy(): ImmutableArray -``` - -Create an immutable shallow copy of this array. - -##### `indexOf` - -```wing -indexOf(searchElement: T1): num -``` - -Returns the index of the first occurrence of searchElement found. - -###### `searchElement`Required - -- *Type:* T1 - -to search for. - ---- - -##### `join` - -```wing -join(separator?: str): str -``` - -Returns a new string containing the concatenated values in this array, separated by commas or a specified separator string. - -If the array has only -one item, then that item will be returned without using the separator. - -###### `separator`Optional - -- *Type:* str - ---- - -##### `lastIndexOf` - -```wing -lastIndexOf(searchElement: T1): num -``` - -Returns the index of the last occurrence of searchElement found. - -###### `searchElement`Required - -- *Type:* T1 - -to search for. - ---- - -##### `pop` - -```wing -pop(): T1 -``` - -Remove value from end of array. - -##### `push` - -```wing -push(value: T1): void -``` - -Add value to end of array. - -###### `value`Required - -- *Type:* T1 - -value to add. - ---- - - -#### Properties - -| **Name** | **Type** | **Description** | -| --- | --- | --- | -| length | num | The length of the array. | - ---- - -##### `length`Required - -```wing -length: num; -``` - -- *Type:* num - -The length of the array. - ---- - - -### MutableMap - -Mutable Map. - -#### Initializers - -```wing -bring std; - -new std.MutableMap() -``` - -| **Name** | **Type** | **Description** | -| --- | --- | --- | - ---- - -#### Methods - -| **Name** | **Description** | -| --- | --- | -| clear | Removes all elements. | -| copy | Create an immutable shallow copy of this map. | -| delete | Removes the specified element from a map. | -| get | Returns a specified element from the map. | -| has | Returns a boolean indicating whether an element with the specified key exists or not. | -| keys | Returns the keys of this map. | -| set | Adds or updates an entry in a Map object with a specified key and a value. | -| size | Returns the number of elements in the map. | -| values | Returns the values of this map. | - ---- - -##### `clear` - -```wing -clear(): void -``` - -Removes all elements. - -##### `copy` - -```wing -copy(): ImmutableMap -``` - -Create an immutable shallow copy of this map. - -##### `delete` - -```wing -delete(key: str): bool -``` - -Removes the specified element from a map. - -###### `key`Required - -- *Type:* str - -The key. - ---- - -##### `get` - -```wing -get(key: str): T1 -``` - -Returns a specified element from the map. - -If the value that is associated to the provided key is an object, then you will get a reference -to that object and any change made to that object will effectively modify it inside the map. - -###### `key`Required - -- *Type:* str - -The key of the element to return. - ---- - -##### `has` - -```wing -has(key: str): bool -``` - -Returns a boolean indicating whether an element with the specified key exists or not. - -###### `key`Required - -- *Type:* str - -The key of the element to test for presence. - ---- - -##### `keys` - -```wing -keys(): MutArray -``` - -Returns the keys of this map. - -##### `set` - -```wing -set(key: str, value: T1): void -``` - -Adds or updates an entry in a Map object with a specified key and a value. - -TODO: revisit this macro after we support indexed args https://github.com/winglang/wing/issues/1659 - -###### `key`Required - -- *Type:* str - -The key of the element to add. - ---- - -###### `value`Required - -- *Type:* T1 - -The value of the element to add. - ---- - -##### `size` - -```wing -size(): num -``` - -Returns the number of elements in the map. - -TODO: For now this has to be a method rather than a getter as macros only work on methods https://github.com/winglang/wing/issues/1658 - -##### `values` - -```wing -values(): ImmutableArray -``` - -Returns the values of this map. - - - - -### MutableSet - -Mutable Set. - -#### Initializers - -```wing -bring std; - -new std.MutableSet() -``` - -| **Name** | **Type** | **Description** | -| --- | --- | --- | - ---- - -#### Methods - -| **Name** | **Description** | -| --- | --- | -| add | Add value to set. | -| clear | The clear() method removes all elements from a set. | -| copy | Create an immutable shallow copy of this set. | -| delete | Removes a specified value from a set, if it is in the set. | -| has | Returns a boolean indicating whether an element with the specified value exists in the set. | - ---- - -##### `add` - -```wing -add(value: T1): MutableSet -``` - -Add value to set. - -###### `value`Required - -- *Type:* T1 - -value to add. - ---- - -##### `clear` - -```wing -clear(): void -``` - -The clear() method removes all elements from a set. - -##### `copy` - -```wing -copy(): ImmutableSet -``` - -Create an immutable shallow copy of this set. - -##### `delete` - -```wing -delete(value: T1): bool -``` - -Removes a specified value from a set, if it is in the set. - -###### `value`Required - -- *Type:* T1 - -The value to remove from the set. - ---- - -##### `has` - -```wing -has(value: T1): bool -``` - -Returns a boolean indicating whether an element with the specified value exists in the set. - -###### `value`Required - -- *Type:* T1 - -The value to test for presence in the Set object. - ---- - - -#### Properties - -| **Name** | **Type** | **Description** | -| --- | --- | --- | -| size | num | The length of the set. | - ---- - -##### `size`Required - -```wing -size: num; -``` - -- *Type:* num - -The length of the set. - ---- - - -### MutJson - -Mutable Json. - -#### Initializers - -```wing -bring std; - -new std.MutJson() -``` - -| **Name** | **Type** | **Description** | -| --- | --- | --- | - ---- - -#### Methods - -| **Name** | **Description** | -| --- | --- | -| get | Returns a specified element from the Json. | -| getAt | Returns a specified element at a given index from MutJson Array. | -| set | Adds or updates an element in MutJson with a specific key and value. | -| setAt | Set element in MutJson Array with a specific key and value. | - ---- - -##### `get` - -```wing -get(key: str): MutJson -``` - -Returns a specified element from the Json. - -###### `key`Required - -- *Type:* str - -The key of the element to return. - ---- - -##### `getAt` - -```wing -getAt(index: num): MutJson -``` - -Returns a specified element at a given index from MutJson Array. - -###### `index`Required - -- *Type:* num - -The index of the element in the MutJson Array to return. - ---- - -##### `set` - -```wing -set(key: str, value: MutJson): void -``` - -Adds or updates an element in MutJson with a specific key and value. - -###### `key`Required - -- *Type:* str - -The key of the element to add. - ---- - -###### `value`Required - -- *Type:* MutJson - -The value of the element to add. - ---- - -##### `setAt` - -```wing -setAt(index: num, value: MutJson): void -``` - -Set element in MutJson Array with a specific key and value. - -###### `index`Required - -- *Type:* num - ---- - -###### `value`Required - -- *Type:* MutJson - -The value of the element to set. - ---- - -#### Static Functions - -| **Name** | **Description** | -| --- | --- | -| deepCopy | Creates an immutable deep copy of the Json. | - ---- - -##### `deepCopy` - -```wing -bring std; - -std.MutJson.deepCopy(json: MutJson) -``` - -Creates an immutable deep copy of the Json. - -###### `json`Required - -- *Type:* MutJson - -to copy. - ---- - - - -### Number - -Number. - -#### Initializers - -```wing -bring std; - -new std.Number() -``` - -| **Name** | **Type** | **Description** | -| --- | --- | --- | - ---- - - -#### Static Functions - -| **Name** | **Description** | -| --- | --- | -| fromJson | Parse a number from Json. | -| fromStr | Parse a number from string. | - ---- - -##### `fromJson` - -```wing -bring std; - -std.Number.fromJson(json: Json) -``` - -Parse a number from Json. - -###### `json`Required - -- *Type:* Json - -to parse number from. - ---- - -##### `fromStr` - -```wing -bring std; - -std.Number.fromStr(str: str) -``` - -Parse a number from string. - -###### `str`Required - -- *Type:* str - -to parse number from. - ---- - - - -### Range - -Range. - -#### Initializers - -```wing -bring std; - -new std.Range() -``` - -| **Name** | **Type** | **Description** | -| --- | --- | --- | - ---- - - - - - -### String - -String. - -#### Initializers - -```wing -bring std; - -new std.String() -``` - -| **Name** | **Type** | **Description** | -| --- | --- | --- | - ---- - -#### Methods - -| **Name** | **Description** | -| --- | --- | -| at | Returns the character at the specified index. | -| concat | Combines the text of two (or more) strings and returns a new string. | -| contains | Checks if string includes substring. | -| endsWith | Does this string end with the given searchString? | -| indexOf | Returns the index of the first occurrence of searchString found. | -| lowercase | Returns this string in lower case. | -| split | Splits string by separator. | -| startsWith | Does this string start with the given searchString? | -| substring | Returns a string between indexStart, indexEnd. | -| trim | Removes white spaces from start and end of this string. | -| uppercase | Returns this string in upper case. | - ---- - -##### `at` - -```wing -at(index: num): str -``` - -Returns the character at the specified index. - -###### `index`Required - -- *Type:* num - -position of the character. - ---- - -##### `concat` - -```wing -concat(strN: str): str -``` - -Combines the text of two (or more) strings and returns a new string. - -###### `strN`Required - -- *Type:* str - -one or more strings to concatenate to this string. - ---- - -##### `contains` - -```wing -contains(searchString: str): bool -``` - -Checks if string includes substring. - -###### `searchString`Required - -- *Type:* str - -substring to search for. - ---- - -##### `endsWith` - -```wing -endsWith(searchString: str): bool -``` - -Does this string end with the given searchString? - -###### `searchString`Required - -- *Type:* str - -substring to search for. - ---- - -##### `indexOf` - -```wing -indexOf(searchString: str): num -``` - -Returns the index of the first occurrence of searchString found. - -###### `searchString`Required - -- *Type:* str - -substring to search for. - ---- - -##### `lowercase` - -```wing -lowercase(): str -``` - -Returns this string in lower case. - -##### `split` - -```wing -split(separator: str): MutArray -``` - -Splits string by separator. - -###### `separator`Required - -- *Type:* str - -separator to split by. - ---- - -##### `startsWith` - -```wing -startsWith(searchString: str): bool -``` - -Does this string start with the given searchString? - -###### `searchString`Required - -- *Type:* str - -substring to search for. - ---- - -##### `substring` - -```wing -substring(indexStart: num, indexEnd?: num): str -``` - -Returns a string between indexStart, indexEnd. - -###### `indexStart`Required - -- *Type:* num - -index of the character we slice at. - ---- - -###### `indexEnd`Optional - -- *Type:* num - -optional - index of the character we end slicing at. - ---- - -##### `trim` - -```wing -trim(): str -``` - -Removes white spaces from start and end of this string. - -##### `uppercase` - -```wing -uppercase(): str -``` - -Returns this string in upper case. - -#### Static Functions - -| **Name** | **Description** | -| --- | --- | -| fromJson | Parse string from Json. | - ---- - -##### `fromJson` - -```wing -bring std; - -std.String.fromJson(json: Json) -``` - -Parse string from Json. - -###### `json`Required - -- *Type:* Json - -to create string from. - ---- - -#### Properties - -| **Name** | **Type** | **Description** | -| --- | --- | --- | -| length | num | The length of the string. | - ---- - -##### `length`Required - -```wing -length: num; -``` - -- *Type:* num - -The length of the string. - ---- - - -### T1 - -Generic type argument. - -This type is replaced at compile time. - -#### Initializers - -```wing -bring std; - -new std.T1() -``` - -| **Name** | **Type** | **Description** | -| --- | --- | --- | - ---- - - - - - -### Util - -Utility functions. - -#### Initializers - -```wing -bring util; - -new util.Util() -``` - -| **Name** | **Type** | **Description** | -| --- | --- | --- | - ---- - - -#### Static Functions - -| **Name** | **Description** | -| --- | --- | -| env | Returns the value of an environment variable. | -| sleep | Suspends execution for a given duration. | -| tryEnv | Returns the value of an environment variable. | -| waitUntil | Run a predicate repeatedly, waiting until it returns true or until the timeout elapses. | - +The type of the source that emitted the trace. + --- -##### `env` +##### `timestamp`Required ```wing -bring util; - -util.Util.env(name: str) +timestamp: str; ``` -Returns the value of an environment variable. - -Throws if not found or empty. - -###### `name`Required - - *Type:* str -The name of the environment variable. +The timestamp of the event, in ISO 8601 format. --- -##### `sleep` +*Example* ```wing -bring util; - -util.Util.sleep(delay: Duration) +2020-01-01T00:00:00.000Z ``` -**Inflight client:** [true](#true) -Suspends execution for a given duration. +##### `type`Required -###### `delay`Required +```wing +type: TraceType; +``` -- *Type:* Duration +- *Type:* TraceType -The time to suspend execution. +The type of a trace. --- -##### `tryEnv` +### WebsiteProps + +website props. + +#### Initializer ```wing -bring util; +bring cloud; -util.Util.tryEnv(name: str) +let WebsiteProps = cloud.WebsiteProps{ ... } ``` -Returns the value of an environment variable. +#### Properties + +| **Name** | **Type** | **Description** | +| --- | --- | --- | +| path | str | Local path to the website's static files, relative to the Wing source file or absolute. | +| domain | str | The website's custom domain name. | + +--- -Returns `nil` if not found or empty. +##### `path`Required -###### `name`Required +```wing +path: str; +``` - *Type:* str -The name of the environment variable. +Local path to the website's static files, relative to the Wing source file or absolute. --- -##### `waitUntil` +*Example* ```wing -bring util; - -util.Util.waitUntil(predicate: IPredicateHandler, props?: WaitUntilProps) +"./dist" ``` -**Inflight client:** [true](#true) -Run a predicate repeatedly, waiting until it returns true or until the timeout elapses. +##### `domain`Optional -###### `predicate`Required +```wing +domain: str; +``` -- *Type:* IPredicateHandler +- *Type:* str +- *Default:* a domain is generated by the cloud provider -The function that will be evaluated. +The website's custom domain name. --- -###### `props`Optional - -- *Type:* WaitUntilProps - -Timeout and interval values, default to one 1m timeout and 0.1sec interval. +*Example* ---- +```wing +"example.com" +``` @@ -5826,117 +3441,6 @@ Entrypoint function that will be called when the cloud function is invoked. --- -### IInflightHost - -- *Extends:* IResource - -- *Implemented By:* Function, Test, IInflightHost - -A resource that can run inflight code. - - -#### Properties - -| **Name** | **Type** | **Description** | -| --- | --- | --- | -| node | constructs.Node | The tree node. | -| display | Display | Information on how to display a resource in the UI. | - ---- - -##### `node`Required - -```wing -node: Node; -``` - -- *Type:* constructs.Node - -The tree node. - ---- - -##### `display`Required - -```wing -display: Display; -``` - -- *Type:* Display - -Information on how to display a resource in the UI. - ---- - -### IPredicateHandler - -- *Extends:* IResource - -- *Implemented By:* IPredicateHandler - -**Inflight client:** [@winglang/sdk.util.IPredicateHandlerClient](#@winglang/sdk.util.IPredicateHandlerClient) - -Represents a predicate with an inflight "handle" method that can be passed to `util.busyWait`. - - -#### Properties - -| **Name** | **Type** | **Description** | -| --- | --- | --- | -| node | constructs.Node | The tree node. | -| display | Display | Information on how to display a resource in the UI. | - ---- - -##### `node`Required - -```wing -node: Node; -``` - -- *Type:* constructs.Node - -The tree node. - ---- - -##### `display`Required - -```wing -display: Display; -``` - -- *Type:* Display - -Information on how to display a resource in the UI. - ---- - -### IPredicateHandlerClient - -- *Implemented By:* IPredicateHandlerClient - -Inflight client for `IPredicateHandler`. - -#### Methods - -| **Name** | **Description** | -| --- | --- | -| handle | The Predicate function that is called. | - ---- - -##### `handle` - -```wing -handle(): bool -``` - -**Inflight client:** [true](#true) - -The Predicate function that is called. - - ### IQueueClient - *Implemented By:* IQueueClient @@ -6078,48 +3582,6 @@ Function that will be called when a message is received from the queue. --- -### IResource - -- *Extends:* IInspectable, constructs.IConstruct - -- *Implemented By:* Api, Bucket, Counter, Function, Queue, Schedule, Secret, Service, Table, TestRunner, Topic, Website, Redis, Resource, Test, IApiEndpointHandler, IBucketEventHandler, IFunctionHandler, IQueueSetConsumerHandler, IScheduleOnTickHandler, IServiceOnEventHandler, ITopicOnMessageHandler, IInflightHost, IResource, ITestHandler, IPredicateHandler - -Abstract interface for `Resource`. - - -#### Properties - -| **Name** | **Type** | **Description** | -| --- | --- | --- | -| node | constructs.Node | The tree node. | -| display | Display | Information on how to display a resource in the UI. | - ---- - -##### `node`Required - -```wing -node: Node; -``` - -- *Type:* constructs.Node - -The tree node. - ---- - -##### `display`Required - -```wing -display: Display; -``` - -- *Type:* Display - -Information on how to display a resource in the UI. - ---- - ### IScheduleClient - *Implemented By:* IScheduleClient @@ -6467,75 +3929,6 @@ data to be updated. --- -### ITestHandler - -- *Extends:* IResource - -- *Implemented By:* ITestHandler - -**Inflight client:** [@winglang/sdk.std.ITestHandlerClient](#@winglang/sdk.std.ITestHandlerClient) - -Interface with an inflight "handle" method that can be used to construct a `std.Test`. - - -#### Properties - -| **Name** | **Type** | **Description** | -| --- | --- | --- | -| node | constructs.Node | The tree node. | -| display | Display | Information on how to display a resource in the UI. | - ---- - -##### `node`Required - -```wing -node: Node; -``` - -- *Type:* constructs.Node - -The tree node. - ---- - -##### `display`Required - -```wing -display: Display; -``` - -- *Type:* Display - -Information on how to display a resource in the UI. - ---- - -### ITestHandlerClient - -- *Implemented By:* ITestHandlerClient - -Inflight client for `ITestHandler`. - -#### Methods - -| **Name** | **Description** | -| --- | --- | -| handle | Inflight function that will be called when the test is run. | - ---- - -##### `handle` - -```wing -handle(): void -``` - -**Inflight client:** [true](#true) - -Inflight function that will be called when the test is run. - - ### ITestRunnerClient - *Implemented By:* ITestRunnerClient @@ -6782,36 +4175,6 @@ json type. --- -### Direction - -The direction of a connection. - -Visually speaking, if a resource A has an outbound connection with resource B, -the arrow would point from A to B, and vice versa for inbound connections. - -#### Members - -| **Name** | **Description** | -| --- | --- | -| OUTBOUND | Indicates that this resource calls, triggers, or references the resource it is connected to. | -| INBOUND | Indicates that this resource is called, triggered, or referenced by the resource it is connected to. | - ---- - -##### `OUTBOUND` - -Indicates that this resource calls, triggers, or references the resource it is connected to. - ---- - - -##### `INBOUND` - -Indicates that this resource is called, triggered, or referenced by the resource it is connected to. - ---- - - ### HttpMethod Allowed HTTP methods for a endpoint. diff --git a/docs/docs/04-standard-library/01-cloud/api.md b/docs/docs/04-standard-library/01-cloud/api.md new file mode 100644 index 00000000000..65adc282fc5 --- /dev/null +++ b/docs/docs/04-standard-library/01-cloud/api.md @@ -0,0 +1,36 @@ +--- +title: Api +id: api +description: A built-in resource for creating HTTP endpoints in the cloud. +keywords: + [ + Wing reference, + Wing language, + language, + Wing standard library, + Wing programming language, + APIs, + Endpoints, + HTTP endpoint, + ] +sidebar_position: 1 +--- + +The `cloud.Api` resource represents a collection of HTTP endpoints that can be invoked by clients over the internet. +APIs often serve as the front door for applications to access data, business logic, or functionality from your backend services. + +The `Api` resource models an endpoint as a collection of routes, each mapped to an event handler function. +A route is a combination of a path, like `"/users/{userid}"` and a set of HTTP methods, like `GET`, `POST`, or `DELETE`. +When a client invokes a route, the corresponding event handler function executes. + +## Usage + +TODO + +## Target-specific details + +TODO + +## API Reference + +The full list of APIs for `cloud.Api` is available in the [API Reference](../api-reference). diff --git a/docs/04-standard-library/01-cloud/bucket.md b/docs/docs/04-standard-library/01-cloud/bucket.md similarity index 97% rename from docs/04-standard-library/01-cloud/bucket.md rename to docs/docs/04-standard-library/01-cloud/bucket.md index 92a98fc2583..878ba296e44 100644 --- a/docs/04-standard-library/01-cloud/bucket.md +++ b/docs/docs/04-standard-library/01-cloud/bucket.md @@ -1,5 +1,5 @@ --- -title: cloud.Bucket +title: Bucket id: bucket description: A built-in resource for handling object storage in the cloud. keywords: @@ -12,6 +12,7 @@ keywords: Object storage, Buckets, ] +sidebar_position: 1 --- The `cloud.Bucket` resource represents a container for storing data in the cloud. @@ -116,4 +117,4 @@ The Google Cloud implementation of `cloud.Bucket` uses [Google Cloud Storage](ht ## API Reference -The full list of APIs for `cloud.Bucket` is available in the [API Reference](../04-api-reference.md). +The full list of APIs for `cloud.Bucket` is available in the [API Reference](../api-reference). diff --git a/docs/04-standard-library/01-cloud/counter.md b/docs/docs/04-standard-library/01-cloud/counter.md similarity index 96% rename from docs/04-standard-library/01-cloud/counter.md rename to docs/docs/04-standard-library/01-cloud/counter.md index 6fb8d2829fc..ed69ec3b2e3 100644 --- a/docs/04-standard-library/01-cloud/counter.md +++ b/docs/docs/04-standard-library/01-cloud/counter.md @@ -1,8 +1,9 @@ --- -title: cloud.Counter +title: Counter id: counter description: A built-in resource for representing an container for numbers in the cloud. keywords: [Wing reference, Wing language, language, Wing standard library, Wing programming language, Counter] +sidebar_position: 1 --- The `cloud.Counter` resource represents a stateful container for one or more numbers in the cloud. @@ -64,4 +65,4 @@ The AWS implementation of `cloud.Counter` uses [Amazon DynamoDB](https://aws.ama ## API Reference -The full list of APIs for `cloud.Counter` is available in the [API Reference](../04-api-reference.md). +The full list of APIs for `cloud.Counter` is available in the [API Reference](../api-reference). diff --git a/docs/docs/04-standard-library/01-cloud/function.md b/docs/docs/04-standard-library/01-cloud/function.md new file mode 100644 index 00000000000..71d5c063427 --- /dev/null +++ b/docs/docs/04-standard-library/01-cloud/function.md @@ -0,0 +1,36 @@ +--- +title: Function +id: function +description: A built-in resource for creating serverless functions. +keywords: + [ + Wing reference, + Wing language, + language, + Wing standard library, + Wing programming language, + Serverless function, + ] +sidebar_position: 1 +--- + +The `cloud.Function` resource represents a serverless function for performing short, stateless tasks. +Functions are typically used to run business logic in response to events, such as a file being uploaded to a bucket, a message being pushed to a queue, or a timer expiring. + +When a function is invoked on a cloud provider, it is typically executed in a container that is spun up on demand. +The container is then destroyed after the function finishes executing. + +Functions may be invoked more than once, and some cloud providers may automatically retry failed invocations. +For performance reasons, most cloud providers impose a timeout on functions, after which the function is automatically terminated. + +## Usage + +TODO + +## Target-specific details + +TODO + +## API Reference + +The full list of APIs for `cloud.Function` is available in the [API Reference](../api-reference). diff --git a/docs/docs/04-standard-library/01-cloud/queue.md b/docs/docs/04-standard-library/01-cloud/queue.md new file mode 100644 index 00000000000..08c84b151f3 --- /dev/null +++ b/docs/docs/04-standard-library/01-cloud/queue.md @@ -0,0 +1,34 @@ +--- +title: Queue +id: queue +description: A built-in resource for creating distributed queues - a data structure for storing messages. +keywords: + [ + Wing reference, + Wing language, + language, + Wing standard library, + Wing programming language, + Queue, + Distributed queue, + Messaging queue, + FIFO queue, + Channel, + ] +sidebar_position: 1 +--- + +The `cloud.Queue` resource represents a data structure for holding a list of messages. +Queues are typically used to decouple producers of data and the consumers of said data in distributed systems. + +## Usage + +TODO + +## Target-specific details + +TODO + +## API Reference + +The full list of APIs for `cloud.Queue` is available in the [API Reference](../api-reference). diff --git a/docs/docs/04-standard-library/01-cloud/schedule.md b/docs/docs/04-standard-library/01-cloud/schedule.md new file mode 100644 index 00000000000..2de097e82ca --- /dev/null +++ b/docs/docs/04-standard-library/01-cloud/schedule.md @@ -0,0 +1,32 @@ +--- +title: Schedule +id: schedule +description: A built-in resource for defining scheduled tasks. +keywords: + [ + Wing reference, + Wing language, + language, + Wing standard library, + Wing programming language, + Schedule, + Cron job, + ] +sidebar_position: 1 +--- + +The `cloud.Schedule` resource is used to trigger events at a regular interval. +Schedules are useful for periodic tasks, such as running backups or sending daily reports. + + +## Usage + +TODO + +## Target-specific details + +TODO + +## API Reference + +The full list of APIs for `cloud.Schedule` is available in the [API Reference](../api-reference). diff --git a/docs/04-standard-library/01-cloud/secret.md b/docs/docs/04-standard-library/01-cloud/secret.md similarity index 97% rename from docs/04-standard-library/01-cloud/secret.md rename to docs/docs/04-standard-library/01-cloud/secret.md index c1cce40d3ef..efb91ec2e36 100644 --- a/docs/04-standard-library/01-cloud/secret.md +++ b/docs/docs/04-standard-library/01-cloud/secret.md @@ -1,8 +1,9 @@ --- -title: cloud.Secret +title: Secret id: secret description: A built-in resource for securely storing secrets in the cloud. keywords: [Wing reference, Wing language, language, Wing standard library, Wing programming language, secrets] +sidebar_position: 1 --- The `cloud.Secret` class represents a secret value (like an API key, certificate, etc.) that is securely stored in the cloud. @@ -77,4 +78,4 @@ See [AWS documentation](https://docs.aws.amazon.com/secretsmanager/latest/usergu ## API Reference -The full list of APIs for `cloud.Secret` is available in the [API Reference](../04-api-reference.md). +The full list of APIs for `cloud.Secret` is available in the [API Reference](../api-reference). diff --git a/docs/04-standard-library/01-cloud/service.md b/docs/docs/04-standard-library/01-cloud/service.md similarity index 97% rename from docs/04-standard-library/01-cloud/service.md rename to docs/docs/04-standard-library/01-cloud/service.md index 72c8217828e..c42a865a61c 100644 --- a/docs/04-standard-library/01-cloud/service.md +++ b/docs/docs/04-standard-library/01-cloud/service.md @@ -1,8 +1,9 @@ --- -title: cloud.Service +title: Service id: service description: A built-in resource for publishing messages to subscribers. keywords: [Wing reference, Wing language, language, Wing standard library, Wing programming language, services] +sidebar_position: 1 --- The `cloud.Service` class represents a cloud service that has a start and optional stop lifecycle. @@ -109,4 +110,4 @@ Within the context of the simulator, services are just spawned processes ran wit ## API Reference -The full list of APIs for `cloud.Service` is available in the [API Reference](../04-api-reference.md). +The full list of APIs for `cloud.Service` is available in the [API Reference](../api-reference). diff --git a/docs/04-standard-library/01-cloud/topic.md b/docs/docs/04-standard-library/01-cloud/topic.md similarity index 97% rename from docs/04-standard-library/01-cloud/topic.md rename to docs/docs/04-standard-library/01-cloud/topic.md index 6426412bb72..900ea7147e6 100644 --- a/docs/04-standard-library/01-cloud/topic.md +++ b/docs/docs/04-standard-library/01-cloud/topic.md @@ -1,8 +1,9 @@ --- -title: cloud.Topic +title: Topic id: topic description: A built-in resource for publishing messages to subscribers. keywords: [Wing reference, Wing language, language, Wing standard library, Wing programming language, topics] +sidebar_position: 1 --- The `cloud.Topic` class represents a subject of data that is open for subscription. @@ -95,4 +96,4 @@ AWS implementations of `cloud.Topic` use [AWS SNS](https://docs.aws.amazon.com/s ## API Reference -The full list of APIs for `cloud.Topic` is available in the [API Reference](../04-api-reference.md). +The full list of APIs for `cloud.Topic` is available in the [API Reference](../api-reference). diff --git a/docs/docs/04-standard-library/01-cloud/website.md b/docs/docs/04-standard-library/01-cloud/website.md new file mode 100644 index 00000000000..c5eba3c518b --- /dev/null +++ b/docs/docs/04-standard-library/01-cloud/website.md @@ -0,0 +1,31 @@ +--- +title: Website +id: website +description: A built-in resource for creating static websites. +keywords: + [ + Wing reference, + Wing language, + language, + Wing standard library, + Wing programming language, + Schedule, + Cron job, + ] +sidebar_position: 1 +--- + +The `cloud.Website` resource represents a static website that can be hosted in the cloud. +Websites are typically used to serve static content, such as HTML, CSS, and JavaScript files, which are updated whenever the application is redeployed. + +## Usage + +TODO + +## Target-specific details + +TODO + +## API Reference + +The full list of APIs for `cloud.Website` is available in the [API Reference](../api-reference). diff --git a/docs/docs/04-standard-library/02-std/_category_.yml b/docs/docs/04-standard-library/02-std/_category_.yml new file mode 100644 index 00000000000..97d25885bc1 --- /dev/null +++ b/docs/docs/04-standard-library/02-std/_category_.yml @@ -0,0 +1,3 @@ +label: Standard types +collapsible: true +collapsed: true diff --git a/docs/docs/04-standard-library/02-std/api-reference.md b/docs/docs/04-standard-library/02-std/api-reference.md new file mode 100644 index 00000000000..7ca68c91e3c --- /dev/null +++ b/docs/docs/04-standard-library/02-std/api-reference.md @@ -0,0 +1,2515 @@ +--- +title: API reference +id: api-reference +description: Wing standard library API reference for the std module +keywords: [Wing sdk, sdk, Wing API Reference] +hide_title: true +sidebar_position: 100 +--- + + + +# API Reference + +## Resources + +### Resource + +- *Implements:* IResource + +Shared behavior between all Wing SDK resources. + +#### Initializers + +```wing +bring std; + +new std.Resource() +``` + +| **Name** | **Type** | **Description** | +| --- | --- | --- | + +--- + + + +#### Properties + +| **Name** | **Type** | **Description** | +| --- | --- | --- | +| node | constructs.Node | The tree node. | +| display | Display | Information on how to display a resource in the UI. | + +--- + +##### `node`Required + +```wing +node: Node; +``` + +- *Type:* constructs.Node + +The tree node. + +--- + +##### `display`Required + +```wing +display: Display; +``` + +- *Type:* Display + +Information on how to display a resource in the UI. + +--- + + +### Test + +- *Implements:* IInflightHost + +**Inflight client:** [@winglang/sdk.cloud.ITestClient](#@winglang/sdk.cloud.ITestClient) + +Represents a unit test. + +#### Initializers + +```wing +bring std; + +new std.Test(inflight: ITestHandler, props?: TestProps) +``` + +| **Name** | **Type** | **Description** | +| --- | --- | --- | +| inflight | ITestHandler | *No description.* | +| props | TestProps | *No description.* | + +--- + +##### `inflight`Required + +- *Type:* ITestHandler + +--- + +##### `props`Optional + +- *Type:* TestProps + +--- + + + +#### Properties + +| **Name** | **Type** | **Description** | +| --- | --- | --- | +| node | constructs.Node | The tree node. | +| display | Display | Information on how to display a resource in the UI. | + +--- + +##### `node`Required + +```wing +node: Node; +``` + +- *Type:* constructs.Node + +The tree node. + +--- + +##### `display`Required + +```wing +display: Display; +``` + +- *Type:* Display + +Information on how to display a resource in the UI. + +--- + + +## Structs + +### AddConnectionProps + +Props for `Resource.addConnection`. + +#### Initializer + +```wing +bring std; + +let AddConnectionProps = std.AddConnectionProps{ ... } +``` + +#### Properties + +| **Name** | **Type** | **Description** | +| --- | --- | --- | +| from | IResource | The resource creating the connection to `to`. | +| relationship | str | The type of relationship between the resources. | +| to | IResource | The resource `from` is connecting to. | +| implicit | bool | Whether the relationship is implicit, i.e. it is not explicitly defined by the user. | + +--- + +##### `from`Required + +```wing +from: IResource; +``` + +- *Type:* IResource + +The resource creating the connection to `to`. + +--- + +##### `relationship`Required + +```wing +relationship: str; +``` + +- *Type:* str + +The type of relationship between the resources. + +--- + +##### `to`Required + +```wing +to: IResource; +``` + +- *Type:* IResource + +The resource `from` is connecting to. + +--- + +##### `implicit`Optional + +```wing +implicit: bool; +``` + +- *Type:* bool +- *Default:* false + +Whether the relationship is implicit, i.e. it is not explicitly defined by the user. + +--- + +### Connection + +A connection between two resources. + +#### Initializer + +```wing +bring std; + +let Connection = std.Connection{ ... } +``` + +#### Properties + +| **Name** | **Type** | **Description** | +| --- | --- | --- | +| direction | Direction | The direction of the connection. | +| implicit | bool | Whether the relationship is implicit, i.e. it is not explicitly defined by the user. | +| relationship | str | The type of relationship with the resource. | +| resource | IResource | The resource this connection is to. | + +--- + +##### `direction`Required + +```wing +direction: Direction; +``` + +- *Type:* Direction + +The direction of the connection. + +--- + +##### `implicit`Required + +```wing +implicit: bool; +``` + +- *Type:* bool + +Whether the relationship is implicit, i.e. it is not explicitly defined by the user. + +--- + +##### `relationship`Required + +```wing +relationship: str; +``` + +- *Type:* str + +The type of relationship with the resource. + +--- + +##### `resource`Required + +```wing +resource: IResource; +``` + +- *Type:* IResource + +The resource this connection is to. + +--- + +### DisplayProps + +Properties for the Display class. + +#### Initializer + +```wing +bring std; + +let DisplayProps = std.DisplayProps{ ... } +``` + +#### Properties + +| **Name** | **Type** | **Description** | +| --- | --- | --- | +| description | str | Description of the resource. | +| hidden | bool | Whether the resource should be hidden from the UI. | +| title | str | Title of the resource. | + +--- + +##### `description`Optional + +```wing +description: str; +``` + +- *Type:* str +- *Default:* No description. + +Description of the resource. + +--- + +##### `hidden`Optional + +```wing +hidden: bool; +``` + +- *Type:* bool +- *Default:* Undefined + +Whether the resource should be hidden from the UI. + +--- + +##### `title`Optional + +```wing +title: str; +``` + +- *Type:* str +- *Default:* No title. + +Title of the resource. + +--- + +### TestProps + +Properties for `Test`. + +This is the type users see when constructing a std.Test instance. + +#### Initializer + +```wing +bring std; + +let TestProps = std.TestProps{ ... } +``` + +#### Properties + +| **Name** | **Type** | **Description** | +| --- | --- | --- | +| env | MutMap<str> | Environment variables to pass to the function. | +| memory | num | The amount of memory to allocate to the function, in MB. | +| timeout | Duration | The maximum amount of time the function can run. | + +--- + +##### `env`Optional + +```wing +env: MutMap; +``` + +- *Type:* MutMap<str> +- *Default:* No environment variables. + +Environment variables to pass to the function. + +--- + +##### `memory`Optional + +```wing +memory: num; +``` + +- *Type:* num +- *Default:* 128 + +The amount of memory to allocate to the function, in MB. + +--- + +##### `timeout`Optional + +```wing +timeout: Duration; +``` + +- *Type:* Duration +- *Default:* 1m + +The maximum amount of time the function can run. + +--- + +## Classes + +### Array + +Immutable Array. + +#### Methods + +| **Name** | **Description** | +| --- | --- | +| at | Get the value at the given index. | +| concat | Merge arr to the end of this array. | +| contains | Checks if this array includes searchElement. | +| copyMut | Create a mutable shallow copy of this array. | +| indexOf | Returns the index of the first occurrence of searchElement found. | +| join | Returns a new string containing the concatenated values in this array, separated by commas or a specified separator string. | +| lastIndexOf | Returns the index of the last occurrence of searchElement found. | + +--- + +##### `at` + +```wing +at(index: num): T1 +``` + +Get the value at the given index. + +###### `index`Required + +- *Type:* num + +index of the value to get. + +--- + +##### `concat` + +```wing +concat(arr: Array): Array +``` + +Merge arr to the end of this array. + +###### `arr`Required + +- *Type:* Array + +array to merge. + +--- + +##### `contains` + +```wing +contains(searchElement: T1): bool +``` + +Checks if this array includes searchElement. + +###### `searchElement`Required + +- *Type:* T1 + +to search for. + +--- + +##### `copyMut` + +```wing +copyMut(): MutArray +``` + +Create a mutable shallow copy of this array. + +##### `indexOf` + +```wing +indexOf(searchElement: T1): num +``` + +Returns the index of the first occurrence of searchElement found. + +###### `searchElement`Required + +- *Type:* T1 + +to search for. + +--- + +##### `join` + +```wing +join(separator?: str): str +``` + +Returns a new string containing the concatenated values in this array, separated by commas or a specified separator string. + +If the array has only +one item, then that item will be returned without using the separator. + +###### `separator`Optional + +- *Type:* str + +--- + +##### `lastIndexOf` + +```wing +lastIndexOf(searchElement: T1): num +``` + +Returns the index of the last occurrence of searchElement found. + +###### `searchElement`Required + +- *Type:* T1 + +to search for. + +--- + + +#### Properties + +| **Name** | **Type** | **Description** | +| --- | --- | --- | +| length | num | The length of the array. | + +--- + +##### `length`Required + +```wing +length: num; +``` + +- *Type:* num + +The length of the array. + +--- + + +### Boolean + +Boolean. + + +#### Static Functions + +| **Name** | **Description** | +| --- | --- | +| fromJson | Parse a boolean from Json. | + +--- + +##### `fromJson` + +```wing +bring std; + +std.Boolean.fromJson(json: Json) +``` + +Parse a boolean from Json. + +###### `json`Required + +- *Type:* Json + +to parse boolean from. + +--- + + + +### Display + +Information on how to display a resource in the UI. + +#### Initializers + +```wing +bring std; + +new std.Display(props?: DisplayProps) +``` + +| **Name** | **Type** | **Description** | +| --- | --- | --- | +| props | DisplayProps | *No description.* | + +--- + +##### `props`Optional + +- *Type:* DisplayProps + +--- + + + +#### Properties + +| **Name** | **Type** | **Description** | +| --- | --- | --- | +| description | str | Description of the resource. | +| hidden | bool | Whether the resource should be hidden from the UI. | +| title | str | Title of the resource. | + +--- + +##### `description`Optional + +```wing +description: str; +``` + +- *Type:* str + +Description of the resource. + +--- + +##### `hidden`Optional + +```wing +hidden: bool; +``` + +- *Type:* bool + +Whether the resource should be hidden from the UI. + +--- + +##### `title`Optional + +```wing +title: str; +``` + +- *Type:* str + +Title of the resource. + +--- + + +### Duration + +Represents a length of time. + + +#### Static Functions + +| **Name** | **Description** | +| --- | --- | +| fromDays | Create a Duration representing an amount of days. | +| fromHours | Create a Duration representing an amount of hours. | +| fromMilliseconds | Create a Duration representing an amount of milliseconds. | +| fromMinutes | Create a Duration representing an amount of minutes. | +| fromMonths | Create a Duration representing an amount of months. | +| fromSeconds | Create a Duration representing an amount of seconds. | +| fromYears | Create a Duration representing an amount of years. | + +--- + +##### `fromDays` + +```wing +bring std; + +std.Duration.fromDays(amount: num) +``` + +Create a Duration representing an amount of days. + +###### `amount`Required + +- *Type:* num + +the amount of Days the `Duration` will represent. + +--- + +##### `fromHours` + +```wing +bring std; + +std.Duration.fromHours(amount: num) +``` + +Create a Duration representing an amount of hours. + +###### `amount`Required + +- *Type:* num + +the amount of Hours the `Duration` will represent. + +--- + +##### `fromMilliseconds` + +```wing +bring std; + +std.Duration.fromMilliseconds(amount: num) +``` + +Create a Duration representing an amount of milliseconds. + +###### `amount`Required + +- *Type:* num + +the amount of Milliseconds the `Duration` will represent. + +--- + +##### `fromMinutes` + +```wing +bring std; + +std.Duration.fromMinutes(amount: num) +``` + +Create a Duration representing an amount of minutes. + +###### `amount`Required + +- *Type:* num + +the amount of Minutes the `Duration` will represent. + +--- + +##### `fromMonths` + +```wing +bring std; + +std.Duration.fromMonths(amount: num) +``` + +Create a Duration representing an amount of months. + +###### `amount`Required + +- *Type:* num + +the amount of Months the `Duration` will represent. + +--- + +##### `fromSeconds` + +```wing +bring std; + +std.Duration.fromSeconds(amount: num) +``` + +Create a Duration representing an amount of seconds. + +###### `amount`Required + +- *Type:* num + +the amount of Seconds the `Duration` will represent. + +--- + +##### `fromYears` + +```wing +bring std; + +std.Duration.fromYears(amount: num) +``` + +Create a Duration representing an amount of years. + +###### `amount`Required + +- *Type:* num + +the amount of Years the `Duration` will represent. + +--- + +#### Properties + +| **Name** | **Type** | **Description** | +| --- | --- | --- | +| days | num | Return the total number of days in this Duration. | +| hours | num | Return the total number of hours in this Duration. | +| milliseconds | num | Return the total number of milliseconds in this Duration. | +| minutes | num | Return the total number of minutes in this Duration. | +| months | num | Return the total number of months in this Duration. | +| seconds | num | Return the total number of seconds in this Duration. | +| years | num | Return the total number of years in this Duration. | + +--- + +##### `days`Required + +```wing +days: num; +``` + +- *Type:* num + +Return the total number of days in this Duration. + +--- + +##### `hours`Required + +```wing +hours: num; +``` + +- *Type:* num + +Return the total number of hours in this Duration. + +--- + +##### `milliseconds`Required + +```wing +milliseconds: num; +``` + +- *Type:* num + +Return the total number of milliseconds in this Duration. + +--- + +##### `minutes`Required + +```wing +minutes: num; +``` + +- *Type:* num + +Return the total number of minutes in this Duration. + +--- + +##### `months`Required + +```wing +months: num; +``` + +- *Type:* num + +Return the total number of months in this Duration. + +--- + +##### `seconds`Required + +```wing +seconds: num; +``` + +- *Type:* num + +Return the total number of seconds in this Duration. + +--- + +##### `years`Required + +```wing +years: num; +``` + +- *Type:* num + +Return the total number of years in this Duration. + +--- + + +### Json + +Immutable Json. + +#### Initializers + +```wing +bring std; + +new std.Json() +``` + +| **Name** | **Type** | **Description** | +| --- | --- | --- | + +--- + +#### Methods + +| **Name** | **Description** | +| --- | --- | +| asBool | Convert Json element to number if possible. | +| asNum | Convert Json element to number if possible. | +| asStr | Convert Json element to string if possible. | +| get | Returns a specified element from the Json. | +| getAt | Returns a specified element at a given index from Json Array. | +| tryAsBool | Convert Json element to boolean if possible. | +| tryAsNum | Convert Json element to string if possible. | +| tryAsStr | Convert Json element to string if possible. | +| tryGet | Optionally returns an specified element from the Json. | +| tryGetAt | Optionally returns a specified element at a given index from Json Array. | + +--- + +##### `asBool` + +```wing +asBool(): bool +``` + +Convert Json element to number if possible. + +##### `asNum` + +```wing +asNum(): num +``` + +Convert Json element to number if possible. + +##### `asStr` + +```wing +asStr(): str +``` + +Convert Json element to string if possible. + +##### `get` + +```wing +get(key: str): Json +``` + +Returns a specified element from the Json. + +###### `key`Required + +- *Type:* str + +The key of the element to return. + +--- + +##### `getAt` + +```wing +getAt(index: num): Json +``` + +Returns a specified element at a given index from Json Array. + +###### `index`Required + +- *Type:* num + +The index of the element in the Json Array to return. + +--- + +##### `tryAsBool` + +```wing +tryAsBool(): bool +``` + +Convert Json element to boolean if possible. + +##### `tryAsNum` + +```wing +tryAsNum(): num +``` + +Convert Json element to string if possible. + +##### `tryAsStr` + +```wing +tryAsStr(): str +``` + +Convert Json element to string if possible. + +##### `tryGet` + +```wing +tryGet(key: str): Json +``` + +Optionally returns an specified element from the Json. + +###### `key`Required + +- *Type:* str + +The key of the element to return. + +--- + +##### `tryGetAt` + +```wing +tryGetAt(index: num): Json +``` + +Optionally returns a specified element at a given index from Json Array. + +###### `index`Required + +- *Type:* num + +The index of the element in the Json Array to return. + +--- + +#### Static Functions + +| **Name** | **Description** | +| --- | --- | +| deepCopy | Creates an immutable deep copy of the Json. | +| deepCopyMut | Creates a mutable deep copy of the Json. | +| delete | Deletes a key in a given Json. | +| has | Checks if a Json object has a given key. | +| keys | Returns the keys from the Json object. | +| parse | Parse a string into a Json. | +| stringify | Formats Json as string. | +| tryParse | Try to parse a string into a Json. | +| values | Returns the values from the Json. | + +--- + +##### `deepCopy` + +```wing +bring std; + +std.Json.deepCopy(json: MutJson) +``` + +Creates an immutable deep copy of the Json. + +###### `json`Required + +- *Type:* MutJson + +to copy. + +--- + +##### `deepCopyMut` + +```wing +bring std; + +std.Json.deepCopyMut(json: Json) +``` + +Creates a mutable deep copy of the Json. + +###### `json`Required + +- *Type:* Json + +to copy. + +--- + +##### `delete` + +```wing +bring std; + +std.Json.delete(json: MutJson, key: str) +``` + +Deletes a key in a given Json. + +###### `json`Required + +- *Type:* MutJson + +to delete key from. + +--- + +###### `key`Required + +- *Type:* str + +the key to delete. + +--- + +##### `has` + +```wing +bring std; + +std.Json.has(json: Json, key: str) +``` + +Checks if a Json object has a given key. + +###### `json`Required + +- *Type:* Json + +The json object to inspect. + +--- + +###### `key`Required + +- *Type:* str + +The key to check. + +--- + +##### `keys` + +```wing +bring std; + +std.Json.keys(json: any) +``` + +Returns the keys from the Json object. + +###### `json`Required + +- *Type:* any + +to get keys from. + +--- + +##### `parse` + +```wing +bring std; + +std.Json.parse(str: str) +``` + +Parse a string into a Json. + +###### `str`Required + +- *Type:* str + +to parse as Json. + +--- + +##### `stringify` + +```wing +bring std; + +std.Json.stringify(json: any, indent?: num) +``` + +Formats Json as string. + +(JSON.stringify($args$)) + +###### `json`Required + +- *Type:* any + +to format as string. + +--- + +###### `indent`Optional + +- *Type:* num + +--- + +##### `tryParse` + +```wing +bring std; + +std.Json.tryParse(str: str) +``` + +Try to parse a string into a Json. + +###### `str`Required + +- *Type:* str + +to parse as Json. + +--- + +##### `values` + +```wing +bring std; + +std.Json.values(json: Json) +``` + +Returns the values from the Json. + +###### `json`Required + +- *Type:* Json + +to get values from. + +--- + + + +### Map + +Immutable Map. + +#### Methods + +| **Name** | **Description** | +| --- | --- | +| copyMut | Create a mutable shallow copy of this map. | +| get | Returns a specified element from the map. | +| has | Returns a boolean indicating whether an element with the specified key exists or not. | +| keys | Returns the keys of this map. | +| size | Returns the number of elements in the map. | +| values | Returns the values of this map. | + +--- + +##### `copyMut` + +```wing +copyMut(): MutMap +``` + +Create a mutable shallow copy of this map. + +##### `get` + +```wing +get(key: str): T1 +``` + +Returns a specified element from the map. + +If the value that is associated to the provided key is an object, then you will get a reference +to that object and any change made to that object will effectively modify it inside the map. + +###### `key`Required + +- *Type:* str + +The key of the element to return. + +--- + +##### `has` + +```wing +has(key: str): bool +``` + +Returns a boolean indicating whether an element with the specified key exists or not. + +###### `key`Required + +- *Type:* str + +The key of the element to test for presence. + +--- + +##### `keys` + +```wing +keys(): MutArray +``` + +Returns the keys of this map. + +##### `size` + +```wing +size(): num +``` + +Returns the number of elements in the map. + +TODO: For now this has to be a method rather than a getter as macros only work on methods https://github.com/winglang/wing/issues/1658 + +##### `values` + +```wing +values(): Array +``` + +Returns the values of this map. + + + + +### MutArray + +Mutable Array. + +#### Methods + +| **Name** | **Description** | +| --- | --- | +| at | Get the value at the given index. | +| concat | Merge arr to the end of this array. | +| contains | Checks if this array includes searchElement. | +| copy | Create an immutable shallow copy of this array. | +| indexOf | Returns the index of the first occurrence of searchElement found. | +| join | Returns a new string containing the concatenated values in this array, separated by commas or a specified separator string. | +| lastIndexOf | Returns the index of the last occurrence of searchElement found. | +| pop | Remove value from end of array. | +| push | Add value to end of array. | + +--- + +##### `at` + +```wing +at(index: num): T1 +``` + +Get the value at the given index. + +###### `index`Required + +- *Type:* num + +index of the value to get. + +--- + +##### `concat` + +```wing +concat(arr: MutArray): MutArray +``` + +Merge arr to the end of this array. + +###### `arr`Required + +- *Type:* MutArray + +array to merge. + +--- + +##### `contains` + +```wing +contains(searchElement: T1): bool +``` + +Checks if this array includes searchElement. + +###### `searchElement`Required + +- *Type:* T1 + +to search for. + +--- + +##### `copy` + +```wing +copy(): Array +``` + +Create an immutable shallow copy of this array. + +##### `indexOf` + +```wing +indexOf(searchElement: T1): num +``` + +Returns the index of the first occurrence of searchElement found. + +###### `searchElement`Required + +- *Type:* T1 + +to search for. + +--- + +##### `join` + +```wing +join(separator?: str): str +``` + +Returns a new string containing the concatenated values in this array, separated by commas or a specified separator string. + +If the array has only +one item, then that item will be returned without using the separator. + +###### `separator`Optional + +- *Type:* str + +--- + +##### `lastIndexOf` + +```wing +lastIndexOf(searchElement: T1): num +``` + +Returns the index of the last occurrence of searchElement found. + +###### `searchElement`Required + +- *Type:* T1 + +to search for. + +--- + +##### `pop` + +```wing +pop(): T1 +``` + +Remove value from end of array. + +##### `push` + +```wing +push(value: T1): void +``` + +Add value to end of array. + +###### `value`Required + +- *Type:* T1 + +value to add. + +--- + + +#### Properties + +| **Name** | **Type** | **Description** | +| --- | --- | --- | +| length | num | The length of the array. | + +--- + +##### `length`Required + +```wing +length: num; +``` + +- *Type:* num + +The length of the array. + +--- + + +### MutJson + +Mutable Json. + +#### Initializers + +```wing +bring std; + +new std.MutJson() +``` + +| **Name** | **Type** | **Description** | +| --- | --- | --- | + +--- + +#### Methods + +| **Name** | **Description** | +| --- | --- | +| asBool | Convert Json element to number if possible. | +| asNum | Convert Json element to number if possible. | +| asStr | Convert Json element to string if possible. | +| get | Returns a specified element from the Json. | +| getAt | Returns a specified element at a given index from MutJson Array. | +| set | Adds or updates an element in MutJson with a specific key and value. | +| setAt | Set element in MutJson Array with a specific key and value. | +| tryAsBool | Convert Json element to boolean if possible. | +| tryAsNum | Convert Json element to string if possible. | +| tryAsStr | Convert Json element to string if possible. | +| tryGet | Optionally returns an specified element from the Json. | +| tryGetAt | Optionally returns a specified element at a given index from Json Array. | + +--- + +##### `asBool` + +```wing +asBool(): bool +``` + +Convert Json element to number if possible. + +##### `asNum` + +```wing +asNum(): num +``` + +Convert Json element to number if possible. + +##### `asStr` + +```wing +asStr(): str +``` + +Convert Json element to string if possible. + +##### `get` + +```wing +get(key: str): MutJson +``` + +Returns a specified element from the Json. + +###### `key`Required + +- *Type:* str + +The key of the element to return. + +--- + +##### `getAt` + +```wing +getAt(index: num): MutJson +``` + +Returns a specified element at a given index from MutJson Array. + +###### `index`Required + +- *Type:* num + +The index of the element in the MutJson Array to return. + +--- + +##### `set` + +```wing +set(key: str, value: MutJson): void +``` + +Adds or updates an element in MutJson with a specific key and value. + +###### `key`Required + +- *Type:* str + +The key of the element to add. + +--- + +###### `value`Required + +- *Type:* MutJson + +The value of the element to add. + +--- + +##### `setAt` + +```wing +setAt(index: num, value: MutJson): void +``` + +Set element in MutJson Array with a specific key and value. + +###### `index`Required + +- *Type:* num + +--- + +###### `value`Required + +- *Type:* MutJson + +The value of the element to set. + +--- + +##### `tryAsBool` + +```wing +tryAsBool(): bool +``` + +Convert Json element to boolean if possible. + +##### `tryAsNum` + +```wing +tryAsNum(): num +``` + +Convert Json element to string if possible. + +##### `tryAsStr` + +```wing +tryAsStr(): str +``` + +Convert Json element to string if possible. + +##### `tryGet` + +```wing +tryGet(key: str): MutJson +``` + +Optionally returns an specified element from the Json. + +###### `key`Required + +- *Type:* str + +The key of the element to return. + +--- + +##### `tryGetAt` + +```wing +tryGetAt(index: num): MutJson +``` + +Optionally returns a specified element at a given index from Json Array. + +###### `index`Required + +- *Type:* num + +The index of the element in the Json Array to return. + +--- + + + + +### MutMap + +Mutable Map. + +#### Methods + +| **Name** | **Description** | +| --- | --- | +| clear | Removes all elements. | +| copy | Create an immutable shallow copy of this map. | +| delete | Removes the specified element from a map. | +| get | Returns a specified element from the map. | +| has | Returns a boolean indicating whether an element with the specified key exists or not. | +| keys | Returns the keys of this map. | +| set | Adds or updates an entry in a Map object with a specified key and a value. | +| size | Returns the number of elements in the map. | +| values | Returns the values of this map. | + +--- + +##### `clear` + +```wing +clear(): void +``` + +Removes all elements. + +##### `copy` + +```wing +copy(): Map +``` + +Create an immutable shallow copy of this map. + +##### `delete` + +```wing +delete(key: str): bool +``` + +Removes the specified element from a map. + +###### `key`Required + +- *Type:* str + +The key. + +--- + +##### `get` + +```wing +get(key: str): T1 +``` + +Returns a specified element from the map. + +If the value that is associated to the provided key is an object, then you will get a reference +to that object and any change made to that object will effectively modify it inside the map. + +###### `key`Required + +- *Type:* str + +The key of the element to return. + +--- + +##### `has` + +```wing +has(key: str): bool +``` + +Returns a boolean indicating whether an element with the specified key exists or not. + +###### `key`Required + +- *Type:* str + +The key of the element to test for presence. + +--- + +##### `keys` + +```wing +keys(): MutArray +``` + +Returns the keys of this map. + +##### `set` + +```wing +set(key: str, value: T1): void +``` + +Adds or updates an entry in a Map object with a specified key and a value. + +TODO: revisit this macro after we support indexed args https://github.com/winglang/wing/issues/1659 + +###### `key`Required + +- *Type:* str + +The key of the element to add. + +--- + +###### `value`Required + +- *Type:* T1 + +The value of the element to add. + +--- + +##### `size` + +```wing +size(): num +``` + +Returns the number of elements in the map. + +TODO: For now this has to be a method rather than a getter as macros only work on methods https://github.com/winglang/wing/issues/1658 + +##### `values` + +```wing +values(): Array +``` + +Returns the values of this map. + + + + +### MutSet + +Mutable Set. + +#### Methods + +| **Name** | **Description** | +| --- | --- | +| add | Add value to set. | +| clear | The clear() method removes all elements from a set. | +| copy | Create an immutable shallow copy of this set. | +| delete | Removes a specified value from a set, if it is in the set. | +| has | Returns a boolean indicating whether an element with the specified value exists in the set. | + +--- + +##### `add` + +```wing +add(value: T1): MutSet +``` + +Add value to set. + +###### `value`Required + +- *Type:* T1 + +value to add. + +--- + +##### `clear` + +```wing +clear(): void +``` + +The clear() method removes all elements from a set. + +##### `copy` + +```wing +copy(): Set +``` + +Create an immutable shallow copy of this set. + +##### `delete` + +```wing +delete(value: T1): bool +``` + +Removes a specified value from a set, if it is in the set. + +###### `value`Required + +- *Type:* T1 + +The value to remove from the set. + +--- + +##### `has` + +```wing +has(value: T1): bool +``` + +Returns a boolean indicating whether an element with the specified value exists in the set. + +###### `value`Required + +- *Type:* T1 + +The value to test for presence in the Set object. + +--- + + +#### Properties + +| **Name** | **Type** | **Description** | +| --- | --- | --- | +| size | num | The length of the set. | + +--- + +##### `size`Required + +```wing +size: num; +``` + +- *Type:* num + +The length of the set. + +--- + + +### Number + +Number. + + +#### Static Functions + +| **Name** | **Description** | +| --- | --- | +| fromJson | Parse a number from Json. | +| fromStr | Parse a number from string. | + +--- + +##### `fromJson` + +```wing +bring std; + +std.Number.fromJson(json: Json) +``` + +Parse a number from Json. + +###### `json`Required + +- *Type:* Json + +to parse number from. + +--- + +##### `fromStr` + +```wing +bring std; + +std.Number.fromStr(str: str) +``` + +Parse a number from string. + +###### `str`Required + +- *Type:* str + +to parse number from. + +--- + + + +### Range + +Range. + + + + + +### Set + +Immutable Set. + +#### Methods + +| **Name** | **Description** | +| --- | --- | +| copyMut | Create a mutable shallow copy of this set. | +| has | Returns a boolean indicating whether an element with the specified value exists in the set. | + +--- + +##### `copyMut` + +```wing +copyMut(): MutSet +``` + +Create a mutable shallow copy of this set. + +##### `has` + +```wing +has(value: T1): bool +``` + +Returns a boolean indicating whether an element with the specified value exists in the set. + +###### `value`Required + +- *Type:* T1 + +The value to test for presence in the Set object. + +--- + + +#### Properties + +| **Name** | **Type** | **Description** | +| --- | --- | --- | +| size | num | The length of the set. | + +--- + +##### `size`Required + +```wing +size: num; +``` + +- *Type:* num + +The length of the set. + +--- + + +### String + +String. + +#### Methods + +| **Name** | **Description** | +| --- | --- | +| at | Returns the character at the specified index. | +| concat | Combines the text of two (or more) strings and returns a new string. | +| contains | Checks if string includes substring. | +| endsWith | Does this string end with the given searchString? | +| indexOf | Returns the index of the first occurrence of searchString found. | +| lowercase | Returns this string in lower case. | +| split | Splits string by separator. | +| startsWith | Does this string start with the given searchString? | +| substring | Returns a string between indexStart, indexEnd. | +| trim | Removes white spaces from start and end of this string. | +| uppercase | Returns this string in upper case. | + +--- + +##### `at` + +```wing +at(index: num): str +``` + +Returns the character at the specified index. + +###### `index`Required + +- *Type:* num + +position of the character. + +--- + +##### `concat` + +```wing +concat(strN: str): str +``` + +Combines the text of two (or more) strings and returns a new string. + +###### `strN`Required + +- *Type:* str + +one or more strings to concatenate to this string. + +--- + +##### `contains` + +```wing +contains(searchString: str): bool +``` + +Checks if string includes substring. + +###### `searchString`Required + +- *Type:* str + +substring to search for. + +--- + +##### `endsWith` + +```wing +endsWith(searchString: str): bool +``` + +Does this string end with the given searchString? + +###### `searchString`Required + +- *Type:* str + +substring to search for. + +--- + +##### `indexOf` + +```wing +indexOf(searchString: str): num +``` + +Returns the index of the first occurrence of searchString found. + +###### `searchString`Required + +- *Type:* str + +substring to search for. + +--- + +##### `lowercase` + +```wing +lowercase(): str +``` + +Returns this string in lower case. + +##### `split` + +```wing +split(separator: str): MutArray +``` + +Splits string by separator. + +###### `separator`Required + +- *Type:* str + +separator to split by. + +--- + +##### `startsWith` + +```wing +startsWith(searchString: str): bool +``` + +Does this string start with the given searchString? + +###### `searchString`Required + +- *Type:* str + +substring to search for. + +--- + +##### `substring` + +```wing +substring(indexStart: num, indexEnd?: num): str +``` + +Returns a string between indexStart, indexEnd. + +###### `indexStart`Required + +- *Type:* num + +index of the character we slice at. + +--- + +###### `indexEnd`Optional + +- *Type:* num + +optional - index of the character we end slicing at. + +--- + +##### `trim` + +```wing +trim(): str +``` + +Removes white spaces from start and end of this string. + +##### `uppercase` + +```wing +uppercase(): str +``` + +Returns this string in upper case. + +#### Static Functions + +| **Name** | **Description** | +| --- | --- | +| fromJson | Parse string from Json. | + +--- + +##### `fromJson` + +```wing +bring std; + +std.String.fromJson(json: Json) +``` + +Parse string from Json. + +###### `json`Required + +- *Type:* Json + +to create string from. + +--- + +#### Properties + +| **Name** | **Type** | **Description** | +| --- | --- | --- | +| length | num | The length of the string. | + +--- + +##### `length`Required + +```wing +length: num; +``` + +- *Type:* num + +The length of the string. + +--- + + +### T1 + +Generic type argument. + +This type is replaced at compile time. + +#### Initializers + +```wing +bring std; + +new std.T1() +``` + +| **Name** | **Type** | **Description** | +| --- | --- | --- | + +--- + + + + + +## Protocols + +### IInflightHost + +- *Extends:* IResource + +- *Implemented By:* Function, Test, IInflightHost + +A resource that can run inflight code. + + +#### Properties + +| **Name** | **Type** | **Description** | +| --- | --- | --- | +| node | constructs.Node | The tree node. | +| display | Display | Information on how to display a resource in the UI. | + +--- + +##### `node`Required + +```wing +node: Node; +``` + +- *Type:* constructs.Node + +The tree node. + +--- + +##### `display`Required + +```wing +display: Display; +``` + +- *Type:* Display + +Information on how to display a resource in the UI. + +--- + +### IResource + +- *Extends:* IInspectable, constructs.IConstruct + +- *Implemented By:* Api, Bucket, Counter, Function, Queue, Schedule, Secret, Service, Table, TestRunner, Topic, Website, Redis, Resource, Test, IApiEndpointHandler, IBucketEventHandler, IFunctionHandler, IQueueSetConsumerHandler, IScheduleOnTickHandler, IServiceOnEventHandler, ITopicOnMessageHandler, IInflightHost, IResource, ITestHandler, IPredicateHandler + +Abstract interface for `Resource`. + + +#### Properties + +| **Name** | **Type** | **Description** | +| --- | --- | --- | +| node | constructs.Node | The tree node. | +| display | Display | Information on how to display a resource in the UI. | + +--- + +##### `node`Required + +```wing +node: Node; +``` + +- *Type:* constructs.Node + +The tree node. + +--- + +##### `display`Required + +```wing +display: Display; +``` + +- *Type:* Display + +Information on how to display a resource in the UI. + +--- + +### ITestHandler + +- *Extends:* IResource + +- *Implemented By:* ITestHandler + +**Inflight client:** [@winglang/sdk.std.ITestHandlerClient](#@winglang/sdk.std.ITestHandlerClient) + +Interface with an inflight "handle" method that can be used to construct a `std.Test`. + + +#### Properties + +| **Name** | **Type** | **Description** | +| --- | --- | --- | +| node | constructs.Node | The tree node. | +| display | Display | Information on how to display a resource in the UI. | + +--- + +##### `node`Required + +```wing +node: Node; +``` + +- *Type:* constructs.Node + +The tree node. + +--- + +##### `display`Required + +```wing +display: Display; +``` + +- *Type:* Display + +Information on how to display a resource in the UI. + +--- + +### ITestHandlerClient + +- *Implemented By:* ITestHandlerClient + +Inflight client for `ITestHandler`. + +#### Methods + +| **Name** | **Description** | +| --- | --- | +| handle | Inflight function that will be called when the test is run. | + +--- + +##### `handle` + +```wing +handle(): void +``` + +**Inflight client:** [true](#true) + +Inflight function that will be called when the test is run. + + +## Enums + +### Direction + +The direction of a connection. + +Visually speaking, if a resource A has an outbound connection with resource B, +the arrow would point from A to B, and vice versa for inbound connections. + +#### Members + +| **Name** | **Description** | +| --- | --- | +| OUTBOUND | Indicates that this resource calls, triggers, or references the resource it is connected to. | +| INBOUND | Indicates that this resource is called, triggered, or referenced by the resource it is connected to. | + +--- + +##### `OUTBOUND` + +Indicates that this resource calls, triggers, or references the resource it is connected to. + +--- + + +##### `INBOUND` + +Indicates that this resource is called, triggered, or referenced by the resource it is connected to. + +--- + diff --git a/docs/docs/04-standard-library/03-http/_category_.yml b/docs/docs/04-standard-library/03-http/_category_.yml new file mode 100644 index 00000000000..7109e454139 --- /dev/null +++ b/docs/docs/04-standard-library/03-http/_category_.yml @@ -0,0 +1,3 @@ +label: HTTP +collapsible: true +collapsed: true diff --git a/docs/docs/04-standard-library/03-http/api-reference.md b/docs/docs/04-standard-library/03-http/api-reference.md new file mode 100644 index 00000000000..c12bdab297c --- /dev/null +++ b/docs/docs/04-standard-library/03-http/api-reference.md @@ -0,0 +1,535 @@ +--- +title: API reference +id: api-reference +description: Wing standard library API reference for the http module +keywords: [Wing sdk, sdk, Wing API Reference] +hide_title: true +sidebar_position: 100 +--- + + + +# API Reference + + +## Structs + +### RequestOptions + +An object containing any custom settings that you want to apply to the request. + +#### Initializer + +```wing +bring http; + +let RequestOptions = http.RequestOptions{ ... } +``` + +#### Properties + +| **Name** | **Type** | **Description** | +| --- | --- | --- | +| body | str | Any body that you want to add to your request. | +| cache | RequestCache | The cache mode you want to use for the request. | +| headers | MutMap<str> | Any headers you want to add to your request. | +| method | HttpMethod | The request method, e.g., GET, POST. The default is GET. | +| redirect | RequestRedirect | he redirect mode to use: follow, error. | +| referrer | str | A string specifying "no-referrer", client, or a URL. | + +--- + +##### `body`Optional + +```wing +body: str; +``` + +- *Type:* str + +Any body that you want to add to your request. + +Note that a request using the GET or HEAD method cannot have a body. + +--- + +##### `cache`Optional + +```wing +cache: RequestCache; +``` + +- *Type:* RequestCache + +The cache mode you want to use for the request. + +--- + +##### `headers`Optional + +```wing +headers: MutMap; +``` + +- *Type:* MutMap<str> + +Any headers you want to add to your request. + +--- + +##### `method`Optional + +```wing +method: HttpMethod; +``` + +- *Type:* HttpMethod +- *Default:* GET + +The request method, e.g., GET, POST. The default is GET. + +--- + +##### `redirect`Optional + +```wing +redirect: RequestRedirect; +``` + +- *Type:* RequestRedirect +- *Default:* follow + +he redirect mode to use: follow, error. + +The default is follow. + +--- + +##### `referrer`Optional + +```wing +referrer: str; +``` + +- *Type:* str +- *Default:* about:client + +A string specifying "no-referrer", client, or a URL. + +The default is "about:client". + +--- + +### Response + +Represents the response to a request. + +#### Initializer + +```wing +bring http; + +let Response = http.Response{ ... } +``` + +#### Properties + +| **Name** | **Type** | **Description** | +| --- | --- | --- | +| headers | MutMap<str> | The map of header information associated with the response. | +| ok | bool | A boolean indicating whether the response was successful (status in the range 200 โ€“ 299) or not. | +| status | num | The status code of the response. | +| url | str | The URL of the response. | +| body | str | A string represents the body contents. | + +--- + +##### `headers`Required + +```wing +headers: MutMap; +``` + +- *Type:* MutMap<str> + +The map of header information associated with the response. + +--- + +##### `ok`Required + +```wing +ok: bool; +``` + +- *Type:* bool + +A boolean indicating whether the response was successful (status in the range 200 โ€“ 299) or not. + +--- + +##### `status`Required + +```wing +status: num; +``` + +- *Type:* num + +The status code of the response. + +(This will be 200 for a success). + +--- + +##### `url`Required + +```wing +url: str; +``` + +- *Type:* str + +The URL of the response. + +--- + +##### `body`Optional + +```wing +body: str; +``` + +- *Type:* str + +A string represents the body contents. + +--- + +## Classes + +### Util + +**Inflight client:** [true](#true) + +the Http class is used for calling different HTTP methods and requesting and sending information online, as well as testing public accessible resources. + +#### Initializers + +```wing +bring http; + +new http.Util() +``` + +| **Name** | **Type** | **Description** | +| --- | --- | --- | + +--- + + +#### Static Functions + +| **Name** | **Description** | +| --- | --- | +| delete | Sends a DELETE request. | +| fetch | Sends an HTTP request to a URL, returning a fulfilled or failed response. | +| get | Sends a GET request. | +| patch | Sends a PATCH request. | +| post | Sends a POST request. | +| put | Sends a PUT request. | + +--- + +##### `delete` + +```wing +bring http; + +http.Util.delete(url: str, options?: RequestOptions) +``` + +**Inflight client:** [true](#true) + +Sends a DELETE request. + +###### `url`Required + +- *Type:* str + +--- + +###### `options`Optional + +- *Type:* RequestOptions + +--- + +##### `fetch` + +```wing +bring http; + +http.Util.fetch(url: str, options?: RequestOptions) +``` + +**Inflight client:** [true](#true) + +Sends an HTTP request to a URL, returning a fulfilled or failed response. + +###### `url`Required + +- *Type:* str + +--- + +###### `options`Optional + +- *Type:* RequestOptions + +--- + +##### `get` + +```wing +bring http; + +http.Util.get(url: str, options?: RequestOptions) +``` + +**Inflight client:** [true](#true) + +Sends a GET request. + +###### `url`Required + +- *Type:* str + +--- + +###### `options`Optional + +- *Type:* RequestOptions + +--- + +##### `patch` + +```wing +bring http; + +http.Util.patch(url: str, options?: RequestOptions) +``` + +**Inflight client:** [true](#true) + +Sends a PATCH request. + +###### `url`Required + +- *Type:* str + +--- + +###### `options`Optional + +- *Type:* RequestOptions + +--- + +##### `post` + +```wing +bring http; + +http.Util.post(url: str, options?: RequestOptions) +``` + +**Inflight client:** [true](#true) + +Sends a POST request. + +###### `url`Required + +- *Type:* str + +--- + +###### `options`Optional + +- *Type:* RequestOptions + +--- + +##### `put` + +```wing +bring http; + +http.Util.put(url: str, options?: RequestOptions) +``` + +**Inflight client:** [true](#true) + +Sends a PUT request. + +###### `url`Required + +- *Type:* str + +--- + +###### `options`Optional + +- *Type:* RequestOptions + +--- + + + + +## Enums + +### HttpMethod + +The request's method. + +#### Members + +| **Name** | **Description** | +| --- | --- | +| GET | GET. | +| PUT | PUT. | +| DELETE | DELETE. | +| PATCH | PATCH. | +| POST | POST. | + +--- + +##### `GET` + +GET. + +--- + + +##### `PUT` + +PUT. + +--- + + +##### `DELETE` + +DELETE. + +--- + + +##### `PATCH` + +PATCH. + +--- + + +##### `POST` + +POST. + +--- + + +### RequestCache + +The cache mode of the request. + +It controls how a request will interact with the system's HTTP cache. + +#### Members + +| **Name** | **Description** | +| --- | --- | +| DEFAULT | The runtime environment looks for a matching request in its HTTP cache. | +| NO_STORE | The runtime environment fetches the resource from the remote server without first looking in the cache, and will not update the cache with the downloaded resource. | +| RELOAD | The runtime environment fetches the resource from the remote server without first looking in the cache, but then will update the cache with the downloaded resource. | +| NO_CACHE | The runtime environment looks for a matching request in its HTTP cache. | +| FORCE_CACHE | The runtime environment looks for a matching request in its HTTP cache. | + +--- + +##### `DEFAULT` + +The runtime environment looks for a matching request in its HTTP cache. + +* If there is a match and it is fresh, it will be returned from the cache. +* If there is a match but it is stale, the runtime environment will make a conditional request to the remote server. +* If the server indicates that the resource has not changed, it will be returned from the cache. +* Otherwise the resource will be downloaded from the server and the cache will be updated. +* If there is no match, the runtime environment will make a normal request, and will update the cache with the downloaded resource. + +--- + + +##### `NO_STORE` + +The runtime environment fetches the resource from the remote server without first looking in the cache, and will not update the cache with the downloaded resource. + +--- + + +##### `RELOAD` + +The runtime environment fetches the resource from the remote server without first looking in the cache, but then will update the cache with the downloaded resource. + +--- + + +##### `NO_CACHE` + +The runtime environment looks for a matching request in its HTTP cache. + +* If there is a match, fresh or stale, the runtime environment will make a conditional request to the remote server. +* If the server indicates that the resource has not changed, it will be returned from the cache. Otherwise the resource will be downloaded from the server and the cache will be updated. +* If there is no match, the runtime environment will make a normal request, and will update the cache with the downloaded resource. + +--- + + +##### `FORCE_CACHE` + +The runtime environment looks for a matching request in its HTTP cache. + +* If there is a match, fresh or stale, it will be returned from the cache. +* If there is no match, the runtime environment will make a normal request, and will update the cache with the downloaded resource. + +--- + + +### RequestRedirect + +The redirect read-only property that contains the mode for how redirects are handled. + +#### Members + +| **Name** | **Description** | +| --- | --- | +| FOLLOW | Follow all redirects incurred when fetching a resource. | +| ERROR | Return a network error when a request is met with a redirect. | + +--- + +##### `FOLLOW` + +Follow all redirects incurred when fetching a resource. + +--- + + +##### `ERROR` + +Return a network error when a request is met with a redirect. + +--- + diff --git a/docs/docs/04-standard-library/04-util/_category_.yml b/docs/docs/04-standard-library/04-util/_category_.yml new file mode 100644 index 00000000000..f67075442ba --- /dev/null +++ b/docs/docs/04-standard-library/04-util/_category_.yml @@ -0,0 +1,3 @@ +label: Utilities +collapsible: true +collapsed: true \ No newline at end of file diff --git a/docs/docs/04-standard-library/04-util/api-reference.md b/docs/docs/04-standard-library/04-util/api-reference.md new file mode 100644 index 00000000000..84eb5c89662 --- /dev/null +++ b/docs/docs/04-standard-library/04-util/api-reference.md @@ -0,0 +1,255 @@ +--- +title: API reference +id: api-reference +description: Wing standard library API reference for the util module +keywords: [Wing sdk, sdk, Wing API Reference] +hide_title: true +sidebar_position: 100 +--- + + + +# API Reference + + +## Structs + +### WaitUntilProps + +Properties for `util.waitUntil`. + +#### Initializer + +```wing +bring util; + +let WaitUntilProps = util.WaitUntilProps{ ... } +``` + +#### Properties + +| **Name** | **Type** | **Description** | +| --- | --- | --- | +| interval | Duration | Interval between predicate retries. | +| timeout | Duration | The timeout for keep trying predicate. | + +--- + +##### `interval`Optional + +```wing +interval: Duration; +``` + +- *Type:* Duration +- *Default:* 0.1s + +Interval between predicate retries. + +--- + +##### `timeout`Optional + +```wing +timeout: Duration; +``` + +- *Type:* Duration +- *Default:* 1m + +The timeout for keep trying predicate. + +--- + +## Classes + +### Util + +Utility functions. + +#### Initializers + +```wing +bring util; + +new util.Util() +``` + +| **Name** | **Type** | **Description** | +| --- | --- | --- | + +--- + + +#### Static Functions + +| **Name** | **Description** | +| --- | --- | +| env | Returns the value of an environment variable. | +| sleep | Suspends execution for a given duration. | +| tryEnv | Returns the value of an environment variable. | +| waitUntil | Run a predicate repeatedly, waiting until it returns true or until the timeout elapses. | + +--- + +##### `env` + +```wing +bring util; + +util.Util.env(name: str) +``` + +Returns the value of an environment variable. + +Throws if not found or empty. + +###### `name`Required + +- *Type:* str + +The name of the environment variable. + +--- + +##### `sleep` + +```wing +bring util; + +util.Util.sleep(delay: Duration) +``` + +**Inflight client:** [true](#true) + +Suspends execution for a given duration. + +###### `delay`Required + +- *Type:* Duration + +The time to suspend execution. + +--- + +##### `tryEnv` + +```wing +bring util; + +util.Util.tryEnv(name: str) +``` + +Returns the value of an environment variable. + +Returns `nil` if not found or empty. + +###### `name`Required + +- *Type:* str + +The name of the environment variable. + +--- + +##### `waitUntil` + +```wing +bring util; + +util.Util.waitUntil(predicate: IPredicateHandler, props?: WaitUntilProps) +``` + +**Inflight client:** [true](#true) + +Run a predicate repeatedly, waiting until it returns true or until the timeout elapses. + +###### `predicate`Required + +- *Type:* IPredicateHandler + +The function that will be evaluated. + +--- + +###### `props`Optional + +- *Type:* WaitUntilProps + +Timeout and interval values, default to one 1m timeout and 0.1sec interval. + +--- + + + +## Protocols + +### IPredicateHandler + +- *Extends:* IResource + +- *Implemented By:* IPredicateHandler + +**Inflight client:** [@winglang/sdk.util.IPredicateHandlerClient](#@winglang/sdk.util.IPredicateHandlerClient) + +Represents a predicate with an inflight "handle" method that can be passed to `util.busyWait`. + + +#### Properties + +| **Name** | **Type** | **Description** | +| --- | --- | --- | +| node | constructs.Node | The tree node. | +| display | Display | Information on how to display a resource in the UI. | + +--- + +##### `node`Required + +```wing +node: Node; +``` + +- *Type:* constructs.Node + +The tree node. + +--- + +##### `display`Required + +```wing +display: Display; +``` + +- *Type:* Display + +Information on how to display a resource in the UI. + +--- + +### IPredicateHandlerClient + +- *Implemented By:* IPredicateHandlerClient + +Inflight client for `IPredicateHandler`. + +#### Methods + +| **Name** | **Description** | +| --- | --- | +| handle | The Predicate function that is called. | + +--- + +##### `handle` + +```wing +handle(): bool +``` + +**Inflight client:** [true](#true) + +The Predicate function that is called. + + diff --git a/docs/docs/04-standard-library/05-redis/_category_.yml b/docs/docs/04-standard-library/05-redis/_category_.yml new file mode 100644 index 00000000000..72414db5a8d --- /dev/null +++ b/docs/docs/04-standard-library/05-redis/_category_.yml @@ -0,0 +1,3 @@ +label: Redis +collapsible: true +collapsed: true diff --git a/docs/docs/04-standard-library/05-redis/api-reference.md b/docs/docs/04-standard-library/05-redis/api-reference.md new file mode 100644 index 00000000000..b6390a8df90 --- /dev/null +++ b/docs/docs/04-standard-library/05-redis/api-reference.md @@ -0,0 +1,466 @@ +--- +title: API reference +id: api-reference +description: Wing standard library API reference for the redis module +keywords: [Wing sdk, sdk, Wing API Reference] +hide_title: true +sidebar_position: 100 +--- + + + +# API Reference + +## Resources + +### Redis + +**Inflight client:** [@winglang/sdk.redis.IRedisClient](#@winglang/sdk.redis.IRedisClient) + +Represents a cloud redis db. + +#### Initializers + +```wing +bring redis; + +new redis.Redis() +``` + +| **Name** | **Type** | **Description** | +| --- | --- | --- | + +--- + + + +#### Properties + +| **Name** | **Type** | **Description** | +| --- | --- | --- | +| node | constructs.Node | The tree node. | +| display | Display | Information on how to display a resource in the UI. | + +--- + +##### `node`Required + +```wing +node: Node; +``` + +- *Type:* constructs.Node + +The tree node. + +--- + +##### `display`Required + +```wing +display: Display; +``` + +- *Type:* Display + +Information on how to display a resource in the UI. + +--- + + + +## Classes + +### RedisClientBase + +- *Implements:* IRedisClient + +Base class for `Redis` Client. + +#### Initializers + +```wing +bring redis; + +new redis.RedisClientBase() +``` + +| **Name** | **Type** | **Description** | +| --- | --- | --- | + +--- + +#### Methods + +| **Name** | **Description** | +| --- | --- | +| del | Removes the specified key. | +| get | Get value at given key. | +| hget | Returns the value associated with field in the hash stored at key. | +| hset | Sets the specified field to respective value in the hash stored at key. | +| rawClient | Get raw redis client (currently IoRedis). | +| sadd | Add the specified members to the set stored at key. | +| set | Set key value pair. | +| smembers | Returns all the members of the set value stored at key. | +| url | Get url of redis server. | + +--- + +##### `del` + +```wing +del(key: str): num +``` + +Removes the specified key. + +###### `key`Required + +- *Type:* str + +--- + +##### `get` + +```wing +get(key: str): str +``` + +Get value at given key. + +###### `key`Required + +- *Type:* str + +--- + +##### `hget` + +```wing +hget(key: str, field: str): str +``` + +Returns the value associated with field in the hash stored at key. + +###### `key`Required + +- *Type:* str + +--- + +###### `field`Required + +- *Type:* str + +--- + +##### `hset` + +```wing +hset(key: str, field: str, value: str): num +``` + +Sets the specified field to respective value in the hash stored at key. + +###### `key`Required + +- *Type:* str + +--- + +###### `field`Required + +- *Type:* str + +--- + +###### `value`Required + +- *Type:* str + +--- + +##### `rawClient` + +```wing +rawClient(): any +``` + +Get raw redis client (currently IoRedis). + +##### `sadd` + +```wing +sadd(key: str, value: str): num +``` + +Add the specified members to the set stored at key. + +###### `key`Required + +- *Type:* str + +--- + +###### `value`Required + +- *Type:* str + +--- + +##### `set` + +```wing +set(key: str, value: str): void +``` + +Set key value pair. + +###### `key`Required + +- *Type:* str + +--- + +###### `value`Required + +- *Type:* str + +--- + +##### `smembers` + +```wing +smembers(key: str): MutArray +``` + +Returns all the members of the set value stored at key. + +###### `key`Required + +- *Type:* str + +--- + +##### `url` + +```wing +url(): str +``` + +Get url of redis server. + + + + +## Protocols + +### IRedisClient + +- *Implemented By:* RedisClientBase, IRedisClient + +Inflight interface for `Redis`. + +#### Methods + +| **Name** | **Description** | +| --- | --- | +| del | Removes the specified key. | +| get | Get value at given key. | +| hget | Returns the value associated with field in the hash stored at key. | +| hset | Sets the specified field to respective value in the hash stored at key. | +| rawClient | Get raw redis client (currently IoRedis). | +| sadd | Add the specified members to the set stored at key. | +| set | Set key value pair. | +| smembers | Returns all the members of the set value stored at key. | +| url | Get url of redis server. | + +--- + +##### `del` + +```wing +del(key: str): num +``` + +**Inflight client:** [true](#true) + +Removes the specified key. + +###### `key`Required + +- *Type:* str + +the key. + +--- + +##### `get` + +```wing +get(key: str): str +``` + +**Inflight client:** [true](#true) + +Get value at given key. + +###### `key`Required + +- *Type:* str + +the key to get. + +--- + +##### `hget` + +```wing +hget(key: str, field: str): str +``` + +**Inflight client:** [true](#true) + +Returns the value associated with field in the hash stored at key. + +###### `key`Required + +- *Type:* str + +the key. + +--- + +###### `field`Required + +- *Type:* str + +the field at given key. + +--- + +##### `hset` + +```wing +hset(key: str, field: str, value: str): num +``` + +**Inflight client:** [true](#true) + +Sets the specified field to respective value in the hash stored at key. + +###### `key`Required + +- *Type:* str + +key to set. + +--- + +###### `field`Required + +- *Type:* str + +field in key to set. + +--- + +###### `value`Required + +- *Type:* str + +value to set at field in key. + +--- + +##### `rawClient` + +```wing +rawClient(): any +``` + +**Inflight client:** [true](#true) + +Get raw redis client (currently IoRedis). + +##### `sadd` + +```wing +sadd(key: str, value: str): num +``` + +**Inflight client:** [true](#true) + +Add the specified members to the set stored at key. + +###### `key`Required + +- *Type:* str + +the key. + +--- + +###### `value`Required + +- *Type:* str + +the value to add to the set at given key. + +--- + +##### `set` + +```wing +set(key: str, value: str): void +``` + +**Inflight client:** [true](#true) + +Set key value pair. + +###### `key`Required + +- *Type:* str + +the key to set. + +--- + +###### `value`Required + +- *Type:* str + +the value to store at given key. + +--- + +##### `smembers` + +```wing +smembers(key: str): MutArray +``` + +**Inflight client:** [true](#true) + +Returns all the members of the set value stored at key. + +###### `key`Required + +- *Type:* str + +the key. + +--- + +##### `url` + +```wing +url(): str +``` + +**Inflight client:** [true](#true) + +Get url of redis server. + + diff --git a/docs/04-standard-library/03-winglang_support_metrix.mdx b/docs/docs/04-standard-library/80-winglang_support_metrix.mdx similarity index 100% rename from docs/04-standard-library/03-winglang_support_metrix.mdx rename to docs/docs/04-standard-library/80-winglang_support_metrix.mdx diff --git a/docs/04-standard-library/_category_.yml b/docs/docs/04-standard-library/_category_.yml similarity index 71% rename from docs/04-standard-library/_category_.yml rename to docs/docs/04-standard-library/_category_.yml index 4e29447b639..87e048e9321 100644 --- a/docs/04-standard-library/_category_.yml +++ b/docs/docs/04-standard-library/_category_.yml @@ -1,3 +1,3 @@ label: Standard library collapsible: true -collapsed: false +collapsed: true diff --git a/docs/04-standard-library/compatibility/compatibility-table.jsx b/docs/docs/04-standard-library/compatibility/compatibility-table.jsx similarity index 97% rename from docs/04-standard-library/compatibility/compatibility-table.jsx rename to docs/docs/04-standard-library/compatibility/compatibility-table.jsx index 1ed930e7c07..199aa897c97 100644 --- a/docs/04-standard-library/compatibility/compatibility-table.jsx +++ b/docs/docs/04-standard-library/compatibility/compatibility-table.jsx @@ -50,7 +50,7 @@ export const Table = () => { {index === 0 && ( - + {item} diff --git a/docs/04-standard-library/compatibility/compatibility.json b/docs/docs/04-standard-library/compatibility/compatibility.json similarity index 96% rename from docs/04-standard-library/compatibility/compatibility.json rename to docs/docs/04-standard-library/compatibility/compatibility.json index 453afc89b8d..3261199c7d9 100644 --- a/docs/04-standard-library/compatibility/compatibility.json +++ b/docs/docs/04-standard-library/compatibility/compatibility.json @@ -14,35 +14,35 @@ "tf-gcp": {"implemented": false}, "aws-cdk": {"implemented": true} }, - "on_upload": { + "onUpload": { "sim": {"implemented": true}, "tf-aws": {"implemented": true}, "tf-azure": {"implemented": false, "issue": 1954}, "tf-gcp": {"implemented": false}, - "aws-cdk": {"implemented": false} + "aws-cdk": {"implemented": true} }, - "on_delete": { + "onDelete": { "sim": {"implemented": true}, "tf-aws": {"implemented": true}, "tf-azure": {"implemented": false, "issue": 1954}, "tf-gcp": {"implemented": false}, - "aws-cdk": {"implemented": false} + "aws-cdk": {"implemented": true} }, - "on_update": { + "onUpdate": { "sim": {"implemented": true}, "tf-aws": {"implemented": true}, "tf-azure": {"implemented": false, "issue": 1954}, "tf-gcp": {"implemented": false}, - "aws-cdk": {"implemented": false} + "aws-cdk": {"implemented": true} }, - "on_event": { + "onEvent": { "sim": {"implemented": true}, "tf-aws": {"implemented": true}, "tf-azure": {"implemented": false, "issue": 1954}, "tf-gcp": {"implemented": false}, - "aws-cdk": {"implemented": false} + "aws-cdk": {"implemented": true} }, - "add_object": { + "addObject": { "sim": {"implemented": true}, "tf-aws": {"implemented": true}, "tf-azure": {"implemented": true}, @@ -56,7 +56,7 @@ "tf-gcp": {"implemented": false, "issue": 1282}, "aws-cdk": {"implemented": true} }, - "put_json": { + "putJson": { "sim": {"implemented": true}, "tf-aws": {"implemented": true}, "tf-azure": {"implemented": true}, @@ -70,21 +70,21 @@ "tf-gcp": {"implemented": false, "issue": 1282}, "aws-cdk": {"implemented": true} }, - "try_get": { + "tryGet": { "sim": {"implemented": true}, "tf-aws": {"implemented": true}, "tf-azure": {"implemented": true}, "tf-gcp": {"implemented": false}, "aws-cdk": {"implemented": false} }, - "get_json": { + "getJson": { "sim": {"implemented": true}, "tf-aws": {"implemented": true}, "tf-azure": {"implemented": true}, "tf-gcp": {"implemented": false}, "aws-cdk": {"implemented": false} }, - "try_get_json": { + "tryGetJson": { "sim": {"implemented": true}, "tf-aws": {"implemented": true}, "tf-azure": {"implemented": true}, @@ -98,7 +98,7 @@ "tf-gcp": {"implemented": false, "issue": 1282}, "aws-cdk": {"implemented": true} }, - "try_delete": { + "tryDelete": { "sim": {"implemented": true}, "tf-aws": {"implemented": true}, "tf-azure": {"implemented": true}, @@ -140,14 +140,14 @@ "tf-gcp": {"implemented": false}, "aws-cdk": {"implemented": true} }, - "public_url": { + "publicUrl": { "sim": {"implemented": true}, "tf-aws": {"implemented": true}, "tf-azure": {"implemented": false, "issue": 1805}, "tf-gcp": {"implemented": false, "issue": 1282}, "aws-cdk": {"implemented": true} }, - "signed_url": { + "signedUrl": { "sim": {"implemented": false, "issue": 1383}, "tf-aws": {"implemented": false, "issue": 1383}, "tf-azure": {"implemented": false}, @@ -184,14 +184,14 @@ "tf-gcp": {"implemented": false}, "aws-cdk": {"implemented": true} }, - "add_consumer": { + "setConsumer": { "sim": {"implemented": true}, "tf-aws": {"implemented": true}, "tf-azure": {"implemented": false}, "tf-gcp": {"implemented": false}, "aws-cdk": {"implemented": true} }, - "approx_size": { + "approxSize": { "sim": {"implemented": true}, "tf-aws": {"implemented": true}, "tf-azure": {"implemented": false}, @@ -270,7 +270,7 @@ "tf-gcp": {"implemented": false}, "aws-cdk": {"implemented": false} }, - "add_env": { + "addEnv": { "sim": {"implemented": false}, "tf-aws": {"implemented": false}, "tf-azure": {"implemented": false}, @@ -284,7 +284,7 @@ "tf-gcp": {"implemented": false, "issue": 614}, "aws-cdk": {"implemented": true} }, - "invoke_async": { + "invokeAsync": { "sim": {"implemented": false}, "tf-aws": {"implemented": false}, "tf-azure": {"implemented": false}, @@ -337,7 +337,7 @@ "tf-gcp": {"implemented": false, "issue": 620}, "aws-cdk": {"implemented": true} }, - "on_message": { + "onMessage": { "sim": {"implemented": true}, "tf-aws": {"implemented": true}, "tf-azure": {"implemented": false, "issue": 621}, @@ -346,21 +346,21 @@ } }, "Schedule": { - "from_cron": { + "fromCron": { "sim": {"implemented": false}, "tf-aws": {"implemented": false}, "tf-azure": {"implemented": false, "issue": 1291}, "tf-gcp": {"implemented": false, "issue": 1292}, "aws-cdk": {"implemented": false} }, - "from_rate": { + "fromRate": { "sim": {"implemented": false}, "tf-aws": {"implemented": false}, "tf-azure": {"implemented": false, "issue": 1291}, "tf-gcp": {"implemented": false, "issue": 1292}, "aws-cdk": {"implemented": false} }, - "on_tick": { + "onTick": { "sim": {"implemented": true}, "tf-aws": {"implemented": true}, "tf-azure": {"implemented": false, "issue": 1291}, @@ -486,7 +486,7 @@ "tf-gcp": {"implemented": false, "issue": 2179}, "aws-cdk": {"implemented": true} }, - "SecretProps.value_json": { + "SecretProps.valueJson": { "sim": {"implemented": true}, "tf-aws": {"implemented": true}, "tf-azure": {"implemented": false, "issue": 2178}, @@ -495,7 +495,7 @@ } }, "Service": { - "ServiceProps.buildpack_path": { + "ServiceProps.buildpackPath": { "sim": {"implemented": false, "issue": 1305}, "tf-aws": {"implemented": false, "issue": 1306}, "tf-azure": {"implemented": false, "issue": 1307}, @@ -544,7 +544,7 @@ "tf-gcp": {"implemented": false, "issue": 1308}, "aws-cdk": {"implemented": false} }, - "buildpack_path": { + "buildpackPath": { "sim": {"implemented": false, "issue": 1305}, "tf-aws": {"implemented": false, "issue": 1306}, "tf-azure": {"implemented": false, "issue": 1307}, @@ -586,7 +586,7 @@ "tf-gcp": {"implemented": false, "issue": 1308}, "aws-cdk": {"implemented": false} }, - "add_env": { + "addEnv": { "sim": {"implemented": false, "issue": 1305}, "tf-aws": {"implemented": false, "issue": 1306}, "tf-azure": {"implemented": false, "issue": 1307}, @@ -616,7 +616,7 @@ "tf-gcp": {"implemented": false, "issue": 1316}, "aws-cdk": {"implemented": false} }, - "TableProps.primary_key": { + "TableProps.primaryKey": { "sim": {"implemented": true}, "tf-aws": {"implemented": true}, "tf-azure": {"implemented": false, "issue": 1315}, @@ -637,13 +637,20 @@ "tf-gcp": {"implemented": false, "issue": 1316}, "aws-cdk": {"implemented": false} }, - "primary_key": { + "primaryKey": { "sim": {"implemented": true}, "tf-aws": {"implemented": true}, "tf-azure": {"implemented": false, "issue": 1315}, "tf-gcp": {"implemented": false, "issue": 1316}, "aws-cdk": {"implemented": false} }, + "addRow": { + "sim": {"implemented": true}, + "tf-aws": {"implemented": true}, + "tf-azure": {"implemented": false}, + "tf-gcp": {"implemented": false}, + "aws-cdk": {"implemented": false} + }, "insert": { "sim": {"implemented": true}, "tf-aws": {"implemented": true}, diff --git a/docs/04-standard-library/compatibility/style.css b/docs/docs/04-standard-library/compatibility/style.css similarity index 100% rename from docs/04-standard-library/compatibility/style.css rename to docs/docs/04-standard-library/compatibility/style.css diff --git a/docs/05-wing-console/01-installation.md b/docs/docs/05-wing-console/01-installation.md similarity index 100% rename from docs/05-wing-console/01-installation.md rename to docs/docs/05-wing-console/01-installation.md diff --git a/docs/05-wing-console/02-navigation.md b/docs/docs/05-wing-console/02-navigation.md similarity index 100% rename from docs/05-wing-console/02-navigation.md rename to docs/docs/05-wing-console/02-navigation.md diff --git a/docs/05-wing-console/03-interacting.md b/docs/docs/05-wing-console/03-interacting.md similarity index 100% rename from docs/05-wing-console/03-interacting.md rename to docs/docs/05-wing-console/03-interacting.md diff --git a/docs/05-wing-console/04-testing.md b/docs/docs/05-wing-console/04-testing.md similarity index 100% rename from docs/05-wing-console/04-testing.md rename to docs/docs/05-wing-console/04-testing.md diff --git a/docs/05-wing-console/05-logging.md b/docs/docs/05-wing-console/05-logging.md similarity index 100% rename from docs/05-wing-console/05-logging.md rename to docs/docs/05-wing-console/05-logging.md diff --git a/docs/05-wing-console/_category_.yml b/docs/docs/05-wing-console/_category_.yml similarity index 69% rename from docs/05-wing-console/_category_.yml rename to docs/docs/05-wing-console/_category_.yml index 5950799b4f7..e9dbfe5523a 100644 --- a/docs/05-wing-console/_category_.yml +++ b/docs/docs/05-wing-console/_category_.yml @@ -1,3 +1,3 @@ label: Wing Console collapsible: true -collapsed: false +collapsed: true diff --git a/docs/06-reference/01-cli.md b/docs/docs/06-tools/01-cli.md similarity index 100% rename from docs/06-reference/01-cli.md rename to docs/docs/06-tools/01-cli.md diff --git a/docs/06-reference/03-plugins.md b/docs/docs/06-tools/02-plugins.md similarity index 100% rename from docs/06-reference/03-plugins.md rename to docs/docs/06-tools/02-plugins.md diff --git a/docs/docs/06-tools/_category_.yml b/docs/docs/06-tools/_category_.yml new file mode 100644 index 00000000000..6b33f4526a6 --- /dev/null +++ b/docs/docs/06-tools/_category_.yml @@ -0,0 +1,3 @@ +label: Tools +collapsible: true +collapsed: true diff --git a/docs/docs/07-examples/01-variable-declaration.md b/docs/docs/07-examples/01-variable-declaration.md new file mode 100644 index 00000000000..1380d408875 --- /dev/null +++ b/docs/docs/07-examples/01-variable-declaration.md @@ -0,0 +1,42 @@ +--- +title: Variable declaration +id: variable-declaration +keywords: [Wing example] +--- + +### Assignment + +```ts +let x = 12; +x = 77; // ERROR: x is non reassignable + +let var y = "hello"; +y = "world"; // OK (y is reassignable) +``` + +### Inferred typing +```ts playground +let x1 = 12; +let x2: num = 12; // equivalent +``` + +### Optionals +```ts playground +let var x1 = "Hello"; // type str, value "Hello" +let var x2: str = "Hello"; // same as above +let var x3: str? = "Hello"; // type str? (optional), value "Hello" +let var x4: str? = nil; // type str? (optional), value nil + +x1 = nil; // ERROR: Expected type to be "str", but got "nil" instead +x3 = nil; // OK (x3 is optional) +``` +### Scopes +```ts playground +let s = "parent"; +log(s); // prints parent +if true { + let s = "inner"; + log(s); // prints inner +} +log(s); // prints parent +``` diff --git a/docs/docs/07-examples/02-primitives.md b/docs/docs/07-examples/02-primitives.md new file mode 100644 index 00000000000..f5a65cd2ce0 --- /dev/null +++ b/docs/docs/07-examples/02-primitives.md @@ -0,0 +1,78 @@ +--- +title: Primitives +id: primitives +keywords: [Wing example] +--- + + +## Str +### Concat and Interpolate +```ts playground +let s1 = "Hello Wing String"; +log(s1); // prints Hello Wing String +let s2 = "Interpolate: ${s1}"; // string interpolation +log(s2); // prints Interpolate Hello Wing String +let s3 = "Concat: " + s1; // string concatenation +log(s3); // prints Concat: Hello Wing String +``` + +### Str methods +```ts playground +let s = "Hello to a new Wing world"; + +// lets start with split +for w in s.split(" ") { + if w.startsWith("H") { + log(w); // 'Hello' starts with H + } + if w.length > 3 && w.lowercase() == w { + log(w); // 'world' is lowercased with more then 3 chars + } + if w.contains("in") && w.endsWith("g") { + log(w); // 'Wing' has in and end with g + } + if s.indexOf(w) == 6 { + log(w); // 'to' position is 6 + } + if s.at(9) == w { + log(w); // 'a' is a single char + } + if s.substring(11,14) == w { + log(w); // 'new' position is 11-14 + } +} +``` + +## Num + +```ts playground +let n1 = 10; +log("${n1}"); // 10 + +let n2 = n1 - 10 / 10 + 1 * 10 ; // arithmetic +log("${n2}"); // 1 + +let n3 = 10 % 7; // modulo +log("${n3}"); // 3 + +let n4 = 10 \ 7; // FloorDiv +log("${n4}"); // 1 + +let n5 = 2 ** 10; // power of +log("${n5}"); // 1024 + +let n6 = (10 + 1) / (12 - 1) + (20 / 2) * 2 + 10 * 2**10 / 512 + 1; +log("${n6}"); // The meaning of the universe +``` + + +## Bool + +```ts playground +let b1 = true; +let b2 = false; + +if b1 && !b2 { + log("${b1},${b2}"); // prints true, false +} +``` \ No newline at end of file diff --git a/docs/docs/07-examples/03-functions.md b/docs/docs/07-examples/03-functions.md new file mode 100644 index 00000000000..67f40064f4b --- /dev/null +++ b/docs/docs/07-examples/03-functions.md @@ -0,0 +1,51 @@ +--- +title: Functions +id: functions-example +keywords: [Wing example] +--- + + +### Preflight function + +```ts playground +// preflight function - when declared in preflight context +let dup = (s: str, count: num): str => { + // code +}; +``` + +### Inflight functions + +Inflight functions are Wing's distributed computing primitive. They are isolated code blocks which can be packaged and executed on compute platforms in the cloud (such as containers, Lambda/Cloud Function, etc..). + +```ts playground + +let handler = inflight (message: str): void => { + // using the inflight modifier + let dup = inflight (s: str, count: num): str => { + // code + }; + // inflight modifier is not required when function is declared in inflight context + let dup = (s: str, count: num): str => { + // code + }; +}; +``` +### Struct Expansion +```ts playground +struct Options { + prefix: str?; + delim: str; +} + +let join_str = (a: Array, opts: Options):str => { + let prefix = opts.prefix ?? ""; + return prefix + a.join(opts.delim); +}; + +log(join_str(["hello", "world"], delim: ", ")); // "!hello.world" + +// also OK to pass an object +let opts = Options { delim: "/" , prefix: "!!" }; +log(join_str(["hello", "world"], opts)); // "!!hello/world"); +``` diff --git a/docs/docs/07-examples/04-flow-controls.md b/docs/docs/07-examples/04-flow-controls.md new file mode 100644 index 00000000000..0b6686b644e --- /dev/null +++ b/docs/docs/07-examples/04-flow-controls.md @@ -0,0 +1,97 @@ +--- +title: Flow controls +id: flow-controls +keywords: [Wing example] +--- + +### For in + +```ts playground +let iterable = ["a", "b", "c", "d", "e", "f", "g", "h"]; +for value in iterable { + if value == "g" { + // stoping at g + break; + } + if value == "b" { + // skipping b + continue; + } + log(value); +} +/** + * prints + a + c + d + e + f +**/ +``` + +### For through a range + +```ts playground +// print numbers from 0 to 9 +for value in 0..10 { + log("${value}"); +} +``` + +### If elif else + +```ts playground +let grade = (score: num): str => { + // Parentheses are optional in conditions. + // However, curly braces are required in `if/else` statements. + if 0 < score && score < 55 { + return "F"; + } elif 55 <= score && score < 65 { + return "C"; + } elif 65 <= score && score < 75 { + return "B"; + } elif 75 <= score && score <= 100 { + return "A"; + } else { + return "Invalid grade"; + } +}; + +log("54 is ${grade(54)}"); // 54 is F +log("62 is ${grade(62)}"); // 62 is C +log("68 is ${grade(68)}"); // 68 is B +log("99 is ${grade(99)}"); // 99 is A +log("101 is ${grade(101)}"); // 101 is Invalid grade +``` + +### While + +```ts playground +let var i = 0; +while i < 100 { + i = i + 1; + if i == 20 { + // although the while loop goes to 100, we break it at 20 + break; + } + if i % 2 == 0 { + // continue for even numbers + continue; + } + log("${i}"); +} +/** + * prints + 1 + 3 + 5 + 7 + 9 + 11 + 13 + 15 + 17 + 19 +**/ +``` + diff --git a/docs/docs/07-examples/05-optionality.md b/docs/docs/07-examples/05-optionality.md new file mode 100644 index 00000000000..40f5b5c4c8a --- /dev/null +++ b/docs/docs/07-examples/05-optionality.md @@ -0,0 +1,102 @@ +--- +title: Optionality +id: optionality +keywords: [Wing example] +--- + +## Definition + +```ts playground +let s1: str? = "Hello"; // type str? (optional), value "Hello" +let s2: str? = nil; // type str? (optional), value nil +``` + +## Testing existence +```ts playground +let s1: str? = "Hello"; // type str? (optional), value "Hello" +let s2: str? = nil; // type str? (optional), value nil + +if s1? { + log("x1 is not nil"); +} +if !s2? { + log("x2 is nil"); +} +``` + +## Using if let +```ts playground +let s1: str? = "Hello"; // type str? (optional), value "Hello" + +// unwrap optional s1 and create s from type str +if let s = s1 { + log("s is not optional, value ${s}"); +} else { + log("s1 was nil, s doesn't exists in this scope"); +} + +// same as above but shadowing s1 variable +if let s1 = s1 { + log("s1 type is str, value ${s1}"); +} else { + log("s1 was nil"); +} +log("s1 type is optional str"); +``` + +## Using ?? + +```ts playground +let s1: str? = nil; // type str? (optional), value nil +let s2 = s1 ?? "default value"; // s2 is of type str +log(s2); // prints default value +``` + +## Optional Chaining + +```ts playground +let j = Json { + working: { + a: { + b: "value" + } + }, + broken: {} +}; + +if let value = j.tryGet("working")?.tryGet("a")?.tryGet("b")?.tryAsStr() { + log("value is ${value}"); +} + +if let value = j.tryGet("broken")?.tryGet("a")?.tryGet("b")?.tryAsStr() { + // not reachable +} else { + log("value was not found"); +} +``` + +## Optional bool + +```ts playground +let b3: bool? = false; + +if b3? { + log("although b3 is false, the if statement here checks for existence of value"); +} + +if let b3 = b3 { // unboxing b3 and shadowing original b3 + if b3 { + log("b3 is true"); + } else { + log("b3 is false"); + } +} else { + log("b3 is nil"); +} + +/** + * prints: + although b3 is false, the if statement here checks for existence of value + b3 is false +**/ +``` \ No newline at end of file diff --git a/docs/docs/07-examples/06-json.md b/docs/docs/07-examples/06-json.md new file mode 100644 index 00000000000..44767a42f06 --- /dev/null +++ b/docs/docs/07-examples/06-json.md @@ -0,0 +1,118 @@ +--- +title: Json +id: json +keywords: [Wing example] +--- +## Create Json values + +### Using Json literal +```js playground +let j = Json { + k1: 1, + k2: "hello", + k3: true, + k4: { + k1: [1, "a", true, {} ] + } +}; +log("${j}"); + +let jsonStrValue = Json "Hello"; +log("${jsonStrValue}"); + +let jsonNumValue = Json 42; +log("${jsonNumValue}"); + +let jsonBoolValue = Json true; +log("${jsonBoolValue}"); + +let jsonHomogeneousArrayValue = Json ["a", "b"]; +log("${jsonHomogeneousArrayValue}"); +``` + +### From existing variables + +```js playground +let x: num = 42; +let jsonNum = Json x; +log("${j}"); // 42 + +let chars = Array["a", "b"]; +let jsonChars = Json chars; +log("${chars}"); // ["a","b"] + +let jsonComplex = Json { "first": x, "second": chars }; +log("${jsonComplex}"); // {"first": 42, "second": ["a","b"]} +``` + +### Parsing `str` +```js playground +let jsonFromParse = Json.parse("{\"k1\":\"v\"}"); +log("${jsonFromParse}"); + +if let jsonFromTryParse = Json.tryParse("{\"k1\":\"v\"}") { + log("${jsonFromTryParse}"); +} else { + log("failed to parse string to JSON"); +} +``` + +## Enumerating +### Over keys +```js playground +let j = Json { + k1: "v1", + k2: "v2" +}; +for k in Json.keys(j) { + let value = j.get(k); + log("found key ${k} with value ${value}"); +} +``` +### Over values +```js playground +let j = Json { + k1: "v1", + k2: "v2" +}; +for value in Json.values(j) { + log("found value ${value}"); +} +``` + +### Over a json array +```js playground +let arrayValue = Json ["a", "b", "c"]; +for v in Json.values(arrayValue) { + log(str.fromJson(v)); +} +``` + +## Safely convert to primitives +### To `str` +```js playground +let j = Json { + k: "hello" +}; + +log(j.get("k").asStr()); +``` + +### To `num` +```js playground +let j = Json { + k: 12 +}; +log(j.get("k").asNum()); +``` + +### To `bool` + +```js playground +let j = Json { + k:true +}; +log(j.get("k").asBool()); +``` + +Future support for converting to structs and other types: [#2188](https://github.com/winglang/wing/issues/2118) \ No newline at end of file diff --git a/docs/docs/07-examples/07-structs.md b/docs/docs/07-examples/07-structs.md new file mode 100644 index 00000000000..74d2578b068 --- /dev/null +++ b/docs/docs/07-examples/07-structs.md @@ -0,0 +1,76 @@ +--- +title: Structs +id: structs +keywords: [Wing example] +--- + +## Deceleration and Initialization + +### Required fields +```ts playground +struct Example { + a: str; + b: num; + c: bool; +} + +let example = Example { a: "a", b: 0, c: false }; +log(example.a); // prints "a" +``` + +### Optional fields +```ts playground +struct Example { + a: str?; + b: num?; + c: bool?; +} + +let example = Example { }; +if ! example.a? { + log("a is nil"); +} +``` + +### Composition +```ts playground +struct Another { + hello: str; +} + +struct MyData { + a: str; + b: num?; + c: Another; +} + +let data = MyData { + a: "hello", + c: Another { + hello: "two" + } +}; + +log(data.a); // prints hello +log(data.c.hello); // prints two +``` + + +## Struct expansion in function calls +```ts playground +struct Options { + prefix: str?; + delim: str; +} + +let join_str = (a: Array, opts: Options):str => { + let prefix = opts.prefix ?? ""; + return prefix + a.join(opts.delim); +}; + +log(join_str(["hello", "world"], delim: ", ")); // "!hello.world" + +// also OK to pass an object +let opts = Options { delim: "," }; +log(join_str(["hello", "world"], opts)); // "!!hello/world"); +``` \ No newline at end of file diff --git a/docs/docs/07-examples/08-classes.md b/docs/docs/07-examples/08-classes.md new file mode 100644 index 00000000000..1cdc696af91 --- /dev/null +++ b/docs/docs/07-examples/08-classes.md @@ -0,0 +1,156 @@ +--- +title: Classes +id: classes +keywords: [Wing example] +--- + +### Preflight class +```ts playground +bring cloud; +bring util; + +class Foo { + field1: str; // <-- readonly + var field2: num; // <-- reassignable + inflight field3: Array; + + init() { + this.field1 = "hello"; + this.field2 = 123; + } + + setField2(value: num): void { + this.field2 = value; + } + + inflight init() { + this.field3 = ["value created on inflight init"]; + log("at inflight init"); + } + + inflight doStuff() { + // all code is async and runs on the cloud + log("field3[0]='${this.field3.at(0)}'"); + util.sleep(1s); + log("done"); + } +} + +let f = new Foo(); +log("field1=${f.field1}"); +log("field2=${f.field2}"); + +new cloud.Function(inflight () => { + f.doStuff(); +}); + +``` + +### Inflight interface +```js playground +bring cloud; + +interface IProfile { + inflight name(): str; +} + +inflight class WingPerson impl IProfile { + inflight name(): str { + return "Fairy Wing"; + } +} + +let logName = inflight(profile: IProfile): void => { + log(profile.name()); +}; + +new cloud.Function(inflight () => { + logName(new WingPerson()); +}); +``` + +### Preflight interface +```ts playground +/** + * Preflight Interface + **/ +interface IKVStore extends std.IResource { // https://github.com/winglang/wing/issues/1961 + inflight get(key: str): Json; + inflight set(key: str, value: Json): void; +} + +class BucketBasedKeyValueStore impl IKVStore { + bucket: cloud.Bucket; + init() { + this.bucket = new cloud.Bucket(); + } + inflight get(key: str): Json { + return this.bucket.getJson(key); + } + inflight set(key: str, value: Json): void { + this.bucket.putJson(key, value); + } +} + +``` + +### Complete IKVStore +```js playground +bring cloud; + +interface IKVStore extends std.IResource { + inflight get(key: str): Json; + inflight set(key: str, value: Json): void; +} + +class BucketBasedKeyValueStore impl IKVStore { + bucket: cloud.Bucket; + init() { + this.bucket = new cloud.Bucket(); + } + inflight get(key: str): Json { + return this.bucket.getJson(key); + } + inflight set(key: str, value: Json): void { + this.bucket.putJson(key, value); + } +} + +class TableBasedKeyValueStore impl IKVStore { + table: cloud.Table; + init() { + this.table = new cloud.Table( + name: "table", + primaryKey: "key", + columns: { + value: cloud.ColumnType.STRING + } + ); + } + inflight get(key: str): Json { + return this.table.get(key); + } + inflight set(key: str, value: Json): str { + this.table.insert(key, value); + } +} + +let bucketBased: IKVStore = new BucketBasedKeyValueStore(); +let tableBased: IKVStore = new TableBasedKeyValueStore(); + +let testKv = inflight (kv: IKVStore):void => { + kv.set("k", Json { + value: "v" + }); + let result = kv.get("k"); + log("${result.get("value")}"); + assert("v" == str.fromJson(result.get("value"))); +}; + +new cloud.Function(inflight () => { + log("testing bucketBased KVStore"); + testKv(bucketBased); + log("testing tableBased KVStore"); + testKv(tableBased); +}); +``` \ No newline at end of file diff --git a/docs/docs/07-examples/10-using-javascript.md b/docs/docs/07-examples/10-using-javascript.md new file mode 100644 index 00000000000..8e68e9a2374 --- /dev/null +++ b/docs/docs/07-examples/10-using-javascript.md @@ -0,0 +1,66 @@ +--- +title: Using javascript +id: using-javascript +keywords: [Wing example] +--- + +These examples require a separate file named `url_utils.js` with this code: + +```js +exports.isValidUrl = function(url) { + try { + new URL(url); + return true; + } catch { + return false; + } +}; +``` + +### Preflight static function +```ts +class JsExample { + // preflight static + extern "./url_utils.js" static isValidUrl(url: str): bool; +} + +assert(JsExample.isValidUrl("http://www.google.com")); +assert(!JsExample.isValidUrl("X?Y")); +``` +### Preflight method +```ts +class JsExample { + // preflight method + extern "./url_utils.js" isValidUrl(url: str): bool; +} + +let j = new JsExample(); +assert(j.isValidUrl("http://www.google.com")); +assert(!j.isValidUrl("X?Y")); +``` + +### Inflight static +```ts +class JsExample { + // inflight static method + extern "./url_utils.js" static inflight isValidUrl(url: str): bool; +} + +test "main" { + assert(JsExample.isValidUrl("http://www.google.com")); + assert(!JsExample.isValidUrl("X?Y")); +} +``` +### Inflight method +```ts +class JsExample { + // inflight method + extern "./url_utils.js" inflight isValidUrl(url: str): bool; +} + +let j = new JsExample(); +test "main" { + assert(j.isValidUrl("http://www.google.com")); + assert(!j.isValidUrl("X?Y")); +} +``` diff --git a/docs/docs/07-examples/13-api-gateway.md b/docs/docs/07-examples/13-api-gateway.md new file mode 100644 index 00000000000..31eb1d95ff1 --- /dev/null +++ b/docs/docs/07-examples/13-api-gateway.md @@ -0,0 +1,76 @@ +--- +title: API gateway +id: api-gateway +keywords: [Wing example] +--- + +### Creating routes +```js playground +bring cloud; + +let api = new cloud.Api(); + +api.get("/", inflight (request: cloud.ApiRequest): cloud.ApiResponse => { + return cloud.ApiResponse { + status: 200, + body: "Hello GET" + }; +}); +api.post("/", inflight (request: cloud.ApiRequest): cloud.ApiResponse => { + return cloud.ApiResponse { + status: 200, + body: "Hello POST" + }; +}); +api.put("/", inflight (request: cloud.ApiRequest): cloud.ApiResponse => { + return cloud.ApiResponse { + status: 200, body: + "Hello PUT" + }; +}); +api.delete("/", inflight (request: cloud.ApiRequest): cloud.ApiResponse => { + return cloud.ApiResponse { + status: 200, + body: "Hello DELETE" + }; +}); +``` + +### Path parameters +```js playground +bring cloud; + +let api = new cloud.Api(); + +api.get("/items/{id}/{value}", inflight (req: cloud.ApiRequest): cloud.ApiResponse => { + let itemId = req.vars.get("id"); + let itemValue = req.vars.get("value"); + log("Received itemId:${itemId}, itemValue:${itemValue}"); + return cloud.ApiResponse { + status: 200, + body: "Received itemId:${itemId}, itemValue:${itemValue}" + }; +}); + +``` + +### Json body +```js playground +bring cloud; + +let api = new cloud.Api(); + +api.put("/items/{id}", inflight (req: cloud.ApiRequest): cloud.ApiResponse => { + let itemId = req.vars.get("id"); + if let itemBody = Json.tryParse(req.body ?? "") { + return cloud.ApiResponse { + status: 200, + body: "Received id ${itemId} with body ${itemBody}" + }; + } + return cloud.ApiResponse { + status: 400, + body: "Missing body" + }; +}); +``` \ No newline at end of file diff --git a/docs/docs/07-examples/99-examples-repo.md b/docs/docs/07-examples/99-examples-repo.md new file mode 100644 index 00000000000..557c77dad0c --- /dev/null +++ b/docs/docs/07-examples/99-examples-repo.md @@ -0,0 +1,7 @@ +--- +title: Examples repository +id: examples-repository +keywords: [Wing examples, samples] +--- + +Visit [github.com/winglang/examples](https://github.com/winglang/examples) for a complete list of Wing examples. diff --git a/docs/07-examples/_category_.yml b/docs/docs/07-examples/_category_.yml similarity index 66% rename from docs/07-examples/_category_.yml rename to docs/docs/07-examples/_category_.yml index 2b72c2abe7d..33750a07f6c 100644 --- a/docs/07-examples/_category_.yml +++ b/docs/docs/07-examples/_category_.yml @@ -1,3 +1,3 @@ label: Examples collapsible: true -collapsed: false +collapsed: true diff --git a/docs/docs/08-guides/02-ci-cd.md b/docs/docs/08-guides/02-ci-cd.md new file mode 100644 index 00000000000..347cf151182 --- /dev/null +++ b/docs/docs/08-guides/02-ci-cd.md @@ -0,0 +1,9 @@ +--- +title: CI/CD +id: ci-cd +keywords: [CICD, Continuous integration, Continuous deployment, Deployment, GitHub actions] +--- + +For an example of a Wing application continuously deployed to AWS using GitHub actions, check out https://github.com/winglang/gwomp. + +๐Ÿšง This guide is under construction. ๐Ÿšง diff --git a/docs/08-guides/_category_.yml b/docs/docs/08-guides/_category_.yml similarity index 65% rename from docs/08-guides/_category_.yml rename to docs/docs/08-guides/_category_.yml index aec47d16805..918a085a016 100644 --- a/docs/08-guides/_category_.yml +++ b/docs/docs/08-guides/_category_.yml @@ -1,3 +1,3 @@ label: Guides collapsible: true -collapsed: false +collapsed: true diff --git a/docs/999-faq/004-what-pains-wing-solves.md b/docs/docs/999-faq/004-what-pains-wing-solves.md similarity index 100% rename from docs/999-faq/004-what-pains-wing-solves.md rename to docs/docs/999-faq/004-what-pains-wing-solves.md diff --git a/docs/999-faq/005-why-a-language.md b/docs/docs/999-faq/005-why-a-language.md similarity index 100% rename from docs/999-faq/005-why-a-language.md rename to docs/docs/999-faq/005-why-a-language.md diff --git a/docs/999-faq/010-good-fit.md b/docs/docs/999-faq/010-good-fit.md similarity index 81% rename from docs/999-faq/010-good-fit.md rename to docs/docs/999-faq/010-good-fit.md index 3df1a183fdb..3a8eb8291e3 100644 --- a/docs/999-faq/010-good-fit.md +++ b/docs/docs/999-faq/010-good-fit.md @@ -8,15 +8,15 @@ keywords: [faq, main features, winglang, Wing programming language, Wing languag Wing was built from the ground up to make it an ideal choice for building applications on any cloud. It includes an assembly of different features that serve that purpose: -* [Cloud services](https://docs.winglang.io/concepts/resources) as first-class citizens, with [phase modifiers](https://docs.winglang.io/contributors/rfcs/language-spec#13-phase-modifiers) for config or runtime (`preflight` and `inflight`). -* Higher level of cloud abstraction with a [standard library](https://docs.winglang.io/contributors/rfcs/2023-01-20-wingsdk-spec). +* [Cloud services](https://docs.winglang.io/concepts/resources) as first-class citizens, with [phase modifiers](https://docs.winglang.io/contributing/rfcs/language-spec#13-phase-modifiers) for config or runtime (`preflight` and `inflight`). +* Higher level of cloud abstraction with a [standard library](https://docs.winglang.io/contributing/rfcs/2023-01-20-wingsdk-spec). * [Distributed computing primitives](https://docs.winglang.io/concepts/inflights). * [Compiler plugins](https://docs.winglang.io/reference/compiler-plugins) that can be used to customize the compilation output, such as infrastructure definitions. -* [JavaScript interoperability](https://docs.winglang.io/contributors/rfcs/language-spec#5-interoperability). +* [JavaScript interoperability](https://docs.winglang.io/contributing/rfcs/language-spec#5-interoperability). * Automatic generation of IAM policies and other cloud mechanics based on intent. -* [Native JSON](https://docs.winglang.io/contributors/rfcs/language-spec#114-json-type) and schema validation support. +* [Native JSON](https://docs.winglang.io/contributing/rfcs/language-spec#114-json-type) and schema validation support. * [Default immutability](https://docs.winglang.io/blog/2023/02/02/good-cognitive-friction#immutable-by-default). -* [Implicit async](https://docs.winglang.io/contributors/rfcs/language-spec#113-asynchronous-model), explicit defer. +* [Implicit async](https://docs.winglang.io/contributing/rfcs/language-spec#113-asynchronous-model), explicit defer. For a more in-depth look at Wing's features and benefits, check out our [documentation](https://docs.winglang.io/). diff --git a/docs/999-faq/012-can-we-abstract-the-cloud.md b/docs/docs/999-faq/012-can-we-abstract-the-cloud.md similarity index 100% rename from docs/999-faq/012-can-we-abstract-the-cloud.md rename to docs/docs/999-faq/012-can-we-abstract-the-cloud.md diff --git a/docs/999-faq/020-supported-clouds-services-and-engines/021-supported-clouds.md b/docs/docs/999-faq/020-supported-clouds-services-and-engines/021-supported-clouds.md similarity index 100% rename from docs/999-faq/020-supported-clouds-services-and-engines/021-supported-clouds.md rename to docs/docs/999-faq/020-supported-clouds-services-and-engines/021-supported-clouds.md diff --git a/docs/999-faq/020-supported-clouds-services-and-engines/022-supported-services.md b/docs/docs/999-faq/020-supported-clouds-services-and-engines/022-supported-services.md similarity index 100% rename from docs/999-faq/020-supported-clouds-services-and-engines/022-supported-services.md rename to docs/docs/999-faq/020-supported-clouds-services-and-engines/022-supported-services.md diff --git a/docs/999-faq/020-supported-clouds-services-and-engines/023-supported-provisioning-engines.md b/docs/docs/999-faq/020-supported-clouds-services-and-engines/023-supported-provisioning-engines.md similarity index 100% rename from docs/999-faq/020-supported-clouds-services-and-engines/023-supported-provisioning-engines.md rename to docs/docs/999-faq/020-supported-clouds-services-and-engines/023-supported-provisioning-engines.md diff --git a/docs/999-faq/020-supported-clouds-services-and-engines/025-kubernetes-support.md b/docs/docs/999-faq/020-supported-clouds-services-and-engines/025-kubernetes-support.md similarity index 100% rename from docs/999-faq/020-supported-clouds-services-and-engines/025-kubernetes-support.md rename to docs/docs/999-faq/020-supported-clouds-services-and-engines/025-kubernetes-support.md diff --git a/docs/999-faq/020-supported-clouds-services-and-engines/_category_.yml b/docs/docs/999-faq/020-supported-clouds-services-and-engines/_category_.yml similarity index 100% rename from docs/999-faq/020-supported-clouds-services-and-engines/_category_.yml rename to docs/docs/999-faq/020-supported-clouds-services-and-engines/_category_.yml diff --git a/docs/999-faq/030-who-is-behind-wing.md b/docs/docs/999-faq/030-who-is-behind-wing.md similarity index 100% rename from docs/999-faq/030-who-is-behind-wing.md rename to docs/docs/999-faq/030-who-is-behind-wing.md diff --git a/docs/999-faq/040-alternatives/041-terraform-vs-wing.md b/docs/docs/999-faq/040-alternatives/041-terraform-vs-wing.md similarity index 100% rename from docs/999-faq/040-alternatives/041-terraform-vs-wing.md rename to docs/docs/999-faq/040-alternatives/041-terraform-vs-wing.md diff --git a/docs/999-faq/040-alternatives/042-pulumi-vs-wing.md b/docs/docs/999-faq/040-alternatives/042-pulumi-vs-wing.md similarity index 100% rename from docs/999-faq/040-alternatives/042-pulumi-vs-wing.md rename to docs/docs/999-faq/040-alternatives/042-pulumi-vs-wing.md diff --git a/docs/999-faq/040-alternatives/043-awscdk-vs-wing.md b/docs/docs/999-faq/040-alternatives/043-awscdk-vs-wing.md similarity index 100% rename from docs/999-faq/040-alternatives/043-awscdk-vs-wing.md rename to docs/docs/999-faq/040-alternatives/043-awscdk-vs-wing.md diff --git a/docs/999-faq/040-alternatives/044-cdktf-vs-wing.md b/docs/docs/999-faq/040-alternatives/044-cdktf-vs-wing.md similarity index 100% rename from docs/999-faq/040-alternatives/044-cdktf-vs-wing.md rename to docs/docs/999-faq/040-alternatives/044-cdktf-vs-wing.md diff --git a/docs/999-faq/040-alternatives/047-darklang-vs-wing.md b/docs/docs/999-faq/040-alternatives/047-darklang-vs-wing.md similarity index 100% rename from docs/999-faq/040-alternatives/047-darklang-vs-wing.md rename to docs/docs/999-faq/040-alternatives/047-darklang-vs-wing.md diff --git a/docs/999-faq/040-alternatives/_category_.yml b/docs/docs/999-faq/040-alternatives/_category_.yml similarity index 100% rename from docs/999-faq/040-alternatives/_category_.yml rename to docs/docs/999-faq/040-alternatives/_category_.yml diff --git a/docs/999-faq/061-import-custom-terraform-modules.md b/docs/docs/999-faq/061-import-custom-terraform-modules.md similarity index 100% rename from docs/999-faq/061-import-custom-terraform-modules.md rename to docs/docs/999-faq/061-import-custom-terraform-modules.md diff --git a/docs/999-faq/071-state-handling.md b/docs/docs/999-faq/071-state-handling.md similarity index 100% rename from docs/999-faq/071-state-handling.md rename to docs/docs/999-faq/071-state-handling.md diff --git a/docs/999-faq/093-secrets.md b/docs/docs/999-faq/093-secrets.md similarity index 94% rename from docs/999-faq/093-secrets.md rename to docs/docs/999-faq/093-secrets.md index 8cd4b15c199..0c6031cefcd 100644 --- a/docs/999-faq/093-secrets.md +++ b/docs/docs/999-faq/093-secrets.md @@ -13,4 +13,4 @@ When the Secret resource is compiled to a cloud provider, it is provisioned usin In the future, Wing may include support for secret rotation. -You can find more info in the [SDK spec](https://docs.winglang.io/contributors/rfcs/2023-01-20-wingsdk-spec#secret). \ No newline at end of file +You can find more info in the [SDK spec](https://docs.winglang.io/contributing/rfcs/2023-01-20-wingsdk-spec#secret). \ No newline at end of file diff --git a/docs/999-faq/097-why-start-with-js-interop.md b/docs/docs/999-faq/097-why-start-with-js-interop.md similarity index 100% rename from docs/999-faq/097-why-start-with-js-interop.md rename to docs/docs/999-faq/097-why-start-with-js-interop.md diff --git a/docs/999-faq/_category_.yml b/docs/docs/999-faq/_category_.yml similarity index 100% rename from docs/999-faq/_category_.yml rename to docs/docs/999-faq/_category_.yml diff --git a/docs/999-faq/diff-interfaces.gif b/docs/docs/999-faq/diff-interfaces.gif similarity index 100% rename from docs/999-faq/diff-interfaces.gif rename to docs/docs/999-faq/diff-interfaces.gif diff --git a/docs/banner.png b/docs/docs/banner.png similarity index 100% rename from docs/banner.png rename to docs/docs/banner.png diff --git a/docs/src/components/CodeComparison.jsx b/docs/docs/src/components/CodeComparison.jsx similarity index 100% rename from docs/src/components/CodeComparison.jsx rename to docs/docs/src/components/CodeComparison.jsx diff --git a/docs/src/components/CodeComparison.module.css b/docs/docs/src/components/CodeComparison.module.css similarity index 100% rename from docs/src/components/CodeComparison.module.css rename to docs/docs/src/components/CodeComparison.module.css diff --git a/docs/src/components/FileCodeBlock.jsx b/docs/docs/src/components/FileCodeBlock.jsx similarity index 100% rename from docs/src/components/FileCodeBlock.jsx rename to docs/docs/src/components/FileCodeBlock.jsx diff --git a/docs/src/examples/function-upload-to-bucket/aws-cdk/hello.js.txt b/docs/docs/src/examples/function-upload-to-bucket/aws-cdk/hello.js.txt similarity index 100% rename from docs/src/examples/function-upload-to-bucket/aws-cdk/hello.js.txt rename to docs/docs/src/examples/function-upload-to-bucket/aws-cdk/hello.js.txt diff --git a/docs/src/examples/function-upload-to-bucket/aws-cdk/index.js.txt b/docs/docs/src/examples/function-upload-to-bucket/aws-cdk/index.js.txt similarity index 100% rename from docs/src/examples/function-upload-to-bucket/aws-cdk/index.js.txt rename to docs/docs/src/examples/function-upload-to-bucket/aws-cdk/index.js.txt diff --git a/docs/src/examples/function-upload-to-bucket/cdktf/index.js.txt b/docs/docs/src/examples/function-upload-to-bucket/cdktf/index.js.txt similarity index 100% rename from docs/src/examples/function-upload-to-bucket/cdktf/index.js.txt rename to docs/docs/src/examples/function-upload-to-bucket/cdktf/index.js.txt diff --git a/docs/src/examples/function-upload-to-bucket/cdktf/main.ts b/docs/docs/src/examples/function-upload-to-bucket/cdktf/main.ts similarity index 100% rename from docs/src/examples/function-upload-to-bucket/cdktf/main.ts rename to docs/docs/src/examples/function-upload-to-bucket/cdktf/main.ts diff --git a/docs/src/examples/function-upload-to-bucket/cloudformation/index.js.txt b/docs/docs/src/examples/function-upload-to-bucket/cloudformation/index.js.txt similarity index 100% rename from docs/src/examples/function-upload-to-bucket/cloudformation/index.js.txt rename to docs/docs/src/examples/function-upload-to-bucket/cloudformation/index.js.txt diff --git a/docs/src/examples/function-upload-to-bucket/cloudformation/template.yaml b/docs/docs/src/examples/function-upload-to-bucket/cloudformation/template.yaml similarity index 100% rename from docs/src/examples/function-upload-to-bucket/cloudformation/template.yaml rename to docs/docs/src/examples/function-upload-to-bucket/cloudformation/template.yaml diff --git a/docs/src/examples/function-upload-to-bucket/platforms.js b/docs/docs/src/examples/function-upload-to-bucket/platforms.js similarity index 100% rename from docs/src/examples/function-upload-to-bucket/platforms.js rename to docs/docs/src/examples/function-upload-to-bucket/platforms.js diff --git a/docs/src/examples/function-upload-to-bucket/pulumi/index.js.txt b/docs/docs/src/examples/function-upload-to-bucket/pulumi/index.js.txt similarity index 100% rename from docs/src/examples/function-upload-to-bucket/pulumi/index.js.txt rename to docs/docs/src/examples/function-upload-to-bucket/pulumi/index.js.txt diff --git a/docs/src/examples/function-upload-to-bucket/pulumi/main.ts b/docs/docs/src/examples/function-upload-to-bucket/pulumi/main.ts similarity index 100% rename from docs/src/examples/function-upload-to-bucket/pulumi/main.ts rename to docs/docs/src/examples/function-upload-to-bucket/pulumi/main.ts diff --git a/docs/src/examples/function-upload-to-bucket/pulumi/pulumi.yaml b/docs/docs/src/examples/function-upload-to-bucket/pulumi/pulumi.yaml similarity index 100% rename from docs/src/examples/function-upload-to-bucket/pulumi/pulumi.yaml rename to docs/docs/src/examples/function-upload-to-bucket/pulumi/pulumi.yaml diff --git a/docs/src/examples/function-upload-to-bucket/terraform/index.js.txt b/docs/docs/src/examples/function-upload-to-bucket/terraform/index.js.txt similarity index 100% rename from docs/src/examples/function-upload-to-bucket/terraform/index.js.txt rename to docs/docs/src/examples/function-upload-to-bucket/terraform/index.js.txt diff --git a/docs/src/examples/function-upload-to-bucket/terraform/main.tf b/docs/docs/src/examples/function-upload-to-bucket/terraform/main.tf similarity index 100% rename from docs/src/examples/function-upload-to-bucket/terraform/main.tf rename to docs/docs/src/examples/function-upload-to-bucket/terraform/main.tf diff --git a/docs/src/examples/function-upload-to-bucket/wing.js b/docs/docs/src/examples/function-upload-to-bucket/wing.js similarity index 100% rename from docs/src/examples/function-upload-to-bucket/wing.js rename to docs/docs/src/examples/function-upload-to-bucket/wing.js diff --git a/docs/src/examples/function-upload-to-bucket/wing/hello.w b/docs/docs/src/examples/function-upload-to-bucket/wing/hello.w similarity index 100% rename from docs/src/examples/function-upload-to-bucket/wing/hello.w rename to docs/docs/src/examples/function-upload-to-bucket/wing/hello.w diff --git a/docs/src/examples/getExamplePlatforms.js b/docs/docs/src/examples/getExamplePlatforms.js similarity index 100% rename from docs/src/examples/getExamplePlatforms.js rename to docs/docs/src/examples/getExamplePlatforms.js diff --git a/docs/src/examples/getExampleWingFile.js b/docs/docs/src/examples/getExampleWingFile.js similarity index 100% rename from docs/src/examples/getExampleWingFile.js rename to docs/docs/src/examples/getExampleWingFile.js diff --git a/docs/src/examples/pulumi/pulumi.yaml b/docs/docs/src/examples/pulumi/pulumi.yaml similarity index 100% rename from docs/src/examples/pulumi/pulumi.yaml rename to docs/docs/src/examples/pulumi/pulumi.yaml diff --git a/examples/README.md b/examples/README.md index f266dffb675..e1c0864d23d 100644 --- a/examples/README.md +++ b/examples/README.md @@ -1,6 +1,6 @@ # Wing Examples -This directory contains a collection of Wing examples of the kinds of apps you can build in Wing! Check out the [Wing Contributor's Handbook](https://docs.winglang.io/contributors/docs#%EF%B8%8F-how-do-i-add-an-example) for a guide on on how to add your own example. +This directory contains a collection of Wing examples of the kinds of apps you can build in Wing! Check out the [Wing Contributor's Handbook](https://docs.winglang.io/contributing/docs#%EF%B8%8F-how-do-i-add-an-example) for a guide on on how to add your own example. The examples in the `tests` directory are examples specifically used for testing the compiler. `tests/valid` are examples that should compile successfully, and `tests/invalid` are examples that should fail. diff --git a/examples/proposed/url-shortener.js b/examples/proposed/url-shortener.js index 5988bdada4b..13336e06069 100644 --- a/examples/proposed/url-shortener.js +++ b/examples/proposed/url-shortener.js @@ -1,5 +1,3 @@ -const fetch = require("node-fetch"); - exports.makeId = function() { let id = ""; const possible = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789"; diff --git a/examples/proposed/url-shortener.w b/examples/proposed/url-shortener.w index b220d2193a6..afb667d6fb4 100644 --- a/examples/proposed/url-shortener.w +++ b/examples/proposed/url-shortener.w @@ -1,7 +1,5 @@ bring cloud; -let EMPTY_JSON = Json "empty"; - class Utils { extern "./url-shortener.js" inflight makeId(): str; extern "./url-shortener.js" inflight fetch(url: str, method: str, body: Json?): str; @@ -73,15 +71,16 @@ class UrlShortenerApi { this.api.post("/create", inflight (req: cloud.ApiRequest): cloud.ApiResponse => { let var requestUrl = ""; try { - // TODO: use `x ?? throw()` syntax - requestUrl = str.fromJson((req.body ?? EMPTY_JSON).get("url")); + if let body = req.body { + requestUrl = str.fromJson(Json.parse(body).get("url")); + } } catch e { log(e); return cloud.ApiResponse { status: 400, - body: Json { + body: Json.stringify(Json { "error": "missing url field", - }, + }), }; } log("Generating shortened URL for ${requestUrl}"); @@ -93,9 +92,9 @@ class UrlShortenerApi { log("Shortened URL: ${shortenedUrl}"); return cloud.ApiResponse { status: 200, - body: Json { + body: Json.stringify(Json { "shortenedUrl": shortenedUrl, - }, + }), }; }); @@ -114,9 +113,9 @@ class UrlShortenerApi { } else { return cloud.ApiResponse { status: 404, - body: Json { + body: Json.stringify(Json { "error": "url not found", - }, + }), }; } }); diff --git a/examples/tests/invalid/bring_non_std_construct.w b/examples/tests/invalid/bring_non_std_construct.w new file mode 100644 index 00000000000..58488138151 --- /dev/null +++ b/examples/tests/invalid/bring_non_std_construct.w @@ -0,0 +1,18 @@ +bring "cdktf" as cdktf; + +// We want to test importing a construct that doesn't have a `scope`/`id` pair as its first arguments. +// Such constructs are technically valid but go against CDK conventions. Nonetheless we need to see +// we support them and provide correct diagnosticts when the user uses them. +// We use cdktf's backends as an example of such constructs. + +new cdktf.S3Backend(); +//^ Expected 1 positional argument(s) but got 0 + +class Foo { + init() { + new cdktf.S3Backend(this, cdktf.S3BackendConfig {bucket: "foo", key: "bar"}) as "s3_backend"; + //^ Cannot set id of non-standard preflight class "S3Backend" using `as` + new cdktf.S3Backend(this, cdktf.S3BackendConfig {bucket: "foo", key: "bar"}) in this; + //^ Cannot set scope of non-standard preflight class "S3Backend" using `in` + } +} \ No newline at end of file diff --git a/examples/tests/invalid/capture_mutables.w b/examples/tests/invalid/capture_mutables.w deleted file mode 100644 index 5ccd12c88f9..00000000000 --- a/examples/tests/invalid/capture_mutables.w +++ /dev/null @@ -1,16 +0,0 @@ -let a = MutArray["hello"]; -let s = MutSet{12}; -let m = MutMap{"hello": true}; - -let aCloned = (Array["hello"]).copyMut(); - -let i = inflight () => { - assert(a.length == 1); - // ^ Cannot reference 'a' of type 'MutArray' from an inflight context - assert(s.size == 1); - // ^ Cannot reference 's' of type 'MutSet' from an inflight context - assert(m.size() == 1); - // ^ Cannot reference 'm' of type 'MutMap' from an inflight context - assert(aCloned.length == 1); - // ^ Cannot reference 'aCloned' of type 'MutArray' from an inflight context -}; \ No newline at end of file diff --git a/examples/tests/invalid/capture_reassignable.w b/examples/tests/invalid/capture_reassignable.w deleted file mode 100644 index 8cc5b47ba6d..00000000000 --- a/examples/tests/invalid/capture_reassignable.w +++ /dev/null @@ -1,8 +0,0 @@ -bring cloud; - -let var x = 5; - -let handler = inflight (m: str): str => { - log("x: ${x}"); - // ^ error: cannot capture reassignable variable "x" -}; diff --git a/examples/tests/invalid/json.w b/examples/tests/invalid/json.w index 14c9053d2c3..0e6e8eef8ad 100644 --- a/examples/tests/invalid/json.w +++ b/examples/tests/invalid/json.w @@ -28,4 +28,13 @@ let jsonObj = Json { boom: bkt }; // ^^^ Expected "Json" elements to be Json Value (https://www.json.org/json-en.html), but got "Bucket" which is not Json Value let jsonIncomplete = Json; -// ^^^^ Expected a "Json" element \ No newline at end of file +// ^^^^ Expected a "Json" element + +let tryNum: num? = j.tryAsStr(); +// ^^^^^^^^^^^^ Expected type to be "num?", but got "str?" instead + +let tryStr: str? = j.tryAsBool(); +// ^^^^^^^^^^^^ Expected type to be "str?", but got "bool?" instead + +let tryBool: bool? = j.tryAsNum(); +// ^^^^^^^^^^^^ Expected type to be "bool?", but got "num?" instead \ No newline at end of file diff --git a/examples/tests/invalid/package-lock.json b/examples/tests/invalid/package-lock.json index 7f55eab5cac..1669cbd3112 100644 --- a/examples/tests/invalid/package-lock.json +++ b/examples/tests/invalid/package-lock.json @@ -5,9 +5,559 @@ "packages": { "": { "dependencies": { + "cdktf": "0.17.0", "jsii-code-samples": "1.7.0" } }, + "node_modules/cdktf": { + "version": "0.17.0", + "resolved": "https://registry.npmjs.org/cdktf/-/cdktf-0.17.0.tgz", + "integrity": "sha512-4R57uBLBqeb8NgfKZdn/az8UE3yXxGHyzH6Xjsz1Oo9kNvSkPibX7YqNLUpuCgdYNVgU2fdaNoHj9h4LXc6iCw==", + "bundleDependencies": [ + "archiver", + "json-stable-stringify", + "semver" + ], + "dependencies": { + "archiver": "5.3.1", + "json-stable-stringify": "^1.0.2", + "semver": "^7.3.8" + }, + "peerDependencies": { + "constructs": "^10.0.25" + } + }, + "node_modules/cdktf/node_modules/archiver": { + "version": "5.3.1", + "inBundle": true, + "license": "MIT", + "dependencies": { + "archiver-utils": "^2.1.0", + "async": "^3.2.3", + "buffer-crc32": "^0.2.1", + "readable-stream": "^3.6.0", + "readdir-glob": "^1.0.0", + "tar-stream": "^2.2.0", + "zip-stream": "^4.1.0" + }, + "engines": { + "node": ">= 10" + } + }, + "node_modules/cdktf/node_modules/archiver-utils": { + "version": "2.1.0", + "inBundle": true, + "license": "MIT", + "dependencies": { + "glob": "^7.1.4", + "graceful-fs": "^4.2.0", + "lazystream": "^1.0.0", + "lodash.defaults": "^4.2.0", + "lodash.difference": "^4.5.0", + "lodash.flatten": "^4.4.0", + "lodash.isplainobject": "^4.0.6", + "lodash.union": "^4.6.0", + "normalize-path": "^3.0.0", + "readable-stream": "^2.0.0" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/cdktf/node_modules/archiver-utils/node_modules/readable-stream": { + "version": "2.3.7", + "inBundle": true, + "license": "MIT", + "dependencies": { + "core-util-is": "~1.0.0", + "inherits": "~2.0.3", + "isarray": "~1.0.0", + "process-nextick-args": "~2.0.0", + "safe-buffer": "~5.1.1", + "string_decoder": "~1.1.1", + "util-deprecate": "~1.0.1" + } + }, + "node_modules/cdktf/node_modules/archiver-utils/node_modules/string_decoder": { + "version": "1.1.1", + "inBundle": true, + "license": "MIT", + "dependencies": { + "safe-buffer": "~5.1.0" + } + }, + "node_modules/cdktf/node_modules/async": { + "version": "3.2.4", + "inBundle": true, + "license": "MIT" + }, + "node_modules/cdktf/node_modules/balanced-match": { + "version": "1.0.2", + "inBundle": true, + "license": "MIT" + }, + "node_modules/cdktf/node_modules/base64-js": { + "version": "1.5.1", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], + "inBundle": true, + "license": "MIT" + }, + "node_modules/cdktf/node_modules/bl": { + "version": "4.1.0", + "inBundle": true, + "license": "MIT", + "dependencies": { + "buffer": "^5.5.0", + "inherits": "^2.0.4", + "readable-stream": "^3.4.0" + } + }, + "node_modules/cdktf/node_modules/brace-expansion": { + "version": "2.0.1", + "inBundle": true, + "license": "MIT", + "dependencies": { + "balanced-match": "^1.0.0" + } + }, + "node_modules/cdktf/node_modules/buffer": { + "version": "5.7.1", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], + "inBundle": true, + "license": "MIT", + "dependencies": { + "base64-js": "^1.3.1", + "ieee754": "^1.1.13" + } + }, + "node_modules/cdktf/node_modules/buffer-crc32": { + "version": "0.2.13", + "inBundle": true, + "license": "MIT", + "engines": { + "node": "*" + } + }, + "node_modules/cdktf/node_modules/compress-commons": { + "version": "4.1.1", + "inBundle": true, + "license": "MIT", + "dependencies": { + "buffer-crc32": "^0.2.13", + "crc32-stream": "^4.0.2", + "normalize-path": "^3.0.0", + "readable-stream": "^3.6.0" + }, + "engines": { + "node": ">= 10" + } + }, + "node_modules/cdktf/node_modules/concat-map": { + "version": "0.0.1", + "inBundle": true, + "license": "MIT" + }, + "node_modules/cdktf/node_modules/core-util-is": { + "version": "1.0.3", + "inBundle": true, + "license": "MIT" + }, + "node_modules/cdktf/node_modules/crc-32": { + "version": "1.2.2", + "inBundle": true, + "license": "Apache-2.0", + "bin": { + "crc32": "bin/crc32.njs" + }, + "engines": { + "node": ">=0.8" + } + }, + "node_modules/cdktf/node_modules/crc32-stream": { + "version": "4.0.2", + "inBundle": true, + "license": "MIT", + "dependencies": { + "crc-32": "^1.2.0", + "readable-stream": "^3.4.0" + }, + "engines": { + "node": ">= 10" + } + }, + "node_modules/cdktf/node_modules/end-of-stream": { + "version": "1.4.4", + "inBundle": true, + "license": "MIT", + "dependencies": { + "once": "^1.4.0" + } + }, + "node_modules/cdktf/node_modules/fs-constants": { + "version": "1.0.0", + "inBundle": true, + "license": "MIT" + }, + "node_modules/cdktf/node_modules/fs.realpath": { + "version": "1.0.0", + "inBundle": true, + "license": "ISC" + }, + "node_modules/cdktf/node_modules/glob": { + "version": "7.2.3", + "inBundle": true, + "license": "ISC", + "dependencies": { + "fs.realpath": "^1.0.0", + "inflight": "^1.0.4", + "inherits": "2", + "minimatch": "^3.1.1", + "once": "^1.3.0", + "path-is-absolute": "^1.0.0" + }, + "engines": { + "node": "*" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/cdktf/node_modules/glob/node_modules/brace-expansion": { + "version": "1.1.11", + "inBundle": true, + "license": "MIT", + "dependencies": { + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" + } + }, + "node_modules/cdktf/node_modules/glob/node_modules/minimatch": { + "version": "3.1.2", + "inBundle": true, + "license": "ISC", + "dependencies": { + "brace-expansion": "^1.1.7" + }, + "engines": { + "node": "*" + } + }, + "node_modules/cdktf/node_modules/graceful-fs": { + "version": "4.2.10", + "inBundle": true, + "license": "ISC" + }, + "node_modules/cdktf/node_modules/ieee754": { + "version": "1.2.1", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], + "inBundle": true, + "license": "BSD-3-Clause" + }, + "node_modules/cdktf/node_modules/inflight": { + "version": "1.0.6", + "inBundle": true, + "license": "ISC", + "dependencies": { + "once": "^1.3.0", + "wrappy": "1" + } + }, + "node_modules/cdktf/node_modules/inherits": { + "version": "2.0.4", + "inBundle": true, + "license": "ISC" + }, + "node_modules/cdktf/node_modules/isarray": { + "version": "1.0.0", + "inBundle": true, + "license": "MIT" + }, + "node_modules/cdktf/node_modules/json-stable-stringify": { + "version": "1.0.2", + "inBundle": true, + "license": "MIT", + "dependencies": { + "jsonify": "^0.0.1" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/cdktf/node_modules/jsonify": { + "version": "0.0.1", + "inBundle": true, + "license": "Public Domain", + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/cdktf/node_modules/lazystream": { + "version": "1.0.1", + "inBundle": true, + "license": "MIT", + "dependencies": { + "readable-stream": "^2.0.5" + }, + "engines": { + "node": ">= 0.6.3" + } + }, + "node_modules/cdktf/node_modules/lazystream/node_modules/readable-stream": { + "version": "2.3.7", + "inBundle": true, + "license": "MIT", + "dependencies": { + "core-util-is": "~1.0.0", + "inherits": "~2.0.3", + "isarray": "~1.0.0", + "process-nextick-args": "~2.0.0", + "safe-buffer": "~5.1.1", + "string_decoder": "~1.1.1", + "util-deprecate": "~1.0.1" + } + }, + "node_modules/cdktf/node_modules/lazystream/node_modules/string_decoder": { + "version": "1.1.1", + "inBundle": true, + "license": "MIT", + "dependencies": { + "safe-buffer": "~5.1.0" + } + }, + "node_modules/cdktf/node_modules/lodash.defaults": { + "version": "4.2.0", + "inBundle": true, + "license": "MIT" + }, + "node_modules/cdktf/node_modules/lodash.difference": { + "version": "4.5.0", + "inBundle": true, + "license": "MIT" + }, + "node_modules/cdktf/node_modules/lodash.flatten": { + "version": "4.4.0", + "inBundle": true, + "license": "MIT" + }, + "node_modules/cdktf/node_modules/lodash.isplainobject": { + "version": "4.0.6", + "inBundle": true, + "license": "MIT" + }, + "node_modules/cdktf/node_modules/lodash.union": { + "version": "4.6.0", + "inBundle": true, + "license": "MIT" + }, + "node_modules/cdktf/node_modules/lru-cache": { + "version": "6.0.0", + "inBundle": true, + "license": "ISC", + "dependencies": { + "yallist": "^4.0.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/cdktf/node_modules/minimatch": { + "version": "5.1.0", + "inBundle": true, + "license": "ISC", + "dependencies": { + "brace-expansion": "^2.0.1" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/cdktf/node_modules/normalize-path": { + "version": "3.0.0", + "inBundle": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/cdktf/node_modules/once": { + "version": "1.4.0", + "inBundle": true, + "license": "ISC", + "dependencies": { + "wrappy": "1" + } + }, + "node_modules/cdktf/node_modules/path-is-absolute": { + "version": "1.0.1", + "inBundle": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/cdktf/node_modules/process-nextick-args": { + "version": "2.0.1", + "inBundle": true, + "license": "MIT" + }, + "node_modules/cdktf/node_modules/readable-stream": { + "version": "3.6.0", + "inBundle": true, + "license": "MIT", + "dependencies": { + "inherits": "^2.0.3", + "string_decoder": "^1.1.1", + "util-deprecate": "^1.0.1" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/cdktf/node_modules/readdir-glob": { + "version": "1.1.2", + "inBundle": true, + "license": "Apache-2.0", + "dependencies": { + "minimatch": "^5.1.0" + } + }, + "node_modules/cdktf/node_modules/safe-buffer": { + "version": "5.1.2", + "inBundle": true, + "license": "MIT" + }, + "node_modules/cdktf/node_modules/semver": { + "version": "7.3.8", + "inBundle": true, + "license": "ISC", + "dependencies": { + "lru-cache": "^6.0.0" + }, + "bin": { + "semver": "bin/semver.js" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/cdktf/node_modules/string_decoder": { + "version": "1.3.0", + "inBundle": true, + "license": "MIT", + "dependencies": { + "safe-buffer": "~5.2.0" + } + }, + "node_modules/cdktf/node_modules/string_decoder/node_modules/safe-buffer": { + "version": "5.2.1", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], + "inBundle": true, + "license": "MIT" + }, + "node_modules/cdktf/node_modules/tar-stream": { + "version": "2.2.0", + "inBundle": true, + "license": "MIT", + "dependencies": { + "bl": "^4.0.3", + "end-of-stream": "^1.4.1", + "fs-constants": "^1.0.0", + "inherits": "^2.0.3", + "readable-stream": "^3.1.1" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/cdktf/node_modules/util-deprecate": { + "version": "1.0.2", + "inBundle": true, + "license": "MIT" + }, + "node_modules/cdktf/node_modules/wrappy": { + "version": "1.0.2", + "inBundle": true, + "license": "ISC" + }, + "node_modules/cdktf/node_modules/yallist": { + "version": "4.0.0", + "inBundle": true, + "license": "ISC" + }, + "node_modules/cdktf/node_modules/zip-stream": { + "version": "4.1.0", + "inBundle": true, + "license": "MIT", + "dependencies": { + "archiver-utils": "^2.1.0", + "compress-commons": "^4.1.0", + "readable-stream": "^3.6.0" + }, + "engines": { + "node": ">= 10" + } + }, + "node_modules/constructs": { + "version": "10.2.59", + "resolved": "https://registry.npmjs.org/constructs/-/constructs-10.2.59.tgz", + "integrity": "sha512-mfdCXkCTCPv130DT4Nj8u9YZaKEVbAAwTihStBglsiuF/RzlIolJ1pQe95CK9EGA812QUl8RLWZKK2zrKtSkog==", + "peer": true, + "engines": { + "node": ">= 16.14.0" + } + }, "node_modules/jsii-code-samples": { "version": "1.7.0", "resolved": "https://registry.npmjs.org/jsii-code-samples/-/jsii-code-samples-1.7.0.tgz", @@ -15,6 +565,378 @@ } }, "dependencies": { + "cdktf": { + "version": "0.17.0", + "resolved": "https://registry.npmjs.org/cdktf/-/cdktf-0.17.0.tgz", + "integrity": "sha512-4R57uBLBqeb8NgfKZdn/az8UE3yXxGHyzH6Xjsz1Oo9kNvSkPibX7YqNLUpuCgdYNVgU2fdaNoHj9h4LXc6iCw==", + "requires": { + "archiver": "5.3.1", + "json-stable-stringify": "^1.0.2", + "semver": "^7.3.8" + }, + "dependencies": { + "archiver": { + "version": "5.3.1", + "bundled": true, + "requires": { + "archiver-utils": "^2.1.0", + "async": "^3.2.3", + "buffer-crc32": "^0.2.1", + "readable-stream": "^3.6.0", + "readdir-glob": "^1.0.0", + "tar-stream": "^2.2.0", + "zip-stream": "^4.1.0" + } + }, + "archiver-utils": { + "version": "2.1.0", + "bundled": true, + "requires": { + "glob": "^7.1.4", + "graceful-fs": "^4.2.0", + "lazystream": "^1.0.0", + "lodash.defaults": "^4.2.0", + "lodash.difference": "^4.5.0", + "lodash.flatten": "^4.4.0", + "lodash.isplainobject": "^4.0.6", + "lodash.union": "^4.6.0", + "normalize-path": "^3.0.0", + "readable-stream": "^2.0.0" + }, + "dependencies": { + "readable-stream": { + "version": "2.3.7", + "bundled": true, + "requires": { + "core-util-is": "~1.0.0", + "inherits": "~2.0.3", + "isarray": "~1.0.0", + "process-nextick-args": "~2.0.0", + "safe-buffer": "~5.1.1", + "string_decoder": "~1.1.1", + "util-deprecate": "~1.0.1" + } + }, + "string_decoder": { + "version": "1.1.1", + "bundled": true, + "requires": { + "safe-buffer": "~5.1.0" + } + } + } + }, + "async": { + "version": "3.2.4", + "bundled": true + }, + "balanced-match": { + "version": "1.0.2", + "bundled": true + }, + "base64-js": { + "version": "1.5.1", + "bundled": true + }, + "bl": { + "version": "4.1.0", + "bundled": true, + "requires": { + "buffer": "^5.5.0", + "inherits": "^2.0.4", + "readable-stream": "^3.4.0" + } + }, + "brace-expansion": { + "version": "2.0.1", + "bundled": true, + "requires": { + "balanced-match": "^1.0.0" + } + }, + "buffer": { + "version": "5.7.1", + "bundled": true, + "requires": { + "base64-js": "^1.3.1", + "ieee754": "^1.1.13" + } + }, + "buffer-crc32": { + "version": "0.2.13", + "bundled": true + }, + "compress-commons": { + "version": "4.1.1", + "bundled": true, + "requires": { + "buffer-crc32": "^0.2.13", + "crc32-stream": "^4.0.2", + "normalize-path": "^3.0.0", + "readable-stream": "^3.6.0" + } + }, + "concat-map": { + "version": "0.0.1", + "bundled": true + }, + "core-util-is": { + "version": "1.0.3", + "bundled": true + }, + "crc-32": { + "version": "1.2.2", + "bundled": true + }, + "crc32-stream": { + "version": "4.0.2", + "bundled": true, + "requires": { + "crc-32": "^1.2.0", + "readable-stream": "^3.4.0" + } + }, + "end-of-stream": { + "version": "1.4.4", + "bundled": true, + "requires": { + "once": "^1.4.0" + } + }, + "fs-constants": { + "version": "1.0.0", + "bundled": true + }, + "fs.realpath": { + "version": "1.0.0", + "bundled": true + }, + "glob": { + "version": "7.2.3", + "bundled": true, + "requires": { + "fs.realpath": "^1.0.0", + "inflight": "^1.0.4", + "inherits": "2", + "minimatch": "^3.1.1", + "once": "^1.3.0", + "path-is-absolute": "^1.0.0" + }, + "dependencies": { + "brace-expansion": { + "version": "1.1.11", + "bundled": true, + "requires": { + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" + } + }, + "minimatch": { + "version": "3.1.2", + "bundled": true, + "requires": { + "brace-expansion": "^1.1.7" + } + } + } + }, + "graceful-fs": { + "version": "4.2.10", + "bundled": true + }, + "ieee754": { + "version": "1.2.1", + "bundled": true + }, + "inflight": { + "version": "1.0.6", + "bundled": true, + "requires": { + "once": "^1.3.0", + "wrappy": "1" + } + }, + "inherits": { + "version": "2.0.4", + "bundled": true + }, + "isarray": { + "version": "1.0.0", + "bundled": true + }, + "json-stable-stringify": { + "version": "1.0.2", + "bundled": true, + "requires": { + "jsonify": "^0.0.1" + } + }, + "jsonify": { + "version": "0.0.1", + "bundled": true + }, + "lazystream": { + "version": "1.0.1", + "bundled": true, + "requires": { + "readable-stream": "^2.0.5" + }, + "dependencies": { + "readable-stream": { + "version": "2.3.7", + "bundled": true, + "requires": { + "core-util-is": "~1.0.0", + "inherits": "~2.0.3", + "isarray": "~1.0.0", + "process-nextick-args": "~2.0.0", + "safe-buffer": "~5.1.1", + "string_decoder": "~1.1.1", + "util-deprecate": "~1.0.1" + } + }, + "string_decoder": { + "version": "1.1.1", + "bundled": true, + "requires": { + "safe-buffer": "~5.1.0" + } + } + } + }, + "lodash.defaults": { + "version": "4.2.0", + "bundled": true + }, + "lodash.difference": { + "version": "4.5.0", + "bundled": true + }, + "lodash.flatten": { + "version": "4.4.0", + "bundled": true + }, + "lodash.isplainobject": { + "version": "4.0.6", + "bundled": true + }, + "lodash.union": { + "version": "4.6.0", + "bundled": true + }, + "lru-cache": { + "version": "6.0.0", + "bundled": true, + "requires": { + "yallist": "^4.0.0" + } + }, + "minimatch": { + "version": "5.1.0", + "bundled": true, + "requires": { + "brace-expansion": "^2.0.1" + } + }, + "normalize-path": { + "version": "3.0.0", + "bundled": true + }, + "once": { + "version": "1.4.0", + "bundled": true, + "requires": { + "wrappy": "1" + } + }, + "path-is-absolute": { + "version": "1.0.1", + "bundled": true + }, + "process-nextick-args": { + "version": "2.0.1", + "bundled": true + }, + "readable-stream": { + "version": "3.6.0", + "bundled": true, + "requires": { + "inherits": "^2.0.3", + "string_decoder": "^1.1.1", + "util-deprecate": "^1.0.1" + } + }, + "readdir-glob": { + "version": "1.1.2", + "bundled": true, + "requires": { + "minimatch": "^5.1.0" + } + }, + "safe-buffer": { + "version": "5.1.2", + "bundled": true + }, + "semver": { + "version": "7.3.8", + "bundled": true, + "requires": { + "lru-cache": "^6.0.0" + } + }, + "string_decoder": { + "version": "1.3.0", + "bundled": true, + "requires": { + "safe-buffer": "~5.2.0" + }, + "dependencies": { + "safe-buffer": { + "version": "5.2.1", + "bundled": true + } + } + }, + "tar-stream": { + "version": "2.2.0", + "bundled": true, + "requires": { + "bl": "^4.0.3", + "end-of-stream": "^1.4.1", + "fs-constants": "^1.0.0", + "inherits": "^2.0.3", + "readable-stream": "^3.1.1" + } + }, + "util-deprecate": { + "version": "1.0.2", + "bundled": true + }, + "wrappy": { + "version": "1.0.2", + "bundled": true + }, + "yallist": { + "version": "4.0.0", + "bundled": true + }, + "zip-stream": { + "version": "4.1.0", + "bundled": true, + "requires": { + "archiver-utils": "^2.1.0", + "compress-commons": "^4.1.0", + "readable-stream": "^3.6.0" + } + } + } + }, + "constructs": { + "version": "10.2.59", + "resolved": "https://registry.npmjs.org/constructs/-/constructs-10.2.59.tgz", + "integrity": "sha512-mfdCXkCTCPv130DT4Nj8u9YZaKEVbAAwTihStBglsiuF/RzlIolJ1pQe95CK9EGA812QUl8RLWZKK2zrKtSkog==", + "peer": true + }, "jsii-code-samples": { "version": "1.7.0", "resolved": "https://registry.npmjs.org/jsii-code-samples/-/jsii-code-samples-1.7.0.tgz", diff --git a/examples/tests/invalid/package.json b/examples/tests/invalid/package.json index 06f4bae2177..3f9649f19bc 100644 --- a/examples/tests/invalid/package.json +++ b/examples/tests/invalid/package.json @@ -1,9 +1,10 @@ { "dependencies": { - "jsii-code-samples": "1.7.0" + "jsii-code-samples": "1.7.0", + "cdktf": "0.17.0" }, "volta": { "node": "18.16.0", "npm": "8.19.3" } -} +} \ No newline at end of file diff --git a/examples/tests/invalid/return_types.w b/examples/tests/invalid/return_types.w new file mode 100644 index 00000000000..18238901fb2 --- /dev/null +++ b/examples/tests/invalid/return_types.w @@ -0,0 +1,22 @@ + return 9; +// ^^^^^^^^^ Return statement outside of function cannot return a value +if true { + return 9; +// ^^^^^^^^^ Return statement outside of function cannot return a value +} + +inflight (): void => { + return 9; +//^^^^^^^^^ Unexpected return value from void function + if true { + return 9; +// ^^^^^^^^^ Unexpected return value from void function + } +}; + +class C { + func() { + return 9; +// ^^^^^^^^^ Unexpected return value from void function + } +} diff --git a/examples/tests/sdk_tests/api/delete.w b/examples/tests/sdk_tests/api/delete.w new file mode 100644 index 00000000000..c0d910eb1bc --- /dev/null +++ b/examples/tests/sdk_tests/api/delete.w @@ -0,0 +1,38 @@ +bring cloud; +bring http; + +// https://github.com/winglang/wing/issues/3049 +let http_DELETE = http.HttpMethod.DELETE; +let api_DELETE = cloud.HttpMethod.DELETE; + +let api = new cloud.Api(); + +api.delete("/path", inflight (req: cloud.ApiRequest): cloud.ApiResponse => { + assert(req.method == api_DELETE); + assert(req.query?.get("all") == "true"); + assert(req.query?.get("page") == "6"); + assert(req.path == "/path"); + + return cloud.ApiResponse { + status: 200, + body: req.query?.get("page") + }; +}); + + +test "http.delete and http.fetch can preform a call to an api" { + let url = "${api.url}/path?all=true&page=6"; + let response: http.Response = http.delete(url); + let fetchResponse: http.Response = http.fetch(url, {method: http_DELETE}); + + // TODO: adding a fetch request when the enums + + assert(response.body == "6"); + assert(response.status == 200); + assert(response.url == url); + + assert(fetchResponse.body == "6"); + assert(fetchResponse.status == 200); + assert(fetchResponse.url == url); + +} \ No newline at end of file diff --git a/examples/tests/sdk_tests/api/get.w b/examples/tests/sdk_tests/api/get.w new file mode 100644 index 00000000000..74f46313472 --- /dev/null +++ b/examples/tests/sdk_tests/api/get.w @@ -0,0 +1,43 @@ +bring cloud; +bring http; + +// https://github.com/winglang/wing/issues/3049 +let http_GET = http.HttpMethod.GET; +let api_GET = cloud.HttpMethod.GET; + +let api = new cloud.Api(); +let body = "ok!"; + +api.get("/path", inflight (req: cloud.ApiRequest): cloud.ApiResponse => { + assert(req.method == api_GET); + assert(req.path == "/path"); + // req.body is not a string in sim- https://github.com/winglang/wing/issues/3024 + // assert(req.body?.length == 0); + assert(req.headers?.get("content-type") == "application/json"); + + return cloud.ApiResponse { + status: 200, + body: body + }; +}); + + +test "http.get and http.fetch can preform a call to an api" { + let url = api.url + "/path"; + let getResponse: http.Response = http.get(url, { headers: { "content-type": "application/json" }}); + let fetchResponse: http.Response = http.fetch(url, http.RequestOptions { method: http_GET, headers: { "content-type": "application/json" }}); + let fetchResponseNoMethod: http.Response = http.fetch(url, http.RequestOptions { headers: { "content-type": "application/json" }}); + + + assert(getResponse.body == body); + assert(getResponse.status == 200); + assert(getResponse.url == url); + + assert(fetchResponse.body == body); + assert(fetchResponse.status == 200); + assert(fetchResponse.url == url); + + assert(fetchResponseNoMethod.body == body); + assert(fetchResponseNoMethod.status == 200); + assert(fetchResponseNoMethod.url == url); +} \ No newline at end of file diff --git a/examples/tests/sdk_tests/api/patch.w b/examples/tests/sdk_tests/api/patch.w new file mode 100644 index 00000000000..378fb442d5e --- /dev/null +++ b/examples/tests/sdk_tests/api/patch.w @@ -0,0 +1,41 @@ +bring cloud; +bring http; + +// https://github.com/winglang/wing/issues/3049 +let http_PATCH = http.HttpMethod.PATCH; +let api_PATCH = cloud.HttpMethod.PATCH; + +let api = new cloud.Api(); + +let body = Json {"cat": "Tion"}; +let _id = "12345"; + +api.patch("/path/{id}", inflight (req: cloud.ApiRequest): cloud.ApiResponse => { + assert(req.method == api_PATCH); + + assert(req.vars?.get("id") == _id); + assert(req.path == "/path/"+ _id); + assert(req.body == Json.stringify(body)); + assert(req.headers?.get("content-type") == "application/json"); + + return cloud.ApiResponse { + status: 200, + body: req.vars?.get("id") + }; +}); + + +test "http.patch and http.fetch can preform a call to an api" { + let url = "${api.url}/path/${_id}"; + let response: http.Response = http.patch(url, http.RequestOptions { headers: { "content-type": "application/json" }, body: Json.stringify(body)}); + let fetchResponse: http.Response = http.patch(url, http.RequestOptions {method: http_PATCH, headers: { "content-type": "application/json" }, body: Json.stringify(body)}); + + assert(response.body == _id); + assert(response.status == 200); + assert(response.url == url); + + assert(fetchResponse.body == _id); + assert(fetchResponse.status == 200); + assert(fetchResponse.url == url); + +} \ No newline at end of file diff --git a/examples/tests/sdk_tests/api/post.w b/examples/tests/sdk_tests/api/post.w new file mode 100644 index 00000000000..5ba55255b45 --- /dev/null +++ b/examples/tests/sdk_tests/api/post.w @@ -0,0 +1,37 @@ +bring cloud; +bring http; + +// https://github.com/winglang/wing/issues/3049 +let http_POST = http.HttpMethod.POST; +let api_POST = cloud.HttpMethod.POST; + +let api = new cloud.Api(); +let body = Json {"cat": "Tion"}; + +api.post("/path", inflight (req: cloud.ApiRequest): cloud.ApiResponse => { + assert(req.method == api_POST); + assert(req.path == "/path"); + assert(req.body == Json.stringify(body)); + assert(req.headers?.get("content-type") == "application/json"); + + return cloud.ApiResponse { + status: 200, + body: req.body + }; +}); + + +test "http.post and http.fetch can preform a call to an api" { + let url = api.url + "/path"; + let response: http.Response = http.post(url, http.RequestOptions { headers: { "content-type": "application/json" }, body: Json.stringify(body)}); + let fetchResponse: http.Response = http.post(url, http.RequestOptions {method: http_POST, headers: { "content-type": "application/json" }, body: Json.stringify(body)}); + + assert(response.body == Json.stringify(body)); + assert(response.status == 200); + assert(response.url == url); + + assert(fetchResponse.body == Json.stringify(body)); + assert(fetchResponse.status == 200); + assert(fetchResponse.url == url); + +} \ No newline at end of file diff --git a/examples/tests/sdk_tests/api/put.w b/examples/tests/sdk_tests/api/put.w new file mode 100644 index 00000000000..27986c5bbd8 --- /dev/null +++ b/examples/tests/sdk_tests/api/put.w @@ -0,0 +1,45 @@ +bring cloud; +bring http; + +// https://github.com/winglang/wing/issues/3049 +let http_PUT = http.HttpMethod.PUT; +let api_PUT = cloud.HttpMethod.PUT; + +let api = new cloud.Api(); + +let body = Json {"cat": "Tion"}; +let user = "guy"; +let _id = "12345"; + +api.put("/path/{id}/nn/{user}", inflight (req: cloud.ApiRequest): cloud.ApiResponse => { + let path = "/path/${_id}/nn/${user}"; + assert(req.method == api_PUT); + assert(req.vars?.get("id") == _id); + assert(req.vars?.get("user") == user); + //TODO: + assert(req.path == path); + assert(req.body == Json.stringify(body)); + assert(req.headers?.get("content-type") == "application/json"); + + return cloud.ApiResponse { + status: 200, + body: req.vars?.get("id") + }; +}); + + +test "http.put and http.fetch can preform a call to an api" { + let url = "${api.url}/path/${_id}/nn/${user}"; + let response: http.Response = http.put(url, http.RequestOptions { headers: { "content-type": "application/json" }, body: Json.stringify(body)}); + let fetchResponse: http.Response = http.put(url, http.RequestOptions { method: http_PUT, headers: { "content-type": "application/json" }, body: Json.stringify(body)}); + + + assert(response.body == _id); + assert(response.status == 200); + assert(response.url == url); + + assert(fetchResponse.body == _id); + assert(fetchResponse.status == 200); + assert(fetchResponse.url == url); +} + diff --git a/examples/tests/sdk_tests/std/array.w b/examples/tests/sdk_tests/std/array.w index 817c123cecf..b8850fd8c23 100644 --- a/examples/tests/sdk_tests/std/array.w +++ b/examples/tests/sdk_tests/std/array.w @@ -1,6 +1,16 @@ +bring cloud; //----------------------------------------------------------------------------- // length +// Bucket can be tested only in preflight mode + +let bucket = new cloud.Bucket() as "myBucket"; +let buckets = Array[bucket]; +let anotherBucket = new cloud.Bucket() as "mySecondBucket"; +let anotherBuckets = Array[anotherBucket]; + +assert(buckets.length == 1); + assert([1,2,3].length == 3); assert(MutArray[1,2,3].length == 3); @@ -15,14 +25,15 @@ test "length" { assert(["hello"].at(0) == "hello"); assert(MutArray["hello", "world"].at(1) == "world"); +assert(buckets.at(0).node.id == "myBucket"); + test "at()" { assert(["hello"].at(0) == "hello"); assert(MutArray["hello", "world"].at(1) == "world"); - } //----------------------------------------------------------------------------- -// push() +// push() & pop() let a = MutArray["hello"]; assert(a.length == 1); @@ -30,24 +41,198 @@ a.push("world"); assert(a.length == 2); assert(a.at(0) == "hello"); assert(a.at(1) == "world"); +let item = a.pop(); +assert(item == "world"); +assert(a.length == 1); +assert(a.at(0) == "hello"); -test "push()" { +test "pushAndPop()" { let a = MutArray["hello"]; assert(a.length == 1); a.push("world"); assert(a.length == 2); assert(a.at(0) == "hello"); assert(a.at(1) == "world"); + let item = a.pop(); + assert(item == "world"); + assert(a.length == 1); + assert(a.at(0) == "hello"); } //----------------------------------------------------------------------------- -// TODO: https://github.com/winglang/wing/issues/2785 - // concat() +let array = Array["hello"]; +assert(array.length == 1); +let mergedArray = array.concat(Array["wing"]); +assert(mergedArray.length == 2); +assert(mergedArray.at(0) == "hello"); +assert(mergedArray.at(1) == "wing"); + +let b = MutArray["hello"]; +assert(b.length == 1); +let d = b.concat(MutArray["wing"]); +assert(d.length == 2); +assert(d.at(0) == "hello"); +assert(d.at(1) == "wing"); + +let mergedBuckets = buckets.concat(anotherBuckets); +assert(mergedBuckets.length == 2); +assert(mergedBuckets.at(0).node.id == "myBucket"); +assert(mergedBuckets.at(1).node.id == "mySecondBucket"); + +test "concatMutArray()" { + let b = MutArray["hello"]; + assert(b.length == 1); + let d = b.concat(MutArray["wing"]); + assert(d.length == 2); + assert(d.at(0) == "hello"); + assert(d.at(1) == "wing"); +} + +test "concatArray()" { + let array = Array["hello"]; + assert(array.length == 1); + let anotherArray = Array["wing"]; + assert(anotherArray.length == 1); + let mergedArray = array.concat(anotherArray); + assert(mergedArray.length == 2); + assert(mergedArray.at(0) == "hello"); + assert(mergedArray.at(1) == "wing"); +} + +//----------------------------------------------------------------------------- // contains() -// copy() -// copyMut() + +let e = MutArray["hello", "wing"]; +assert(e.contains("wing")); +assert(!e.contains("NotThere")); + +assert(buckets.contains(buckets.at(0))); +let dummyBucket = new cloud.Bucket(); +assert(!buckets.contains(dummyBucket)); + +let h = Array["hello", "wing"]; +assert(h.contains("wing")); +assert(!h.contains("NotThere")); + +test "contains()" { + let e = MutArray["hello", "wing"]; + assert(e.contains("wing")); + assert(!e.contains("NotThere")); + + let h = Array["hello", "wing"]; + assert(h.contains("wing")); + assert(!h.contains("NotThere")); +} + +//----------------------------------------------------------------------------- // indexOf() + +let g = MutArray["hello", "wing"]; +assert(g.indexOf("wing") == 1); +assert(g.indexOf("notThere") == -1); +assert(buckets.indexOf(bucket) == 0); +assert(buckets.indexOf(dummyBucket) == -1); + +test "indexOf()" { + let g = MutArray["hello", "wing"]; + assert(g.indexOf("wing") == 1); + assert(g.indexOf("notThere") == -1); +} + +let q = MutArray["hello", "wing"]; +assert(q.indexOf("wing") == 1); +assert(q.indexOf("notThere") == -1); + + +test "indexOfArray()" { + let g = Array["hello", "wing"]; + assert(g.indexOf("wing") == 1); + assert(g.indexOf("notThere") == -1); +} + +//----------------------------------------------------------------------------- // join() + +let m = MutArray["hello", "wing"]; +let delimeter = ";"; +let joinedString = m.join(delimeter); +let expectedString = m.at(0) + delimeter + m.at(1); +assert(joinedString == expectedString); + +let l = MutArray["hello", "wing"]; +let separator = ","; +let joinedStringWithDefault = m.join(); +let expectedStringWithDefault = m.at(0) + separator + m.at(1); +assert(joinedStringWithDefault == expectedStringWithDefault); + +test "join()" { + let i = MutArray["hello", "wing"]; + let separator = ";"; + let joinedString = i.join(separator); + let expectedString = i.at(0) + separator + i.at(1); + assert(joinedString == expectedString); +} + +test "joinWithDefaultSeparator()" { + let i = MutArray["hello", "wing"]; + let separator = ","; + let joinedString = i.join(); + let expectedString = i.at(0) + separator + i.at(1); + assert(joinedString == expectedString); +} + +//----------------------------------------------------------------------------- +// copy() + +let o = MutArray["hello", "wing"]; +let p = o.copy(); +assert(o.length == p.length); +assert(o.at(0) == p.at(0)); + +let copiedBuckets = buckets.copyMut(); +assert(copiedBuckets.length == 1); +assert(copiedBuckets.at(0).node.id == "myBucket"); + +test "copy()" { + let o = MutArray["hello", "wing"]; + let p = o.copy(); + assert(o.length == p.length); + assert(o.at(0) == p.at(0)); +} + +let v = Array["hello", "wing"]; +let r = v.copyMut(); +assert(q.length == r.length); +assert(q.at(0) == r.at(0)); + +//----------------------------------------------------------------------------- +// copyMut() + +test "copyMut()" { + let q = Array["hello", "wing"]; + let r = q.copyMut(); + assert(q.length == r.length); + assert(q.at(0) == r.at(0)); +} + +//----------------------------------------------------------------------------- // lastIndexOf() -// pop() \ No newline at end of file + +let lastStr = "wing"; +let s = MutArray["hello", lastStr, lastStr]; +assert(s.lastIndexOf(lastStr) == 2); + +assert(s.lastIndexOf("something") == -1); + +let multipleBuckets = MutArray[bucket, bucket, anotherBucket]; +assert(multipleBuckets.lastIndexOf(bucket) == 1); +assert(multipleBuckets.lastIndexOf(dummyBucket) == -1); + +test "lastIndexOf()" { + let lastStr = "wing"; + let s = MutArray["hello", lastStr, lastStr]; + assert(s.lastIndexOf(lastStr) == 2); + + assert(s.lastIndexOf("something") == -1); +} diff --git a/examples/tests/sdk_tests/table/add_row.w b/examples/tests/sdk_tests/table/add_row.w new file mode 100644 index 00000000000..6525f108efe --- /dev/null +++ b/examples/tests/sdk_tests/table/add_row.w @@ -0,0 +1,18 @@ +bring cloud; + +let table = new cloud.Table( + name: "users", + primaryKey: "name", + columns: { gender: cloud.ColumnType.STRING } +); + +let marioInfo = Json { gender: "male", role: "plumber" }; +let peachInfo = Json { gender: "female", role: "princess" }; +table.addRow("mario", marioInfo); +table.addRow("peach", peachInfo); + + +test "addRow" { + assert(Json.stringify(table.get("mario")) == Json.stringify(marioInfo)); + assert(Json.stringify(table.get("peach")) == Json.stringify(peachInfo)); +} diff --git a/examples/tests/valid/api_path_vars.js b/examples/tests/valid/api_path_vars.js deleted file mode 100644 index 82b4d71030e..00000000000 --- a/examples/tests/valid/api_path_vars.js +++ /dev/null @@ -1,13 +0,0 @@ -const fetch = require("node-fetch"); - -exports.get = async function (url) { - const res = await fetch(url.toString()); - return { - status: res.status, - headers: [...res.headers.entries()].map(([key, value]) => ({ - key, - value, - })), - body: await res.json(), - }; -}; diff --git a/examples/tests/valid/api_path_vars.w b/examples/tests/valid/api_path_vars.w index 51943e64bc7..60f11a5bb7c 100644 --- a/examples/tests/valid/api_path_vars.w +++ b/examples/tests/valid/api_path_vars.w @@ -1,10 +1,8 @@ bring cloud; +bring http; let api = new cloud.Api(); -class Fetch { - extern "./api_path_vars.js" inflight get(url: str): Json; -} let handler = inflight (req: cloud.ApiRequest): cloud.ApiResponse => { return cloud.ApiResponse { @@ -16,13 +14,12 @@ let handler = inflight (req: cloud.ApiRequest): cloud.ApiResponse => { api.get("/users/{name}", handler); -let f = new Fetch(); test "test" { let username = "tsuf"; - // TODO: change f.get to static when possible - let res = f.get("${api.url}/users/${username}"); + let res: http.Response = http.get("${api.url}/users/${username}"); + - assert(res.get("status") == 200); - assert(res.get("body").get("user") == username); + assert(res.status == 200); + assert(Json.parse(res.body ?? "").get("user") == username); } diff --git a/examples/tests/valid/assert.w b/examples/tests/valid/assert.w new file mode 100644 index 00000000000..3e38d3716bf --- /dev/null +++ b/examples/tests/valid/assert.w @@ -0,0 +1,36 @@ +let s1 = "foo"; +let s2 = "bar"; + +assert("" == ""); +assert("'" == "'"); +assert("\"" == "\""); +assert("`" == "`"); +assert("``" == "``"); +assert("`s1`" == "`s1`"); +assert(s1 == s1); +assert("${s1}" == "${s1}"); +assert("${s1}" != "${s2}"); +assert("a${s1}" == "a${s1}"); +assert("a${s1}" != "b${s1}"); +assert("${s1}a" == "${s1}a"); +assert("${s1}a" != "${s1}b"); +assert("`'${s1}" == "`'${s1}"); +assert("a${s1}b${s2}c" == "a${s1}b${s2}c"); + +test "assert works inflight" { + assert("" == ""); + assert("'" == "'"); + assert("\"" == "\""); + assert("`" == "`"); + assert("``" == "``"); + assert("`s1`" == "`s1`"); + assert(s1 == s1); + assert("${s1}" == "${s1}"); + assert("${s1}" != "${s2}"); + assert("a${s1}" == "a${s1}"); + assert("a${s1}" != "b${s1}"); + assert("${s1}a" == "${s1}a"); + assert("${s1}a" != "${s1}b"); + assert("`'${s1}" == "`'${s1}"); + assert("a${s1}b${s2}c" == "a${s1}b${s2}c"); +} diff --git a/examples/tests/valid/bring_awscdk.w b/examples/tests/valid/bring_awscdk.w index 227dd6273f0..19992ff457f 100644 --- a/examples/tests/valid/bring_awscdk.w +++ b/examples/tests/valid/bring_awscdk.w @@ -8,4 +8,7 @@ class CdkDockerImageFunction { code: awscdk.aws_lambda.DockerImageCode.fromImageAsset("./test.ts"), }) as "DockerImageFunction"; } -} \ No newline at end of file +} + +// Test creating an `App` construct +new awscdk.App(); diff --git a/examples/tests/valid/bring_cdktf.w b/examples/tests/valid/bring_cdktf.w index fdfe3724e03..11ec3f54724 100644 --- a/examples/tests/valid/bring_cdktf.w +++ b/examples/tests/valid/bring_cdktf.w @@ -1,4 +1,5 @@ bring "@cdktf/provider-aws" as aws; +bring "cdktf" as cdktf; new aws.s3Bucket.S3Bucket( bucketPrefix: "hello", @@ -7,3 +8,11 @@ new aws.s3Bucket.S3Bucket( mfaDelete: true, }, ) as "Bucket"; + +class Foo { + init() { + // Test importing a non-standard Construct that doesn't have a `scope`/`id` property pair as its first two arguments + // Some of cdktf's backend constructs are like this. + new cdktf.S3Backend(this, cdktf.S3BackendConfig {bucket: "foo", key: "bar"}); + } +} diff --git a/examples/tests/valid/capture_mutables.w b/examples/tests/valid/capture_mutables.w new file mode 100644 index 00000000000..e5848a609f1 --- /dev/null +++ b/examples/tests/valid/capture_mutables.w @@ -0,0 +1,16 @@ +let a = MutArray["hello"]; +let s = MutSet{12}; +let m = MutMap{"hello": true}; + +let aCloned = (Array["hello"]).copyMut(); + +let handler = inflight () => { + assert(a.length == 1); + assert(s.size == 1); + assert(m.size() == 1); + assert(aCloned.length == 1); +}; + +test "main" { + handler(); +} \ No newline at end of file diff --git a/examples/tests/valid/capture_reassigable_class_field.w b/examples/tests/valid/capture_reassigable_class_field.w new file mode 100644 index 00000000000..f81ad31889c --- /dev/null +++ b/examples/tests/valid/capture_reassigable_class_field.w @@ -0,0 +1,49 @@ +bring cloud; +bring util; + +class KeyValueStore { + bucket: cloud.Bucket; + var onUpdateCallback : inflight (str): void; + init() { + this.bucket = new cloud.Bucket(); + this.onUpdateCallback = inflight (k: str) => {}; + } + + onUpdate(fn: inflight (str):void){ + this.onUpdateCallback = fn; + } + + inflight get(key: str): Json { + this.onUpdateCallback(key); + return this.bucket.getJson(key); + } + inflight set(key: str, value: Json): void { + this.bucket.putJson(key, value); + } +} + +let kv = new KeyValueStore(); +let counter = new cloud.Counter() as "sasa"; +kv.onUpdate(inflight (key: str): void => { + counter.inc(1, key); +}); + +test "main" { + kv.set("k", Json { + value: "v" + }); + kv.set("k2", Json { + value: "v" + }); + kv.get("k"); + kv.get("k"); + kv.get("k2"); + + assert(util.waitUntil((): bool => { + return counter.peek("k") == 2; + })); + + assert(util.waitUntil((): bool => { + return counter.peek("k2") == 1; + })); +} diff --git a/examples/tests/valid/capture_reassignable.w b/examples/tests/valid/capture_reassignable.w new file mode 100644 index 00000000000..6c07ba36847 --- /dev/null +++ b/examples/tests/valid/capture_reassignable.w @@ -0,0 +1,12 @@ +bring cloud; + +let var x = 5; + +let handler = inflight (): void => { + assert(x == 5); + +}; + +test "main" { + handler(); +} diff --git a/examples/tests/valid/json.w b/examples/tests/valid/json.w index ebd5d056e92..d9b3d0282e3 100644 --- a/examples/tests/valid/json.w +++ b/examples/tests/valid/json.w @@ -128,4 +128,65 @@ assert(num.fromJson(thatSuperNestedValue) == 1); // Unested Json Arrays let unestedJsonArr = Json [1, 2, 3]; -assert(unestedJsonArr.getAt(0) == 1); \ No newline at end of file +assert(unestedJsonArr.getAt(0) == 1); + + +let jsonElements = Json { + strings: { + single: "Hello", + array: ["Hello", "World", "!"] + }, + numbers: { + one: 1, + two: 2, + three: 3 + }, + bools: { + t: true, + f: false + } +}; + +if let val = jsonElements.tryGet("strings")?.tryGet("single")?.tryAsStr() { + assert(val == "Hello"); +} else { + // This should not happen + assert(false); +} + +if let vals = jsonElements.tryGet("strings")?.tryGet("array") { + // Try getting an index + if let hello = vals.tryGetAt(0) { + assert(hello == "Hello"); + } else { + // This should not happen + assert(false); + } +} else { + // This should not happen + assert(false); +} + +if let two = jsonElements.tryGet("numbers")?.tryGet("two")?.tryAsNum() { + assert(two + 2 == 4); +} else { + // This should not happen + assert(false); +} + +if let truth = jsonElements.tryGet("bools")?.tryGet("t")?.tryAsBool() { + assert(truth); +} else { + // This should not happen + assert(false); +} + +// tryGet Chains where members are missing +if let val = jsonElements.tryGet("strings")?.tryGet("non")?.tryGet("existant")?.tryGet("element") { + assert(false); // nothing should have been found +} + +// tryGetAt chains with missing members +if let val = jsonElements.tryGet("cant")?.tryGetAt(1000)?.tryGetAt(42) { + assert(false); // nothing should have been found +} \ No newline at end of file diff --git a/examples/tests/valid/json_static.w b/examples/tests/valid/json_static.w index 8ed11c91c34..3b0a891b7ab 100644 --- a/examples/tests/valid/json_static.w +++ b/examples/tests/valid/json_static.w @@ -15,7 +15,7 @@ m.set("a", 321); assert(m.get("a") == 321); // Immutable Deep Copy -let n = MutJson.deepCopy(m); +let n = Json.deepCopy(m); assert(m != n); // Deleting keys diff --git a/examples/tests/valid/json_string_interpolation.w b/examples/tests/valid/json_string_interpolation.w new file mode 100644 index 00000000000..66f4f6abfa4 --- /dev/null +++ b/examples/tests/valid/json_string_interpolation.w @@ -0,0 +1,9 @@ +let obj = Json { + strValue: "test", + numValue: 1 +}; + +let notStringifyStrValue = "string: ${obj.get("strValue")}"; +assert(notStringifyStrValue == "string: test"); +let stringifyNumValue = "number: ${obj.get("numValue")}"; +assert(stringifyNumValue == "number: 1"); diff --git a/examples/tests/valid/package-lock.json b/examples/tests/valid/package-lock.json index b54d7b6f2e0..6b5dc2fe60d 100644 --- a/examples/tests/valid/package-lock.json +++ b/examples/tests/valid/package-lock.json @@ -9,7 +9,6 @@ "aws-cdk-lib": "^2.77.0", "constructs": "^10", "jsii-code-samples": "1.7.0", - "node-fetch": "^2", "projen": "^0.71.60", "uuid": "^9.0.0" } @@ -998,25 +997,6 @@ "resolved": "https://registry.npmjs.org/jsii-code-samples/-/jsii-code-samples-1.7.0.tgz", "integrity": "sha512-op3y4UUzd6J6lfjV+UP/hhEQIPUtpsLNtMRXLO1v5X7hbJ8N76gdO6UHu7RqyCElRjUaNqtGug0pkQBC5sDepg==" }, - "node_modules/node-fetch": { - "version": "2.6.9", - "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.6.9.tgz", - "integrity": "sha512-DJm/CJkZkRjKKj4Zi4BsKVZh3ValV5IR5s7LVZnW+6YMh0W1BfNA8XSs6DLMGYlId5F3KnA70uu2qepcR08Qqg==", - "dependencies": { - "whatwg-url": "^5.0.0" - }, - "engines": { - "node": "4.x || >=6.0.0" - }, - "peerDependencies": { - "encoding": "^0.1.0" - }, - "peerDependenciesMeta": { - "encoding": { - "optional": true - } - } - }, "node_modules/projen": { "version": "0.71.60", "resolved": "https://registry.npmjs.org/projen/-/projen-0.71.60.tgz", @@ -1700,11 +1680,6 @@ "node": ">=12" } }, - "node_modules/tr46": { - "version": "0.0.3", - "resolved": "https://registry.npmjs.org/tr46/-/tr46-0.0.3.tgz", - "integrity": "sha512-N3WMsuqV66lT30CrXNbEjx4GEwlow3v6rr4mCcv6prnfwhS01rkgyFdjPNBYd9br7LpXV1+Emh01fHnq2Gdgrw==" - }, "node_modules/uuid": { "version": "9.0.0", "resolved": "https://registry.npmjs.org/uuid/-/uuid-9.0.0.tgz", @@ -1712,20 +1687,6 @@ "bin": { "uuid": "dist/bin/uuid" } - }, - "node_modules/webidl-conversions": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-3.0.1.tgz", - "integrity": "sha512-2JAn3z8AR6rjK8Sm8orRC0h/bcl/DqL7tRPdGZ4I1CjdF+EaMLmYxBHyXuKL849eucPFhvBoxMsflfOb8kxaeQ==" - }, - "node_modules/whatwg-url": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-5.0.0.tgz", - "integrity": "sha512-saE57nupxk6v3HY35+jzBwYa0rKSy0XR8JSxZPwgLr7ys0IBzhGviA1/TUGJLmSVqs8pb9AnvICXEuOHLprYTw==", - "dependencies": { - "tr46": "~0.0.3", - "webidl-conversions": "^3.0.0" - } } }, "dependencies": { @@ -2401,14 +2362,6 @@ "resolved": "https://registry.npmjs.org/jsii-code-samples/-/jsii-code-samples-1.7.0.tgz", "integrity": "sha512-op3y4UUzd6J6lfjV+UP/hhEQIPUtpsLNtMRXLO1v5X7hbJ8N76gdO6UHu7RqyCElRjUaNqtGug0pkQBC5sDepg==" }, - "node-fetch": { - "version": "2.6.9", - "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.6.9.tgz", - "integrity": "sha512-DJm/CJkZkRjKKj4Zi4BsKVZh3ValV5IR5s7LVZnW+6YMh0W1BfNA8XSs6DLMGYlId5F3KnA70uu2qepcR08Qqg==", - "requires": { - "whatwg-url": "^5.0.0" - } - }, "projen": { "version": "0.71.60", "resolved": "https://registry.npmjs.org/projen/-/projen-0.71.60.tgz", @@ -2847,29 +2800,10 @@ } } }, - "tr46": { - "version": "0.0.3", - "resolved": "https://registry.npmjs.org/tr46/-/tr46-0.0.3.tgz", - "integrity": "sha512-N3WMsuqV66lT30CrXNbEjx4GEwlow3v6rr4mCcv6prnfwhS01rkgyFdjPNBYd9br7LpXV1+Emh01fHnq2Gdgrw==" - }, "uuid": { "version": "9.0.0", "resolved": "https://registry.npmjs.org/uuid/-/uuid-9.0.0.tgz", "integrity": "sha512-MXcSTerfPa4uqyzStbRoTgt5XIe3x5+42+q1sDuy3R5MDk66URdLMOZe5aPX/SQd+kuYAh0FdP/pO28IkQyTeg==" - }, - "webidl-conversions": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-3.0.1.tgz", - "integrity": "sha512-2JAn3z8AR6rjK8Sm8orRC0h/bcl/DqL7tRPdGZ4I1CjdF+EaMLmYxBHyXuKL849eucPFhvBoxMsflfOb8kxaeQ==" - }, - "whatwg-url": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-5.0.0.tgz", - "integrity": "sha512-saE57nupxk6v3HY35+jzBwYa0rKSy0XR8JSxZPwgLr7ys0IBzhGviA1/TUGJLmSVqs8pb9AnvICXEuOHLprYTw==", - "requires": { - "tr46": "~0.0.3", - "webidl-conversions": "^3.0.0" - } } } } diff --git a/examples/tests/valid/package.json b/examples/tests/valid/package.json index 0d09305c984..2bacbcc9b06 100644 --- a/examples/tests/valid/package.json +++ b/examples/tests/valid/package.json @@ -4,7 +4,6 @@ "aws-cdk-lib": "^2.77.0", "constructs": "^10", "jsii-code-samples": "1.7.0", - "node-fetch": "^2", "projen": "^0.71.60", "uuid": "^9.0.0" }, diff --git a/examples/plugins/app.w b/examples/tests/valid/plugins/app.w similarity index 100% rename from examples/plugins/app.w rename to examples/tests/valid/plugins/app.w diff --git a/examples/plugins/permission-boundary.js b/examples/tests/valid/plugins/permission-boundary.js similarity index 100% rename from examples/plugins/permission-boundary.js rename to examples/tests/valid/plugins/permission-boundary.js diff --git a/examples/plugins/replicate-s3.js b/examples/tests/valid/plugins/replicate-s3.js similarity index 100% rename from examples/plugins/replicate-s3.js rename to examples/tests/valid/plugins/replicate-s3.js diff --git a/examples/plugins/tf-backend.js b/examples/tests/valid/plugins/tf-backend.js similarity index 100% rename from examples/plugins/tf-backend.js rename to examples/tests/valid/plugins/tf-backend.js diff --git a/libs/tree-sitter-wing/package.json b/libs/tree-sitter-wing/package.json index ade1fc4b02d..782dd86a4a9 100644 --- a/libs/tree-sitter-wing/package.json +++ b/libs/tree-sitter-wing/package.json @@ -24,9 +24,9 @@ "test:watch": "npx -y nodemon --watch grammar.js --watch src/scanner.c --exec \"npm run test\"", "build": "npx -y tree-sitter-cli generate", "build:watch": "npx -y nodemon --watch grammar.js --watch src/scanner.c --exec \"npm run build\"", - "build:wasm": "npm run build && npx -y tree-sitter-cli build-wasm --docker", - "playground": "npm run build:wasm && npx -y tree-sitter-cli playground", - "playground:quiet": "npm run build:wasm && npx -y tree-sitter-cli playground -q", + "build:wasm": "npm run build && npx -y tree-sitter-cli@0.20.6 build-wasm --docker", + "playground": "npm run build:wasm && npx -y tree-sitter-cli@0.20.6 playground", + "playground:quiet": "npm run build:wasm && npx -y tree-sitter-cli@0.20.6 playground -q", "playground:watch": "npx -y nodemon --watch grammar.js --watch src/scanner.c --exec \"npm run playground:quiet\"" }, "volta": { diff --git a/libs/wingc/project.json b/libs/wingc/project.json index 8e5562162ce..dac4d7b346a 100644 --- a/libs/wingc/project.json +++ b/libs/wingc/project.json @@ -9,11 +9,6 @@ "options": { "command": "cargo test", "cwd": "libs/wingc" - }, - "configurations": { - "release": { - "command": "INSTA_UPDATE=\"no\" cargo test" - } } }, "lint": { diff --git a/libs/wingc/src/ast.rs b/libs/wingc/src/ast.rs index 9f269cdd83a..7e3ffd72208 100644 --- a/libs/wingc/src/ast.rs +++ b/libs/wingc/src/ast.rs @@ -494,13 +494,15 @@ impl Expr { pub struct ArgList { pub pos_args: Vec, pub named_args: IndexMap, + pub span: WingSpan, } impl ArgList { - pub fn new() -> Self { + pub fn new(span: WingSpan) -> Self { ArgList { pos_args: vec![], named_args: IndexMap::new(), + span, } } } diff --git a/libs/wingc/src/closure_transform.rs b/libs/wingc/src/closure_transform.rs index a2fb8e4bed7..e01ff30f388 100644 --- a/libs/wingc/src/closure_transform.rs +++ b/libs/wingc/src/closure_transform.rs @@ -276,6 +276,7 @@ impl Fold for ClosureTransformer { arg_list: ArgList { named_args: IndexMap::new(), pos_args: vec![], + span: WingSpan::default(), }, obj_id: None, obj_scope: None, diff --git a/libs/wingc/src/comp_ctx.rs b/libs/wingc/src/comp_ctx.rs index 80223a382f2..d0e1ee7052b 100644 --- a/libs/wingc/src/comp_ctx.rs +++ b/libs/wingc/src/comp_ctx.rs @@ -104,7 +104,7 @@ pub fn set_custom_panic_hook() { report_diagnostic(Diagnostic { message: format!( - "Compiler bug ({}) during {}, please report at https://docs.winglang.io/contributors/bugs", + "Compiler bug ({}) during {}, please report at https://docs.winglang.io/contributing/bugs", pi, CompilationContext::get_phase() ), diff --git a/libs/wingc/src/jsify/files.rs b/libs/wingc/src/files.rs similarity index 96% rename from libs/wingc/src/jsify/files.rs rename to libs/wingc/src/files.rs index 69e27250f53..cd5113a134f 100644 --- a/libs/wingc/src/jsify/files.rs +++ b/libs/wingc/src/files.rs @@ -35,6 +35,7 @@ impl From for Diagnostic { impl Error for FilesError {} +#[derive(Default)] pub struct Files { data: HashMap, } @@ -53,6 +54,10 @@ impl Files { Ok(()) } + pub fn get_file>(&self, path: S) -> Option<&String> { + self.data.get(path.as_ref()) + } + pub fn emit_files(&self, out_dir: &Path) -> Result<(), FilesError> { for (path, content) in &self.data { let full_path = out_dir.join(path); diff --git a/libs/wingc/src/fold.rs b/libs/wingc/src/fold.rs index 71c66a9b368..0311466ae43 100644 --- a/libs/wingc/src/fold.rs +++ b/libs/wingc/src/fold.rs @@ -417,6 +417,7 @@ where .into_iter() .map(|(name, arg)| (f.fold_symbol(name), f.fold_expr(arg))) .collect(), + span: node.span, } } diff --git a/libs/wingc/src/jsify.rs b/libs/wingc/src/jsify.rs index 5394a95de03..008e7f2ec9d 100644 --- a/libs/wingc/src/jsify.rs +++ b/libs/wingc/src/jsify.rs @@ -1,5 +1,4 @@ pub mod codemaker; -mod files; use aho_corasick::AhoCorasick; use const_format::formatcp; @@ -24,16 +23,18 @@ use crate::{ comp_ctx::{CompilationContext, CompilationPhase}, dbg_panic, debug, diagnostic::{report_diagnostic, Diagnostic, WingSpan}, + files::Files, type_check::{ resolve_user_defined_type, symbol_env::{LookupResult, SymbolEnv, SymbolEnvRef}, ClassLike, SymbolKind, Type, TypeRef, Types, UnsafeRef, VariableInfo, CLASS_INFLIGHT_INIT_NAME, HANDLE_METHOD_NAME, }, visit::{self, Visit}, - MACRO_REPLACE_ARGS, MACRO_REPLACE_SELF, WINGSDK_ASSEMBLY_NAME, WINGSDK_RESOURCE, WINGSDK_STD_MODULE, + MACRO_REPLACE_ARGS, MACRO_REPLACE_ARGS_TEXT, MACRO_REPLACE_SELF, WINGSDK_ASSEMBLY_NAME, WINGSDK_RESOURCE, + WINGSDK_STD_MODULE, }; -use self::{codemaker::CodeMaker, files::Files}; +use self::codemaker::CodeMaker; const PREFLIGHT_FILE_NAME: &str = "preflight.js"; @@ -62,8 +63,8 @@ pub struct JSifyContext { pub struct JSifier<'a> { pub types: &'a Types, - /// Stores all generated JS files in memory. - files: Files, + source_files: &'a Files, + emitted_files: Files, /// Root of the project, used for resolving extern modules absolute_project_root: &'a Path, shim: bool, @@ -79,10 +80,17 @@ enum BindMethod { } impl<'a> JSifier<'a> { - pub fn new(types: &'a Types, app_name: &'a str, absolute_project_root: &'a Path, shim: bool) -> Self { + pub fn new( + types: &'a Types, + source_files: &'a Files, + app_name: &'a str, + absolute_project_root: &'a Path, + shim: bool, + ) -> Self { Self { types, - files: Files::new(), + source_files, + emitted_files: Files::new(), shim, app_name, absolute_project_root, @@ -180,7 +188,7 @@ impl<'a> JSifier<'a> { output.add_code(js); } - match self.files.add_file(PREFLIGHT_FILE_NAME, output.to_string()) { + match self.emitted_files.add_file(PREFLIGHT_FILE_NAME, output.to_string()) { Ok(()) => {} Err(err) => report_diagnostic(err.into()), } @@ -188,7 +196,7 @@ impl<'a> JSifier<'a> { /// Write all files to the output directory pub fn emit_files(&mut self, out_dir: &Path) { - match self.files.emit_files(out_dir) { + match self.emitted_files.emit_files(out_dir) { Ok(()) => {} Err(err) => report_diagnostic(err.into()), } @@ -303,17 +311,17 @@ impl<'a> JSifier<'a> { let ctor = self.jsify_type(&class.kind, ctx); - let scope = if is_preflight_class { + let scope = if is_preflight_class && class_type.std_construct_args { if let Some(scope) = obj_scope { Some(self.jsify_expression(scope, ctx)) } else { Some("this".to_string()) } } else { - None - }; + None + }; - let id = if is_preflight_class { + let id = if is_preflight_class && class_type.std_construct_args { Some(if let Some(id_exp) = obj_id { self.jsify_expression(id_exp, ctx) } else { @@ -337,26 +345,34 @@ impl<'a> JSifier<'a> { } } ExprKind::Literal(lit) => match lit { - Literal::Nil => "undefined".to_string(), + Literal::Nil => "undefined".to_string(), Literal::String(s) => s.to_string(), - Literal::InterpolatedString(s) => format!( - "`{}`", - s.parts + Literal::InterpolatedString(s) => { + let comma_separated_statics = s + .parts + .iter() + .filter_map(|p| match p { + InterpolatedStringPart::Static(l) => Some(format!("\"{}\"", l.to_string())), + InterpolatedStringPart::Expr(_) => None, + }) + .collect::>() + .join(", "); + let comma_separated_exprs = s + .parts .iter() - .map(|p| match p { - InterpolatedStringPart::Static(l) => l.to_string(), - InterpolatedStringPart::Expr(e) => { - match *self.get_expr_type(e) { - Type::Json | Type::MutJson => { - format!("${{JSON.stringify({}, null, 2)}}", self.jsify_expression(e, ctx)) - } - _ => format!("${{{}}}", self.jsify_expression(e, ctx)), + .filter_map(|p| match p { + InterpolatedStringPart::Static(_) => None, + InterpolatedStringPart::Expr(e) => Some(match *self.get_expr_type(e) { + Type::Json | Type::MutJson => { + format!("((e) => typeof e === 'string' ? e : JSON.stringify(e, null, 2))({})", self.jsify_expression(e, ctx)) } - } + _ => self.jsify_expression(e, ctx), + }) }) .collect::>() - .join("") - ), + .join(", "); + format!("String.raw({{ raw: [{}] }}, {})", comma_separated_statics, comma_separated_exprs) + }, Literal::Number(n) => format!("{}", n), Literal::Boolean(b) => (if *b { "true" } else { "false" }).to_string(), }, @@ -386,7 +402,13 @@ impl<'a> JSifier<'a> { ExprKind::Reference(reference) => self.jsify_reference(reference, ctx), _ => format!("({})", self.jsify_expression(callee, ctx)), }; - let arg_string = self.jsify_arg_list(&arg_list, None, None, ctx); + let args_string = self.jsify_arg_list(&arg_list, None, None, ctx); + let mut args_text_string = lookup_span(&arg_list.span, &self.source_files); + if args_text_string.len() > 0 { + // remove the parens + args_text_string = args_text_string[1..args_text_string.len() - 1].to_string(); + } + let args_text_string = escape_javascript_string(&args_text_string); if let Some(function_sig) = function_sig { if let Some(js_override) = &function_sig.js_override { @@ -399,8 +421,8 @@ impl<'a> JSifier<'a> { _ => expr_string, }; - let patterns = &[MACRO_REPLACE_SELF, MACRO_REPLACE_ARGS]; - let replace_with = &[self_string, &arg_string]; + let patterns = &[MACRO_REPLACE_SELF, MACRO_REPLACE_ARGS, MACRO_REPLACE_ARGS_TEXT]; + let replace_with = &[self_string, &args_string, &args_text_string]; let ac = AhoCorasick::new(patterns); return ac.replace_all(js_override, replace_with); } @@ -408,7 +430,7 @@ impl<'a> JSifier<'a> { // NOTE: if the expression is a "handle" class, the object itself is callable (see // `jsify_class_inflight` below), so we can just call it as-is. - format!("({auto_await}{expr_string}({arg_string}))") + format!("({auto_await}{expr_string}({args_string}))") } ExprKind::Unary { op, exp } => { let js_exp = self.jsify_expression(exp, ctx); @@ -1312,7 +1334,7 @@ impl<'a> JSifier<'a> { code.line(format!("return {name};")); code.close("}"); - match self.files.add_file(inflight_filename(class), code.to_string()) { + match self.emitted_files.add_file(inflight_filename(class), code.to_string()) { Ok(()) => {} Err(err) => report_diagnostic(err.into()), } @@ -1359,7 +1381,7 @@ impl<'a> JSifier<'a> { .filter(|(_, kind, _)| { let var = kind.as_variable().unwrap(); // We capture preflight non-reassignable fields - var.phase != Phase::Inflight && !var.reassignable && var.type_.is_capturable() + var.phase != Phase::Inflight && var.type_.is_capturable() }) .map(|(name, ..)| name) .collect_vec() @@ -1541,19 +1563,8 @@ impl<'ast> Visit<'ast> for FieldReferenceVisitor<'ast> { } // now we need to verify that the component can be captured. - // (1) non-reassignable // (2) capturable type (immutable/resource). - // if the variable is reassignable, bail out - if variable.reassignable { - report_diagnostic(Diagnostic { - message: format!("Cannot capture reassignable field '{curr}'"), - span: Some(curr.span.clone()), - }); - - return; - } - // if this type is not capturable, bail out if !variable.type_.is_capturable() { report_diagnostic(Diagnostic { @@ -1695,19 +1706,28 @@ impl<'a> FieldReferenceVisitor<'a> { let lookup = env.lookup_ext(&x, Some(self.statement_index)); // if the reference is already defined later in this scope, skip it - if let LookupResult::DefinedLater = lookup { + if matches!(lookup, LookupResult::DefinedLater) { return vec![]; } + let id_name = x.name.clone(); + let id_span = x.span.clone(); + let LookupResult::Found(kind, _) = lookup else { return vec![Component { - text: x.name.clone(), - span: x.span.clone(), + text: id_name, + span: id_span, kind: ComponentKind::Unsupported, }]; }; - let var = kind.as_variable().expect("variable"); + let Some(var) = kind.as_variable() else { + return vec![Component { + text: id_name, + span: id_span, + kind: ComponentKind::Unsupported, + }]; + }; // If the reference isn't a preflight (lifted) variable then skip it if var.phase != Phase::Preflight { @@ -1715,8 +1735,8 @@ impl<'a> FieldReferenceVisitor<'a> { } return vec![Component { - text: x.name.clone(), - span: x.span.clone(), + text: id_name, + span: id_span, kind: ComponentKind::Member(var), }]; } @@ -1778,9 +1798,9 @@ impl<'a> FieldReferenceVisitor<'a> { fn determine_component_kind_from_type(obj_type: UnsafeRef, property: &Symbol) -> Option { match &*obj_type { - Type::Void => unreachable!("cannot reference a member of void"), - Type::Function(_) => unreachable!("cannot reference a member of a function"), - Type::Optional(t) => Self::determine_component_kind_from_type(*t, property), + // Invalid cases, should be caught by typechecker + Type::Void | Type::Function(_) | Type::Unresolved => None, + // all fields / methods / values of these types are phase-independent so we can skip them Type::Anything | Type::Number @@ -1790,15 +1810,18 @@ impl<'a> FieldReferenceVisitor<'a> { | Type::Json | Type::MutJson | Type::Nil - | Type::Enum(_) => return None, + | Type::Enum(_) => None, + + Type::Optional(t) => Self::determine_component_kind_from_type(*t, property), + // TODO: collection types are unsupported for now Type::Array(_) | Type::MutArray(_) | Type::Map(_) | Type::MutMap(_) | Type::Set(_) | Type::MutSet(_) => { Some(ComponentKind::Unsupported) } + Type::Class(cls) => Some(ComponentKind::Member(cls.env.lookup(&property, None)?.as_variable()?)), Type::Interface(iface) => Some(ComponentKind::Member(iface.env.lookup(&property, None)?.as_variable()?)), Type::Struct(st) => Some(ComponentKind::Member(st.env.lookup(&property, None)?.as_variable()?)), - Type::Unresolved => panic!("Encountered unresolved type during jsification"), } } } @@ -1889,7 +1912,9 @@ impl<'a> CaptureScanner<'a> { self.captured_vars.insert(fullname); } - SymbolKind::Namespace(_) => todo!(), + // Namespaces are not captured as they are not actually valid references + // The existence of this reference will have already caused an error in the type checker + SymbolKind::Namespace(_) => {} } } } @@ -1961,3 +1986,72 @@ fn jsify_type_name(t: &Vec, phase: Phase) -> String { p.join(".") } } + +fn lookup_span(span: &WingSpan, files: &Files) -> String { + let source = files + .get_file(&span.file_id) + .expect(&format!("failed to find source file with id {}", span.file_id)); + let lines = source.lines().collect_vec(); + + let start_line = span.start.line as usize; + let end_line = span.end.line as usize; + + let start_col = span.start.col as usize; + let end_col = span.end.col as usize; + + let mut result = String::new(); + + if start_line == end_line { + result.push_str(&lines[start_line][start_col..end_col]); + } else { + result.push_str(&lines[start_line][start_col..]); + result.push('\n'); + + for line in lines[start_line + 1..end_line].iter() { + result.push_str(line); + result.push('\n'); + } + + result.push_str(&lines[end_line][..end_col]); + } + + result +} + +fn escape_javascript_string(s: &str) -> String { + let mut result = String::new(); + + // escape all escapable characters -- see the section "Escape sequences" in + // https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Lexical_grammar#literals + for c in s.chars() { + match c { + '\0' => result.push_str("\\0"), + '\'' => result.push_str("\\'"), + '"' => result.push_str("\\\""), + '\\' => result.push_str("\\\\"), + '\n' => result.push_str("\\n"), + '\r' => result.push_str("\\r"), + '\t' => result.push_str("\\t"), + _ => result.push(c), + } + } + + result +} + +#[cfg(test)] +mod tests { + use super::*; + + #[test] + fn test_escape_javascript_string() { + assert_eq!(escape_javascript_string("hello"), String::from("hello")); + assert_eq!(escape_javascript_string("hello\nworld"), String::from("hello\\nworld")); + assert_eq!(escape_javascript_string("hello\rworld"), String::from("hello\\rworld")); + assert_eq!(escape_javascript_string("hello\tworld"), String::from("hello\\tworld")); + assert_eq!(escape_javascript_string("hello\\world"), String::from("hello\\\\world")); + assert_eq!(escape_javascript_string("hello'world"), String::from("hello\\'world")); + assert_eq!(escape_javascript_string("hello\"world"), String::from("hello\\\"world")); + assert_eq!(escape_javascript_string("hello\0world"), String::from("hello\\0world")); + } +} diff --git a/libs/wingc/src/lib.rs b/libs/wingc/src/lib.rs index f0d582c74d8..336875cc0cf 100644 --- a/libs/wingc/src/lib.rs +++ b/libs/wingc/src/lib.rs @@ -11,6 +11,7 @@ use ast::{Scope, Stmt, Symbol, UtilityFunctions}; use closure_transform::ClosureTransformer; use comp_ctx::set_custom_panic_hook; use diagnostic::{found_errors, report_diagnostic, Diagnostic}; +use files::Files; use fold::Fold; use jsify::JSifier; use type_check::jsii_importer::JsiiImportSpec; @@ -39,6 +40,7 @@ mod comp_ctx; pub mod debug; pub mod diagnostic; mod docs; +mod files; pub mod fold; pub mod jsify; pub mod lsp; @@ -54,14 +56,15 @@ pub const WINGSDK_STD_MODULE: &'static str = "std"; const WINGSDK_REDIS_MODULE: &'static str = "redis"; const WINGSDK_CLOUD_MODULE: &'static str = "cloud"; const WINGSDK_UTIL_MODULE: &'static str = "util"; +const WINGSDK_HTTP_MODULE: &'static str = "http"; const WINGSDK_DURATION: &'static str = "std.Duration"; -const WINGSDK_MAP: &'static str = "std.ImmutableMap"; -const WINGSDK_MUT_MAP: &'static str = "std.MutableMap"; -const WINGSDK_ARRAY: &'static str = "std.ImmutableArray"; -const WINGSDK_MUT_ARRAY: &'static str = "std.MutableArray"; -const WINGSDK_SET: &'static str = "std.ImmutableSet"; -const WINGSDK_MUT_SET: &'static str = "std.MutableSet"; +const WINGSDK_MAP: &'static str = "std.Map"; +const WINGSDK_MUT_MAP: &'static str = "std.MutMap"; +const WINGSDK_ARRAY: &'static str = "std.Array"; +const WINGSDK_MUT_ARRAY: &'static str = "std.MutArray"; +const WINGSDK_SET: &'static str = "std.Set"; +const WINGSDK_MUT_SET: &'static str = "std.MutSet"; const WINGSDK_STRING: &'static str = "std.String"; const WINGSDK_JSON: &'static str = "std.Json"; const WINGSDK_MUT_JSON: &'static str = "std.MutJson"; @@ -72,6 +75,7 @@ const CONSTRUCT_BASE_CLASS: &'static str = "constructs.Construct"; const MACRO_REPLACE_SELF: &'static str = "$self$"; const MACRO_REPLACE_ARGS: &'static str = "$args$"; +const MACRO_REPLACE_ARGS_TEXT: &'static str = "$args_text$"; pub struct CompilerOutput {} @@ -134,7 +138,7 @@ pub unsafe extern "C" fn wingc_compile(ptr: u32, len: u32) -> u64 { } } -pub fn parse(source_path: &Path) -> Scope { +pub fn parse(source_path: &Path) -> (Files, Scope) { let language = tree_sitter_wing::language(); let mut parser = tree_sitter::Parser::new(); parser.set_language(language).unwrap(); @@ -153,20 +157,31 @@ pub fn parse(source_path: &Path) -> Scope { env: RefCell::new(None), span: Default::default(), }; - return empty_scope; + return (Files::default(), empty_scope); } }; - let tree = match parser.parse(&source[..], None) { + let mut files = Files::new(); + match files.add_file( + source_path.to_path_buf(), + String::from_utf8(source.clone()).expect("Invalid UTF-8 sequence"), + ) { + Ok(_) => {} + Err(err) => { + panic!("Failed adding source file to parser: {}", err); + } + } + + let tree = match parser.parse(&source, None) { Some(tree) => tree, None => { panic!("Failed parsing source file: {}", source_path.display()); } }; - let wing_parser = Parser::new(&source[..], source_path.to_str().unwrap().to_string()); + let wing_parser = Parser::new(&source, source_path.to_str().unwrap().to_string()); - wing_parser.wingit(&tree.root_node()) + (files, wing_parser.wingit(&tree.root_node())) } pub fn type_check( @@ -177,7 +192,7 @@ pub fn type_check( jsii_imports: &mut Vec, ) { assert!(scope.env.borrow().is_none(), "Scope should not have an env yet"); - let env = SymbolEnv::new(None, types.void(), false, Phase::Preflight, 0); + let env = SymbolEnv::new(None, types.void(), false, false, Phase::Preflight, 0); scope.set_env(env); // note: Globals are emitted here and wrapped in "{ ... }" blocks. Wrapping makes these emissions, actual @@ -210,7 +225,9 @@ pub fn type_check( }], return_type: types.void(), phase: Phase::Independent, - js_override: Some("{((cond) => {if (!cond) throw new Error(`assertion failed: '$args$'`)})($args$)}".to_string()), + js_override: Some( + "{((cond) => {if (!cond) throw new Error(\"assertion failed: $args_text$\")})($args$)}".to_string(), + ), docs: Docs::with_summary("Asserts that a condition is true"), }), scope, @@ -302,7 +319,7 @@ pub fn compile( let out_dir = out_dir.unwrap_or(default_out_dir.as_ref()); // -- PARSING PHASE -- - let scope = parse(&source_path); + let (files, scope) = parse(&source_path); // -- DESUGARING PHASE -- @@ -347,7 +364,7 @@ pub fn compile( return Err(()); } - let mut jsifier = JSifier::new(&types, app_name, &project_dir, true); + let mut jsifier = JSifier::new(&types, &files, app_name, &project_dir, true); jsifier.jsify(&scope); jsifier.emit_files(&out_dir); diff --git a/libs/wingc/src/lsp/completions.rs b/libs/wingc/src/lsp/completions.rs index 8c8cc3fc648..fd3cb6cb7d0 100644 --- a/libs/wingc/src/lsp/completions.rs +++ b/libs/wingc/src/lsp/completions.rs @@ -7,9 +7,9 @@ use tree_sitter::Point; use crate::ast::{Expr, ExprKind, Phase, Scope, Symbol, TypeAnnotation, TypeAnnotationKind, UserDefinedType}; use crate::closure_transform::{CLOSURE_CLASS_PREFIX, PARENT_THIS_NAME}; -use crate::diagnostic::{WingLocation, WingSpan}; +use crate::diagnostic::WingSpan; use crate::docs::Documented; -use crate::lsp::sync::FILES; +use crate::lsp::sync::{FILES, JSII_TYPES}; use crate::type_check::symbol_env::{LookupResult, StatementIdx}; use crate::type_check::{ import_udt_from_jsii, resolve_user_defined_type, ClassLike, Namespace, SymbolKind, Type, Types, UnsafeRef, @@ -19,8 +19,6 @@ use crate::visit::{visit_expr, visit_type_annotation, Visit}; use crate::wasm_util::{ptr_to_string, string_to_combined_ptr, WASM_RETURN_ERROR}; use crate::{WINGSDK_ASSEMBLY_NAME, WINGSDK_STD_MODULE}; -use super::sync::JSII_TYPES; - #[no_mangle] pub unsafe extern "C" fn wingc_on_completion(ptr: u32, len: u32) -> u64 { let parse_string = ptr_to_string(ptr, len); @@ -40,185 +38,201 @@ pub fn on_completion(params: lsp_types::CompletionParams) -> CompletionResponse let mut files = files.borrow_mut(); let uri = params.text_document_position.text_document.uri; let file_data = files.get_mut(&uri).expect("File must be open to get completions"); - let types = &file_data.types; + let root_ts_node = file_data.tree.root_node(); let root_scope = &file_data.scope; let root_env = root_scope.env.borrow(); let root_env = root_env.as_ref().expect("The root scope must have an environment"); + let file = uri.to_file_path().ok().expect("LSP only works on real filesystems"); - let mut point = Point::new( - params.text_document_position.position.line as usize, - max(params.text_document_position.position.character as i64 - 1, 0) as usize, + let node_to_complete = nearest_interesting_node( + Point::new( + params.text_document_position.position.line as usize, + max(params.text_document_position.position.character as i64 - 1, 0) as usize, + ), + &root_ts_node, ); - let mut node_to_complete = file_data - .tree - .root_node() - .descendant_for_point_range(point, point) - .expect("There is always at-least one tree-sitter node"); + let node_to_complete_kind = node_to_complete.kind(); + + let file_id = file.to_str().expect("File path must be valid utf8"); + let mut scope_visitor = ScopeVisitor::new( + node_to_complete.parent().map(|parent| WingSpan { + start: parent.start_position().into(), + end: parent.end_position().into(), + file_id: file_id.to_string(), + }), + WingSpan { + start: node_to_complete.start_position().into(), + end: node_to_complete.end_position().into(), + file_id: file_id.to_string(), + }, + &root_scope, + ); + scope_visitor.visit(); - while point.column > 0 && node_to_complete.kind() == "source" { - // We are somewhere in whitespace aether, so we need to backtrack to the nearest node on this line - point.column -= 1; - node_to_complete = file_data - .tree - .root_node() - .descendant_for_point_range(point, point) - .expect("There is always at-least one tree-sitter node"); - } + let found_env = scope_visitor.found_scope.env.borrow(); + let found_env = found_env.as_ref().unwrap(); - let file = uri.to_file_path().ok().expect("LSP only works on real filesystems"); + if node_to_complete_kind == "." || node_to_complete_kind == "?." { + let parent = node_to_complete.parent().expect("A dot must have a parent"); - let wing_location = WingLocation { - col: point.column as u32, - line: point.row as u32, - }; + if let Some(nearest_expr) = scope_visitor.nearest_expr { + let nearest_expr_type = types.get_expr_type(nearest_expr).unwrap(); - let mut scope_visitor = ScopeVisitor::new(WingSpan { - start: wing_location, - end: wing_location, - file_id: file.to_str().expect("File path must be valid utf8").to_string(), - }); - scope_visitor.visit_scope(root_scope); + // If we are inside an incomplete reference, there is possibly a type error or an anything which has no completions + if !nearest_expr_type.is_unresolved() { + // We need to double-check for an invalid nested reference (e.g. If there are multiple dots in a row) + let mut previous_point = node_to_complete.start_position(); + if previous_point.column > 0 { + previous_point.column -= 1; + let previous_node = nearest_interesting_node(previous_point, &root_ts_node); - let found_env = scope_visitor.found_scope.unwrap(); - let found_env = found_env.env.borrow(); - let found_env = found_env.as_ref().unwrap(); - - let parent = node_to_complete.parent(); - - if node_to_complete.kind() == "." { - let parent = parent.expect("A dot must have a parent"); - - if parent.kind() == "nested_identifier" { - if let Some(nearest_expr) = scope_visitor.nearest_expr { - let nearest_expr_type = types.get_expr_type(nearest_expr).unwrap(); - - // If we are inside an incomplete reference, there is possibly a type error or an anything which has no completions - if !nearest_expr_type.is_anything() && !nearest_expr_type.is_unresolved() { - return get_completions_from_type( - &nearest_expr_type, - types, - scope_visitor - .found_scope - .map(|s| s.env.borrow().as_ref().expect("Scopes must have an environment").phase), - true, - ); + if previous_node.kind() == "." || previous_node.kind() == "?." { + return vec![]; + } } - } - // We're likely in a type reference, so let's use the raw text for a lookup - let wing_source = file_data.contents.as_bytes(); - let mut reference_text = parent - .utf8_text(wing_source) - .expect("The referenced text should be available") - .to_string(); - if reference_text.ends_with(".") { - reference_text.pop(); + return get_completions_from_type(&nearest_expr_type, types, Some(found_env.phase), true); } + } - reference_text = add_std_namespace(&reference_text); + if let Some(nearest_type_annotation) = scope_visitor.nearest_type_annotation { + if let TypeAnnotationKind::UserDefined(udt) = &nearest_type_annotation.kind { + let type_lookup = resolve_user_defined_type(udt, found_env, scope_visitor.found_stmt_index.unwrap_or(0)); + + let mut completions = if let Ok(type_lookup) = type_lookup { + get_completions_from_type(&type_lookup, types, Some(found_env.phase), false) + } else { + // this is probably a namespace, let's look it up + if let Some(namespace) = root_env + .lookup_nested_str(&udt.full_path_str(), scope_visitor.found_stmt_index) + .ok() + .and_then(|n| n.0.as_namespace_ref()) + { + get_completions_from_namespace(&namespace, Some(found_env.phase)) + } else { + // This is not a known type or namespace + vec![] + } + }; + + if parent.parent().expect("custom_type must have a parent node").kind() == "new_expression" { + completions = completions + .iter() + .filter(|c| { + matches!( + c.kind, + Some(CompletionItemKind::CLASS) | Some(CompletionItemKind::MODULE) + ) + }) + .cloned() + .map(|mut c| { + if c.kind == Some(CompletionItemKind::CLASS) { + convert_to_call_completion(&mut c); + } + c + }) + .collect(); + } - let lookup_thing = found_env - .lookup_nested_str(&reference_text, scope_visitor.found_stmt_index) - .ok(); + return completions; + } + } - if let Some((lookup_thing, _)) = lookup_thing { - match lookup_thing { - SymbolKind::Type(t) => { - return get_completions_from_type(&t, types, Some(found_env.phase), false); - } - SymbolKind::Variable(v) => { - return get_completions_from_type( - &v.type_, - types, - scope_visitor - .found_scope - .map(|s| s.env.borrow().as_ref().expect("Scopes must have an environment").phase), - false, - ) - } - SymbolKind::Namespace(n) => { - // If the types in this namespace aren't loaded yet, load them now to get completions - if !n.loaded { - JSII_TYPES.with(|jsii_types| { - let mut jsii_types = jsii_types.borrow_mut(); - let parts = reference_text.split(".").collect::>(); - // Dummy type representing the namespace to be loaded - let udt = UserDefinedType { - root: Symbol::global(parts[0].to_string()), - fields: parts[1..].iter().map(|s| Symbol::global(s.to_string())).collect(), - span: WingSpan::default(), - }; - // Import all types in the namespace by trying to load the "dummy type" - import_udt_from_jsii(&mut file_data.types, &mut jsii_types, &udt, &file_data.jsii_imports); - }); - } - return get_completions_from_namespace(&n, Some(found_env.phase)); + // We're likely in a type reference of some kind, so let's use the raw text for a lookup + let wing_source_bytes = file_data.contents.as_bytes(); + let reference_bytes = &wing_source_bytes[parent.start_byte()..node_to_complete.start_byte()]; + let reference_text = + add_std_namespace(std::str::from_utf8(reference_bytes).expect("Reference must be valid utf8")); + + if let Some((lookup_thing, _)) = found_env + .lookup_nested_str(&reference_text, scope_visitor.found_stmt_index) + .ok() + { + match lookup_thing { + SymbolKind::Type(t) => { + return get_completions_from_type(&t, types, Some(found_env.phase), false); + } + SymbolKind::Variable(v) => return get_completions_from_type(&v.type_, types, Some(found_env.phase), false), + SymbolKind::Namespace(n) => { + // If the types in this namespace aren't loaded yet, load them now to get completions + if !n.loaded { + JSII_TYPES.with(|jsii_types| { + let mut jsii_types = jsii_types.borrow_mut(); + let parts = reference_text.split(".").collect::>(); + // Dummy type representing the namespace to be loaded + let udt = UserDefinedType { + root: Symbol::global(parts[0].to_string()), + fields: parts[1..].iter().map(|s| Symbol::global(s.to_string())).collect(), + span: WingSpan::default(), + }; + // Import all types in the namespace by trying to load the "dummy type" + import_udt_from_jsii(&mut file_data.types, &mut jsii_types, &udt, &file_data.jsii_imports); + }); } + return get_completions_from_namespace(&n, Some(found_env.phase)); } - } else { - return vec![]; } } - if parent.kind() == "custom_type" { - if let Some(nearest_type_annotation) = scope_visitor.nearest_type_annotation { - if let TypeAnnotationKind::UserDefined(udt) = &nearest_type_annotation.kind { - let type_lookup = resolve_user_defined_type(udt, found_env, scope_visitor.found_stmt_index.unwrap()); + return vec![]; + } - if let Ok(type_lookup) = type_lookup { - return get_completions_from_type(&type_lookup, types, Some(found_env.phase), false); - } else { - // this is probably a namespace, let's look it up - if let Some(namespace) = root_env - .lookup_nested_str(&udt.full_path_str(), scope_visitor.found_stmt_index) - .ok() - .and_then(|n| n.0.as_namespace_ref()) - { - let completions = get_completions_from_namespace(&namespace, Some(found_env.phase)); - //for namespaces - return only classes and namespaces - if parent.parent().expect("custom_type must have a parent node").kind() == "new_expression" { - return completions - .iter() - .filter(|c| { - matches!( - c.kind, - Some(CompletionItemKind::CLASS) | Some(CompletionItemKind::MODULE) - ) - }) - .map(|c| { - let mut c = c.clone(); - if c.kind == Some(CompletionItemKind::CLASS) { - c.insert_text = Some(format!("{}($0)", c.label)); - c.insert_text_format = Some(InsertTextFormat::SNIPPET); - c.command = Some(Command { - title: "triggerParameterHints".to_string(), - command: "editor.action.triggerParameterHints".to_string(), - arguments: None, - }); - } - c - }) - .collect(); - } else { - return completions; - } - } + // we are somewhere but not entirely sure + // for now, lets just get all the symbols within the current scope + let mut completions = vec![]; - // This is not a known type or namespace - return vec![]; - } + let mut in_type = false; + + match node_to_complete_kind { + // there are no possible completions that could follow ")" + ")" => return vec![], + + // This is the node we are in in the following case: + // inflight (stuff: ): num => {} + // ^ + "parameter_list" => in_type = true, + + // We are somewhere in the root of a file, so let's add some fun snippets + "source" => { + completions.push(CompletionItem { + label: "test \"\" { }".to_string(), + insert_text: Some("test \"$1\" {\n\t$2\n}".to_string()), + insert_text_format: Some(InsertTextFormat::SNIPPET), + kind: Some(CompletionItemKind::SNIPPET), + ..Default::default() + }); + } + _ => {} + } + + if let Some(parent) = node_to_complete.parent() { + match parent.kind() { + "ERROR" => { + if in_type || node_to_complete_kind == ":" { + in_type = true; + } else { + return vec![]; } } + // we are inside a class definition, so for now let's show nothing at all + "resource_definition" | "class_definition" => { + return vec![CompletionItem { + label: "init".to_string(), + insert_text: Some("init($1) {\n\t$2\n}".to_string()), + insert_text_format: Some(InsertTextFormat::SNIPPET), + kind: Some(CompletionItemKind::SNIPPET), + ..Default::default() + }]; + } + + "custom_type" => in_type = true, + _ => {} } } - // we are somewhere but not entirely sure - // for now, lets just get all the symbols within the current scope let found_stmt_index = scope_visitor.found_stmt_index.unwrap_or_default(); - let mut completions = vec![]; - for symbol_data in found_env.symbol_map.iter().filter(|s| { if let StatementIdx::Index(i) = s.1 .0 { // within the found scope, we only want to show symbols that were defined before the current position @@ -237,29 +251,37 @@ pub fn on_completion(params: lsp_types::CompletionParams) -> CompletionResponse if let Some(parent) = found_env.parent { for data in parent.iter(true) { if let Some(completion) = format_symbol_kind_as_completion(&data.0, &data.1) { - completions.push(completion); + if completions.iter().all(|c| c.label != completion.label) { + completions.push(completion); + } } } } - // lets also add some fun snippets - completions.push(CompletionItem { - label: "inflight () => {}".to_string(), - insert_text: Some("inflight ($1) => {$2}".to_string()), - insert_text_format: Some(InsertTextFormat::SNIPPET), - kind: Some(CompletionItemKind::SNIPPET), - ..Default::default() - }); - - completions.push(CompletionItem { - label: "test \"\" { }".to_string(), - insert_text: Some("test \"$1\" {\n\t$2\n}".to_string()), - insert_text_format: Some(InsertTextFormat::SNIPPET), - kind: Some(CompletionItemKind::SNIPPET), - ..Default::default() - }); + if !in_type { + completions.push(CompletionItem { + label: "inflight () => {}".to_string(), + insert_text: Some("inflight ($1) => {$2}".to_string()), + insert_text_format: Some(InsertTextFormat::SNIPPET), + kind: Some(CompletionItemKind::SNIPPET), + ..Default::default() + }); + } - completions + if in_type { + // show only namespaces and types + completions + .into_iter() + .filter(|c| { + matches!( + c.kind, + Some(CompletionItemKind::CLASS) | Some(CompletionItemKind::MODULE) + ) + }) + .collect() + } else { + completions + } }); final_completions = final_completions @@ -274,6 +296,33 @@ pub fn on_completion(params: lsp_types::CompletionParams) -> CompletionResponse CompletionResponse::Array(final_completions) } +/// Within root_node, find the nearest (previous) node on the same line that is interesting for completion +fn nearest_interesting_node<'a>(mut point: Point, root_node: &'a tree_sitter::Node<'a>) -> tree_sitter::Node<'a> { + loop { + let search_node = root_node + .descendant_for_point_range(point, point) + .expect("There is always at-least one tree-sitter node"); + + if point.column == 0 || (search_node.kind() != "source" && search_node.kind() != "block" && !search_node.is_error()) + { + return search_node; + } + + point.column -= 1; + } +} + +/// Given a CompletionItem, mutates it so it can be used as a snippet to trigger parameter hints +fn convert_to_call_completion(completion_item: &mut CompletionItem) { + completion_item.insert_text = Some(format!("{}($0)", completion_item.label)); + completion_item.insert_text_format = Some(InsertTextFormat::SNIPPET); + completion_item.command = Some(Command { + title: "triggerParameterHints".to_string(), + command: "editor.action.triggerParameterHints".to_string(), + arguments: None, + }); +} + /// LSP sorts completions items alphabetically /// This function returns a string that can be used to sort the completion items in a more logical order fn completion_sort_text(completion_item: &CompletionItem) -> String { @@ -378,19 +427,20 @@ fn add_std_namespace(type_: &str) -> std::string::String { } else { &type_name }; + let type_name = match type_name { - "Set" => "ImmutableSet", - "Map" => "ImmutableMap", - "Array" => "ImmutableArray", - "MutSet" => "MutableSet", - "MutMap" => "MutableMap", - "MutArray" => "MutableArray", - "Json" | "MutJson" | "MutableArray" | "MutableMap" | "MutableSet" | "ImmutableArray" | "ImmutableMap" - | "ImmutableSet" | "String" | "Duration" | "Boolean" | "Number" => type_name, - _ => return type_name.to_string(), + "str" => "String", + "duration" => "Duration", + "bool" => "Boolean", + "num" => "Number", + _ => type_name, }; - format!("{WINGSDK_STD_MODULE}.{type_name}") + match type_name { + "Json" | "MutJson" | "MutArray" | "MutMap" | "MutSet" | "Array" | "Map" | "Set" | "String" | "Duration" + | "Boolean" | "Number" => format!("{WINGSDK_STD_MODULE}.{type_name}"), + _ => type_name.to_string(), + } } fn get_completions_from_namespace( @@ -462,30 +512,21 @@ fn get_completions_from_class( }; let is_method = kind == Some(CompletionItemKind::METHOD); - Some(CompletionItem { - insert_text: if is_method { - Some(format!("{}($0)", symbol_data.0)) - } else { - Some(symbol_data.0.to_string()) - }, + let mut completion_item = CompletionItem { label: symbol_data.0, documentation: Some(Documentation::MarkupContent(MarkupContent { kind: MarkupKind::Markdown, value: symbol_data.1.render_docs(), })), kind, - insert_text_format: Some(InsertTextFormat::SNIPPET), - command: if is_method { - Some(Command { - title: "triggerParameterHints".to_string(), - command: "editor.action.triggerParameterHints".to_string(), - arguments: None, - }) - } else { - None - }, ..Default::default() - }) + }; + + if is_method { + convert_to_call_completion(&mut completion_item); + } + + Some(completion_item) }) .collect() } @@ -539,27 +580,18 @@ fn format_symbol_kind_as_completion(name: &str, symbol_kind: &SymbolKind) -> Opt }; let is_method = kind == Some(CompletionItemKind::FUNCTION); - CompletionItem { + let mut completion_item = CompletionItem { label: name.to_string(), documentation, - insert_text: if is_method { - Some(format!("{name}($0)")) - } else { - Some(name.to_string()) - }, - insert_text_format: Some(InsertTextFormat::SNIPPET), kind, - command: if is_method { - Some(Command { - title: "triggerParameterHints".to_string(), - command: "editor.action.triggerParameterHints".to_string(), - arguments: None, - }) - } else { - None - }, ..Default::default() + }; + + if is_method { + convert_to_call_completion(&mut completion_item); } + + completion_item } SymbolKind::Namespace(..) => CompletionItem { label: name.to_string(), @@ -571,19 +603,21 @@ fn format_symbol_kind_as_completion(name: &str, symbol_kind: &SymbolKind) -> Opt } fn should_exclude_symbol(symbol: &str) -> bool { - symbol == WINGSDK_STD_MODULE || symbol.starts_with(CLOSURE_CLASS_PREFIX) || symbol == PARENT_THIS_NAME + symbol == WINGSDK_STD_MODULE || symbol.starts_with(CLOSURE_CLASS_PREFIX) || symbol.starts_with(PARENT_THIS_NAME) } /// This visitor is used to find the scope /// and relevant expression that contains a given location. pub struct ScopeVisitor<'a> { + /// The area surrounding the location we're looking for + pub parent_span: Option, /// The target location we're looking for - pub location: WingSpan, + pub target_span: WingSpan, /// The index of the statement that contains the target location /// or, the last valid statement before the target location pub found_stmt_index: Option, /// The scope that contains the target location - pub found_scope: Option<&'a Scope>, + pub found_scope: &'a Scope, /// The nearest expression before (or containing) the target location pub nearest_expr: Option<&'a Expr>, /// The nearest type annotation before (or containing) the target location @@ -591,24 +625,29 @@ pub struct ScopeVisitor<'a> { } impl<'a> ScopeVisitor<'a> { - pub fn new(location: WingSpan) -> Self { + pub fn new(parent_span: Option, target_span: WingSpan, starting_scope: &'a Scope) -> Self { Self { - location, + parent_span, + target_span, found_stmt_index: None, nearest_expr: None, - found_scope: None, + found_scope: starting_scope, nearest_type_annotation: None, } } + + pub fn visit(&mut self) { + self.visit_scope(&self.found_scope); + } } impl<'a> Visit<'a> for ScopeVisitor<'a> { fn visit_scope(&mut self, node: &'a Scope) { - if node.span.contains(&self.location.start.into()) { - self.found_scope = Some(node); + if node.span.file_id != "" && node.span.contains(&self.target_span.start.into()) { + self.found_scope = node; for (i, statement) in node.statements.iter().enumerate() { - if statement.span <= self.location { + if statement.span <= self.target_span { self.visit_stmt(&statement); } else if self.found_stmt_index.is_none() { self.found_stmt_index = Some(max(i as i64 - 1, 0) as usize); @@ -624,14 +663,23 @@ impl<'a> Visit<'a> for ScopeVisitor<'a> { fn visit_expr(&mut self, node: &'a Expr) { // We want to find the nearest expression to our target location // i.e we want the expression that is to the left of it - if node.span.end <= self.location.start { - if let Some(nearest_expr) = self.nearest_expr { - // make sure we're not overwriting a more relevant expression - if nearest_expr.span.end < node.span.end { - self.nearest_expr = Some(node); + if node.span.end == self.target_span.start { + self.nearest_expr = Some(node); + } + // if we can't get an exact match, we want to find the nearest expression within the same node-ish + // (this is for cases like `(Json 5).`, since parentheses are not part of the span) + else if node.span.end <= self.target_span.start { + if let Some(parent) = &self.parent_span { + if parent.contains(&node.span.end.into()) { + if let Some(nearest_expr) = self.nearest_expr { + // If we already have a nearest expression, we want to find the one that is closest to our target location + if node.span.end > nearest_expr.span.end { + self.nearest_expr = Some(node); + } + } else { + self.nearest_expr = Some(node); + } } - } else { - self.nearest_expr = Some(node); } } @@ -644,15 +692,8 @@ impl<'a> Visit<'a> for ScopeVisitor<'a> { } fn visit_type_annotation(&mut self, node: &'a TypeAnnotation) { - if node.span <= self.location { - if let Some(nearest_type_annotation) = self.nearest_type_annotation { - // make sure we're not overwriting a more relevant type annotation - if nearest_type_annotation.span.end < node.span.end { - self.nearest_type_annotation = Some(node); - } - } else { - self.nearest_type_annotation = Some(node); - } + if node.span.end == self.target_span.end { + self.nearest_type_annotation = Some(node); } visit_type_annotation(self, node); @@ -685,13 +726,16 @@ mod tests { partial_result_params: Default::default(), }); - if let CompletionResponse::Array($name) = completion { + if let CompletionResponse::Array(mut $name) = completion { insta::with_settings!( { prepend_module_to_snapshot => false, omit_expression => true, snapshot_path => "./snapshots/completions", }, { + // sort the vec by sort_text + $name.sort_by(|a, b| a.sort_text.cmp(&b.sort_text)); + insta::assert_yaml_snapshot!($name); } ); @@ -711,7 +755,8 @@ mod tests { bring cloud; new cloud. - //^"#, + //^ +"#, assert!(!new_expression_nested.is_empty()) // all items are classes @@ -730,7 +775,8 @@ class Resource { } Resource. - //^"#, + //^ +"#, assert!(!static_method_call.is_empty()) assert!(static_method_call.iter().filter(|c| c.label == "hello").count() == 1) @@ -748,7 +794,8 @@ if a == 1 { let b = //^ -let c = 3;"#, +let c = 3; +"#, assert!(!only_show_symbols_in_scope.is_empty()) assert!(only_show_symbols_in_scope.iter().all(|c| c.label != "c")) @@ -801,19 +848,143 @@ test "test" { bring util; util. - //^"#, + //^ +"#, assert!(!util_static_methods.is_empty()) assert!(util_static_methods.iter().filter(|c| c.label == "env").count() == 1) ); + test_completion_list!( + namespace_inflight, + r#" +bring http; + +inflight () => { + http. + //^" +}; +"#, + assert!(!namespace_inflight.is_empty()) + ); + test_completion_list!( mut_json_methods, r#" let j = MutJson {}; j. - //^ + //^ "#, assert!(!mut_json_methods.is_empty()) ); + + test_completion_list!( + static_completions_after_expression, + r#" +2 Json. + //^ +"#, + assert!(!static_completions_after_expression.is_empty()) + ); + + test_completion_list!( + primitives_have_no_completions, + r#" +69. + //^ +"#, + assert!(primitives_have_no_completions.is_empty()) + ); + + test_completion_list!( + multiple_dots_no_completions, + r#" +let x = Json 1; +x.. + //^ +"#, + assert!(multiple_dots_no_completions.is_empty()) + ); + + test_completion_list!( + inside_class_declaration, + r#" +class Foo { + +//^ +} +"#, + assert!(!inside_class_declaration.is_empty()) + ); + + test_completion_list!( + incomplete_inflight_namespace, + r#" +bring cloud; + +let f = inflight (req: cloud. + //^ +"#, + assert!(!incomplete_inflight_namespace.is_empty()) + ); + + test_completion_list!( + namespace_middle_dot, + r#" +bring cloud; +cloud.Bucket. + //^ +"#, + assert!(!namespace_middle_dot.is_empty()) + ); + + test_completion_list!( + variable_type_annotation_namespace, + r#" +bring cloud; +let x: cloud. + //^ +"#, + assert!(!variable_type_annotation_namespace.is_empty()) + ); + + test_completion_list!( + parentheses_expression, + r#" +(Json {}).tryGet("t")?. + //^ +"#, + assert!(!parentheses_expression.is_empty()) + ); + + test_completion_list!( + static_json_after_expression, + r#" +bring cloud; +let b = new cloud.Bucket(); +Json. + //^ +"#, + assert!(!static_json_after_expression.is_empty()) + ); + + test_completion_list!( + static_json_after_expression_statement, + r#" +bring cloud; +let b = new cloud.Bucket();Json. + //^ +"#, + assert!(!static_json_after_expression_statement.is_empty()) + ); + + test_completion_list!( + optional_chaining, + r#" +let j = Json {}; +j.tryGet("")?. + //^ +"#, + assert!(!optional_chaining.is_empty()) + ); } diff --git a/libs/wingc/src/lsp/snapshots/completions/capture_in_test.snap b/libs/wingc/src/lsp/snapshots/completions/capture_in_test.snap index aecf93b13ee..374eb58f914 100644 --- a/libs/wingc/src/lsp/snapshots/completions/capture_in_test.snap +++ b/libs/wingc/src/lsp/snapshots/completions/capture_in_test.snap @@ -1,6 +1,18 @@ --- source: libs/wingc/src/lsp/completions.rs --- +- label: display + kind: 5 + documentation: + kind: markdown + value: "```wing\npreflight display: Display\n```\n---\n```wing\nclass Display\n```\n---\nInformation on how to display a resource in the UI." + sortText: ee|display +- label: node + kind: 5 + documentation: + kind: markdown + value: "```wing\npreflight node: Node\n```\n---\n```wing\nclass Node\n```\n---\nRepresents the construct node in the scope tree." + sortText: ee|node - label: delete kind: 2 documentation: @@ -122,20 +134,4 @@ source: libs/wingc/src/lsp/completions.rs command: title: triggerParameterHints command: editor.action.triggerParameterHints -- label: display - kind: 5 - documentation: - kind: markdown - value: "```wing\npreflight display: Display\n```\n---\n```wing\nclass Display\n```\n---\nInformation on how to display a resource in the UI." - sortText: ee|display - insertText: display - insertTextFormat: 2 -- label: node - kind: 5 - documentation: - kind: markdown - value: "```wing\npreflight node: Node\n```\n---\n```wing\nclass Node\n```\n---\nRepresents the construct node in the scope tree." - sortText: ee|node - insertText: node - insertTextFormat: 2 diff --git a/libs/wingc/src/lsp/snapshots/completions/incomplete_if_statement.snap b/libs/wingc/src/lsp/snapshots/completions/incomplete_if_statement.snap index 380f336e4fe..2a1147865b2 100644 --- a/libs/wingc/src/lsp/snapshots/completions/incomplete_if_statement.snap +++ b/libs/wingc/src/lsp/snapshots/completions/incomplete_if_statement.snap @@ -16,7 +16,7 @@ source: libs/wingc/src/lsp/completions.rs kind: 2 documentation: kind: markdown - value: "```wing\n copy: (): ImmutableMap\n```\n---\nCreate an immutable shallow copy of this map.\n\n### Returns\nan ImmutableMap with the same values as this map" + value: "```wing\n copy: (): Map\n```\n---\nCreate an immutable shallow copy of this map.\n\n### Returns\nan ImmutableMap with the same values as this map" sortText: ff|copy insertText: copy($0) insertTextFormat: 2 @@ -93,7 +93,7 @@ source: libs/wingc/src/lsp/completions.rs kind: 2 documentation: kind: markdown - value: "```wing\n values: (): ImmutableArray\n```\n---\nReturns the values of this map.\n\n### Returns\nan array containing of type T the values of this map" + value: "```wing\n values: (): Array\n```\n---\nReturns the values of this map.\n\n### Returns\nan array containing of type T the values of this map" sortText: ff|values insertText: values($0) insertTextFormat: 2 diff --git a/libs/wingc/src/lsp/snapshots/completions/incomplete_inflight_namespace.snap b/libs/wingc/src/lsp/snapshots/completions/incomplete_inflight_namespace.snap new file mode 100644 index 00000000000..6c12917918f --- /dev/null +++ b/libs/wingc/src/lsp/snapshots/completions/incomplete_inflight_namespace.snap @@ -0,0 +1,466 @@ +--- +source: libs/wingc/src/lsp/completions.rs +--- +- label: Api + kind: 7 + documentation: + kind: markdown + value: "```wing\nclass Api\n```\n---\nFunctionality shared between all `Api` implementations." + sortText: gg|Api +- label: Bucket + kind: 7 + documentation: + kind: markdown + value: "```wing\nclass Bucket\n```\n---\nRepresents a cloud object store." + sortText: gg|Bucket +- label: Counter + kind: 7 + documentation: + kind: markdown + value: "```wing\nclass Counter\n```\n---\nRepresents a distributed atomic counter." + sortText: gg|Counter +- label: Function + kind: 7 + documentation: + kind: markdown + value: "```wing\nclass Function impl IInflightHost\n```\n---\nRepresents a function." + sortText: gg|Function +- label: Queue + kind: 7 + documentation: + kind: markdown + value: "```wing\nclass Queue\n```\n---\nRepresents a queue." + sortText: gg|Queue +- label: Schedule + kind: 7 + documentation: + kind: markdown + value: "```wing\nclass Schedule\n```\n---\nRepresents a schedule." + sortText: gg|Schedule +- label: Secret + kind: 7 + documentation: + kind: markdown + value: "```wing\nclass Secret\n```\n---\nRepresents a cloud secret." + sortText: gg|Secret +- label: Service + kind: 7 + documentation: + kind: markdown + value: "```wing\nclass Service\n```\n---\nRepresents a service." + sortText: gg|Service +- label: Table + kind: 7 + documentation: + kind: markdown + value: "```wing\nclass Table\n```\n---\nRepresents a NoSQL database table that can be used to store and query data." + sortText: gg|Table +- label: TestRunner + kind: 7 + documentation: + kind: markdown + value: "```wing\nclass TestRunner\n```\n---\nRepresents a test engine." + sortText: gg|TestRunner +- label: Topic + kind: 7 + documentation: + kind: markdown + value: "```wing\nclass Topic\n```\n---\nRepresents a topic." + sortText: gg|Topic +- label: Website + kind: 7 + documentation: + kind: markdown + value: "```wing\nclass Website\n```\n---\nRepresents a cloud static website." + sortText: gg|Website +- label: ApiConnectProps + kind: 22 + documentation: + kind: markdown + value: "```wing\nApiConnectProps\n```\n---\nOptions for Api patch endpoint." + sortText: hh|ApiConnectProps +- label: ApiDeleteProps + kind: 22 + documentation: + kind: markdown + value: "```wing\nApiDeleteProps\n```\n---\nOptions for Api put endpoint." + sortText: hh|ApiDeleteProps +- label: ApiGetProps + kind: 22 + documentation: + kind: markdown + value: "```wing\nApiGetProps\n```\n---\nOptions for Api get endpoint." + sortText: hh|ApiGetProps +- label: ApiHeadProps + kind: 22 + documentation: + kind: markdown + value: "```wing\nApiHeadProps\n```\n---\nOptions for Api patch endpoint." + sortText: hh|ApiHeadProps +- label: ApiOptionsProps + kind: 22 + documentation: + kind: markdown + value: "```wing\nApiOptionsProps\n```\n---\nOptions for Api patch endpoint." + sortText: hh|ApiOptionsProps +- label: ApiPatchProps + kind: 22 + documentation: + kind: markdown + value: "```wing\nApiPatchProps\n```\n---\nOptions for Api patch endpoint." + sortText: hh|ApiPatchProps +- label: ApiPostProps + kind: 22 + documentation: + kind: markdown + value: "```wing\nApiPostProps\n```\n---\nOptions for Api post endpoint." + sortText: hh|ApiPostProps +- label: ApiProps + kind: 22 + documentation: + kind: markdown + value: "```wing\nApiProps\n```\n---\nProperties for `Api`." + sortText: hh|ApiProps +- label: ApiPutProps + kind: 22 + documentation: + kind: markdown + value: "```wing\nApiPutProps\n```\n---\nOptions for Api put endpoint." + sortText: hh|ApiPutProps +- label: ApiRequest + kind: 22 + documentation: + kind: markdown + value: "```wing\nApiRequest\n```\n---\nShape of a request to an inflight handler." + sortText: hh|ApiRequest +- label: ApiResponse + kind: 22 + documentation: + kind: markdown + value: "```wing\nApiResponse\n```\n---\nShape of a response from a inflight handler." + sortText: hh|ApiResponse +- label: BucketDeleteOptions + kind: 22 + documentation: + kind: markdown + value: "```wing\nBucketDeleteOptions\n```\n---\nInterface for delete method inside `Bucket`." + sortText: hh|BucketDeleteOptions +- label: BucketEvent + kind: 22 + documentation: + kind: markdown + value: "```wing\nBucketEvent\n```\n---\non_event notification payload- will be in use after solving issue: https://github.com/winglang/wing/issues/1927." + sortText: hh|BucketEvent +- label: BucketOnCreateProps + kind: 22 + documentation: + kind: markdown + value: "```wing\nBucketOnCreateProps\n```\n---\non create event options." + sortText: hh|BucketOnCreateProps +- label: BucketOnDeleteProps + kind: 22 + documentation: + kind: markdown + value: "```wing\nBucketOnDeleteProps\n```\n---\non delete event options." + sortText: hh|BucketOnDeleteProps +- label: BucketOnEventProps + kind: 22 + documentation: + kind: markdown + value: "```wing\nBucketOnEventProps\n```\n---\non any event options." + sortText: hh|BucketOnEventProps +- label: BucketOnUpdateProps + kind: 22 + documentation: + kind: markdown + value: "```wing\nBucketOnUpdateProps\n```\n---\non update event options." + sortText: hh|BucketOnUpdateProps +- label: BucketProps + kind: 22 + documentation: + kind: markdown + value: "```wing\nBucketProps\n```\n---\nProperties for `Bucket`." + sortText: hh|BucketProps +- label: CounterProps + kind: 22 + documentation: + kind: markdown + value: "```wing\nCounterProps\n```\n---\nProperties for `Counter`." + sortText: hh|CounterProps +- label: FunctionProps + kind: 22 + documentation: + kind: markdown + value: "```wing\nFunctionProps\n```\n---\nProperties for `Function`.\n\n### Remarks\nThis is the type users see when constructing a cloud.Function instance." + sortText: hh|FunctionProps +- label: GetSecretValueOptions + kind: 22 + documentation: + kind: markdown + value: "```wing\nGetSecretValueOptions\n```\n---\nOptions when getting a secret value." + sortText: hh|GetSecretValueOptions +- label: QueueProps + kind: 22 + documentation: + kind: markdown + value: "```wing\nQueueProps\n```\n---\nProperties for `Queue`." + sortText: hh|QueueProps +- label: QueueSetConsumerProps + kind: 22 + documentation: + kind: markdown + value: "```wing\nQueueSetConsumerProps\n```\n---\nOptions for Queue.setConsumer." + sortText: hh|QueueSetConsumerProps +- label: ScheduleOnTickProps + kind: 22 + documentation: + kind: markdown + value: "```wing\nScheduleOnTickProps\n```\n---\nOptions for Schedule.onTick." + sortText: hh|ScheduleOnTickProps +- label: ScheduleProps + kind: 22 + documentation: + kind: markdown + value: "```wing\nScheduleProps\n```\n---\nProperties for `Schedule`." + sortText: hh|ScheduleProps +- label: SecretProps + kind: 22 + documentation: + kind: markdown + value: "```wing\nSecretProps\n```\n---\nProperties for `Secret`." + sortText: hh|SecretProps +- label: ServiceOnStartProps + kind: 22 + documentation: + kind: markdown + value: "```wing\nServiceOnStartProps\n```\n---\nOptions for Service.onStart." + sortText: hh|ServiceOnStartProps +- label: ServiceProps + kind: 22 + documentation: + kind: markdown + value: "```wing\nServiceProps\n```\n---\nProperties for `Service`." + sortText: hh|ServiceProps +- label: TableProps + kind: 22 + documentation: + kind: markdown + value: "```wing\nTableProps\n```\n---\nProperties for `Table`." + sortText: hh|TableProps +- label: TestResult + kind: 22 + documentation: + kind: markdown + value: "```wing\nTestResult\n```\n---\nA result of a single test." + sortText: hh|TestResult +- label: TestRunnerProps + kind: 22 + documentation: + kind: markdown + value: "```wing\nTestRunnerProps\n```\n---\nProperties for `TestRunner`." + sortText: hh|TestRunnerProps +- label: TopicOnMessageProps + kind: 22 + documentation: + kind: markdown + value: "```wing\nTopicOnMessageProps\n```\n---\nOptions for `Topic.onMessage`." + sortText: hh|TopicOnMessageProps +- label: TopicProps + kind: 22 + documentation: + kind: markdown + value: "```wing\nTopicProps\n```\n---\nProperties for `Topic`." + sortText: hh|TopicProps +- label: Trace + kind: 22 + documentation: + kind: markdown + value: "```wing\nTrace\n```\n---\nRepresents an trace emitted during simulation." + sortText: hh|Trace +- label: WebsiteProps + kind: 22 + documentation: + kind: markdown + value: "```wing\nWebsiteProps\n```\n---\nwebsite props." + sortText: hh|WebsiteProps +- label: IApiClient + kind: 8 + documentation: + kind: markdown + value: "```wing\nIApiClient\n```\n---\nInflight methods and members of `cloud.Api`." + sortText: ii|IApiClient +- label: IApiEndpointHandler + kind: 8 + documentation: + kind: markdown + value: "```wing\nIApiEndpointHandler\n```\n---\nRepresents a resource with an inflight \"handle\" method that can be passed to one of the `Api` request preflight methods." + sortText: ii|IApiEndpointHandler +- label: IApiEndpointHandlerClient + kind: 8 + documentation: + kind: markdown + value: "```wing\nIApiEndpointHandlerClient\n```\n---\nInflight client for `IApiEndpointHandler`." + sortText: ii|IApiEndpointHandlerClient +- label: IBucketClient + kind: 8 + documentation: + kind: markdown + value: "```wing\nIBucketClient\n```\n---\nInflight interface for `Bucket`." + sortText: ii|IBucketClient +- label: IBucketEventHandler + kind: 8 + documentation: + kind: markdown + value: "```wing\nIBucketEventHandler\n```\n---\nRepresents a resource with an inflight \"handle\" method that can be passed to the bucket events." + sortText: ii|IBucketEventHandler +- label: IBucketEventHandlerClient + kind: 8 + documentation: + kind: markdown + value: "```wing\nIBucketEventHandlerClient\n```\n---\nRepresents a resource with an inflight \"handle\" method that can be passed to the bucket events." + sortText: ii|IBucketEventHandlerClient +- label: ICounterClient + kind: 8 + documentation: + kind: markdown + value: "```wing\nICounterClient\n```\n---\nInflight interface for `Counter`." + sortText: ii|ICounterClient +- label: IFunctionClient + kind: 8 + documentation: + kind: markdown + value: "```wing\nIFunctionClient\n```\n---\nInflight interface for `Function`." + sortText: ii|IFunctionClient +- label: IFunctionHandler + kind: 8 + documentation: + kind: markdown + value: "```wing\nIFunctionHandler\n```\n---\nRepresents a resource with an inflight \"handle\" method that can be used to create a `cloud.Function`." + sortText: ii|IFunctionHandler +- label: IFunctionHandlerClient + kind: 8 + documentation: + kind: markdown + value: "```wing\nIFunctionHandlerClient\n```\n---\nInflight client for `IFunctionHandler`." + sortText: ii|IFunctionHandlerClient +- label: IQueueClient + kind: 8 + documentation: + kind: markdown + value: "```wing\nIQueueClient\n```\n---\nInflight interface for `Queue`." + sortText: ii|IQueueClient +- label: IQueueSetConsumerHandler + kind: 8 + documentation: + kind: markdown + value: "```wing\nIQueueSetConsumerHandler\n```\n---\nRepresents a resource with an inflight \"handle\" method that can be passed to `Queue.setConsumer`." + sortText: ii|IQueueSetConsumerHandler +- label: IQueueSetConsumerHandlerClient + kind: 8 + documentation: + kind: markdown + value: "```wing\nIQueueSetConsumerHandlerClient\n```\n---\nInflight client for `IQueueSetConsumerHandler`." + sortText: ii|IQueueSetConsumerHandlerClient +- label: IScheduleClient + kind: 8 + documentation: + kind: markdown + value: "```wing\nIScheduleClient\n```\n---\nInflight interface for `Schedule`." + sortText: ii|IScheduleClient +- label: IScheduleOnTickHandler + kind: 8 + documentation: + kind: markdown + value: "```wing\nIScheduleOnTickHandler\n```\n---\nRepresents a resource with an inflight \"handle\" method that can be passed to `Schedule.on_tick`." + sortText: ii|IScheduleOnTickHandler +- label: IScheduleOnTickHandlerClient + kind: 8 + documentation: + kind: markdown + value: "```wing\nIScheduleOnTickHandlerClient\n```\n---\nInflight client for `IScheduleOnTickHandler`." + sortText: ii|IScheduleOnTickHandlerClient +- label: ISecretClient + kind: 8 + documentation: + kind: markdown + value: "```wing\nISecretClient\n```\n---\nInflight interface for `Secret`." + sortText: ii|ISecretClient +- label: IServiceClient + kind: 8 + documentation: + kind: markdown + value: "```wing\nIServiceClient\n```\n---\nInflight interface for `Service`." + sortText: ii|IServiceClient +- label: IServiceOnEventClient + kind: 8 + documentation: + kind: markdown + value: "```wing\nIServiceOnEventClient\n```\n---\nInflight client for `IServiceOnEventHandler`." + sortText: ii|IServiceOnEventClient +- label: IServiceOnEventHandler + kind: 8 + documentation: + kind: markdown + value: "```wing\nIServiceOnEventHandler\n```\n---\nRepresents a resource with an inflight \"handle\" method that can be passed to `ServiceProps.on_start` || `ServiceProps.on_stop`." + sortText: ii|IServiceOnEventHandler +- label: ITableClient + kind: 8 + documentation: + kind: markdown + value: "```wing\nITableClient\n```\n---\nInflight interface for `Table`." + sortText: ii|ITableClient +- label: ITestRunnerClient + kind: 8 + documentation: + kind: markdown + value: "```wing\nITestRunnerClient\n```\n---\nInflight interface for `TestRunner`." + sortText: ii|ITestRunnerClient +- label: ITopicClient + kind: 8 + documentation: + kind: markdown + value: "```wing\nITopicClient\n```\n---\nInflight interface for `Topic`." + sortText: ii|ITopicClient +- label: ITopicOnMessageHandler + kind: 8 + documentation: + kind: markdown + value: "```wing\nITopicOnMessageHandler\n```\n---\nRepresents a resource with an inflight \"handle\" method that can be passed to `Topic.on_message`." + sortText: ii|ITopicOnMessageHandler +- label: ITopicOnMessageHandlerClient + kind: 8 + documentation: + kind: markdown + value: "```wing\nITopicOnMessageHandlerClient\n```\n---\nInflight client for `ITopicOnMessageHandler`." + sortText: ii|ITopicOnMessageHandlerClient +- label: IWebsiteClient + kind: 8 + documentation: + kind: markdown + value: "```wing\nIWebsiteClient\n```\n---\nInflight methods and members of `cloud.Website`." + sortText: ii|IWebsiteClient +- label: BucketEventType + kind: 13 + documentation: + kind: markdown + value: "" + sortText: jj|BucketEventType +- label: ColumnType + kind: 13 + documentation: + kind: markdown + value: "" + sortText: jj|ColumnType +- label: HttpMethod + kind: 13 + documentation: + kind: markdown + value: "" + sortText: jj|HttpMethod +- label: TraceType + kind: 13 + documentation: + kind: markdown + value: "" + sortText: jj|TraceType + diff --git a/libs/wingc/src/lsp/snapshots/completions/inside_class_declaration.snap b/libs/wingc/src/lsp/snapshots/completions/inside_class_declaration.snap new file mode 100644 index 00000000000..2cb9f9c85b7 --- /dev/null +++ b/libs/wingc/src/lsp/snapshots/completions/inside_class_declaration.snap @@ -0,0 +1,9 @@ +--- +source: libs/wingc/src/lsp/completions.rs +--- +- label: init + kind: 15 + sortText: ll|init + insertText: "init($1) {\n\t$2\n}" + insertTextFormat: 2 + diff --git a/libs/wingc/src/lsp/snapshots/completions/json_statics.snap b/libs/wingc/src/lsp/snapshots/completions/json_statics.snap index 35256ef430d..568d47cbac6 100644 --- a/libs/wingc/src/lsp/snapshots/completions/json_statics.snap +++ b/libs/wingc/src/lsp/snapshots/completions/json_statics.snap @@ -1,6 +1,17 @@ --- source: libs/wingc/src/lsp/completions.rs --- +- label: deepCopy + kind: 2 + documentation: + kind: markdown + value: "```wing\nstatic deepCopy: (json: MutJson): Json\n```\n---\nCreates an immutable deep copy of the Json.\n\n### Parameters\n - *json* - to copy.\n\n### Returns\nthe immutable copy of the Json" + sortText: ff|deepCopy + insertText: deepCopy($0) + insertTextFormat: 2 + command: + title: triggerParameterHints + command: editor.action.triggerParameterHints - label: deepCopyMut kind: 2 documentation: @@ -16,7 +27,7 @@ source: libs/wingc/src/lsp/completions.rs kind: 2 documentation: kind: markdown - value: "```wing\nstatic delete: (json: Json, key: str): void\n```\n---\nDeletes a key in a given Json.\n\n### Parameters\n - *json* - to delete key from.\n - *key* - the key to delete." + value: "```wing\nstatic delete: (json: MutJson, key: str): void\n```\n---\nDeletes a key in a given Json.\n\n### Parameters\n - *json* - to delete key from.\n - *key* - the key to delete." sortText: ff|delete insertText: delete($0) insertTextFormat: 2 @@ -38,7 +49,7 @@ source: libs/wingc/src/lsp/completions.rs kind: 2 documentation: kind: markdown - value: "```wing\nstatic keys: (json: Json): Array\n```\n---\nReturns the keys from the Json object.\n\n### Parameters\n - *json* - to get keys from.\n\n### Returns\nthe keys from the Json object as string array" + value: "```wing\nstatic keys: (json: any): Array\n```\n---\nReturns the keys from the Json object.\n\n### Parameters\n - *json* - to get keys from.\n\n### Returns\nthe keys from the Json object as string array" sortText: ff|keys insertText: keys($0) insertTextFormat: 2 @@ -60,7 +71,7 @@ source: libs/wingc/src/lsp/completions.rs kind: 2 documentation: kind: markdown - value: "```wing\nstatic stringify: (json: Json, indent: num?): str\n```\n---\nFormats Json as string.\n\n### Parameters\n - *json* - to format as string.\n - *indent*\n\n### Returns\nstring representation of the Json\n\n### Remarks\n(JSON.stringify($args$))" + value: "```wing\nstatic stringify: (json: any, indent: num?): str\n```\n---\nFormats Json as string.\n\n### Parameters\n - *json* - to format as string.\n - *indent*\n\n### Returns\nstring representation of the Json\n\n### Remarks\n(JSON.stringify($args$))" sortText: ff|stringify insertText: stringify($0) insertTextFormat: 2 diff --git a/libs/wingc/src/lsp/snapshots/completions/multiple_dots_no_completions.snap b/libs/wingc/src/lsp/snapshots/completions/multiple_dots_no_completions.snap new file mode 100644 index 00000000000..2382299ee10 --- /dev/null +++ b/libs/wingc/src/lsp/snapshots/completions/multiple_dots_no_completions.snap @@ -0,0 +1,5 @@ +--- +source: libs/wingc/src/lsp/completions.rs +--- +[] + diff --git a/libs/wingc/src/lsp/snapshots/completions/mut_json_methods.snap b/libs/wingc/src/lsp/snapshots/completions/mut_json_methods.snap index 3f2eb5cb4bb..8056ceaa6fb 100644 --- a/libs/wingc/src/lsp/snapshots/completions/mut_json_methods.snap +++ b/libs/wingc/src/lsp/snapshots/completions/mut_json_methods.snap @@ -1,66 +1,136 @@ --- source: libs/wingc/src/lsp/completions.rs --- -- label: assert - kind: 3 +- label: asBool + kind: 2 documentation: kind: markdown - value: "```wing\n assert: (condition: bool): void\n```\n---\nAsserts that a condition is true\n\n### Parameters\n - *condition* - The condition to assert" - sortText: cc|assert - insertText: assert($0) + value: "```wing\n asBool: (): bool\n```\n---\nConvert Json element to number if possible.\n\n### Returns\na string." + sortText: ff|asBool + insertText: asBool($0) insertTextFormat: 2 command: title: triggerParameterHints command: editor.action.triggerParameterHints -- label: j - kind: 6 +- label: asNum + kind: 2 documentation: kind: markdown - value: "```wing\npreflight j: MutJson\n```\n---" - sortText: bb|j - insertText: j + value: "```wing\n asNum: (): num\n```\n---\nConvert Json element to number if possible.\n\n### Returns\na string." + sortText: ff|asNum + insertText: asNum($0) insertTextFormat: 2 -- label: log - kind: 3 + command: + title: triggerParameterHints + command: editor.action.triggerParameterHints +- label: asStr + kind: 2 + documentation: + kind: markdown + value: "```wing\n asStr: (): str\n```\n---\nConvert Json element to string if possible.\n\n### Returns\na string." + sortText: ff|asStr + insertText: asStr($0) + insertTextFormat: 2 + command: + title: triggerParameterHints + command: editor.action.triggerParameterHints +- label: get + kind: 2 + documentation: + kind: markdown + value: "```wing\n get: (key: str): MutJson\n```\n---\nReturns a specified element from the Json.\n\n### Parameters\n - *key* - The key of the element to return.\n\n### Returns\nThe element associated with the specified key, or undefined if the key can't be found" + sortText: ff|get + insertText: get($0) + insertTextFormat: 2 + command: + title: triggerParameterHints + command: editor.action.triggerParameterHints +- label: getAt + kind: 2 documentation: kind: markdown - value: "```wing\n log: (message: str): void\n```\n---\nLogs a message\n\n### Parameters\n - *message* - The message to log" - sortText: cc|log - insertText: log($0) + value: "```wing\n getAt: (index: num): MutJson\n```\n---\nReturns a specified element at a given index from MutJson Array.\n\n### Parameters\n - *index* - The index of the element in the MutJson Array to return.\n\n### Returns\nThe element at given index in MutJson Array, or undefined if index is not valid" + sortText: ff|getAt + insertText: getAt($0) insertTextFormat: 2 command: title: triggerParameterHints command: editor.action.triggerParameterHints -- label: panic - kind: 3 +- label: set + kind: 2 documentation: kind: markdown - value: "```wing\n panic: (message: str): void\n```\n---\npanics with an error\n\n### Parameters\n - *message* - The message to panic with" - sortText: cc|panic - insertText: panic($0) + value: "```wing\n set: (key: str, value: MutJson): void\n```\n---\nAdds or updates an element in MutJson with a specific key and value.\n\n### Parameters\n - *key* - The key of the element to add.\n - *value* - The value of the element to add." + sortText: ff|set + insertText: set($0) insertTextFormat: 2 command: title: triggerParameterHints command: editor.action.triggerParameterHints -- label: throw - kind: 3 +- label: setAt + kind: 2 documentation: kind: markdown - value: "```wing\n throw: (message: str): void\n```\n---\nthrows an error\n\n### Parameters\n - *message* - The message to throw" - sortText: cc|throw - insertText: throw($0) + value: "```wing\n setAt: (index: num, value: MutJson): void\n```\n---\nSet element in MutJson Array with a specific key and value.\n\n### Parameters\n - *index*\n - *value* - The value of the element to set." + sortText: ff|setAt + insertText: setAt($0) insertTextFormat: 2 command: title: triggerParameterHints command: editor.action.triggerParameterHints -- label: "inflight () => {}" - kind: 15 - sortText: "ll|inflight () => {}" - insertText: "inflight ($1) => {$2}" +- label: tryAsBool + kind: 2 + documentation: + kind: markdown + value: "```wing\n tryAsBool: (): bool?\n```\n---\nConvert Json element to boolean if possible.\n\n### Returns\na string." + sortText: ff|tryAsBool + insertText: tryAsBool($0) insertTextFormat: 2 -- label: "test \"\" { }" - kind: 15 - sortText: "ll|test \"\" { }" - insertText: "test \"$1\" {\n\t$2\n}" + command: + title: triggerParameterHints + command: editor.action.triggerParameterHints +- label: tryAsNum + kind: 2 + documentation: + kind: markdown + value: "```wing\n tryAsNum: (): num?\n```\n---\nConvert Json element to string if possible.\n\n### Returns\na string." + sortText: ff|tryAsNum + insertText: tryAsNum($0) insertTextFormat: 2 + command: + title: triggerParameterHints + command: editor.action.triggerParameterHints +- label: tryAsStr + kind: 2 + documentation: + kind: markdown + value: "```wing\n tryAsStr: (): str?\n```\n---\nConvert Json element to string if possible.\n\n### Returns\na string." + sortText: ff|tryAsStr + insertText: tryAsStr($0) + insertTextFormat: 2 + command: + title: triggerParameterHints + command: editor.action.triggerParameterHints +- label: tryGet + kind: 2 + documentation: + kind: markdown + value: "```wing\n tryGet: (key: str): MutJson?\n```\n---\nOptionally returns an specified element from the Json.\n\n### Parameters\n - *key* - The key of the element to return.\n\n### Returns\nThe element associated with the specified key, or undefined if the key can't be found" + sortText: ff|tryGet + insertText: tryGet($0) + insertTextFormat: 2 + command: + title: triggerParameterHints + command: editor.action.triggerParameterHints +- label: tryGetAt + kind: 2 + documentation: + kind: markdown + value: "```wing\n tryGetAt: (index: num): MutJson?\n```\n---\nOptionally returns a specified element at a given index from Json Array.\n\n### Parameters\n - *index* - The index of the element in the Json Array to return.\n\n### Returns\nThe element at given index in Json Array, or undefined if index is not valid" + sortText: ff|tryGetAt + insertText: tryGetAt($0) + insertTextFormat: 2 + command: + title: triggerParameterHints + command: editor.action.triggerParameterHints diff --git a/libs/wingc/src/lsp/snapshots/completions/namespace_inflight.snap b/libs/wingc/src/lsp/snapshots/completions/namespace_inflight.snap new file mode 100644 index 00000000000..5fbed86be76 --- /dev/null +++ b/libs/wingc/src/lsp/snapshots/completions/namespace_inflight.snap @@ -0,0 +1,106 @@ +--- +source: libs/wingc/src/lsp/completions.rs +--- +- label: delete + kind: 2 + documentation: + kind: markdown + value: "```wing\nstatic delete: (url: str, options: RequestOptions?): Response\n```\n---\nSends a DELETE request.\n\n### Returns\nthe formatted response of the call" + sortText: ff|delete + insertText: delete($0) + insertTextFormat: 2 + command: + title: triggerParameterHints + command: editor.action.triggerParameterHints +- label: fetch + kind: 2 + documentation: + kind: markdown + value: "```wing\nstatic fetch: (url: str, options: RequestOptions?): Response\n```\n---\nSends an HTTP request to a URL, returning a fulfilled or failed response.\n\n### Returns\nthe formatted response of the call\n\n*@throws* *Only throws if there is a networking error*" + sortText: ff|fetch + insertText: fetch($0) + insertTextFormat: 2 + command: + title: triggerParameterHints + command: editor.action.triggerParameterHints +- label: get + kind: 2 + documentation: + kind: markdown + value: "```wing\nstatic get: (url: str, options: RequestOptions?): Response\n```\n---\nSends a GET request.\n\n### Returns\nthe formatted response of the call" + sortText: ff|get + insertText: get($0) + insertTextFormat: 2 + command: + title: triggerParameterHints + command: editor.action.triggerParameterHints +- label: patch + kind: 2 + documentation: + kind: markdown + value: "```wing\nstatic patch: (url: str, options: RequestOptions?): Response\n```\n---\nSends a PATCH request.\n\n### Returns\nthe formatted response of the call" + sortText: ff|patch + insertText: patch($0) + insertTextFormat: 2 + command: + title: triggerParameterHints + command: editor.action.triggerParameterHints +- label: post + kind: 2 + documentation: + kind: markdown + value: "```wing\nstatic post: (url: str, options: RequestOptions?): Response\n```\n---\nSends a POST request.\n\n### Returns\nthe formatted response of the call" + sortText: ff|post + insertText: post($0) + insertTextFormat: 2 + command: + title: triggerParameterHints + command: editor.action.triggerParameterHints +- label: put + kind: 2 + documentation: + kind: markdown + value: "```wing\nstatic put: (url: str, options: RequestOptions?): Response\n```\n---\nSends a PUT request.\n\n### Returns\nthe formatted response of the call" + sortText: ff|put + insertText: put($0) + insertTextFormat: 2 + command: + title: triggerParameterHints + command: editor.action.triggerParameterHints +- label: Util + kind: 7 + documentation: + kind: markdown + value: "```wing\nclass Util\n```\n---\nthe Http class is used for calling different HTTP methods and requesting and sending information online, as well as testing public accessible resources." + sortText: gg|Util +- label: RequestOptions + kind: 22 + documentation: + kind: markdown + value: "```wing\nRequestOptions\n```\n---\nAn object containing any custom settings that you want to apply to the request." + sortText: hh|RequestOptions +- label: Response + kind: 22 + documentation: + kind: markdown + value: "```wing\nResponse\n```\n---\nRepresents the response to a request." + sortText: hh|Response +- label: HttpMethod + kind: 13 + documentation: + kind: markdown + value: "" + sortText: jj|HttpMethod +- label: RequestCache + kind: 13 + documentation: + kind: markdown + value: "" + sortText: jj|RequestCache +- label: RequestRedirect + kind: 13 + documentation: + kind: markdown + value: "" + sortText: jj|RequestRedirect + diff --git a/libs/wingc/src/lsp/snapshots/completions/namespace_middle_dot.snap b/libs/wingc/src/lsp/snapshots/completions/namespace_middle_dot.snap new file mode 100644 index 00000000000..6c12917918f --- /dev/null +++ b/libs/wingc/src/lsp/snapshots/completions/namespace_middle_dot.snap @@ -0,0 +1,466 @@ +--- +source: libs/wingc/src/lsp/completions.rs +--- +- label: Api + kind: 7 + documentation: + kind: markdown + value: "```wing\nclass Api\n```\n---\nFunctionality shared between all `Api` implementations." + sortText: gg|Api +- label: Bucket + kind: 7 + documentation: + kind: markdown + value: "```wing\nclass Bucket\n```\n---\nRepresents a cloud object store." + sortText: gg|Bucket +- label: Counter + kind: 7 + documentation: + kind: markdown + value: "```wing\nclass Counter\n```\n---\nRepresents a distributed atomic counter." + sortText: gg|Counter +- label: Function + kind: 7 + documentation: + kind: markdown + value: "```wing\nclass Function impl IInflightHost\n```\n---\nRepresents a function." + sortText: gg|Function +- label: Queue + kind: 7 + documentation: + kind: markdown + value: "```wing\nclass Queue\n```\n---\nRepresents a queue." + sortText: gg|Queue +- label: Schedule + kind: 7 + documentation: + kind: markdown + value: "```wing\nclass Schedule\n```\n---\nRepresents a schedule." + sortText: gg|Schedule +- label: Secret + kind: 7 + documentation: + kind: markdown + value: "```wing\nclass Secret\n```\n---\nRepresents a cloud secret." + sortText: gg|Secret +- label: Service + kind: 7 + documentation: + kind: markdown + value: "```wing\nclass Service\n```\n---\nRepresents a service." + sortText: gg|Service +- label: Table + kind: 7 + documentation: + kind: markdown + value: "```wing\nclass Table\n```\n---\nRepresents a NoSQL database table that can be used to store and query data." + sortText: gg|Table +- label: TestRunner + kind: 7 + documentation: + kind: markdown + value: "```wing\nclass TestRunner\n```\n---\nRepresents a test engine." + sortText: gg|TestRunner +- label: Topic + kind: 7 + documentation: + kind: markdown + value: "```wing\nclass Topic\n```\n---\nRepresents a topic." + sortText: gg|Topic +- label: Website + kind: 7 + documentation: + kind: markdown + value: "```wing\nclass Website\n```\n---\nRepresents a cloud static website." + sortText: gg|Website +- label: ApiConnectProps + kind: 22 + documentation: + kind: markdown + value: "```wing\nApiConnectProps\n```\n---\nOptions for Api patch endpoint." + sortText: hh|ApiConnectProps +- label: ApiDeleteProps + kind: 22 + documentation: + kind: markdown + value: "```wing\nApiDeleteProps\n```\n---\nOptions for Api put endpoint." + sortText: hh|ApiDeleteProps +- label: ApiGetProps + kind: 22 + documentation: + kind: markdown + value: "```wing\nApiGetProps\n```\n---\nOptions for Api get endpoint." + sortText: hh|ApiGetProps +- label: ApiHeadProps + kind: 22 + documentation: + kind: markdown + value: "```wing\nApiHeadProps\n```\n---\nOptions for Api patch endpoint." + sortText: hh|ApiHeadProps +- label: ApiOptionsProps + kind: 22 + documentation: + kind: markdown + value: "```wing\nApiOptionsProps\n```\n---\nOptions for Api patch endpoint." + sortText: hh|ApiOptionsProps +- label: ApiPatchProps + kind: 22 + documentation: + kind: markdown + value: "```wing\nApiPatchProps\n```\n---\nOptions for Api patch endpoint." + sortText: hh|ApiPatchProps +- label: ApiPostProps + kind: 22 + documentation: + kind: markdown + value: "```wing\nApiPostProps\n```\n---\nOptions for Api post endpoint." + sortText: hh|ApiPostProps +- label: ApiProps + kind: 22 + documentation: + kind: markdown + value: "```wing\nApiProps\n```\n---\nProperties for `Api`." + sortText: hh|ApiProps +- label: ApiPutProps + kind: 22 + documentation: + kind: markdown + value: "```wing\nApiPutProps\n```\n---\nOptions for Api put endpoint." + sortText: hh|ApiPutProps +- label: ApiRequest + kind: 22 + documentation: + kind: markdown + value: "```wing\nApiRequest\n```\n---\nShape of a request to an inflight handler." + sortText: hh|ApiRequest +- label: ApiResponse + kind: 22 + documentation: + kind: markdown + value: "```wing\nApiResponse\n```\n---\nShape of a response from a inflight handler." + sortText: hh|ApiResponse +- label: BucketDeleteOptions + kind: 22 + documentation: + kind: markdown + value: "```wing\nBucketDeleteOptions\n```\n---\nInterface for delete method inside `Bucket`." + sortText: hh|BucketDeleteOptions +- label: BucketEvent + kind: 22 + documentation: + kind: markdown + value: "```wing\nBucketEvent\n```\n---\non_event notification payload- will be in use after solving issue: https://github.com/winglang/wing/issues/1927." + sortText: hh|BucketEvent +- label: BucketOnCreateProps + kind: 22 + documentation: + kind: markdown + value: "```wing\nBucketOnCreateProps\n```\n---\non create event options." + sortText: hh|BucketOnCreateProps +- label: BucketOnDeleteProps + kind: 22 + documentation: + kind: markdown + value: "```wing\nBucketOnDeleteProps\n```\n---\non delete event options." + sortText: hh|BucketOnDeleteProps +- label: BucketOnEventProps + kind: 22 + documentation: + kind: markdown + value: "```wing\nBucketOnEventProps\n```\n---\non any event options." + sortText: hh|BucketOnEventProps +- label: BucketOnUpdateProps + kind: 22 + documentation: + kind: markdown + value: "```wing\nBucketOnUpdateProps\n```\n---\non update event options." + sortText: hh|BucketOnUpdateProps +- label: BucketProps + kind: 22 + documentation: + kind: markdown + value: "```wing\nBucketProps\n```\n---\nProperties for `Bucket`." + sortText: hh|BucketProps +- label: CounterProps + kind: 22 + documentation: + kind: markdown + value: "```wing\nCounterProps\n```\n---\nProperties for `Counter`." + sortText: hh|CounterProps +- label: FunctionProps + kind: 22 + documentation: + kind: markdown + value: "```wing\nFunctionProps\n```\n---\nProperties for `Function`.\n\n### Remarks\nThis is the type users see when constructing a cloud.Function instance." + sortText: hh|FunctionProps +- label: GetSecretValueOptions + kind: 22 + documentation: + kind: markdown + value: "```wing\nGetSecretValueOptions\n```\n---\nOptions when getting a secret value." + sortText: hh|GetSecretValueOptions +- label: QueueProps + kind: 22 + documentation: + kind: markdown + value: "```wing\nQueueProps\n```\n---\nProperties for `Queue`." + sortText: hh|QueueProps +- label: QueueSetConsumerProps + kind: 22 + documentation: + kind: markdown + value: "```wing\nQueueSetConsumerProps\n```\n---\nOptions for Queue.setConsumer." + sortText: hh|QueueSetConsumerProps +- label: ScheduleOnTickProps + kind: 22 + documentation: + kind: markdown + value: "```wing\nScheduleOnTickProps\n```\n---\nOptions for Schedule.onTick." + sortText: hh|ScheduleOnTickProps +- label: ScheduleProps + kind: 22 + documentation: + kind: markdown + value: "```wing\nScheduleProps\n```\n---\nProperties for `Schedule`." + sortText: hh|ScheduleProps +- label: SecretProps + kind: 22 + documentation: + kind: markdown + value: "```wing\nSecretProps\n```\n---\nProperties for `Secret`." + sortText: hh|SecretProps +- label: ServiceOnStartProps + kind: 22 + documentation: + kind: markdown + value: "```wing\nServiceOnStartProps\n```\n---\nOptions for Service.onStart." + sortText: hh|ServiceOnStartProps +- label: ServiceProps + kind: 22 + documentation: + kind: markdown + value: "```wing\nServiceProps\n```\n---\nProperties for `Service`." + sortText: hh|ServiceProps +- label: TableProps + kind: 22 + documentation: + kind: markdown + value: "```wing\nTableProps\n```\n---\nProperties for `Table`." + sortText: hh|TableProps +- label: TestResult + kind: 22 + documentation: + kind: markdown + value: "```wing\nTestResult\n```\n---\nA result of a single test." + sortText: hh|TestResult +- label: TestRunnerProps + kind: 22 + documentation: + kind: markdown + value: "```wing\nTestRunnerProps\n```\n---\nProperties for `TestRunner`." + sortText: hh|TestRunnerProps +- label: TopicOnMessageProps + kind: 22 + documentation: + kind: markdown + value: "```wing\nTopicOnMessageProps\n```\n---\nOptions for `Topic.onMessage`." + sortText: hh|TopicOnMessageProps +- label: TopicProps + kind: 22 + documentation: + kind: markdown + value: "```wing\nTopicProps\n```\n---\nProperties for `Topic`." + sortText: hh|TopicProps +- label: Trace + kind: 22 + documentation: + kind: markdown + value: "```wing\nTrace\n```\n---\nRepresents an trace emitted during simulation." + sortText: hh|Trace +- label: WebsiteProps + kind: 22 + documentation: + kind: markdown + value: "```wing\nWebsiteProps\n```\n---\nwebsite props." + sortText: hh|WebsiteProps +- label: IApiClient + kind: 8 + documentation: + kind: markdown + value: "```wing\nIApiClient\n```\n---\nInflight methods and members of `cloud.Api`." + sortText: ii|IApiClient +- label: IApiEndpointHandler + kind: 8 + documentation: + kind: markdown + value: "```wing\nIApiEndpointHandler\n```\n---\nRepresents a resource with an inflight \"handle\" method that can be passed to one of the `Api` request preflight methods." + sortText: ii|IApiEndpointHandler +- label: IApiEndpointHandlerClient + kind: 8 + documentation: + kind: markdown + value: "```wing\nIApiEndpointHandlerClient\n```\n---\nInflight client for `IApiEndpointHandler`." + sortText: ii|IApiEndpointHandlerClient +- label: IBucketClient + kind: 8 + documentation: + kind: markdown + value: "```wing\nIBucketClient\n```\n---\nInflight interface for `Bucket`." + sortText: ii|IBucketClient +- label: IBucketEventHandler + kind: 8 + documentation: + kind: markdown + value: "```wing\nIBucketEventHandler\n```\n---\nRepresents a resource with an inflight \"handle\" method that can be passed to the bucket events." + sortText: ii|IBucketEventHandler +- label: IBucketEventHandlerClient + kind: 8 + documentation: + kind: markdown + value: "```wing\nIBucketEventHandlerClient\n```\n---\nRepresents a resource with an inflight \"handle\" method that can be passed to the bucket events." + sortText: ii|IBucketEventHandlerClient +- label: ICounterClient + kind: 8 + documentation: + kind: markdown + value: "```wing\nICounterClient\n```\n---\nInflight interface for `Counter`." + sortText: ii|ICounterClient +- label: IFunctionClient + kind: 8 + documentation: + kind: markdown + value: "```wing\nIFunctionClient\n```\n---\nInflight interface for `Function`." + sortText: ii|IFunctionClient +- label: IFunctionHandler + kind: 8 + documentation: + kind: markdown + value: "```wing\nIFunctionHandler\n```\n---\nRepresents a resource with an inflight \"handle\" method that can be used to create a `cloud.Function`." + sortText: ii|IFunctionHandler +- label: IFunctionHandlerClient + kind: 8 + documentation: + kind: markdown + value: "```wing\nIFunctionHandlerClient\n```\n---\nInflight client for `IFunctionHandler`." + sortText: ii|IFunctionHandlerClient +- label: IQueueClient + kind: 8 + documentation: + kind: markdown + value: "```wing\nIQueueClient\n```\n---\nInflight interface for `Queue`." + sortText: ii|IQueueClient +- label: IQueueSetConsumerHandler + kind: 8 + documentation: + kind: markdown + value: "```wing\nIQueueSetConsumerHandler\n```\n---\nRepresents a resource with an inflight \"handle\" method that can be passed to `Queue.setConsumer`." + sortText: ii|IQueueSetConsumerHandler +- label: IQueueSetConsumerHandlerClient + kind: 8 + documentation: + kind: markdown + value: "```wing\nIQueueSetConsumerHandlerClient\n```\n---\nInflight client for `IQueueSetConsumerHandler`." + sortText: ii|IQueueSetConsumerHandlerClient +- label: IScheduleClient + kind: 8 + documentation: + kind: markdown + value: "```wing\nIScheduleClient\n```\n---\nInflight interface for `Schedule`." + sortText: ii|IScheduleClient +- label: IScheduleOnTickHandler + kind: 8 + documentation: + kind: markdown + value: "```wing\nIScheduleOnTickHandler\n```\n---\nRepresents a resource with an inflight \"handle\" method that can be passed to `Schedule.on_tick`." + sortText: ii|IScheduleOnTickHandler +- label: IScheduleOnTickHandlerClient + kind: 8 + documentation: + kind: markdown + value: "```wing\nIScheduleOnTickHandlerClient\n```\n---\nInflight client for `IScheduleOnTickHandler`." + sortText: ii|IScheduleOnTickHandlerClient +- label: ISecretClient + kind: 8 + documentation: + kind: markdown + value: "```wing\nISecretClient\n```\n---\nInflight interface for `Secret`." + sortText: ii|ISecretClient +- label: IServiceClient + kind: 8 + documentation: + kind: markdown + value: "```wing\nIServiceClient\n```\n---\nInflight interface for `Service`." + sortText: ii|IServiceClient +- label: IServiceOnEventClient + kind: 8 + documentation: + kind: markdown + value: "```wing\nIServiceOnEventClient\n```\n---\nInflight client for `IServiceOnEventHandler`." + sortText: ii|IServiceOnEventClient +- label: IServiceOnEventHandler + kind: 8 + documentation: + kind: markdown + value: "```wing\nIServiceOnEventHandler\n```\n---\nRepresents a resource with an inflight \"handle\" method that can be passed to `ServiceProps.on_start` || `ServiceProps.on_stop`." + sortText: ii|IServiceOnEventHandler +- label: ITableClient + kind: 8 + documentation: + kind: markdown + value: "```wing\nITableClient\n```\n---\nInflight interface for `Table`." + sortText: ii|ITableClient +- label: ITestRunnerClient + kind: 8 + documentation: + kind: markdown + value: "```wing\nITestRunnerClient\n```\n---\nInflight interface for `TestRunner`." + sortText: ii|ITestRunnerClient +- label: ITopicClient + kind: 8 + documentation: + kind: markdown + value: "```wing\nITopicClient\n```\n---\nInflight interface for `Topic`." + sortText: ii|ITopicClient +- label: ITopicOnMessageHandler + kind: 8 + documentation: + kind: markdown + value: "```wing\nITopicOnMessageHandler\n```\n---\nRepresents a resource with an inflight \"handle\" method that can be passed to `Topic.on_message`." + sortText: ii|ITopicOnMessageHandler +- label: ITopicOnMessageHandlerClient + kind: 8 + documentation: + kind: markdown + value: "```wing\nITopicOnMessageHandlerClient\n```\n---\nInflight client for `ITopicOnMessageHandler`." + sortText: ii|ITopicOnMessageHandlerClient +- label: IWebsiteClient + kind: 8 + documentation: + kind: markdown + value: "```wing\nIWebsiteClient\n```\n---\nInflight methods and members of `cloud.Website`." + sortText: ii|IWebsiteClient +- label: BucketEventType + kind: 13 + documentation: + kind: markdown + value: "" + sortText: jj|BucketEventType +- label: ColumnType + kind: 13 + documentation: + kind: markdown + value: "" + sortText: jj|ColumnType +- label: HttpMethod + kind: 13 + documentation: + kind: markdown + value: "" + sortText: jj|HttpMethod +- label: TraceType + kind: 13 + documentation: + kind: markdown + value: "" + sortText: jj|TraceType + diff --git a/libs/wingc/src/lsp/snapshots/completions/only_show_symbols_in_scope.snap b/libs/wingc/src/lsp/snapshots/completions/only_show_symbols_in_scope.snap index dff5f7f4477..72019aa7ec7 100644 --- a/libs/wingc/src/lsp/snapshots/completions/only_show_symbols_in_scope.snap +++ b/libs/wingc/src/lsp/snapshots/completions/only_show_symbols_in_scope.snap @@ -7,8 +7,12 @@ source: libs/wingc/src/lsp/completions.rs kind: markdown value: "```wing\npreflight a: num\n```\n---" sortText: bb|a - insertText: a - insertTextFormat: 2 +- label: b + kind: 6 + documentation: + kind: markdown + value: "```wing\npreflight b: unresolved\n```\n---" + sortText: bb|b - label: assert kind: 3 documentation: @@ -20,14 +24,6 @@ source: libs/wingc/src/lsp/completions.rs command: title: triggerParameterHints command: editor.action.triggerParameterHints -- label: b - kind: 6 - documentation: - kind: markdown - value: "```wing\npreflight b: unresolved\n```\n---" - sortText: bb|b - insertText: b - insertTextFormat: 2 - label: log kind: 3 documentation: @@ -66,9 +62,4 @@ source: libs/wingc/src/lsp/completions.rs sortText: "ll|inflight () => {}" insertText: "inflight ($1) => {$2}" insertTextFormat: 2 -- label: "test \"\" { }" - kind: 15 - sortText: "ll|test \"\" { }" - insertText: "test \"$1\" {\n\t$2\n}" - insertTextFormat: 2 diff --git a/libs/wingc/src/lsp/snapshots/completions/optional_chaining.snap b/libs/wingc/src/lsp/snapshots/completions/optional_chaining.snap new file mode 100644 index 00000000000..84fd4dfb4b5 --- /dev/null +++ b/libs/wingc/src/lsp/snapshots/completions/optional_chaining.snap @@ -0,0 +1,114 @@ +--- +source: libs/wingc/src/lsp/completions.rs +--- +- label: asBool + kind: 2 + documentation: + kind: markdown + value: "```wing\n asBool: (): bool\n```\n---\nConvert Json element to number if possible.\n\n### Returns\na string." + sortText: ff|asBool + insertText: asBool($0) + insertTextFormat: 2 + command: + title: triggerParameterHints + command: editor.action.triggerParameterHints +- label: asNum + kind: 2 + documentation: + kind: markdown + value: "```wing\n asNum: (): num\n```\n---\nConvert Json element to number if possible.\n\n### Returns\na string." + sortText: ff|asNum + insertText: asNum($0) + insertTextFormat: 2 + command: + title: triggerParameterHints + command: editor.action.triggerParameterHints +- label: asStr + kind: 2 + documentation: + kind: markdown + value: "```wing\n asStr: (): str\n```\n---\nConvert Json element to string if possible.\n\n### Returns\na string." + sortText: ff|asStr + insertText: asStr($0) + insertTextFormat: 2 + command: + title: triggerParameterHints + command: editor.action.triggerParameterHints +- label: get + kind: 2 + documentation: + kind: markdown + value: "```wing\n get: (key: str): Json\n```\n---\nReturns a specified element from the Json.\n\n### Parameters\n - *key* - The key of the element to return.\n\n### Returns\nThe element associated with the specified key, or undefined if the key can't be found" + sortText: ff|get + insertText: get($0) + insertTextFormat: 2 + command: + title: triggerParameterHints + command: editor.action.triggerParameterHints +- label: getAt + kind: 2 + documentation: + kind: markdown + value: "```wing\n getAt: (index: num): Json\n```\n---\nReturns a specified element at a given index from Json Array.\n\n### Parameters\n - *index* - The index of the element in the Json Array to return.\n\n### Returns\nThe element at given index in Json Array, or undefined if index is not valid" + sortText: ff|getAt + insertText: getAt($0) + insertTextFormat: 2 + command: + title: triggerParameterHints + command: editor.action.triggerParameterHints +- label: tryAsBool + kind: 2 + documentation: + kind: markdown + value: "```wing\n tryAsBool: (): bool?\n```\n---\nConvert Json element to boolean if possible.\n\n### Returns\na string." + sortText: ff|tryAsBool + insertText: tryAsBool($0) + insertTextFormat: 2 + command: + title: triggerParameterHints + command: editor.action.triggerParameterHints +- label: tryAsNum + kind: 2 + documentation: + kind: markdown + value: "```wing\n tryAsNum: (): num?\n```\n---\nConvert Json element to string if possible.\n\n### Returns\na string." + sortText: ff|tryAsNum + insertText: tryAsNum($0) + insertTextFormat: 2 + command: + title: triggerParameterHints + command: editor.action.triggerParameterHints +- label: tryAsStr + kind: 2 + documentation: + kind: markdown + value: "```wing\n tryAsStr: (): str?\n```\n---\nConvert Json element to string if possible.\n\n### Returns\na string." + sortText: ff|tryAsStr + insertText: tryAsStr($0) + insertTextFormat: 2 + command: + title: triggerParameterHints + command: editor.action.triggerParameterHints +- label: tryGet + kind: 2 + documentation: + kind: markdown + value: "```wing\n tryGet: (key: str): Json?\n```\n---\nOptionally returns an specified element from the Json.\n\n### Parameters\n - *key* - The key of the element to return.\n\n### Returns\nThe element associated with the specified key, or undefined if the key can't be found" + sortText: ff|tryGet + insertText: tryGet($0) + insertTextFormat: 2 + command: + title: triggerParameterHints + command: editor.action.triggerParameterHints +- label: tryGetAt + kind: 2 + documentation: + kind: markdown + value: "```wing\n tryGetAt: (index: num): Json?\n```\n---\nOptionally returns a specified element at a given index from Json Array.\n\n### Parameters\n - *index* - The index of the element in the Json Array to return.\n\n### Returns\nThe element at given index in Json Array, or undefined if index is not valid" + sortText: ff|tryGetAt + insertText: tryGetAt($0) + insertTextFormat: 2 + command: + title: triggerParameterHints + command: editor.action.triggerParameterHints + diff --git a/libs/wingc/src/lsp/snapshots/completions/parentheses_expression.snap b/libs/wingc/src/lsp/snapshots/completions/parentheses_expression.snap new file mode 100644 index 00000000000..84fd4dfb4b5 --- /dev/null +++ b/libs/wingc/src/lsp/snapshots/completions/parentheses_expression.snap @@ -0,0 +1,114 @@ +--- +source: libs/wingc/src/lsp/completions.rs +--- +- label: asBool + kind: 2 + documentation: + kind: markdown + value: "```wing\n asBool: (): bool\n```\n---\nConvert Json element to number if possible.\n\n### Returns\na string." + sortText: ff|asBool + insertText: asBool($0) + insertTextFormat: 2 + command: + title: triggerParameterHints + command: editor.action.triggerParameterHints +- label: asNum + kind: 2 + documentation: + kind: markdown + value: "```wing\n asNum: (): num\n```\n---\nConvert Json element to number if possible.\n\n### Returns\na string." + sortText: ff|asNum + insertText: asNum($0) + insertTextFormat: 2 + command: + title: triggerParameterHints + command: editor.action.triggerParameterHints +- label: asStr + kind: 2 + documentation: + kind: markdown + value: "```wing\n asStr: (): str\n```\n---\nConvert Json element to string if possible.\n\n### Returns\na string." + sortText: ff|asStr + insertText: asStr($0) + insertTextFormat: 2 + command: + title: triggerParameterHints + command: editor.action.triggerParameterHints +- label: get + kind: 2 + documentation: + kind: markdown + value: "```wing\n get: (key: str): Json\n```\n---\nReturns a specified element from the Json.\n\n### Parameters\n - *key* - The key of the element to return.\n\n### Returns\nThe element associated with the specified key, or undefined if the key can't be found" + sortText: ff|get + insertText: get($0) + insertTextFormat: 2 + command: + title: triggerParameterHints + command: editor.action.triggerParameterHints +- label: getAt + kind: 2 + documentation: + kind: markdown + value: "```wing\n getAt: (index: num): Json\n```\n---\nReturns a specified element at a given index from Json Array.\n\n### Parameters\n - *index* - The index of the element in the Json Array to return.\n\n### Returns\nThe element at given index in Json Array, or undefined if index is not valid" + sortText: ff|getAt + insertText: getAt($0) + insertTextFormat: 2 + command: + title: triggerParameterHints + command: editor.action.triggerParameterHints +- label: tryAsBool + kind: 2 + documentation: + kind: markdown + value: "```wing\n tryAsBool: (): bool?\n```\n---\nConvert Json element to boolean if possible.\n\n### Returns\na string." + sortText: ff|tryAsBool + insertText: tryAsBool($0) + insertTextFormat: 2 + command: + title: triggerParameterHints + command: editor.action.triggerParameterHints +- label: tryAsNum + kind: 2 + documentation: + kind: markdown + value: "```wing\n tryAsNum: (): num?\n```\n---\nConvert Json element to string if possible.\n\n### Returns\na string." + sortText: ff|tryAsNum + insertText: tryAsNum($0) + insertTextFormat: 2 + command: + title: triggerParameterHints + command: editor.action.triggerParameterHints +- label: tryAsStr + kind: 2 + documentation: + kind: markdown + value: "```wing\n tryAsStr: (): str?\n```\n---\nConvert Json element to string if possible.\n\n### Returns\na string." + sortText: ff|tryAsStr + insertText: tryAsStr($0) + insertTextFormat: 2 + command: + title: triggerParameterHints + command: editor.action.triggerParameterHints +- label: tryGet + kind: 2 + documentation: + kind: markdown + value: "```wing\n tryGet: (key: str): Json?\n```\n---\nOptionally returns an specified element from the Json.\n\n### Parameters\n - *key* - The key of the element to return.\n\n### Returns\nThe element associated with the specified key, or undefined if the key can't be found" + sortText: ff|tryGet + insertText: tryGet($0) + insertTextFormat: 2 + command: + title: triggerParameterHints + command: editor.action.triggerParameterHints +- label: tryGetAt + kind: 2 + documentation: + kind: markdown + value: "```wing\n tryGetAt: (index: num): Json?\n```\n---\nOptionally returns a specified element at a given index from Json Array.\n\n### Parameters\n - *index* - The index of the element in the Json Array to return.\n\n### Returns\nThe element at given index in Json Array, or undefined if index is not valid" + sortText: ff|tryGetAt + insertText: tryGetAt($0) + insertTextFormat: 2 + command: + title: triggerParameterHints + command: editor.action.triggerParameterHints + diff --git a/libs/wingc/src/lsp/snapshots/completions/primitives_have_no_completions.snap b/libs/wingc/src/lsp/snapshots/completions/primitives_have_no_completions.snap new file mode 100644 index 00000000000..2382299ee10 --- /dev/null +++ b/libs/wingc/src/lsp/snapshots/completions/primitives_have_no_completions.snap @@ -0,0 +1,5 @@ +--- +source: libs/wingc/src/lsp/completions.rs +--- +[] + diff --git a/libs/wingc/src/lsp/snapshots/completions/renamed_builtin_type_statics.snap b/libs/wingc/src/lsp/snapshots/completions/renamed_builtin_type_statics.snap new file mode 100644 index 00000000000..91776d490e4 --- /dev/null +++ b/libs/wingc/src/lsp/snapshots/completions/renamed_builtin_type_statics.snap @@ -0,0 +1,15 @@ +--- +source: libs/wingc/src/lsp/completions.rs +--- +- label: fromJson + kind: 2 + documentation: + kind: markdown + value: "```wing\nstatic fromJson: (json: Json): str\n```\n---\nParse string from Json.\n\n### Parameters\n - *json* - to create string from.\n\n### Returns\na string." + sortText: ff|fromJson + insertText: fromJson($0) + insertTextFormat: 2 + command: + title: triggerParameterHints + command: editor.action.triggerParameterHints + diff --git a/libs/wingc/src/lsp/snapshots/completions/static_completions_after_expression.snap b/libs/wingc/src/lsp/snapshots/completions/static_completions_after_expression.snap new file mode 100644 index 00000000000..568d47cbac6 --- /dev/null +++ b/libs/wingc/src/lsp/snapshots/completions/static_completions_after_expression.snap @@ -0,0 +1,103 @@ +--- +source: libs/wingc/src/lsp/completions.rs +--- +- label: deepCopy + kind: 2 + documentation: + kind: markdown + value: "```wing\nstatic deepCopy: (json: MutJson): Json\n```\n---\nCreates an immutable deep copy of the Json.\n\n### Parameters\n - *json* - to copy.\n\n### Returns\nthe immutable copy of the Json" + sortText: ff|deepCopy + insertText: deepCopy($0) + insertTextFormat: 2 + command: + title: triggerParameterHints + command: editor.action.triggerParameterHints +- label: deepCopyMut + kind: 2 + documentation: + kind: markdown + value: "```wing\nstatic deepCopyMut: (json: Json): MutJson\n```\n---\nCreates a mutable deep copy of the Json.\n\n### Parameters\n - *json* - to copy.\n\n### Returns\nthe mutable copy of the Json" + sortText: ff|deepCopyMut + insertText: deepCopyMut($0) + insertTextFormat: 2 + command: + title: triggerParameterHints + command: editor.action.triggerParameterHints +- label: delete + kind: 2 + documentation: + kind: markdown + value: "```wing\nstatic delete: (json: MutJson, key: str): void\n```\n---\nDeletes a key in a given Json.\n\n### Parameters\n - *json* - to delete key from.\n - *key* - the key to delete." + sortText: ff|delete + insertText: delete($0) + insertTextFormat: 2 + command: + title: triggerParameterHints + command: editor.action.triggerParameterHints +- label: has + kind: 2 + documentation: + kind: markdown + value: "```wing\nstatic has: (json: Json, key: str): bool\n```\n---\nChecks if a Json object has a given key.\n\n### Parameters\n - *json* - The json object to inspect.\n - *key* - The key to check.\n\n### Returns\nBoolean value corresponding to whether the key exists" + sortText: ff|has + insertText: has($0) + insertTextFormat: 2 + command: + title: triggerParameterHints + command: editor.action.triggerParameterHints +- label: keys + kind: 2 + documentation: + kind: markdown + value: "```wing\nstatic keys: (json: any): Array\n```\n---\nReturns the keys from the Json object.\n\n### Parameters\n - *json* - to get keys from.\n\n### Returns\nthe keys from the Json object as string array" + sortText: ff|keys + insertText: keys($0) + insertTextFormat: 2 + command: + title: triggerParameterHints + command: editor.action.triggerParameterHints +- label: parse + kind: 2 + documentation: + kind: markdown + value: "```wing\nstatic parse: (str: str): Json\n```\n---\nParse a string into a Json.\n\n### Parameters\n - *str* - to parse as Json.\n\n### Returns\nJson representation of the string" + sortText: ff|parse + insertText: parse($0) + insertTextFormat: 2 + command: + title: triggerParameterHints + command: editor.action.triggerParameterHints +- label: stringify + kind: 2 + documentation: + kind: markdown + value: "```wing\nstatic stringify: (json: any, indent: num?): str\n```\n---\nFormats Json as string.\n\n### Parameters\n - *json* - to format as string.\n - *indent*\n\n### Returns\nstring representation of the Json\n\n### Remarks\n(JSON.stringify($args$))" + sortText: ff|stringify + insertText: stringify($0) + insertTextFormat: 2 + command: + title: triggerParameterHints + command: editor.action.triggerParameterHints +- label: tryParse + kind: 2 + documentation: + kind: markdown + value: "```wing\nstatic tryParse: (str: str): Json?\n```\n---\nTry to parse a string into a Json.\n\n### Parameters\n - *str* - to parse as Json.\n\n### Returns\nJson representation of the string or undefined if string is not parsable" + sortText: ff|tryParse + insertText: tryParse($0) + insertTextFormat: 2 + command: + title: triggerParameterHints + command: editor.action.triggerParameterHints +- label: values + kind: 2 + documentation: + kind: markdown + value: "```wing\nstatic values: (json: Json): Array\n```\n---\nReturns the values from the Json.\n\n### Parameters\n - *json* - to get values from.\n\n### Returns\nthe values from the Json as array of Json" + sortText: ff|values + insertText: values($0) + insertTextFormat: 2 + command: + title: triggerParameterHints + command: editor.action.triggerParameterHints + diff --git a/libs/wingc/src/lsp/snapshots/completions/static_json_after_expression.snap b/libs/wingc/src/lsp/snapshots/completions/static_json_after_expression.snap new file mode 100644 index 00000000000..568d47cbac6 --- /dev/null +++ b/libs/wingc/src/lsp/snapshots/completions/static_json_after_expression.snap @@ -0,0 +1,103 @@ +--- +source: libs/wingc/src/lsp/completions.rs +--- +- label: deepCopy + kind: 2 + documentation: + kind: markdown + value: "```wing\nstatic deepCopy: (json: MutJson): Json\n```\n---\nCreates an immutable deep copy of the Json.\n\n### Parameters\n - *json* - to copy.\n\n### Returns\nthe immutable copy of the Json" + sortText: ff|deepCopy + insertText: deepCopy($0) + insertTextFormat: 2 + command: + title: triggerParameterHints + command: editor.action.triggerParameterHints +- label: deepCopyMut + kind: 2 + documentation: + kind: markdown + value: "```wing\nstatic deepCopyMut: (json: Json): MutJson\n```\n---\nCreates a mutable deep copy of the Json.\n\n### Parameters\n - *json* - to copy.\n\n### Returns\nthe mutable copy of the Json" + sortText: ff|deepCopyMut + insertText: deepCopyMut($0) + insertTextFormat: 2 + command: + title: triggerParameterHints + command: editor.action.triggerParameterHints +- label: delete + kind: 2 + documentation: + kind: markdown + value: "```wing\nstatic delete: (json: MutJson, key: str): void\n```\n---\nDeletes a key in a given Json.\n\n### Parameters\n - *json* - to delete key from.\n - *key* - the key to delete." + sortText: ff|delete + insertText: delete($0) + insertTextFormat: 2 + command: + title: triggerParameterHints + command: editor.action.triggerParameterHints +- label: has + kind: 2 + documentation: + kind: markdown + value: "```wing\nstatic has: (json: Json, key: str): bool\n```\n---\nChecks if a Json object has a given key.\n\n### Parameters\n - *json* - The json object to inspect.\n - *key* - The key to check.\n\n### Returns\nBoolean value corresponding to whether the key exists" + sortText: ff|has + insertText: has($0) + insertTextFormat: 2 + command: + title: triggerParameterHints + command: editor.action.triggerParameterHints +- label: keys + kind: 2 + documentation: + kind: markdown + value: "```wing\nstatic keys: (json: any): Array\n```\n---\nReturns the keys from the Json object.\n\n### Parameters\n - *json* - to get keys from.\n\n### Returns\nthe keys from the Json object as string array" + sortText: ff|keys + insertText: keys($0) + insertTextFormat: 2 + command: + title: triggerParameterHints + command: editor.action.triggerParameterHints +- label: parse + kind: 2 + documentation: + kind: markdown + value: "```wing\nstatic parse: (str: str): Json\n```\n---\nParse a string into a Json.\n\n### Parameters\n - *str* - to parse as Json.\n\n### Returns\nJson representation of the string" + sortText: ff|parse + insertText: parse($0) + insertTextFormat: 2 + command: + title: triggerParameterHints + command: editor.action.triggerParameterHints +- label: stringify + kind: 2 + documentation: + kind: markdown + value: "```wing\nstatic stringify: (json: any, indent: num?): str\n```\n---\nFormats Json as string.\n\n### Parameters\n - *json* - to format as string.\n - *indent*\n\n### Returns\nstring representation of the Json\n\n### Remarks\n(JSON.stringify($args$))" + sortText: ff|stringify + insertText: stringify($0) + insertTextFormat: 2 + command: + title: triggerParameterHints + command: editor.action.triggerParameterHints +- label: tryParse + kind: 2 + documentation: + kind: markdown + value: "```wing\nstatic tryParse: (str: str): Json?\n```\n---\nTry to parse a string into a Json.\n\n### Parameters\n - *str* - to parse as Json.\n\n### Returns\nJson representation of the string or undefined if string is not parsable" + sortText: ff|tryParse + insertText: tryParse($0) + insertTextFormat: 2 + command: + title: triggerParameterHints + command: editor.action.triggerParameterHints +- label: values + kind: 2 + documentation: + kind: markdown + value: "```wing\nstatic values: (json: Json): Array\n```\n---\nReturns the values from the Json.\n\n### Parameters\n - *json* - to get values from.\n\n### Returns\nthe values from the Json as array of Json" + sortText: ff|values + insertText: values($0) + insertTextFormat: 2 + command: + title: triggerParameterHints + command: editor.action.triggerParameterHints + diff --git a/libs/wingc/src/lsp/snapshots/completions/static_json_after_expression_statement.snap b/libs/wingc/src/lsp/snapshots/completions/static_json_after_expression_statement.snap new file mode 100644 index 00000000000..568d47cbac6 --- /dev/null +++ b/libs/wingc/src/lsp/snapshots/completions/static_json_after_expression_statement.snap @@ -0,0 +1,103 @@ +--- +source: libs/wingc/src/lsp/completions.rs +--- +- label: deepCopy + kind: 2 + documentation: + kind: markdown + value: "```wing\nstatic deepCopy: (json: MutJson): Json\n```\n---\nCreates an immutable deep copy of the Json.\n\n### Parameters\n - *json* - to copy.\n\n### Returns\nthe immutable copy of the Json" + sortText: ff|deepCopy + insertText: deepCopy($0) + insertTextFormat: 2 + command: + title: triggerParameterHints + command: editor.action.triggerParameterHints +- label: deepCopyMut + kind: 2 + documentation: + kind: markdown + value: "```wing\nstatic deepCopyMut: (json: Json): MutJson\n```\n---\nCreates a mutable deep copy of the Json.\n\n### Parameters\n - *json* - to copy.\n\n### Returns\nthe mutable copy of the Json" + sortText: ff|deepCopyMut + insertText: deepCopyMut($0) + insertTextFormat: 2 + command: + title: triggerParameterHints + command: editor.action.triggerParameterHints +- label: delete + kind: 2 + documentation: + kind: markdown + value: "```wing\nstatic delete: (json: MutJson, key: str): void\n```\n---\nDeletes a key in a given Json.\n\n### Parameters\n - *json* - to delete key from.\n - *key* - the key to delete." + sortText: ff|delete + insertText: delete($0) + insertTextFormat: 2 + command: + title: triggerParameterHints + command: editor.action.triggerParameterHints +- label: has + kind: 2 + documentation: + kind: markdown + value: "```wing\nstatic has: (json: Json, key: str): bool\n```\n---\nChecks if a Json object has a given key.\n\n### Parameters\n - *json* - The json object to inspect.\n - *key* - The key to check.\n\n### Returns\nBoolean value corresponding to whether the key exists" + sortText: ff|has + insertText: has($0) + insertTextFormat: 2 + command: + title: triggerParameterHints + command: editor.action.triggerParameterHints +- label: keys + kind: 2 + documentation: + kind: markdown + value: "```wing\nstatic keys: (json: any): Array\n```\n---\nReturns the keys from the Json object.\n\n### Parameters\n - *json* - to get keys from.\n\n### Returns\nthe keys from the Json object as string array" + sortText: ff|keys + insertText: keys($0) + insertTextFormat: 2 + command: + title: triggerParameterHints + command: editor.action.triggerParameterHints +- label: parse + kind: 2 + documentation: + kind: markdown + value: "```wing\nstatic parse: (str: str): Json\n```\n---\nParse a string into a Json.\n\n### Parameters\n - *str* - to parse as Json.\n\n### Returns\nJson representation of the string" + sortText: ff|parse + insertText: parse($0) + insertTextFormat: 2 + command: + title: triggerParameterHints + command: editor.action.triggerParameterHints +- label: stringify + kind: 2 + documentation: + kind: markdown + value: "```wing\nstatic stringify: (json: any, indent: num?): str\n```\n---\nFormats Json as string.\n\n### Parameters\n - *json* - to format as string.\n - *indent*\n\n### Returns\nstring representation of the Json\n\n### Remarks\n(JSON.stringify($args$))" + sortText: ff|stringify + insertText: stringify($0) + insertTextFormat: 2 + command: + title: triggerParameterHints + command: editor.action.triggerParameterHints +- label: tryParse + kind: 2 + documentation: + kind: markdown + value: "```wing\nstatic tryParse: (str: str): Json?\n```\n---\nTry to parse a string into a Json.\n\n### Parameters\n - *str* - to parse as Json.\n\n### Returns\nJson representation of the string or undefined if string is not parsable" + sortText: ff|tryParse + insertText: tryParse($0) + insertTextFormat: 2 + command: + title: triggerParameterHints + command: editor.action.triggerParameterHints +- label: values + kind: 2 + documentation: + kind: markdown + value: "```wing\nstatic values: (json: Json): Array\n```\n---\nReturns the values from the Json.\n\n### Parameters\n - *json* - to get values from.\n\n### Returns\nthe values from the Json as array of Json" + sortText: ff|values + insertText: values($0) + insertTextFormat: 2 + command: + title: triggerParameterHints + command: editor.action.triggerParameterHints + diff --git a/libs/wingc/src/lsp/snapshots/completions/static_method_call.snap b/libs/wingc/src/lsp/snapshots/completions/static_method_call.snap index 56771d466f9..30d53b5a228 100644 --- a/libs/wingc/src/lsp/snapshots/completions/static_method_call.snap +++ b/libs/wingc/src/lsp/snapshots/completions/static_method_call.snap @@ -1,24 +1,24 @@ --- source: libs/wingc/src/lsp/completions.rs --- -- label: hello +- label: addConnection kind: 2 documentation: kind: markdown - value: "```wing\nstatic preflight hello: preflight (): void\n```\n---" - sortText: ff|hello - insertText: hello($0) + value: "```wing\nstatic preflight addConnection: preflight (props: AddConnectionProps): void\n```\n---\nAdds a connection between two resources.\n\n### Remarks\nA connection is a piece of\nmetadata describing how one resource is related to another resource. This\nmetadata is recorded in the tree.json file." + sortText: ff|addConnection + insertText: addConnection($0) insertTextFormat: 2 command: title: triggerParameterHints command: editor.action.triggerParameterHints -- label: addConnection +- label: hello kind: 2 documentation: kind: markdown - value: "```wing\nstatic preflight addConnection: preflight (props: AddConnectionProps): void\n```\n---\nAdds a connection between two resources.\n\n### Remarks\nA connection is a piece of\nmetadata describing how one resource is related to another resource. This\nmetadata is recorded in the tree.json file." - sortText: ff|addConnection - insertText: addConnection($0) + value: "```wing\nstatic preflight hello: preflight (): void\n```\n---" + sortText: ff|hello + insertText: hello($0) insertTextFormat: 2 command: title: triggerParameterHints diff --git a/libs/wingc/src/lsp/snapshots/completions/util_static_methods.snap b/libs/wingc/src/lsp/snapshots/completions/util_static_methods.snap index 7fd86ea0528..34e53f8d897 100644 --- a/libs/wingc/src/lsp/snapshots/completions/util_static_methods.snap +++ b/libs/wingc/src/lsp/snapshots/completions/util_static_methods.snap @@ -1,30 +1,6 @@ --- source: libs/wingc/src/lsp/completions.rs --- -- label: IPredicateHandler - kind: 8 - documentation: - kind: markdown - value: "```wing\nIPredicateHandler\n```\n---\nRepresents a predicate with an inflight \"handle\" method that can be passed to `util.busyWait`." - sortText: ii|IPredicateHandler -- label: IPredicateHandlerClient - kind: 8 - documentation: - kind: markdown - value: "```wing\nIPredicateHandlerClient\n```\n---\nInflight client for `IPredicateHandler`." - sortText: ii|IPredicateHandlerClient -- label: Util - kind: 7 - documentation: - kind: markdown - value: "```wing\nclass Util\n```\n---\nUtility functions." - sortText: gg|Util -- label: WaitUntilProps - kind: 22 - documentation: - kind: markdown - value: "```wing\nWaitUntilProps\n```\n---\nProperties for `util.waitUntil`." - sortText: hh|WaitUntilProps - label: env kind: 2 documentation: @@ -69,4 +45,28 @@ source: libs/wingc/src/lsp/completions.rs command: title: triggerParameterHints command: editor.action.triggerParameterHints +- label: Util + kind: 7 + documentation: + kind: markdown + value: "```wing\nclass Util\n```\n---\nUtility functions." + sortText: gg|Util +- label: WaitUntilProps + kind: 22 + documentation: + kind: markdown + value: "```wing\nWaitUntilProps\n```\n---\nProperties for `util.waitUntil`." + sortText: hh|WaitUntilProps +- label: IPredicateHandler + kind: 8 + documentation: + kind: markdown + value: "```wing\nIPredicateHandler\n```\n---\nRepresents a predicate with an inflight \"handle\" method that can be passed to `util.busyWait`." + sortText: ii|IPredicateHandler +- label: IPredicateHandlerClient + kind: 8 + documentation: + kind: markdown + value: "```wing\nIPredicateHandlerClient\n```\n---\nInflight client for `IPredicateHandler`." + sortText: ii|IPredicateHandlerClient diff --git a/libs/wingc/src/lsp/snapshots/completions/variable_type_annotation_namespace.snap b/libs/wingc/src/lsp/snapshots/completions/variable_type_annotation_namespace.snap new file mode 100644 index 00000000000..6c12917918f --- /dev/null +++ b/libs/wingc/src/lsp/snapshots/completions/variable_type_annotation_namespace.snap @@ -0,0 +1,466 @@ +--- +source: libs/wingc/src/lsp/completions.rs +--- +- label: Api + kind: 7 + documentation: + kind: markdown + value: "```wing\nclass Api\n```\n---\nFunctionality shared between all `Api` implementations." + sortText: gg|Api +- label: Bucket + kind: 7 + documentation: + kind: markdown + value: "```wing\nclass Bucket\n```\n---\nRepresents a cloud object store." + sortText: gg|Bucket +- label: Counter + kind: 7 + documentation: + kind: markdown + value: "```wing\nclass Counter\n```\n---\nRepresents a distributed atomic counter." + sortText: gg|Counter +- label: Function + kind: 7 + documentation: + kind: markdown + value: "```wing\nclass Function impl IInflightHost\n```\n---\nRepresents a function." + sortText: gg|Function +- label: Queue + kind: 7 + documentation: + kind: markdown + value: "```wing\nclass Queue\n```\n---\nRepresents a queue." + sortText: gg|Queue +- label: Schedule + kind: 7 + documentation: + kind: markdown + value: "```wing\nclass Schedule\n```\n---\nRepresents a schedule." + sortText: gg|Schedule +- label: Secret + kind: 7 + documentation: + kind: markdown + value: "```wing\nclass Secret\n```\n---\nRepresents a cloud secret." + sortText: gg|Secret +- label: Service + kind: 7 + documentation: + kind: markdown + value: "```wing\nclass Service\n```\n---\nRepresents a service." + sortText: gg|Service +- label: Table + kind: 7 + documentation: + kind: markdown + value: "```wing\nclass Table\n```\n---\nRepresents a NoSQL database table that can be used to store and query data." + sortText: gg|Table +- label: TestRunner + kind: 7 + documentation: + kind: markdown + value: "```wing\nclass TestRunner\n```\n---\nRepresents a test engine." + sortText: gg|TestRunner +- label: Topic + kind: 7 + documentation: + kind: markdown + value: "```wing\nclass Topic\n```\n---\nRepresents a topic." + sortText: gg|Topic +- label: Website + kind: 7 + documentation: + kind: markdown + value: "```wing\nclass Website\n```\n---\nRepresents a cloud static website." + sortText: gg|Website +- label: ApiConnectProps + kind: 22 + documentation: + kind: markdown + value: "```wing\nApiConnectProps\n```\n---\nOptions for Api patch endpoint." + sortText: hh|ApiConnectProps +- label: ApiDeleteProps + kind: 22 + documentation: + kind: markdown + value: "```wing\nApiDeleteProps\n```\n---\nOptions for Api put endpoint." + sortText: hh|ApiDeleteProps +- label: ApiGetProps + kind: 22 + documentation: + kind: markdown + value: "```wing\nApiGetProps\n```\n---\nOptions for Api get endpoint." + sortText: hh|ApiGetProps +- label: ApiHeadProps + kind: 22 + documentation: + kind: markdown + value: "```wing\nApiHeadProps\n```\n---\nOptions for Api patch endpoint." + sortText: hh|ApiHeadProps +- label: ApiOptionsProps + kind: 22 + documentation: + kind: markdown + value: "```wing\nApiOptionsProps\n```\n---\nOptions for Api patch endpoint." + sortText: hh|ApiOptionsProps +- label: ApiPatchProps + kind: 22 + documentation: + kind: markdown + value: "```wing\nApiPatchProps\n```\n---\nOptions for Api patch endpoint." + sortText: hh|ApiPatchProps +- label: ApiPostProps + kind: 22 + documentation: + kind: markdown + value: "```wing\nApiPostProps\n```\n---\nOptions for Api post endpoint." + sortText: hh|ApiPostProps +- label: ApiProps + kind: 22 + documentation: + kind: markdown + value: "```wing\nApiProps\n```\n---\nProperties for `Api`." + sortText: hh|ApiProps +- label: ApiPutProps + kind: 22 + documentation: + kind: markdown + value: "```wing\nApiPutProps\n```\n---\nOptions for Api put endpoint." + sortText: hh|ApiPutProps +- label: ApiRequest + kind: 22 + documentation: + kind: markdown + value: "```wing\nApiRequest\n```\n---\nShape of a request to an inflight handler." + sortText: hh|ApiRequest +- label: ApiResponse + kind: 22 + documentation: + kind: markdown + value: "```wing\nApiResponse\n```\n---\nShape of a response from a inflight handler." + sortText: hh|ApiResponse +- label: BucketDeleteOptions + kind: 22 + documentation: + kind: markdown + value: "```wing\nBucketDeleteOptions\n```\n---\nInterface for delete method inside `Bucket`." + sortText: hh|BucketDeleteOptions +- label: BucketEvent + kind: 22 + documentation: + kind: markdown + value: "```wing\nBucketEvent\n```\n---\non_event notification payload- will be in use after solving issue: https://github.com/winglang/wing/issues/1927." + sortText: hh|BucketEvent +- label: BucketOnCreateProps + kind: 22 + documentation: + kind: markdown + value: "```wing\nBucketOnCreateProps\n```\n---\non create event options." + sortText: hh|BucketOnCreateProps +- label: BucketOnDeleteProps + kind: 22 + documentation: + kind: markdown + value: "```wing\nBucketOnDeleteProps\n```\n---\non delete event options." + sortText: hh|BucketOnDeleteProps +- label: BucketOnEventProps + kind: 22 + documentation: + kind: markdown + value: "```wing\nBucketOnEventProps\n```\n---\non any event options." + sortText: hh|BucketOnEventProps +- label: BucketOnUpdateProps + kind: 22 + documentation: + kind: markdown + value: "```wing\nBucketOnUpdateProps\n```\n---\non update event options." + sortText: hh|BucketOnUpdateProps +- label: BucketProps + kind: 22 + documentation: + kind: markdown + value: "```wing\nBucketProps\n```\n---\nProperties for `Bucket`." + sortText: hh|BucketProps +- label: CounterProps + kind: 22 + documentation: + kind: markdown + value: "```wing\nCounterProps\n```\n---\nProperties for `Counter`." + sortText: hh|CounterProps +- label: FunctionProps + kind: 22 + documentation: + kind: markdown + value: "```wing\nFunctionProps\n```\n---\nProperties for `Function`.\n\n### Remarks\nThis is the type users see when constructing a cloud.Function instance." + sortText: hh|FunctionProps +- label: GetSecretValueOptions + kind: 22 + documentation: + kind: markdown + value: "```wing\nGetSecretValueOptions\n```\n---\nOptions when getting a secret value." + sortText: hh|GetSecretValueOptions +- label: QueueProps + kind: 22 + documentation: + kind: markdown + value: "```wing\nQueueProps\n```\n---\nProperties for `Queue`." + sortText: hh|QueueProps +- label: QueueSetConsumerProps + kind: 22 + documentation: + kind: markdown + value: "```wing\nQueueSetConsumerProps\n```\n---\nOptions for Queue.setConsumer." + sortText: hh|QueueSetConsumerProps +- label: ScheduleOnTickProps + kind: 22 + documentation: + kind: markdown + value: "```wing\nScheduleOnTickProps\n```\n---\nOptions for Schedule.onTick." + sortText: hh|ScheduleOnTickProps +- label: ScheduleProps + kind: 22 + documentation: + kind: markdown + value: "```wing\nScheduleProps\n```\n---\nProperties for `Schedule`." + sortText: hh|ScheduleProps +- label: SecretProps + kind: 22 + documentation: + kind: markdown + value: "```wing\nSecretProps\n```\n---\nProperties for `Secret`." + sortText: hh|SecretProps +- label: ServiceOnStartProps + kind: 22 + documentation: + kind: markdown + value: "```wing\nServiceOnStartProps\n```\n---\nOptions for Service.onStart." + sortText: hh|ServiceOnStartProps +- label: ServiceProps + kind: 22 + documentation: + kind: markdown + value: "```wing\nServiceProps\n```\n---\nProperties for `Service`." + sortText: hh|ServiceProps +- label: TableProps + kind: 22 + documentation: + kind: markdown + value: "```wing\nTableProps\n```\n---\nProperties for `Table`." + sortText: hh|TableProps +- label: TestResult + kind: 22 + documentation: + kind: markdown + value: "```wing\nTestResult\n```\n---\nA result of a single test." + sortText: hh|TestResult +- label: TestRunnerProps + kind: 22 + documentation: + kind: markdown + value: "```wing\nTestRunnerProps\n```\n---\nProperties for `TestRunner`." + sortText: hh|TestRunnerProps +- label: TopicOnMessageProps + kind: 22 + documentation: + kind: markdown + value: "```wing\nTopicOnMessageProps\n```\n---\nOptions for `Topic.onMessage`." + sortText: hh|TopicOnMessageProps +- label: TopicProps + kind: 22 + documentation: + kind: markdown + value: "```wing\nTopicProps\n```\n---\nProperties for `Topic`." + sortText: hh|TopicProps +- label: Trace + kind: 22 + documentation: + kind: markdown + value: "```wing\nTrace\n```\n---\nRepresents an trace emitted during simulation." + sortText: hh|Trace +- label: WebsiteProps + kind: 22 + documentation: + kind: markdown + value: "```wing\nWebsiteProps\n```\n---\nwebsite props." + sortText: hh|WebsiteProps +- label: IApiClient + kind: 8 + documentation: + kind: markdown + value: "```wing\nIApiClient\n```\n---\nInflight methods and members of `cloud.Api`." + sortText: ii|IApiClient +- label: IApiEndpointHandler + kind: 8 + documentation: + kind: markdown + value: "```wing\nIApiEndpointHandler\n```\n---\nRepresents a resource with an inflight \"handle\" method that can be passed to one of the `Api` request preflight methods." + sortText: ii|IApiEndpointHandler +- label: IApiEndpointHandlerClient + kind: 8 + documentation: + kind: markdown + value: "```wing\nIApiEndpointHandlerClient\n```\n---\nInflight client for `IApiEndpointHandler`." + sortText: ii|IApiEndpointHandlerClient +- label: IBucketClient + kind: 8 + documentation: + kind: markdown + value: "```wing\nIBucketClient\n```\n---\nInflight interface for `Bucket`." + sortText: ii|IBucketClient +- label: IBucketEventHandler + kind: 8 + documentation: + kind: markdown + value: "```wing\nIBucketEventHandler\n```\n---\nRepresents a resource with an inflight \"handle\" method that can be passed to the bucket events." + sortText: ii|IBucketEventHandler +- label: IBucketEventHandlerClient + kind: 8 + documentation: + kind: markdown + value: "```wing\nIBucketEventHandlerClient\n```\n---\nRepresents a resource with an inflight \"handle\" method that can be passed to the bucket events." + sortText: ii|IBucketEventHandlerClient +- label: ICounterClient + kind: 8 + documentation: + kind: markdown + value: "```wing\nICounterClient\n```\n---\nInflight interface for `Counter`." + sortText: ii|ICounterClient +- label: IFunctionClient + kind: 8 + documentation: + kind: markdown + value: "```wing\nIFunctionClient\n```\n---\nInflight interface for `Function`." + sortText: ii|IFunctionClient +- label: IFunctionHandler + kind: 8 + documentation: + kind: markdown + value: "```wing\nIFunctionHandler\n```\n---\nRepresents a resource with an inflight \"handle\" method that can be used to create a `cloud.Function`." + sortText: ii|IFunctionHandler +- label: IFunctionHandlerClient + kind: 8 + documentation: + kind: markdown + value: "```wing\nIFunctionHandlerClient\n```\n---\nInflight client for `IFunctionHandler`." + sortText: ii|IFunctionHandlerClient +- label: IQueueClient + kind: 8 + documentation: + kind: markdown + value: "```wing\nIQueueClient\n```\n---\nInflight interface for `Queue`." + sortText: ii|IQueueClient +- label: IQueueSetConsumerHandler + kind: 8 + documentation: + kind: markdown + value: "```wing\nIQueueSetConsumerHandler\n```\n---\nRepresents a resource with an inflight \"handle\" method that can be passed to `Queue.setConsumer`." + sortText: ii|IQueueSetConsumerHandler +- label: IQueueSetConsumerHandlerClient + kind: 8 + documentation: + kind: markdown + value: "```wing\nIQueueSetConsumerHandlerClient\n```\n---\nInflight client for `IQueueSetConsumerHandler`." + sortText: ii|IQueueSetConsumerHandlerClient +- label: IScheduleClient + kind: 8 + documentation: + kind: markdown + value: "```wing\nIScheduleClient\n```\n---\nInflight interface for `Schedule`." + sortText: ii|IScheduleClient +- label: IScheduleOnTickHandler + kind: 8 + documentation: + kind: markdown + value: "```wing\nIScheduleOnTickHandler\n```\n---\nRepresents a resource with an inflight \"handle\" method that can be passed to `Schedule.on_tick`." + sortText: ii|IScheduleOnTickHandler +- label: IScheduleOnTickHandlerClient + kind: 8 + documentation: + kind: markdown + value: "```wing\nIScheduleOnTickHandlerClient\n```\n---\nInflight client for `IScheduleOnTickHandler`." + sortText: ii|IScheduleOnTickHandlerClient +- label: ISecretClient + kind: 8 + documentation: + kind: markdown + value: "```wing\nISecretClient\n```\n---\nInflight interface for `Secret`." + sortText: ii|ISecretClient +- label: IServiceClient + kind: 8 + documentation: + kind: markdown + value: "```wing\nIServiceClient\n```\n---\nInflight interface for `Service`." + sortText: ii|IServiceClient +- label: IServiceOnEventClient + kind: 8 + documentation: + kind: markdown + value: "```wing\nIServiceOnEventClient\n```\n---\nInflight client for `IServiceOnEventHandler`." + sortText: ii|IServiceOnEventClient +- label: IServiceOnEventHandler + kind: 8 + documentation: + kind: markdown + value: "```wing\nIServiceOnEventHandler\n```\n---\nRepresents a resource with an inflight \"handle\" method that can be passed to `ServiceProps.on_start` || `ServiceProps.on_stop`." + sortText: ii|IServiceOnEventHandler +- label: ITableClient + kind: 8 + documentation: + kind: markdown + value: "```wing\nITableClient\n```\n---\nInflight interface for `Table`." + sortText: ii|ITableClient +- label: ITestRunnerClient + kind: 8 + documentation: + kind: markdown + value: "```wing\nITestRunnerClient\n```\n---\nInflight interface for `TestRunner`." + sortText: ii|ITestRunnerClient +- label: ITopicClient + kind: 8 + documentation: + kind: markdown + value: "```wing\nITopicClient\n```\n---\nInflight interface for `Topic`." + sortText: ii|ITopicClient +- label: ITopicOnMessageHandler + kind: 8 + documentation: + kind: markdown + value: "```wing\nITopicOnMessageHandler\n```\n---\nRepresents a resource with an inflight \"handle\" method that can be passed to `Topic.on_message`." + sortText: ii|ITopicOnMessageHandler +- label: ITopicOnMessageHandlerClient + kind: 8 + documentation: + kind: markdown + value: "```wing\nITopicOnMessageHandlerClient\n```\n---\nInflight client for `ITopicOnMessageHandler`." + sortText: ii|ITopicOnMessageHandlerClient +- label: IWebsiteClient + kind: 8 + documentation: + kind: markdown + value: "```wing\nIWebsiteClient\n```\n---\nInflight methods and members of `cloud.Website`." + sortText: ii|IWebsiteClient +- label: BucketEventType + kind: 13 + documentation: + kind: markdown + value: "" + sortText: jj|BucketEventType +- label: ColumnType + kind: 13 + documentation: + kind: markdown + value: "" + sortText: jj|ColumnType +- label: HttpMethod + kind: 13 + documentation: + kind: markdown + value: "" + sortText: jj|HttpMethod +- label: TraceType + kind: 13 + documentation: + kind: markdown + value: "" + sortText: jj|TraceType + diff --git a/libs/wingc/src/lsp/snapshots/hovers/static_stdtype_method.snap b/libs/wingc/src/lsp/snapshots/hovers/static_stdtype_method.snap index bb52535efa6..ce1babbf9ec 100644 --- a/libs/wingc/src/lsp/snapshots/hovers/static_stdtype_method.snap +++ b/libs/wingc/src/lsp/snapshots/hovers/static_stdtype_method.snap @@ -3,7 +3,7 @@ source: libs/wingc/src/lsp/hover.rs --- contents: kind: markdown - value: "```wing\nstatic stringify: (json: Json, indent: num?): str\n```\n---\nFormats Json as string.\n\n### Parameters\n - *json* - to format as string.\n - *indent*\n\n### Returns\nstring representation of the Json\n\n### Remarks\n(JSON.stringify($args$))" + value: "```wing\nstatic stringify: (json: any, indent: num?): str\n```\n---\nFormats Json as string.\n\n### Parameters\n - *json* - to format as string.\n - *indent*\n\n### Returns\nstring representation of the Json\n\n### Remarks\n(JSON.stringify($args$))" range: start: line: 1 diff --git a/libs/wingc/src/lsp/sync.rs b/libs/wingc/src/lsp/sync.rs index 695ddf6973d..0c0a6f9d2e0 100644 --- a/libs/wingc/src/lsp/sync.rs +++ b/libs/wingc/src/lsp/sync.rs @@ -7,6 +7,7 @@ use tree_sitter::Tree; use crate::closure_transform::ClosureTransformer; use crate::diagnostic::{get_diagnostics, reset_diagnostics, Diagnostic}; +use crate::files::Files; use crate::fold::Fold; use crate::jsify::JSifier; use crate::parser::Parser; @@ -108,6 +109,16 @@ fn partial_compile(source_file: &str, text: &[u8], jsii_types: &mut TypeSystem) let wing_parser = Parser::new(text, source_file.to_string()); let scope = wing_parser.wingit(&tree.root_node()); + let mut files = Files::new(); + match files.add_file( + source_file, + String::from_utf8(text.to_vec()).expect("Invalid utf-8 sequence"), + ) { + Ok(_) => {} + Err(err) => { + panic!("Failed adding source file to parser: {}", err); + } + } // -- DESUGARING PHASE -- @@ -135,7 +146,7 @@ fn partial_compile(source_file: &str, text: &[u8], jsii_types: &mut TypeSystem) let app_name = source_path.file_stem().expect("Empty filename").to_str().unwrap(); let project_dir = source_path.parent().expect("Empty filename"); - let mut jsifier = JSifier::new(&types, app_name, &project_dir, true); + let mut jsifier = JSifier::new(&types, &files, app_name, &project_dir, true); jsifier.jsify(&scope); return FileData { @@ -150,7 +161,7 @@ fn partial_compile(source_file: &str, text: &[u8], jsii_types: &mut TypeSystem) #[cfg(test)] pub mod test_utils { - use std::str::FromStr; + use std::{fs, str::FromStr}; use uuid::Uuid; use lsp_types::*; @@ -179,8 +190,12 @@ pub mod test_utils { /// ``` /// pub fn load_file_with_contents(content: &str) -> TextDocumentPositionParams { - let filename = format!("file:///{}.w", Uuid::new_v4()); - let uri = Url::from_str(&filename).unwrap(); + let temp_dir = tempfile::tempdir().expect("Failed to create temporary directory"); + let filename = format!("{}.w", Uuid::new_v4()); + let file_path = temp_dir.path().join(&filename); + fs::write(&file_path, content).expect("Failed to write to temporary file"); + let file_uri_string = format!("file:///{}", file_path.to_str().unwrap()); + let uri = Url::from_str(&file_uri_string).unwrap(); on_document_did_open(DidOpenTextDocumentParams { text_document: lsp_types::TextDocumentItem { uri: uri.clone(), diff --git a/libs/wingc/src/parser.rs b/libs/wingc/src/parser.rs index b225f307f1a..d74be46d1aa 100644 --- a/libs/wingc/src/parser.rs +++ b/libs/wingc/src/parser.rs @@ -170,6 +170,7 @@ impl<'s> Parser<'s> { arg_list: ArgList { pos_args: vec![Expr::new(ExprKind::Literal(Literal::Number(seconds)), span.clone())], named_args: IndexMap::new(), + span: span.clone(), }, }, span.clone(), @@ -1038,17 +1039,13 @@ impl<'s> Parser<'s> { )) } else { // we are missing the last property, but we can still parse the rest of the expression - let err = self.add_error( + let _ = self.add_error::<()>( "Expected property", &nested_node .child(nested_node.child_count() - 1) .expect("Nested identifier should have at least one child"), ); - if object_expr.kind() == "reference" { - self.build_reference(&object_expr, phase) - } else { - err - } + self.build_expression(&object_expr, phase) } } @@ -1094,6 +1091,7 @@ impl<'s> Parser<'s> { } fn build_arg_list(&self, arg_list_node: &Node, phase: Phase) -> DiagnosticResult { + let span = self.node_span(arg_list_node); let mut pos_args = vec![]; let mut named_args = IndexMap::new(); @@ -1127,7 +1125,11 @@ impl<'s> Parser<'s> { } } - Ok(ArgList { pos_args, named_args }) + Ok(ArgList { + pos_args, + named_args, + span, + }) } fn build_expression(&self, exp_node: &Node, phase: Phase) -> DiagnosticResult { @@ -1141,7 +1143,7 @@ impl<'s> Parser<'s> { let arg_list = if let Ok(args_node) = self.get_child_field(expression_node, "args") { self.build_arg_list(&args_node, phase) } else { - Ok(ArgList::new()) + Ok(ArgList::new(WingSpan::default())) }; let obj_id = if let Some(id_node) = expression_node.child_by_field_name("id") { @@ -1232,13 +1234,11 @@ impl<'s> Parser<'s> { start_from = last_start; } - if interpolation_start != last_start { - parts.push(InterpolatedStringPart::Static( - str::from_utf8(&self.source[start_from..interpolation_start]) - .unwrap() - .into(), - )); - } + parts.push(InterpolatedStringPart::Static( + str::from_utf8(&self.source[start_from..interpolation_start]) + .unwrap() + .into(), + )); parts.push(InterpolatedStringPart::Expr( self.build_expression(&interpolation_node.named_child(0).unwrap(), phase)?, @@ -1249,11 +1249,9 @@ impl<'s> Parser<'s> { start_from = last_end; } - if last_end != end { - parts.push(InterpolatedStringPart::Static( - str::from_utf8(&self.source[last_end..end]).unwrap().into(), - )); - } + parts.push(InterpolatedStringPart::Static( + str::from_utf8(&self.source[last_end..end]).unwrap().into(), + )); Ok(Expr::new( ExprKind::Literal(Literal::InterpolatedString(InterpolatedString { parts })), @@ -1615,6 +1613,7 @@ impl<'s> Parser<'s> { arg_list: ArgList { pos_args: vec![inflight_closure], named_args: IndexMap::new(), + span: type_span.clone(), }, }, span, diff --git a/libs/wingc/src/type_check.rs b/libs/wingc/src/type_check.rs index 7954ff83f8e..9e4dde242da 100644 --- a/libs/wingc/src/type_check.rs +++ b/libs/wingc/src/type_check.rs @@ -12,9 +12,9 @@ use crate::comp_ctx::{CompilationContext, CompilationPhase}; use crate::diagnostic::{report_diagnostic, Diagnostic, TypeError, WingSpan}; use crate::docs::Docs; use crate::{ - dbg_panic, debug, WINGSDK_ARRAY, WINGSDK_ASSEMBLY_NAME, WINGSDK_CLOUD_MODULE, WINGSDK_DURATION, WINGSDK_JSON, - WINGSDK_MAP, WINGSDK_MUT_ARRAY, WINGSDK_MUT_JSON, WINGSDK_MUT_MAP, WINGSDK_MUT_SET, WINGSDK_REDIS_MODULE, - WINGSDK_RESOURCE, WINGSDK_SET, WINGSDK_STD_MODULE, WINGSDK_STRING, WINGSDK_UTIL_MODULE, + dbg_panic, debug, WINGSDK_ARRAY, WINGSDK_ASSEMBLY_NAME, WINGSDK_CLOUD_MODULE, WINGSDK_DURATION, WINGSDK_HTTP_MODULE, + WINGSDK_JSON, WINGSDK_MAP, WINGSDK_MUT_ARRAY, WINGSDK_MUT_JSON, WINGSDK_MUT_MAP, WINGSDK_MUT_SET, + WINGSDK_REDIS_MODULE, WINGSDK_RESOURCE, WINGSDK_SET, WINGSDK_STD_MODULE, WINGSDK_STRING, WINGSDK_UTIL_MODULE, }; use derivative::Derivative; use indexmap::{IndexMap, IndexSet}; @@ -216,6 +216,12 @@ pub struct Class { pub type_parameters: Option>, pub phase: Phase, pub docs: Docs, + + // Preflight classes are CDK Constructs which means they have a scope and id as their first arguments + // this is natively supported by wing using the `as` `in` keywords. However theoretically it is possible + // to have a construct which does not have these arguments, in which case we can't use the `as` `in` keywords + // and instead the user will need to pass the relevant args to the class's init method. + pub std_construct_args: bool, } #[derive(Derivative)] @@ -634,6 +640,7 @@ pub struct FunctionSignature { /// This string may contain special tokens: /// - `$self$`: The expression on which this function was called /// - `$args$`: the arguments passed to this function call + /// - `$args_text$`: the original source text of the arguments passed to this function call, escaped pub js_override: Option, pub docs: Docs, } @@ -740,7 +747,7 @@ impl TypeRef { None } - pub fn as_mut_class(&mut self) -> Option<&mut Class> { + pub fn as_class_mut(&mut self) -> Option<&mut Class> { match **self { Type::Class(ref mut class) => Some(class), _ => None, @@ -828,6 +835,10 @@ impl TypeRef { false } + pub fn is_string(&self) -> bool { + matches!(**self, Type::String) + } + pub fn is_struct(&self) -> bool { matches!(**self, Type::Struct(_)) } @@ -894,10 +905,10 @@ impl TypeRef { Type::Anything => false, Type::Unresolved => false, Type::Void => false, - Type::MutJson => false, - Type::MutArray(_) => false, - Type::MutMap(_) => false, - Type::MutSet(_) => false, + Type::MutJson => true, + Type::MutArray(v) => v.is_capturable(), + Type::MutMap(v) => v.is_capturable(), + Type::MutSet(v) => v.is_capturable(), Type::Function(sig) => sig.phase == Phase::Inflight, // only preflight classes can be captured @@ -1016,7 +1027,7 @@ impl Types { // TODO: this is hack to create the top-level mapping from lib names to symbols // We construct a void ref by hand since we can't call self.void() while constructing the Types struct let void_ref = UnsafeRef::(&*types[void_idx] as *const Type); - let libraries = SymbolEnv::new(None, void_ref, false, Phase::Preflight, 0); + let libraries = SymbolEnv::new(None, void_ref, false, false, Phase::Preflight, 0); Self { types, @@ -1436,6 +1447,8 @@ impl<'a> TypeChecker<'a> { let obj_scope_type = obj_scope.as_ref().map(|x| self.type_check_exp(x, env)); let obj_id_type = obj_id.as_ref().map(|x| self.type_check_exp(x, env)); + let non_std_args = !type_.as_class().unwrap().std_construct_args; + // If this is a preflight class make sure the object's scope and id are of correct type if type_.is_preflight_class() { // Get reference to resource object's scope @@ -1445,6 +1458,17 @@ impl<'a> TypeChecker<'a> { .lookup(&"this".into(), Some(self.statement_idx)) .map(|v| v.as_variable().expect("Expected \"this\" to be a variable").type_) } else { + // If this is a non-standard preflight class, make sure the object's scope isn't explicitly set (using the `in` keywords) + if non_std_args { + self.spanned_error( + obj_scope.as_ref().unwrap(), + format!( + "Cannot set scope of non-standard preflight class \"{}\" using `in`", + type_ + ), + ); + } + obj_scope_type }; @@ -1464,6 +1488,13 @@ impl<'a> TypeChecker<'a> { // Verify the object id is a string if let Some(obj_id_type) = obj_id_type { self.validate_type(obj_id_type, self.types.string(), obj_id.as_ref().unwrap()); + // If this is a non-standard preflight class, make sure the object's id isn't explicitly set (using the `as` keywords) + if non_std_args { + self.spanned_error( + obj_id.as_ref().unwrap(), + format!("Cannot set id of non-standard preflight class \"{}\" using `as`", type_), + ); + } } } else { // This is an inflight class, make sure the object scope and id are not set @@ -1585,8 +1616,8 @@ impl<'a> TypeChecker<'a> { }) .collect(); - // If the struct type is anything, we don't need to validate the fields - if struct_type.is_anything() { + // If we don't have type information for the struct we don't need to validate the fields + if struct_type.is_anything() || struct_type.is_unresolved() { return struct_type; } @@ -1794,6 +1825,7 @@ impl<'a> TypeChecker<'a> { Some(env.get_ref()), sig.return_type, false, + true, func_def.signature.phase, self.statement_idx, ); @@ -2133,7 +2165,7 @@ impl<'a> TypeChecker<'a> { _t => self.types.error(), }; - let mut scope_env = SymbolEnv::new(Some(env.get_ref()), env.return_type, false, env.phase, stmt.idx); + let mut scope_env = SymbolEnv::new(Some(env.get_ref()), env.return_type, false, false, env.phase, stmt.idx); match scope_env.define( &iterator, SymbolKind::make_free_variable(iterator.clone(), iterator_type, false, env.phase), @@ -2156,6 +2188,7 @@ impl<'a> TypeChecker<'a> { Some(env.get_ref()), env.return_type, false, + false, env.phase, stmt.idx, )); @@ -2184,7 +2217,7 @@ impl<'a> TypeChecker<'a> { // and complete the type checking process for additional errors. let var_type = cond_type.maybe_unwrap_option(); - let mut stmt_env = SymbolEnv::new(Some(env.get_ref()), env.return_type, false, env.phase, stmt.idx); + let mut stmt_env = SymbolEnv::new(Some(env.get_ref()), env.return_type, false, false, env.phase, stmt.idx); // Add the variable to if block scope match stmt_env.define( @@ -2206,6 +2239,7 @@ impl<'a> TypeChecker<'a> { Some(env.get_ref()), env.return_type, false, + false, env.phase, stmt.idx, )); @@ -2225,6 +2259,7 @@ impl<'a> TypeChecker<'a> { Some(env.get_ref()), env.return_type, false, + false, env.phase, stmt.idx, )); @@ -2238,6 +2273,7 @@ impl<'a> TypeChecker<'a> { Some(env.get_ref()), env.return_type, false, + false, env.phase, stmt.idx, )); @@ -2249,6 +2285,7 @@ impl<'a> TypeChecker<'a> { Some(env.get_ref()), env.return_type, false, + false, env.phase, stmt.idx, )); @@ -2305,7 +2342,7 @@ impl<'a> TypeChecker<'a> { // we use the module name as the identifier. // For example, `bring cloud` will import the `cloud` namespace from @winglang/sdk and assign it // to an identifier named `cloud`. - WINGSDK_CLOUD_MODULE | WINGSDK_REDIS_MODULE | WINGSDK_UTIL_MODULE => { + WINGSDK_CLOUD_MODULE | WINGSDK_REDIS_MODULE | WINGSDK_UTIL_MODULE | WINGSDK_HTTP_MODULE => { library_name = WINGSDK_ASSEMBLY_NAME.to_string(); namespace_filter = vec![module_name.name.clone()]; alias = identifier.as_ref().unwrap_or(&module_name); @@ -2328,6 +2365,7 @@ impl<'a> TypeChecker<'a> { Some(env.get_ref()), env.return_type, false, + false, env.phase, stmt.idx, )); @@ -2338,6 +2376,8 @@ impl<'a> TypeChecker<'a> { let return_type = self.type_check_exp(return_expression, env); if !env.return_type.is_void() { self.validate_type(return_type, env.return_type, return_expression); + } else if env.is_in_function() { + self.spanned_error(stmt, "Unexpected return value from void function"); } else { self.spanned_error(stmt, "Return statement outside of function cannot return a value"); } @@ -2369,7 +2409,7 @@ impl<'a> TypeChecker<'a> { let (parent_class, parent_class_env) = self.extract_parent_class(parent.as_ref(), *phase, name, env, stmt); // Create environment representing this class, for now it'll be empty just so we can support referencing ourselves from the class definition. - let dummy_env = SymbolEnv::new(None, self.types.void(), false, env.phase, stmt.idx); + let dummy_env = SymbolEnv::new(None, self.types.void(), false, false, env.phase, stmt.idx); let impl_interfaces = implements .iter() @@ -2397,6 +2437,7 @@ impl<'a> TypeChecker<'a> { phase: *phase, type_parameters: None, // TODO no way to have generic args in wing yet docs: Docs::default(), + std_construct_args: *phase == Phase::Preflight, }; let mut class_type = self.types.add_type(Type::Class(class_spec)); match env.define(name, SymbolKind::Type(class_type), StatementIdx::Top) { @@ -2407,7 +2448,7 @@ impl<'a> TypeChecker<'a> { }; // Create a the real class environment to be filled with the class AST types - let mut class_env = SymbolEnv::new(parent_class_env, self.types.void(), false, env.phase, stmt.idx); + let mut class_env = SymbolEnv::new(parent_class_env, self.types.void(), false, false, env.phase, stmt.idx); // Add fields to the class env for field in fields.iter() { @@ -2464,7 +2505,7 @@ impl<'a> TypeChecker<'a> { ); // Replace the dummy class environment with the real one before type checking the methods - class_type.as_mut_class().unwrap().env = class_env; + class_type.as_class_mut().unwrap().env = class_env; let class_env = &class_type.as_class().unwrap().env; if let FunctionBody::Statements(scope) = &inflight_initializer.body { @@ -2558,7 +2599,7 @@ impl<'a> TypeChecker<'a> { } StmtKind::Interface(AstInterface { name, methods, extends }) => { // Create environment representing this interface, for now it'll be empty just so we can support referencing ourselves from the interface definition. - let dummy_env = SymbolEnv::new(None, self.types.void(), false, env.phase, stmt.idx); + let dummy_env = SymbolEnv::new(None, self.types.void(), false, false, env.phase, stmt.idx); let extend_interfaces = extends .iter() @@ -2594,7 +2635,7 @@ impl<'a> TypeChecker<'a> { }; // Create the real interface environment to be filled with the interface AST types - let mut interface_env = SymbolEnv::new(None, self.types.void(), false, env.phase, stmt.idx); + let mut interface_env = SymbolEnv::new(None, self.types.void(), false, false, env.phase, stmt.idx); // Add methods to the interface env for (method_name, sig) in methods.iter() { @@ -2632,7 +2673,7 @@ impl<'a> TypeChecker<'a> { // fail type checking. // Create an environment for the struct - let mut struct_env = SymbolEnv::new(None, self.types.void(), false, env.phase, stmt.idx); + let mut struct_env = SymbolEnv::new(None, self.types.void(), false, false, env.phase, stmt.idx); // Add fields to the struct env for field in fields.iter() { @@ -2706,13 +2747,13 @@ impl<'a> TypeChecker<'a> { finally_statements, } => { // Create a new environment for the try block - let try_env = SymbolEnv::new(Some(env.get_ref()), env.return_type, false, env.phase, stmt.idx); + let try_env = SymbolEnv::new(Some(env.get_ref()), env.return_type, false, false, env.phase, stmt.idx); try_statements.set_env(try_env); self.inner_scopes.push(try_statements); // Create a new environment for the catch block if let Some(catch_block) = catch_block { - let mut catch_env = SymbolEnv::new(Some(env.get_ref()), env.return_type, false, env.phase, stmt.idx); + let mut catch_env = SymbolEnv::new(Some(env.get_ref()), env.return_type, false, false, env.phase, stmt.idx); // Add the exception variable to the catch block if let Some(exception_var) = &catch_block.exception_var { @@ -2733,7 +2774,7 @@ impl<'a> TypeChecker<'a> { // Create a new environment for the finally block if let Some(finally_statements) = finally_statements { - let finally_env = SymbolEnv::new(Some(env.get_ref()), env.return_type, false, env.phase, stmt.idx); + let finally_env = SymbolEnv::new(Some(env.get_ref()), env.return_type, false, false, env.phase, stmt.idx); finally_statements.set_env(finally_env); self.inner_scopes.push(finally_statements); } @@ -2780,6 +2821,7 @@ impl<'a> TypeChecker<'a> { Some(class_env.get_ref()), self.types.void(), true, + true, class_env.phase, scope.statements[0].idx, ); @@ -2892,6 +2934,7 @@ impl<'a> TypeChecker<'a> { Some(parent_env.get_ref()), method_sig.return_type, is_init, + true, method_sig.phase, statement_idx, ); @@ -3113,7 +3156,14 @@ impl<'a> TypeChecker<'a> { types_map.insert(format!("{o}"), (*o, *n)); } - let new_env = SymbolEnv::new(None, original_type_class.env.return_type, false, Phase::Independent, 0); + let new_env = SymbolEnv::new( + None, + original_type_class.env.return_type, + false, + false, + Phase::Independent, + 0, + ); let tt = Type::Class(Class { name: original_type_class.name.clone(), env: new_env, @@ -3124,11 +3174,12 @@ impl<'a> TypeChecker<'a> { type_parameters: Some(type_params), phase: original_type_class.phase, docs: original_type_class.docs.clone(), + std_construct_args: original_type_class.std_construct_args, }); // TODO: here we add a new type regardless whether we already "hydrated" `original_type` with these `type_params`. Cache! let mut new_type = self.types.add_type(tt); - let new_type_class = new_type.as_mut_class().unwrap(); + let new_type_class = new_type.as_class_mut().unwrap(); // Add symbols from original type to new type // Note: this is currently limited to top-level function signatures and fields diff --git a/libs/wingc/src/type_check/jsii_importer.rs b/libs/wingc/src/type_check/jsii_importer.rs index 72b42e7e76e..a33fd9fe08d 100644 --- a/libs/wingc/src/type_check/jsii_importer.rs +++ b/libs/wingc/src/type_check/jsii_importer.rs @@ -200,7 +200,7 @@ impl<'a> JsiiImporter<'a> { } else { let ns = self.wing_types.add_namespace(Namespace { name: type_name.assembly().to_string(), - env: SymbolEnv::new(None, self.wing_types.void(), false, Phase::Preflight, 0), + env: SymbolEnv::new(None, self.wing_types.void(), false, false, Phase::Preflight, 0), loaded: false, }); self @@ -242,7 +242,7 @@ impl<'a> JsiiImporter<'a> { } else { let ns = self.wing_types.add_namespace(Namespace { name: namespace_name.to_string(), - env: SymbolEnv::new(None, self.wing_types.void(), false, Phase::Preflight, 0), + env: SymbolEnv::new(None, self.wing_types.void(), false, false, Phase::Preflight, 0), loaded: false, }); parent_ns @@ -311,6 +311,7 @@ impl<'a> JsiiImporter<'a> { None, self.wing_types.void(), false, + false, Phase::Preflight, self.jsii_spec.import_statement_idx, ); @@ -324,6 +325,7 @@ impl<'a> JsiiImporter<'a> { None, self.wing_types.void(), false, + false, iface_env.phase, self.jsii_spec.import_statement_idx, ), // Dummy env, will be replaced below @@ -336,6 +338,7 @@ impl<'a> JsiiImporter<'a> { None, self.wing_types.void(), false, + false, iface_env.phase, self.jsii_spec.import_statement_idx, ), // Dummy env, will be replaced below @@ -609,7 +612,7 @@ impl<'a> JsiiImporter<'a> { }; // Create environment representing this class, for now it'll be empty just so we can support referencing ourselves from the class definition. - let dummy_env = SymbolEnv::new(None, self.wing_types.void(), false, class_phase, 0); + let dummy_env = SymbolEnv::new(None, self.wing_types.void(), false, false, class_phase, 0); let new_type_symbol = Self::jsii_name_to_symbol(type_name, &jsii_class.location_in_module); // Create the new resource/class type and add it to the current environment. // When adding the class methods below we'll be able to reference this type. @@ -655,32 +658,49 @@ impl<'a> JsiiImporter<'a> { type_parameters: type_params, phase: class_phase, docs: Docs::from(&jsii_class.docs), + std_construct_args: false, // Temporary value, will be updated once we parse the initializer args }; let mut new_type = self.wing_types.add_type(Type::Class(class_spec)); self.register_jsii_type(&jsii_class_fqn, &new_type_symbol, new_type); // Create class's actual environment before we add properties and methods to it - let mut class_env = SymbolEnv::new(base_class_env, self.wing_types.void(), false, class_phase, 0); + let mut class_env = SymbolEnv::new(base_class_env, self.wing_types.void(), false, false, class_phase, 0); // Add constructor to the class environment let jsii_initializer = jsii_class.initializer.as_ref(); - if let Some(initializer) = jsii_initializer { let mut fn_params = vec![]; if let Some(params) = &initializer.parameters { - for (i, param) in params.iter().enumerate() { - // If this is a resource then skip scope and id arguments - // TODO hack - skip this check if the resource's name is "App" - // https://github.com/winglang/wing/issues/1485 - if class_phase == Phase::Preflight && type_name != "App" { - if i == 0 { - assert!(param.name == "scope"); - continue; - } else if i == 1 { - assert!(param.name == "id"); - continue; + let mut params_iter = params.iter(); + + // If this is a preflight class then we need to verify its first two args (scope and id): + // If both exist and are of a preflight class type and string type respectively then this is a standard constrcut type + // otherwise we need to mark it as having non standard constructor args meaning we can't use the `as` `in` keywords + // when instantiating it. + if class_phase == Phase::Preflight { + let scope_arg = params.get(0); + let id_arg = params.get(1); + if let (Some(scope_arg), Some(id_arg)) = (scope_arg, id_arg) { + let scope_arg_type = self.type_ref_to_wing_type(&scope_arg.type_); + let id_arg_type = self.type_ref_to_wing_type(&id_arg.type_); + // If scope is a preflight class, id is a string and both are non variadic non optionals types then this is a standard construct type + if scope_arg.name == "scope" + && id_arg.name == "id" + && scope_arg_type.is_preflight_class() + && id_arg_type.is_string() + && !scope_arg.variadic.unwrap_or(false) + && !scope_arg.optional.unwrap_or(false) + && !id_arg.variadic.unwrap_or(false) + && !id_arg.optional.unwrap_or(false) + { + new_type.as_class_mut().unwrap().std_construct_args = true; + params_iter.next(); + params_iter.next(); } } + } + + for param in params_iter { fn_params.push(FunctionParameter { name: param.name.clone(), typeref: self.parameter_to_wing_type(¶m), @@ -877,7 +897,7 @@ impl<'a> JsiiImporter<'a> { { let ns = self.wing_types.add_namespace(Namespace { name: assembly.name.clone(), - env: SymbolEnv::new(None, self.wing_types.void(), false, Phase::Preflight, 0), + env: SymbolEnv::new(None, self.wing_types.void(), false, false, Phase::Preflight, 0), loaded: false, }); self diff --git a/libs/wingc/src/type_check/symbol_env.rs b/libs/wingc/src/type_check/symbol_env.rs index 5916b38f584..6ddf6c57791 100644 --- a/libs/wingc/src/type_check/symbol_env.rs +++ b/libs/wingc/src/type_check/symbol_env.rs @@ -27,6 +27,8 @@ pub struct SymbolEnv { pub return_type: TypeRef, pub is_init: bool, + // Whether this scope is inside of a function + pub is_function: bool, pub phase: Phase, statement_idx: usize, } @@ -155,6 +157,7 @@ impl SymbolEnv { parent: Option, return_type: TypeRef, is_init: bool, + is_function: bool, phase: Phase, statement_idx: usize, ) -> Self { @@ -166,6 +169,7 @@ impl SymbolEnv { parent, return_type, is_init, + is_function, phase, statement_idx, } @@ -350,6 +354,14 @@ impl SymbolEnv { pub fn iter(&self, with_ancestry: bool) -> SymbolEnvIter { SymbolEnvIter::new(self, with_ancestry) } + + pub fn is_in_function(&self) -> bool { + let mut curr_env = self.get_ref(); + while !curr_env.is_function && !curr_env.is_root() { + curr_env = curr_env.parent.unwrap(); + } + curr_env.is_function + } } pub struct SymbolEnvIter<'a> { @@ -419,12 +431,13 @@ mod tests { #[test] fn test_statement_idx_lookups() { let types = setup_types(); - let mut parent_env = SymbolEnv::new(None, types.void(), false, Phase::Independent, 0); + let mut parent_env = SymbolEnv::new(None, types.void(), false, false, Phase::Independent, 0); let child_scope_idx = 10; let mut child_env = SymbolEnv::new( Some(parent_env.get_ref()), types.void(), false, + false, crate::ast::Phase::Independent, child_scope_idx, ); @@ -538,11 +551,12 @@ mod tests { #[test] fn test_nested_lookups() { let mut types = setup_types(); - let mut parent_env = SymbolEnv::new(None, types.void(), false, Phase::Independent, 0); + let mut parent_env = SymbolEnv::new(None, types.void(), false, false, Phase::Independent, 0); let child_env = SymbolEnv::new( Some(parent_env.get_ref()), types.void(), false, + false, crate::ast::Phase::Independent, 0, ); @@ -550,12 +564,19 @@ mod tests { // Create namespaces let ns1 = types.add_namespace(Namespace { name: "ns1".to_string(), - env: SymbolEnv::new(None, types.void(), false, Phase::Independent, 0), + env: SymbolEnv::new(None, types.void(), false, false, Phase::Independent, 0), loaded: false, }); let ns2 = types.add_namespace(Namespace { name: "ns2".to_string(), - env: SymbolEnv::new(Some(ns1.env.get_ref()), types.void(), false, Phase::Independent, 0), + env: SymbolEnv::new( + Some(ns1.env.get_ref()), + types.void(), + false, + false, + Phase::Independent, + 0, + ), loaded: false, }); diff --git a/libs/wingcompiler/package-lock.json b/libs/wingcompiler/package-lock.json index c3e6ad45aa5..f8a97fcf8d7 100644 --- a/libs/wingcompiler/package-lock.json +++ b/libs/wingcompiler/package-lock.json @@ -130,7 +130,7 @@ "eslint-plugin-prettier": "^4.2.1", "eslint-plugin-sort-exports": "^0.8.0", "fs-extra": "^10.1.0", - "jsii": "~5.0.0", + "jsii": "5.0.11", "jsii-diff": "^1.73.0", "jsii-pacmak": "^1.73.0", "nanoid": "^3.3.4", @@ -3231,7 +3231,7 @@ "express": "^4.18.2", "fs-extra": "^10.1.0", "ioredis": "^5.3.1", - "jsii": "~5.0.0", + "jsii": "5.0.11", "jsii-diff": "^1.73.0", "jsii-pacmak": "^1.73.0", "mime-types": "^2.1.35", diff --git a/libs/wingsdk/.projen/deps.json b/libs/wingsdk/.projen/deps.json index c5047c42485..7b330bea02e 100644 --- a/libs/wingsdk/.projen/deps.json +++ b/libs/wingsdk/.projen/deps.json @@ -114,7 +114,7 @@ }, { "name": "jsii", - "version": "~5.0.0", + "version": "5.0.11", "type": "build" }, { diff --git a/libs/wingsdk/.projen/tasks.json b/libs/wingsdk/.projen/tasks.json index 83deb114ead..8e205218306 100644 --- a/libs/wingsdk/.projen/tasks.json +++ b/libs/wingsdk/.projen/tasks.json @@ -124,16 +124,70 @@ "description": "Generate API.md from .jsii manifest", "steps": [ { - "exec": "cp -r src/cloud/*.md ../../docs/04-standard-library/01-cloud/" + "exec": "cp -r src/cloud/*.md ../../docs/docs/04-standard-library/01-cloud/" }, { - "exec": "jsii-docgen -o API.md -l wing" + "exec": "jsii-docgen -o API.md -l wing --submodule cloud" }, { - "exec": "echo '---\ntitle: API reference\nid: sdk\ndescription: Wing standard library API reference\nkeywords: [Wing sdk, sdk, Wing API Reference]\n---\n' > ../../docs/04-standard-library/04-api-reference.md" + "exec": "mkdir -p ../../docs/docs/04-standard-library/01-cloud" }, { - "exec": "cat API.md >> ../../docs/04-standard-library/04-api-reference.md" + "exec": "echo '---\ntitle: API reference\nid: api-reference\ndescription: Wing standard library API reference for the cloud module\nkeywords: [Wing sdk, sdk, Wing API Reference]\nhide_title: true\nsidebar_position: 100\n---\n\n\n' > ../../docs/docs/04-standard-library/01-cloud/api-reference.md" + }, + { + "exec": "cat API.md >> ../../docs/docs/04-standard-library/01-cloud/api-reference.md" + }, + { + "exec": "jsii-docgen -o API.md -l wing --submodule std" + }, + { + "exec": "mkdir -p ../../docs/docs/04-standard-library/02-std" + }, + { + "exec": "echo '---\ntitle: API reference\nid: api-reference\ndescription: Wing standard library API reference for the std module\nkeywords: [Wing sdk, sdk, Wing API Reference]\nhide_title: true\nsidebar_position: 100\n---\n\n\n' > ../../docs/docs/04-standard-library/02-std/api-reference.md" + }, + { + "exec": "cat API.md >> ../../docs/docs/04-standard-library/02-std/api-reference.md" + }, + { + "exec": "jsii-docgen -o API.md -l wing --submodule http" + }, + { + "exec": "mkdir -p ../../docs/docs/04-standard-library/03-http" + }, + { + "exec": "echo '---\ntitle: API reference\nid: api-reference\ndescription: Wing standard library API reference for the http module\nkeywords: [Wing sdk, sdk, Wing API Reference]\nhide_title: true\nsidebar_position: 100\n---\n\n\n' > ../../docs/docs/04-standard-library/03-http/api-reference.md" + }, + { + "exec": "cat API.md >> ../../docs/docs/04-standard-library/03-http/api-reference.md" + }, + { + "exec": "jsii-docgen -o API.md -l wing --submodule util" + }, + { + "exec": "mkdir -p ../../docs/docs/04-standard-library/04-util" + }, + { + "exec": "echo '---\ntitle: API reference\nid: api-reference\ndescription: Wing standard library API reference for the util module\nkeywords: [Wing sdk, sdk, Wing API Reference]\nhide_title: true\nsidebar_position: 100\n---\n\n\n' > ../../docs/docs/04-standard-library/04-util/api-reference.md" + }, + { + "exec": "cat API.md >> ../../docs/docs/04-standard-library/04-util/api-reference.md" + }, + { + "exec": "jsii-docgen -o API.md -l wing --submodule redis" + }, + { + "exec": "mkdir -p ../../docs/docs/04-standard-library/05-redis" + }, + { + "exec": "echo '---\ntitle: API reference\nid: api-reference\ndescription: Wing standard library API reference for the redis module\nkeywords: [Wing sdk, sdk, Wing API Reference]\nhide_title: true\nsidebar_position: 100\n---\n\n\n' > ../../docs/docs/04-standard-library/05-redis/api-reference.md" + }, + { + "exec": "cat API.md >> ../../docs/docs/04-standard-library/05-redis/api-reference.md" + }, + { + "exec": "rm API.md" } ] }, diff --git a/libs/wingsdk/.projenrc.ts b/libs/wingsdk/.projenrc.ts index 5daeb106cf3..cbf688e0d56 100644 --- a/libs/wingsdk/.projenrc.ts +++ b/libs/wingsdk/.projenrc.ts @@ -11,6 +11,8 @@ const CDKTF_PROVIDERS = [ "google@~>4.63.1", ]; +const PUBLIC_MODULES = ["cloud", "std", "http", "util", "redis"]; + // defines the list of dependencies required for each compilation target that is not built into the // compiler (like Terraform targets). const TARGET_DEPS = { @@ -96,7 +98,7 @@ const project = new cdk.JsiiProject({ codeCovTokenSecret: "CODECOV_TOKEN", github: false, projenrcTs: true, - jsiiVersion: "~5.0.0", + jsiiVersion: "5.0.11", }); project.eslint?.addPlugins("sort-exports"); @@ -187,24 +189,45 @@ project.tasks project.preCompileTask.exec("patch-package"); -const docsFrontMatter = `--- +// --------------- docs ----------------- + +const docsPrefix = (idx: number, name: string) => { + const prefix = idx.toString().padStart(2, "0"); + return `../../docs/docs/04-standard-library/${prefix}-${name}`; +}; +const docsFrontMatter = (name: string) => `--- title: API reference -id: sdk -description: Wing standard library API reference +id: api-reference +description: Wing standard library API reference for the ${name} module keywords: [Wing sdk, sdk, Wing API Reference] +hide_title: true +sidebar_position: 100 --- + + `; -const docsPath = "../../docs/04-standard-library/04-api-reference.md"; const docgen = project.tasks.tryFind("docgen")!; docgen.reset(); -// copy resource docs from src/cloud to docs -docgen.exec(`cp -r src/cloud/*.md ../../docs/04-standard-library/01-cloud/`); +// copy readme docs +docgen.exec( + `cp -r src/cloud/*.md ../../docs/docs/04-standard-library/01-cloud/` +); + +// generate api reference for each submodule +for (const mod of PUBLIC_MODULES) { + const prefix = docsPrefix(PUBLIC_MODULES.indexOf(mod) + 1, mod); + const docsPath = prefix + "/api-reference.md"; + docgen.exec(`jsii-docgen -o API.md -l wing --submodule ${mod}`); + docgen.exec(`mkdir -p ${prefix}`); + docgen.exec(`echo '${docsFrontMatter(mod)}' > ${docsPath}`); + docgen.exec(`cat API.md >> ${docsPath}`); +} + +docgen.exec("rm API.md"); -docgen.exec(`jsii-docgen -o API.md -l wing`); -docgen.exec(`echo '${docsFrontMatter}' > ${docsPath}`); -docgen.exec(`cat API.md >> ${docsPath}`); +// --------------- end of docs ----------------- // set up vitest related config project.addGitIgnore("/coverage/"); diff --git a/libs/wingsdk/package-lock.json b/libs/wingsdk/package-lock.json index f2d95162a36..d5d946f93ac 100644 --- a/libs/wingsdk/package-lock.json +++ b/libs/wingsdk/package-lock.json @@ -88,7 +88,7 @@ "eslint-plugin-prettier": "^4.2.1", "eslint-plugin-sort-exports": "^0.8.0", "fs-extra": "^10.1.0", - "jsii": "~5.0.0", + "jsii": "5.0.11", "jsii-diff": "^1.73.0", "jsii-pacmak": "^1.73.0", "nanoid": "^3.3.4", diff --git a/libs/wingsdk/package.json b/libs/wingsdk/package.json index de89c16d04d..18e8db8f445 100644 --- a/libs/wingsdk/package.json +++ b/libs/wingsdk/package.json @@ -63,7 +63,7 @@ "eslint-plugin-prettier": "^4.2.1", "eslint-plugin-sort-exports": "^0.8.0", "fs-extra": "^10.1.0", - "jsii": "~5.0.0", + "jsii": "5.0.11", "jsii-diff": "^1.73.0", "jsii-pacmak": "^1.73.0", "nanoid": "^3.3.4", diff --git a/libs/wingsdk/patches/@aws-sdk+util-utf8-browser+3.259.0.patch b/libs/wingsdk/patches/@aws-sdk+util-utf8-browser+3.259.0.patch new file mode 100644 index 00000000000..2c84bbb533b --- /dev/null +++ b/libs/wingsdk/patches/@aws-sdk+util-utf8-browser+3.259.0.patch @@ -0,0 +1,13 @@ +diff --git a/node_modules/@aws-sdk/util-utf8-browser/package.json b/node_modules/@aws-sdk/util-utf8-browser/package.json +index f3dd61f..73ec398 100644 +--- a/node_modules/@aws-sdk/util-utf8-browser/package.json ++++ b/node_modules/@aws-sdk/util-utf8-browser/package.json +@@ -31,7 +31,7 @@ + } + }, + "files": [ +- "dist-*" ++ "dist-*/**" + ], + "homepage": "https://github.com/aws/aws-sdk-js-v3/tree/main/packages/util-utf8-browser", + "repository": { diff --git a/libs/wingsdk/patches/@aws-sdk+util-utf8-node++@aws-sdk+is-array-buffer+3.201.0.patch b/libs/wingsdk/patches/@aws-sdk+util-utf8-node++@aws-sdk+is-array-buffer+3.201.0.patch new file mode 100644 index 00000000000..1c580b29803 --- /dev/null +++ b/libs/wingsdk/patches/@aws-sdk+util-utf8-node++@aws-sdk+is-array-buffer+3.201.0.patch @@ -0,0 +1,13 @@ +diff --git a/node_modules/@aws-sdk/util-utf8-node/node_modules/@aws-sdk/is-array-buffer/package.json b/node_modules/@aws-sdk/util-utf8-node/node_modules/@aws-sdk/is-array-buffer/package.json +index 97e05bc..3ff0894 100644 +--- a/node_modules/@aws-sdk/util-utf8-node/node_modules/@aws-sdk/is-array-buffer/package.json ++++ b/node_modules/@aws-sdk/util-utf8-node/node_modules/@aws-sdk/is-array-buffer/package.json +@@ -34,7 +34,7 @@ + } + }, + "files": [ +- "dist-*" ++ "dist-*/**" + ], + "homepage": "https://github.com/aws/aws-sdk-js-v3/tree/main/packages/is-array-buffer", + "repository": { diff --git a/libs/wingsdk/patches/@aws-sdk+util-utf8-node++@aws-sdk+util-buffer-from+3.208.0.patch b/libs/wingsdk/patches/@aws-sdk+util-utf8-node++@aws-sdk+util-buffer-from+3.208.0.patch new file mode 100644 index 00000000000..8a6d04a7187 --- /dev/null +++ b/libs/wingsdk/patches/@aws-sdk+util-utf8-node++@aws-sdk+util-buffer-from+3.208.0.patch @@ -0,0 +1,13 @@ +diff --git a/node_modules/@aws-sdk/util-utf8-node/node_modules/@aws-sdk/util-buffer-from/package.json b/node_modules/@aws-sdk/util-utf8-node/node_modules/@aws-sdk/util-buffer-from/package.json +index 665aa8c..80fce64 100644 +--- a/node_modules/@aws-sdk/util-utf8-node/node_modules/@aws-sdk/util-buffer-from/package.json ++++ b/node_modules/@aws-sdk/util-utf8-node/node_modules/@aws-sdk/util-buffer-from/package.json +@@ -43,7 +43,7 @@ + } + }, + "files": [ +- "dist-*" ++ "dist-*/**" + ], + "homepage": "https://github.com/aws/aws-sdk-js-v3/tree/main/packages/util-buffer-from", + "repository": { diff --git a/libs/wingsdk/patches/@aws-sdk+util-utf8-node+3.259.0.patch b/libs/wingsdk/patches/@aws-sdk+util-utf8-node+3.259.0.patch new file mode 100644 index 00000000000..04ebcd5352b --- /dev/null +++ b/libs/wingsdk/patches/@aws-sdk+util-utf8-node+3.259.0.patch @@ -0,0 +1,13 @@ +diff --git a/node_modules/@aws-sdk/util-utf8-node/package.json b/node_modules/@aws-sdk/util-utf8-node/package.json +index 6a456a1..9914406 100644 +--- a/node_modules/@aws-sdk/util-utf8-node/package.json ++++ b/node_modules/@aws-sdk/util-utf8-node/package.json +@@ -44,7 +44,7 @@ + } + }, + "files": [ +- "dist-*" ++ "dist-*/**" + ], + "homepage": "https://github.com/aws/aws-sdk-js-v3/tree/main/packages/util-utf8-node", + "repository": { diff --git a/libs/wingsdk/patches/jsii+5.0.4.patch b/libs/wingsdk/patches/jsii+5.0.11.patch similarity index 64% rename from libs/wingsdk/patches/jsii+5.0.4.patch rename to libs/wingsdk/patches/jsii+5.0.11.patch index 46fe27c57be..1db8d85a522 100644 --- a/libs/wingsdk/patches/jsii+5.0.4.patch +++ b/libs/wingsdk/patches/jsii+5.0.11.patch @@ -1,8 +1,22 @@ diff --git a/node_modules/jsii/lib/assembler.js b/node_modules/jsii/lib/assembler.js -index c1fa482..5032732 100644 +index c1fa482..9cf0ce2 100644 --- a/node_modules/jsii/lib/assembler.js +++ b/node_modules/jsii/lib/assembler.js -@@ -1583,9 +1583,9 @@ class Assembler { +@@ -1572,7 +1572,12 @@ class Assembler { + return { type: spec.CANONICAL_ANY }; + } + if (type.symbol.name === 'Array') { +- return { type: _arrayType.call(this) }; ++ // "Array" only refers to the real JS array type if it has a type parameter ++ // this is a hack so we can export classes named Array ++ const typeRef = type; ++ if (typeRef.typeArguments && typeRef.typeArguments.length === 1) { ++ return { type: _arrayType.call(this) }; ++ } + } + if (type.symbol.name === '__type' && type.symbol.members) { + return { type: _mapType.call(this) }; +@@ -1583,9 +1588,9 @@ class Assembler { this._diagnostics.push(jsii_diagnostic_1.JsiiDiagnostic.JSII_1002_UNSPECIFIED_PROMISE.create(declaration)); return { type: spec.CANONICAL_ANY }; } diff --git a/libs/wingsdk/src/cloud/api.md b/libs/wingsdk/src/cloud/api.md new file mode 100644 index 00000000000..65adc282fc5 --- /dev/null +++ b/libs/wingsdk/src/cloud/api.md @@ -0,0 +1,36 @@ +--- +title: Api +id: api +description: A built-in resource for creating HTTP endpoints in the cloud. +keywords: + [ + Wing reference, + Wing language, + language, + Wing standard library, + Wing programming language, + APIs, + Endpoints, + HTTP endpoint, + ] +sidebar_position: 1 +--- + +The `cloud.Api` resource represents a collection of HTTP endpoints that can be invoked by clients over the internet. +APIs often serve as the front door for applications to access data, business logic, or functionality from your backend services. + +The `Api` resource models an endpoint as a collection of routes, each mapped to an event handler function. +A route is a combination of a path, like `"/users/{userid}"` and a set of HTTP methods, like `GET`, `POST`, or `DELETE`. +When a client invokes a route, the corresponding event handler function executes. + +## Usage + +TODO + +## Target-specific details + +TODO + +## API Reference + +The full list of APIs for `cloud.Api` is available in the [API Reference](../api-reference). diff --git a/libs/wingsdk/src/cloud/bucket.md b/libs/wingsdk/src/cloud/bucket.md index 05ab1da247a..878ba296e44 100644 --- a/libs/wingsdk/src/cloud/bucket.md +++ b/libs/wingsdk/src/cloud/bucket.md @@ -12,6 +12,7 @@ keywords: Object storage, Buckets, ] +sidebar_position: 1 --- The `cloud.Bucket` resource represents a container for storing data in the cloud. @@ -116,4 +117,4 @@ The Google Cloud implementation of `cloud.Bucket` uses [Google Cloud Storage](ht ## API Reference -The full list of APIs for `cloud.Bucket` is available in the [API Reference](../04-api-reference.md). +The full list of APIs for `cloud.Bucket` is available in the [API Reference](../api-reference). diff --git a/libs/wingsdk/src/cloud/counter.md b/libs/wingsdk/src/cloud/counter.md index 03188adeeb5..ed69ec3b2e3 100644 --- a/libs/wingsdk/src/cloud/counter.md +++ b/libs/wingsdk/src/cloud/counter.md @@ -1,8 +1,9 @@ --- -title: Counter +title: Counter id: counter description: A built-in resource for representing an container for numbers in the cloud. keywords: [Wing reference, Wing language, language, Wing standard library, Wing programming language, Counter] +sidebar_position: 1 --- The `cloud.Counter` resource represents a stateful container for one or more numbers in the cloud. @@ -64,4 +65,4 @@ The AWS implementation of `cloud.Counter` uses [Amazon DynamoDB](https://aws.ama ## API Reference -The full list of APIs for `cloud.Counter` is available in the [API Reference](../04-api-reference.md). +The full list of APIs for `cloud.Counter` is available in the [API Reference](../api-reference). diff --git a/libs/wingsdk/src/cloud/function.md b/libs/wingsdk/src/cloud/function.md new file mode 100644 index 00000000000..71d5c063427 --- /dev/null +++ b/libs/wingsdk/src/cloud/function.md @@ -0,0 +1,36 @@ +--- +title: Function +id: function +description: A built-in resource for creating serverless functions. +keywords: + [ + Wing reference, + Wing language, + language, + Wing standard library, + Wing programming language, + Serverless function, + ] +sidebar_position: 1 +--- + +The `cloud.Function` resource represents a serverless function for performing short, stateless tasks. +Functions are typically used to run business logic in response to events, such as a file being uploaded to a bucket, a message being pushed to a queue, or a timer expiring. + +When a function is invoked on a cloud provider, it is typically executed in a container that is spun up on demand. +The container is then destroyed after the function finishes executing. + +Functions may be invoked more than once, and some cloud providers may automatically retry failed invocations. +For performance reasons, most cloud providers impose a timeout on functions, after which the function is automatically terminated. + +## Usage + +TODO + +## Target-specific details + +TODO + +## API Reference + +The full list of APIs for `cloud.Function` is available in the [API Reference](../api-reference). diff --git a/libs/wingsdk/src/cloud/queue.md b/libs/wingsdk/src/cloud/queue.md new file mode 100644 index 00000000000..08c84b151f3 --- /dev/null +++ b/libs/wingsdk/src/cloud/queue.md @@ -0,0 +1,34 @@ +--- +title: Queue +id: queue +description: A built-in resource for creating distributed queues - a data structure for storing messages. +keywords: + [ + Wing reference, + Wing language, + language, + Wing standard library, + Wing programming language, + Queue, + Distributed queue, + Messaging queue, + FIFO queue, + Channel, + ] +sidebar_position: 1 +--- + +The `cloud.Queue` resource represents a data structure for holding a list of messages. +Queues are typically used to decouple producers of data and the consumers of said data in distributed systems. + +## Usage + +TODO + +## Target-specific details + +TODO + +## API Reference + +The full list of APIs for `cloud.Queue` is available in the [API Reference](../api-reference). diff --git a/libs/wingsdk/src/cloud/schedule.md b/libs/wingsdk/src/cloud/schedule.md new file mode 100644 index 00000000000..2de097e82ca --- /dev/null +++ b/libs/wingsdk/src/cloud/schedule.md @@ -0,0 +1,32 @@ +--- +title: Schedule +id: schedule +description: A built-in resource for defining scheduled tasks. +keywords: + [ + Wing reference, + Wing language, + language, + Wing standard library, + Wing programming language, + Schedule, + Cron job, + ] +sidebar_position: 1 +--- + +The `cloud.Schedule` resource is used to trigger events at a regular interval. +Schedules are useful for periodic tasks, such as running backups or sending daily reports. + + +## Usage + +TODO + +## Target-specific details + +TODO + +## API Reference + +The full list of APIs for `cloud.Schedule` is available in the [API Reference](../api-reference). diff --git a/libs/wingsdk/src/cloud/secret.md b/libs/wingsdk/src/cloud/secret.md index ed7072060e6..efb91ec2e36 100644 --- a/libs/wingsdk/src/cloud/secret.md +++ b/libs/wingsdk/src/cloud/secret.md @@ -1,8 +1,9 @@ --- -title: Secret +title: Secret id: secret description: A built-in resource for securely storing secrets in the cloud. keywords: [Wing reference, Wing language, language, Wing standard library, Wing programming language, secrets] +sidebar_position: 1 --- The `cloud.Secret` class represents a secret value (like an API key, certificate, etc.) that is securely stored in the cloud. @@ -77,4 +78,4 @@ See [AWS documentation](https://docs.aws.amazon.com/secretsmanager/latest/usergu ## API Reference -The full list of APIs for `cloud.Secret` is available in the [API Reference](../04-api-reference.md). +The full list of APIs for `cloud.Secret` is available in the [API Reference](../api-reference). diff --git a/libs/wingsdk/src/cloud/service.md b/libs/wingsdk/src/cloud/service.md index d10c3854484..c42a865a61c 100644 --- a/libs/wingsdk/src/cloud/service.md +++ b/libs/wingsdk/src/cloud/service.md @@ -1,8 +1,9 @@ --- -title: Service +title: Service id: service description: A built-in resource for publishing messages to subscribers. keywords: [Wing reference, Wing language, language, Wing standard library, Wing programming language, services] +sidebar_position: 1 --- The `cloud.Service` class represents a cloud service that has a start and optional stop lifecycle. @@ -109,4 +110,4 @@ Within the context of the simulator, services are just spawned processes ran wit ## API Reference -The full list of APIs for `cloud.Service` is available in the [API Reference](../04-api-reference.md). +The full list of APIs for `cloud.Service` is available in the [API Reference](../api-reference). diff --git a/libs/wingsdk/src/cloud/table.ts b/libs/wingsdk/src/cloud/table.ts index 4ec105b2fb6..838a8d3c110 100644 --- a/libs/wingsdk/src/cloud/table.ts +++ b/libs/wingsdk/src/cloud/table.ts @@ -44,6 +44,11 @@ export interface TableProps { * @default undefined */ readonly primaryKey?: string; + /** + * The table's initial rows. + * @default undefined + */ + readonly initialRows?: { [key: string]: Json }; } /** @@ -105,6 +110,11 @@ export abstract class Table extends Resource { TableInflightMethods.LIST ); } + + /** + * Add a row to the table that is created when the app is deployed. + */ + public abstract addRow(key: string, row: Json): void; } /** diff --git a/libs/wingsdk/src/cloud/topic.md b/libs/wingsdk/src/cloud/topic.md index a27935087da..900ea7147e6 100644 --- a/libs/wingsdk/src/cloud/topic.md +++ b/libs/wingsdk/src/cloud/topic.md @@ -1,8 +1,9 @@ --- -title: Topic +title: Topic id: topic description: A built-in resource for publishing messages to subscribers. keywords: [Wing reference, Wing language, language, Wing standard library, Wing programming language, topics] +sidebar_position: 1 --- The `cloud.Topic` class represents a subject of data that is open for subscription. @@ -95,4 +96,4 @@ AWS implementations of `cloud.Topic` use [AWS SNS](https://docs.aws.amazon.com/s ## API Reference -The full list of APIs for `cloud.Topic` is available in the [API Reference](../04-api-reference.md). +The full list of APIs for `cloud.Topic` is available in the [API Reference](../api-reference). diff --git a/libs/wingsdk/src/cloud/website.md b/libs/wingsdk/src/cloud/website.md new file mode 100644 index 00000000000..c5eba3c518b --- /dev/null +++ b/libs/wingsdk/src/cloud/website.md @@ -0,0 +1,31 @@ +--- +title: Website +id: website +description: A built-in resource for creating static websites. +keywords: + [ + Wing reference, + Wing language, + language, + Wing standard library, + Wing programming language, + Schedule, + Cron job, + ] +sidebar_position: 1 +--- + +The `cloud.Website` resource represents a static website that can be hosted in the cloud. +Websites are typically used to serve static content, such as HTML, CSS, and JavaScript files, which are updated whenever the application is redeployed. + +## Usage + +TODO + +## Target-specific details + +TODO + +## API Reference + +The full list of APIs for `cloud.Website` is available in the [API Reference](../api-reference). diff --git a/libs/wingsdk/src/core/plugin-manager.ts b/libs/wingsdk/src/core/plugin-manager.ts index db3ab744219..d6bae5a07e4 100644 --- a/libs/wingsdk/src/core/plugin-manager.ts +++ b/libs/wingsdk/src/core/plugin-manager.ts @@ -61,8 +61,16 @@ export class PluginManager { const pluginDir = dirname(pluginAbsolutePath); + const modulePaths = module.paths ?? [__dirname]; + + const requireResolve = (path: string) => + require.resolve(path, { paths: [...modulePaths, pluginDir] }); + // eslint-disable-next-line @typescript-eslint/no-require-imports + const pluginRequire = (path: string) => require(requireResolve(path)); + pluginRequire.resolve = requireResolve; + const context = vm.createContext({ - require, + require: pluginRequire, console, exports: hooks, process, diff --git a/libs/wingsdk/src/http/http.ts b/libs/wingsdk/src/http/http.ts new file mode 100644 index 00000000000..850b53ed83e --- /dev/null +++ b/libs/wingsdk/src/http/http.ts @@ -0,0 +1,267 @@ +import { Code, InflightClient } from "../core"; + +/** + * The cache mode of the request. + * It controls how a request will interact with the system's HTTP cache. + */ +export enum RequestCache { + /** + * The runtime environment looks for a matching request in its HTTP cache. + * * If there is a match and it is fresh, it will be returned from the cache. + * * If there is a match but it is stale, the runtime environment will make a conditional request to the remote server. + * * If the server indicates that the resource has not changed, it will be returned from the cache. + * * Otherwise the resource will be downloaded from the server and the cache will be updated. + * * If there is no match, the runtime environment will make a normal request, and will update the cache with the downloaded resource. + */ + DEFAULT = "default", + /** + * The runtime environment fetches the resource from the remote server without first looking in the cache, + * and will not update the cache with the downloaded resource. + */ + NO_STORE = "no-store", + /** + * The runtime environment fetches the resource from the remote server without first looking in the cache, + * but then will update the cache with the downloaded resource. + */ + RELOAD = "reload", + /** + * The runtime environment looks for a matching request in its HTTP cache. + * * If there is a match, fresh or stale, the runtime environment will make a conditional request to the remote server. + * * If the server indicates that the resource has not changed, it will be returned from the cache. Otherwise the resource will be downloaded from the server and the cache will be updated. + * * If there is no match, the runtime environment will make a normal request, and will update the cache with the downloaded resource. + */ + NO_CACHE = "no-cache", + /** + * The runtime environment looks for a matching request in its HTTP cache. + * * If there is a match, fresh or stale, it will be returned from the cache. + * * If there is no match, the runtime environment will make a normal request, and will update the cache with the downloaded resource. + */ + FORCE_CACHE = "force-cache", +} + +/** + * The redirect read-only property that contains the mode for how redirects are handled. + */ +export enum RequestRedirect { + /** + * Follow all redirects incurred when fetching a resource. + */ + FOLLOW = "follow", + /** + * Return a network error when a request is met with a redirect. + */ + ERROR = "error", +} + +/** + * The request's method + */ +export enum HttpMethod { + /** + * GET + */ + GET = "GET", + /** + * PUT + */ + PUT = "PUT", + /** + * DELETE + */ + DELETE = "DELETE", + /** + * PATCH + */ + PATCH = "PATCH", + /** + * POST + */ + POST = "POST", +} + +/** + * An object containing any custom settings that you want to apply to the request. + */ +export interface RequestOptions { + /** + * The request method, e.g., GET, POST. The default is GET. + * @default GET + */ + readonly method?: HttpMethod; + /** + * Any headers you want to add to your request. + */ + readonly headers?: Record; + /** + * Any body that you want to add to your request. + * Note that a request using the GET or HEAD method cannot have a body. + */ + readonly body?: string; + /** + * The cache mode you want to use for the request. + */ + readonly cache?: RequestCache; + /** + * he redirect mode to use: follow, error. The default is follow. + * @default follow + */ + readonly redirect?: RequestRedirect; + /** + * A string specifying "no-referrer", client, or a URL. The default is "about:client". + * @default about:client + */ + readonly referrer?: string; +} +/** + * Represents the response to a request. + */ +export interface Response { + /** + * The status code of the response. (This will be 200 for a success). + */ + readonly status: number; + /** + * The URL of the response. + */ + readonly url: string; + /** + * A boolean indicating whether the response was successful (status in the range 200 โ€“ 299) or not. + */ + readonly ok: boolean; + /** + * The map of header information associated with the response. + */ + readonly headers: Record; + /** + * A string represents the body contents. + */ + readonly body?: string; +} + +/** + * default options to attach to any request + */ +const defaultOptions: RequestOptions = { + method: HttpMethod.GET, + headers: {}, + cache: RequestCache.DEFAULT, + redirect: RequestRedirect.FOLLOW, +}; + +/** + * the Http class is used for calling different HTTP methods and requesting and sending information online, + * as well as testing public accessible resources + * @inflight + */ +export class Util { + /** + * @internal + */ + public static _toInflightType(): Code { + return InflightClient.forType(__filename, this.name); + } + /** + * Sends an HTTP request to a URL, returning a fulfilled or failed response. + * @throws Only throws if there is a networking error + * @param url + * @param options + * @inflight + * @returns the formatted response of the call + */ + static async fetch(url: string, options?: RequestOptions): Promise { + const res = await fetch(url, { ...defaultOptions, ...options }); + return this._formatResponse(res); + } + /** + * Sends a GET request. + * @param url + * @param options + * @inflight + * @returns the formatted response of the call + */ + static async get(url: string, options?: RequestOptions): Promise { + return this.fetch(url, { + ...defaultOptions, + ...options, + method: HttpMethod.GET, + }); + } + /** + * Sends a POST request. + * @param url + * @param options + * @inflight + * @returns the formatted response of the call + */ + static async post(url: string, options?: RequestOptions): Promise { + return this.fetch(url, { + ...defaultOptions, + ...options, + method: HttpMethod.POST, + }); + } + /** + * Sends a PUT request. + * @param url + * @param options + * @inflight + * @returns the formatted response of the call + */ + static async put(url: string, options?: RequestOptions): Promise { + return this.fetch(url, { + ...defaultOptions, + ...options, + method: HttpMethod.PUT, + }); + } + /** + * Sends a PATCH request. + * @param url + * @param options + * @inflight + * @returns the formatted response of the call + */ + static async patch(url: string, options?: RequestOptions): Promise { + return this.fetch(url, { + ...defaultOptions, + ...options, + method: HttpMethod.PATCH, + }); + } + + /** + * Sends a DELETE request. + * @param url + * @param options + * @inflight + * @returns the formatted response of the call + */ + static async delete( + url: string, + options?: RequestOptions + ): Promise { + return this.fetch(url, { + ...defaultOptions, + ...options, + method: HttpMethod.DELETE, + }); + } + + private static async _formatResponse( + response: globalThis.Response + ): Promise { + // convert Headers object into a plain JS object + const headers: Record = {}; + response.headers?.forEach((val: string, key: string) => { + headers[key] = val; + }); + + return { + status: response.status, + url: response.url, + ok: response.ok, + headers: headers, + body: await response.text(), + }; + } +} diff --git a/libs/wingsdk/src/http/index.ts b/libs/wingsdk/src/http/index.ts new file mode 100644 index 00000000000..b4f0c199d63 --- /dev/null +++ b/libs/wingsdk/src/http/index.ts @@ -0,0 +1 @@ +export * from "./http"; diff --git a/libs/wingsdk/src/index.ts b/libs/wingsdk/src/index.ts index f564bcb32ea..528bce9ddd1 100644 --- a/libs/wingsdk/src/index.ts +++ b/libs/wingsdk/src/index.ts @@ -1,6 +1,7 @@ // this file must only export the standard library types and not target-specific types. export * as cloud from "./cloud"; export * as core from "./core"; +export * as http from "./http"; export * as redis from "./redis"; export * as std from "./std"; export * as testing from "./testing"; diff --git a/libs/wingsdk/src/shared-aws/api.onrequest.inflight.ts b/libs/wingsdk/src/shared-aws/api.onrequest.inflight.ts index ed993d0bc60..ca24488382b 100644 --- a/libs/wingsdk/src/shared-aws/api.onrequest.inflight.ts +++ b/libs/wingsdk/src/shared-aws/api.onrequest.inflight.ts @@ -33,7 +33,7 @@ function mapCloudApiResponseToApigatewayResponse( ): APIGatewayProxyResult { return { statusCode: resp.status, - body: resp.body ? JSON.stringify(resp.body) : "", + body: resp.body ?? "", headers: { "Content-Type": "application/json", ...resp.headers, @@ -69,14 +69,16 @@ function mapApigatewayEventToCloudApiRequest( * @param body body * @returns JSON body */ -function parseBody(request: APIGatewayProxyEvent) { +function parseBody(request: APIGatewayProxyEvent): string { if (!request.body) return ""; const contentType = Object.entries(request.headers).find( ([key, _]) => key.toLowerCase() === "content-type" )?.[1]; if (contentType === "application/x-www-form-urlencoded") { - return Object.fromEntries(new URLSearchParams(request.body)); + return JSON.stringify( + Object.fromEntries(new URLSearchParams(request.body)) + ); } - return JSON.parse(request.body); + return request.body; } diff --git a/libs/wingsdk/src/std/array.ts b/libs/wingsdk/src/std/array.ts index 590a318ffa1..25201b9848d 100644 --- a/libs/wingsdk/src/std/array.ts +++ b/libs/wingsdk/src/std/array.ts @@ -10,7 +10,7 @@ import { Code, InflightClient } from "../core"; * * @typeparam T1 */ -export class ImmutableArray { +export class Array { /** * @internal */ @@ -18,6 +18,8 @@ export class ImmutableArray { return InflightClient.forType(__filename, this.name); } + private constructor() {} + /** * The length of the array * @returns the length of the array @@ -42,7 +44,7 @@ export class ImmutableArray { * * @returns a new ImmutableArray with the values of this array followed by the values of arr */ - public concat(arr: ImmutableArray): ImmutableArray { + public concat(arr: Array): Array { arr; throw new Error("Abstract"); } @@ -67,7 +69,7 @@ export class ImmutableArray { * * @returns a MutableArray with the same values as this array */ - public copyMut(): MutableArray { + public copyMut(): MutArray { throw new Error("Macro"); } @@ -116,7 +118,7 @@ export class ImmutableArray { * * @typeparam T1 */ -export class MutableArray { +export class MutArray { /** * @internal */ @@ -124,6 +126,8 @@ export class MutableArray { return InflightClient.forType(__filename, this.name); } + private constructor() {} + /** * The length of the array * @returns the length of the array @@ -148,7 +152,7 @@ export class MutableArray { * * @returns a new MutableArray with the values of this array followed by the values of arr */ - public concat(arr: MutableArray): MutableArray { + public concat(arr: MutArray): MutArray { arr; throw new Error("Abstract"); } @@ -173,7 +177,7 @@ export class MutableArray { * * @returns an ImmutableArray with the same values as this array */ - public copy(): ImmutableArray { + public copy(): Array { throw new Error("Macro"); } diff --git a/libs/wingsdk/src/std/bool.ts b/libs/wingsdk/src/std/bool.ts index c7793cabbcb..8f2c49da9df 100644 --- a/libs/wingsdk/src/std/bool.ts +++ b/libs/wingsdk/src/std/bool.ts @@ -26,4 +26,6 @@ export class Boolean { public static _toInflightType(): Code { return InflightClient.forType(__filename, this.name); } + + private constructor() {} } diff --git a/libs/wingsdk/src/std/json.ts b/libs/wingsdk/src/std/json.ts index a9e1a14ea40..1fb2e3dd6af 100644 --- a/libs/wingsdk/src/std/json.ts +++ b/libs/wingsdk/src/std/json.ts @@ -12,71 +12,84 @@ export class Json { } /** - * Creates a mutable deep copy of the Json. + * Returns the keys from the Json object. * - * @macro (JSON.parse(JSON.stringify($args$))) + * @macro (Object.keys($args$)) * - * @param json to copy - * @returns the mutable copy of the Json + * @param json to get keys from + * @returns the keys from the Json object as string array */ - public static deepCopyMut(json: Json): MutJson { + public static keys(json: Json | MutJson): string[] { json; throw new Error("Macro"); } /** - * Returns the keys from the Json object. + * Deletes a key in a given Json * - * @macro (Object.keys($args$)) + * @macro ((args) => { delete (args[0])[args[1]]; })([$args$]) * - * @param json to get keys from - * @returns the keys from the Json object as string array + * @param json to delete key from + * @param key the key to delete */ - public static keys(json: Json): string[] { + public static delete(json: MutJson, key: string): void { json; + key; throw new Error("Macro"); } /** - * Returns the values from the Json. + * Formats Json as string * - * @macro (Object.values($args$)) + * (JSON.stringify($args$)) * - * @param json to get values from - * @returns the values from the Json as array of Json + * @macro ((args) => { return JSON.stringify(args[0], null, args[1]) })([$args$]) + * + * @param json to format as string + * @returns string representation of the Json */ - public static values(json: Json): Json[] { + public static stringify(json: Json | MutJson, indent?: number): string { json; + indent; throw new Error("Macro"); } /** - * Deletes a key in a given Json + * Creates an immutable deep copy of the Json. * - * @macro ((args) => { delete (args[0])[args[1]]; })([$args$]) + * @macro Object.freeze(JSON.parse(JSON.stringify($args$))) * - * @param json to delete key from - * @param key the key to delete + * @param json to copy + * @returns the immutable copy of the Json */ - public static delete(json: Json, key: string): void { + public static deepCopy(json: MutJson): Json { json; - key; throw new Error("Macro"); } /** - * Formats Json as string + * Creates a mutable deep copy of the Json. * - * (JSON.stringify($args$)) + * @macro (JSON.parse(JSON.stringify($args$))) * - * @macro ((args) => { return JSON.stringify(args[0], null, args[1]) })([$args$]) + * @param json to copy + * @returns the mutable copy of the Json + */ + public static deepCopyMut(json: Json): MutJson { + json; + throw new Error("Macro"); + } + + /** + * Returns the values from the Json. * - * @param json to format as string - * @returns string representation of the Json + * @macro (Object.values($args$)) + * + * @param json to get values from + * @returns the values from the Json as array of Json */ - public static stringify(json: Json, indent?: number): string { + public static values(json: Json): Json[] { json; - indent; throw new Error("Macro"); } @@ -146,6 +159,98 @@ export class Json { index; throw new Error("Macro"); } + + /** + * Optionally returns an specified element from the Json. + * + * @macro ($self$)?.[$args$] + * + * @param key The key of the element to return + * @returns The element associated with the specified key, or undefined if the key can't be found + */ + public tryGet(key: string): Json | undefined { + key; + throw new Error("Macro"); + } + + /** + * Optionally returns a specified element at a given index from Json Array + * + * @macro ($self$)?.[$args$] + * + * @param index The index of the element in the Json Array to return + * @returns The element at given index in Json Array, or undefined if index is not valid + */ + public tryGetAt(index: number): Json | undefined { + index; + throw new Error("Macro"); + } + + /** + * Convert Json element to string if possible. + * + * @macro ((arg) => { if (typeof arg !== "string") {throw new Error("unable to parse " + typeof arg + " " + arg + " as a string")}; return JSON.parse(JSON.stringify(arg)) })($self$) + * + * @returns a string. + */ + public asStr(): string { + throw new Error("Macro"); + } + + /** + * Convert Json element to string if possible. + * + * @macro ((arg) => { return (typeof arg === "string") ? JSON.parse(JSON.stringify(arg)) : undefined })($self$) + * + * @returns a string. + */ + public tryAsStr(): string | undefined { + throw new Error("Macro"); + } + + /** + * Convert Json element to number if possible. + * + * @macro ((arg) => { if (typeof arg !== "number") {throw new Error("unable to parse " + typeof arg + " " + arg + " as a number")}; return JSON.parse(JSON.stringify(arg)) })($self$) + * + * @returns a string. + */ + public asNum(): number { + throw new Error("Macro"); + } + + /** + * Convert Json element to string if possible. + * + * @macro ((arg) => { return (typeof arg === "number") ? JSON.parse(JSON.stringify(arg)) : undefined })($self$) + * + * @returns a string. + */ + public tryAsNum(): number | undefined { + throw new Error("Macro"); + } + + /** + * Convert Json element to number if possible. + * + * @macro ((arg) => { if (typeof arg !== "boolean") {throw new Error("unable to parse " + typeof arg + " " + arg + " as a boolean")}; return JSON.parse(JSON.stringify(arg)) })($self$) + * + * @returns a string. + */ + public asBool(): boolean { + throw new Error("Macro"); + } + + /** + * Convert Json element to boolean if possible. + * + * @macro ((arg) => { return (typeof arg === "boolean") ? JSON.parse(JSON.stringify(arg)) : undefined })($self$) + * + * @returns a string. + */ + public tryAsBool(): boolean | undefined { + throw new Error("Macro"); + } } /** @@ -159,19 +264,6 @@ export class MutJson { return InflightClient.forType(__filename, this.name); } - /** - * Creates an immutable deep copy of the Json. - * - * @macro Object.freeze(JSON.parse(JSON.stringify($args$))) - * - * @param json to copy - * @returns the immutable copy of the Json - */ - public static deepCopy(json: MutJson): Json { - json; - throw new Error("Macro"); - } - /** * Returns a specified element from the Json. * @@ -224,4 +316,96 @@ export class MutJson { value; throw new Error("Macro"); } + + /** + * Optionally returns an specified element from the Json. + * + * @macro ($self$)?.[$args$] + * + * @param key The key of the element to return + * @returns The element associated with the specified key, or undefined if the key can't be found + */ + public tryGet(key: string): MutJson | undefined { + key; + throw new Error("Macro"); + } + + /** + * Optionally returns a specified element at a given index from Json Array + * + * @macro ($self$)?.[$args$] + * + * @param index The index of the element in the Json Array to return + * @returns The element at given index in Json Array, or undefined if index is not valid + */ + public tryGetAt(index: number): MutJson | undefined { + index; + throw new Error("Macro"); + } + + /** + * Convert Json element to string if possible. + * + * @macro ((arg) => { if (typeof arg !== "string") {throw new Error("unable to parse " + typeof arg + " " + arg + " as a string")}; return JSON.parse(JSON.stringify(arg)) })($self$) + * + * @returns a string. + */ + public asStr(): string { + throw new Error("Macro"); + } + + /** + * Convert Json element to string if possible. + * + * @macro ((arg) => { return (typeof arg === "string") ? JSON.parse(JSON.stringify(arg)) : undefined })($self$) + * + * @returns a string. + */ + public tryAsStr(): string | undefined { + throw new Error("Macro"); + } + + /** + * Convert Json element to number if possible. + * + * @macro ((arg) => { if (typeof arg !== "number") {throw new Error("unable to parse " + typeof arg + " " + arg + " as a number")}; return JSON.parse(JSON.stringify(arg)) })($self$) + * + * @returns a string. + */ + public asNum(): number { + throw new Error("Macro"); + } + + /** + * Convert Json element to string if possible. + * + * @macro ((arg) => { return (typeof arg === "number") ? JSON.parse(JSON.stringify(arg)) : undefined })($self$) + * + * @returns a string. + */ + public tryAsNum(): number | undefined { + throw new Error("Macro"); + } + + /** + * Convert Json element to number if possible. + * + * @macro ((arg) => { if (typeof arg !== "boolean") {throw new Error("unable to parse " + typeof arg + " " + arg + " as a boolean")}; return JSON.parse(JSON.stringify(arg)) })($self$) + * + * @returns a string. + */ + public asBool(): boolean { + throw new Error("Macro"); + } + + /** + * Convert Json element to boolean if possible. + * + * @macro ((arg) => { return (typeof arg === "boolean") ? JSON.parse(JSON.stringify(arg)) : undefined })($self$) + * + * @returns a string. + */ + public tryAsBool(): boolean | undefined { + throw new Error("Macro"); + } } diff --git a/libs/wingsdk/src/std/map.ts b/libs/wingsdk/src/std/map.ts index b186f81c472..09e683a1ad8 100644 --- a/libs/wingsdk/src/std/map.ts +++ b/libs/wingsdk/src/std/map.ts @@ -2,7 +2,7 @@ // They should not be consumed directly by users. // TODO: These should be interfaces, currently Wing does not support interface JSII imports -import { ImmutableArray } from "./array"; +import { Array } from "./array"; import { T1 } from "./generics"; import { Code, InflightClient } from "../core"; @@ -11,7 +11,7 @@ import { Code, InflightClient } from "../core"; * * @typeparam T1 */ -export class ImmutableMap { +export class Map { /** * @internal */ @@ -19,6 +19,8 @@ export class ImmutableMap { return InflightClient.forType(__filename, this.name); } + private constructor() {} + /** * Returns the number of elements in the map. * @@ -67,7 +69,7 @@ export class ImmutableMap { * * @returns a MutableMap with the same values as this map */ - public copyMut(): MutableMap { + public copyMut(): MutMap { throw new Error("Macro"); } @@ -89,7 +91,7 @@ export class ImmutableMap { * * @returns an array of type T containing the values of this map */ - public values(): ImmutableArray { + public values(): Array { throw new Error("Macro"); } } @@ -99,7 +101,7 @@ export class ImmutableMap { * * @typeparam T1 */ -export class MutableMap { +export class MutMap { /** * @internal */ @@ -107,6 +109,8 @@ export class MutableMap { return InflightClient.forType(__filename, this.name); } + private constructor() {} + /** * Returns the number of elements in the map. * @@ -135,7 +139,7 @@ export class MutableMap { * * @returns an ImmutableMap with the same values as this map */ - public copy(): ImmutableMap { + public copy(): Map { throw new Error("Macro"); } @@ -214,7 +218,7 @@ export class MutableMap { * * @returns an array containing of type T the values of this map */ - public values(): ImmutableArray { + public values(): Array { throw new Error("Macro"); } } diff --git a/libs/wingsdk/src/std/number.ts b/libs/wingsdk/src/std/number.ts index ca8e1dac6b8..a0dfbb046cc 100644 --- a/libs/wingsdk/src/std/number.ts +++ b/libs/wingsdk/src/std/number.ts @@ -37,4 +37,6 @@ export class Number { public static _toInflightType(): Code { return InflightClient.forType(__filename, this.name); } + + private constructor() {} } diff --git a/libs/wingsdk/src/std/range.ts b/libs/wingsdk/src/std/range.ts index a34441a98c6..02840058056 100644 --- a/libs/wingsdk/src/std/range.ts +++ b/libs/wingsdk/src/std/range.ts @@ -33,4 +33,6 @@ export class Range { public static _toInflightType(): Code { return InflightClient.forType(__filename, this.name); } + + private constructor() {} } diff --git a/libs/wingsdk/src/std/set.ts b/libs/wingsdk/src/std/set.ts index f43fe2b4f1d..6e971bdfc36 100644 --- a/libs/wingsdk/src/std/set.ts +++ b/libs/wingsdk/src/std/set.ts @@ -10,7 +10,7 @@ import { Code, InflightClient } from "../core"; * * @typeparam T1 */ -export class ImmutableSet { +export class Set { /** * @internal */ @@ -18,6 +18,8 @@ export class ImmutableSet { return InflightClient.forType(__filename, this.name); } + private constructor() {} + /** * The length of the set * @returns the length of the set @@ -43,7 +45,7 @@ export class ImmutableSet { * * @returns a MutableSet with the same values as this set */ - public copyMut(): MutableSet { + public copyMut(): MutSet { throw new Error("Macro"); } } @@ -53,7 +55,7 @@ export class ImmutableSet { * * @typeparam T1 */ -export class MutableSet { +export class MutSet { /** * @internal */ @@ -61,6 +63,8 @@ export class MutableSet { return InflightClient.forType(__filename, this.name); } + private constructor() {} + /** * The length of the set * @returns the length of the set @@ -74,7 +78,7 @@ export class MutableSet { * @param value value to add * @returns true if the value was added, false if it was already in the set */ - public add(value: T1): MutableSet { + public add(value: T1): MutSet { value; throw new Error("Abstract"); } @@ -93,7 +97,7 @@ export class MutableSet { * * @returns an ImmutableSet with the same values as this set */ - public copy(): ImmutableSet { + public copy(): Set { throw new Error("Macro"); } diff --git a/libs/wingsdk/src/std/string.ts b/libs/wingsdk/src/std/string.ts index 0a1bd076a71..7de5bf1dd46 100644 --- a/libs/wingsdk/src/std/string.ts +++ b/libs/wingsdk/src/std/string.ts @@ -29,6 +29,8 @@ export class String { throw new Error("Macro"); } + private constructor() {} + /** * The length of the string. */ diff --git a/libs/wingsdk/src/target-awscdk/bucket.ts b/libs/wingsdk/src/target-awscdk/bucket.ts index 550a186dccf..13dce48b142 100644 --- a/libs/wingsdk/src/target-awscdk/bucket.ts +++ b/libs/wingsdk/src/target-awscdk/bucket.ts @@ -79,11 +79,6 @@ export class Bucket extends cloud.Bucket { functionHandler, opts ); - Resource.addConnection({ - from: this, - to: fn, - relationship: cloud.BucketEventType.CREATE, - }); if (!(fn instanceof Function)) { throw new Error( @@ -100,6 +95,12 @@ export class Bucket extends cloud.Bucket { ): void { const fn = this.onEventFunction("OnCreate", inflight, opts); + Resource.addConnection({ + from: this, + to: fn, + relationship: cloud.BucketEventType.CREATE, + }); + this.bucket.addEventNotification( EVENTS[cloud.BucketEventType.CREATE], new LambdaDestination(fn._function) @@ -118,12 +119,6 @@ export class Bucket extends cloud.Bucket { relationship: cloud.BucketEventType.DELETE, }); - Resource.addConnection({ - from: this, - to: fn, - relationship: cloud.BucketEventType.DELETE, - }); - this.bucket.addEventNotification( EVENTS[cloud.BucketEventType.DELETE], new LambdaDestination(fn._function) diff --git a/libs/wingsdk/src/target-sim/schema-resources.ts b/libs/wingsdk/src/target-sim/schema-resources.ts index e09119e0be0..9ded9b063fe 100644 --- a/libs/wingsdk/src/target-sim/schema-resources.ts +++ b/libs/wingsdk/src/target-sim/schema-resources.ts @@ -170,6 +170,7 @@ export interface TableSchema extends BaseResourceSchema { readonly name: string; readonly columns: { [key: string]: ColumnType }; readonly primaryKey: string; + readonly initialRows: Record; }; } diff --git a/libs/wingsdk/src/target-sim/table.inflight.ts b/libs/wingsdk/src/target-sim/table.inflight.ts index db769e0a3aa..13e1496587d 100644 --- a/libs/wingsdk/src/target-sim/table.inflight.ts +++ b/libs/wingsdk/src/target-sim/table.inflight.ts @@ -13,6 +13,7 @@ export class Table implements ITableClient, ISimulatorResourceInstance { private primaryKey: string; private table: Map; private readonly context: ISimulatorContext; + private readonly initialRows: Record; public constructor(props: TableSchema["props"], context: ISimulatorContext) { this.name = props.name; @@ -20,9 +21,18 @@ export class Table implements ITableClient, ISimulatorResourceInstance { this.primaryKey = props.primaryKey; this.table = new Map(); this.context = context; + this.initialRows = props.initialRows ?? {}; } public async init(): Promise { + for (const [key, row] of Object.entries(this.initialRows)) { + await this.context.withTrace({ + message: `Adding initial row (key=${key}).`, + activity: async () => { + return this.table.set(key, row); + }, + }); + } return {}; } diff --git a/libs/wingsdk/src/target-sim/table.ts b/libs/wingsdk/src/target-sim/table.ts index 0580aa6046a..60d331d20b7 100644 --- a/libs/wingsdk/src/target-sim/table.ts +++ b/libs/wingsdk/src/target-sim/table.ts @@ -4,7 +4,7 @@ import { TableSchema, TABLE_TYPE } from "./schema-resources"; import { bindSimulatorResource, makeSimulatorJsClient } from "./util"; import * as cloud from "../cloud"; import * as core from "../core"; -import { IInflightHost } from "../std"; +import { Json, IInflightHost } from "../std"; import { BaseResourceSchema } from "../testing/simulator"; /** @@ -13,9 +13,15 @@ import { BaseResourceSchema } from "../testing/simulator"; * @inflight `@winglang/sdk.cloud.ITableClient` */ export class Table extends cloud.Table implements ISimulatorResource { + private readonly initialRows: Record = {}; constructor(scope: Construct, id: string, props: cloud.TableProps = {}) { super(scope, id, props); } + + public addRow(key: string, row: Json): void { + this.initialRows[key] = row; + } + public toSimulator(): BaseResourceSchema { const schema: TableSchema = { type: TABLE_TYPE, @@ -24,6 +30,7 @@ export class Table extends cloud.Table implements ISimulatorResource { name: this.name, columns: this.columns, primaryKey: this.primaryKey, + initialRows: this.initialRows, }, attrs: {} as any, }; diff --git a/libs/wingsdk/src/target-tf-aws/table.ts b/libs/wingsdk/src/target-tf-aws/table.ts index a1040026f9d..0085d29cedb 100644 --- a/libs/wingsdk/src/target-tf-aws/table.ts +++ b/libs/wingsdk/src/target-tf-aws/table.ts @@ -1,10 +1,12 @@ +import { marshall } from "@aws-sdk/util-dynamodb"; import { Construct } from "constructs"; import { Function } from "./function"; import { DynamodbTable } from "../.gen/providers/aws/dynamodb-table"; +import { DynamodbTableItem } from "../.gen/providers/aws/dynamodb-table-item"; import * as cloud from "../cloud"; import * as core from "../core"; import { NameOptions, ResourceNames } from "../shared/resource-names"; -import { IInflightHost } from "../std"; +import { Json, IInflightHost } from "../std"; /** * Table names must be between 3 and 255 characters. @@ -37,6 +39,18 @@ export class Table extends cloud.Table { }); } + public addRow(key: string, row: Json): void { + const item = { [this.primaryKey]: key, ...row }; + const marshalledItem = marshall(item); + const stringifiedItem = JSON.stringify(marshalledItem); + + new DynamodbTableItem(this, `DynamodbTableItem-${key}`, { + tableName: this.table.name, + hashKey: this.table.hashKey, + item: stringifiedItem, + }); + } + /** @internal */ public _bind(host: IInflightHost, ops: string[]): void { if (!(host instanceof Function)) { diff --git a/libs/wingsdk/test/core/to-inflight-type.test.ts b/libs/wingsdk/test/core/to-inflight-type.test.ts index de9b1992bd7..4eb291274ec 100644 --- a/libs/wingsdk/test/core/to-inflight-type.test.ts +++ b/libs/wingsdk/test/core/to-inflight-type.test.ts @@ -10,6 +10,9 @@ const skip = [ "std.Display", "std.Test", "std.Resource", + "util.RequestCache", // an enum + "util.RequestRedirect", // an enum + "util.HttpMethod", // an enum ]; // checks that the class `className` in module `module` has a `_toInflightType()` method and that it diff --git a/libs/wingsdk/test/http/http.test.ts b/libs/wingsdk/test/http/http.test.ts new file mode 100644 index 00000000000..5975655c094 --- /dev/null +++ b/libs/wingsdk/test/http/http.test.ts @@ -0,0 +1,145 @@ +import { test, describe, beforeEach, vi, Mock, expect } from "vitest"; +import { + Util as Http, + HttpMethod, + Response, + RequestCache, + RequestRedirect, +} from "../../src/http/http"; + +let defaultOptions = { + method: HttpMethod.GET, + headers: {}, + cache: RequestCache.DEFAULT, + redirect: RequestRedirect.FOLLOW, +}; + +describe("fetch", () => { + global.fetch = vi.fn(); + + beforeEach(() => { + (global.fetch as Mock).mockClear(); + }); + + test("get, post, put, patch and delete return response when supplying a url", async () => { + (global.fetch as Mock).mockImplementation((url) => ({ + url, + headers: new Headers([["content-type", "application/json"]]), + status: 200, + text: () => Promise.resolve("ok!"), + })); + + const expectResponse = (response: Response) => { + expect(response.body).toBe("ok!"); + expect(response.url).toBe("url"); + expect(response.status).toBe(200); + expect(response.headers).toEqual({ "content-type": "application/json" }); + }; + + expectResponse(await Http.get("url")); + expectResponse(await Http.put("url")); + expectResponse(await Http.post("url")); + expectResponse(await Http.patch("url")); + expectResponse(await Http.delete("url")); + }); + + test("http.fetch is working with all methods", async () => { + (global.fetch as Mock).mockImplementation((url) => ({ + url, + headers: new Headers([["content-type", "application/json"]]), + status: 200, + text: () => Promise.resolve("ok!"), + })); + + const expectResponse = (response: Response) => { + expect(response.body).toBe("ok!"); + expect(response.url).toBe("url"); + expect(response.status).toBe(200); + expect(response.headers).toEqual({ "content-type": "application/json" }); + }; + + for (let method in HttpMethod) { + expectResponse( + //@ts-expect-error- ts thinks method is a string + await Http.fetch("url", { method }) + ); + } + }); + + test("getting back json body parses well", async () => { + let jsonBody = { a: "hello", b: 2.2, c: false }; + (global.fetch as Mock).mockImplementation((url) => ({ + url, + headers: new Headers([["content-type", "application/json"]]), + status: 200, + text: () => Promise.resolve(JSON.stringify(jsonBody)), + })); + + const expectResponse = (response: Response) => { + expect(JSON.parse(response.body)).toEqual(jsonBody); + expect(response.url).toBe("url"); + expect(response.status).toBe(200); + expect(response.headers).toEqual({ "content-type": "application/json" }); + }; + + for (let method in HttpMethod) { + expectResponse( + //@ts-expect-error- ts thinks method is a string + await Http.fetch("url", { method }) + ); + } + expectResponse(await Http.get("url")); + expectResponse(await Http.put("url")); + expectResponse(await Http.post("url")); + expectResponse(await Http.patch("url")); + expectResponse(await Http.delete("url")); + }); + + test("http.get with no options implements all default options", async () => { + (global.fetch as Mock).mockImplementation((url) => ({ + url, + headers: new Headers([["content-type", "application/json"]]), + status: 200, + text: () => Promise.resolve("ok!"), + })); + + let f = vi.spyOn(global, "fetch"); + + await Http.get("url"); + + expect(f).toBeCalledWith("url", { ...defaultOptions }); + }); + + test("http.fetch with no options implements all default options", async () => { + (global.fetch as Mock).mockImplementation((url) => ({ + url, + headers: new Headers([["content-type", "application/json"]]), + status: 200, + text: () => Promise.resolve("ok!"), + })); + + let f = vi.spyOn(global, "fetch"); + + await Http.fetch("url"); + + expect(f).toBeCalledWith("url", defaultOptions); + }); + + test("http.put method cannot be overridden", async () => { + (global.fetch as Mock).mockImplementation((url) => ({ + url, + headers: new Headers([["content-type", "application/json"]]), + status: 200, + text: () => Promise.resolve("ok!"), + })); + + let f = vi.spyOn(global, "fetch"); + + await Http.put("url", { method: HttpMethod.GET }); + + expect(f).toBeCalledWith("url", { + ...defaultOptions, + method: HttpMethod.PUT, + }); + }); +}); diff --git a/libs/wingsdk/test/shared-aws/api.onrequest.inflight.test.ts b/libs/wingsdk/test/shared-aws/api.onrequest.inflight.test.ts index 17a8afc2a3f..85fd6943640 100644 --- a/libs/wingsdk/test/shared-aws/api.onrequest.inflight.test.ts +++ b/libs/wingsdk/test/shared-aws/api.onrequest.inflight.test.ts @@ -18,7 +18,7 @@ describe("ApiResponseMapper", () => { const handlerResponse: ApiResponse = { status: 200, - body: { key: "value" }, + body: JSON.stringify({ key: "value" }), headers: { "header-1": "value-1" }, }; const requestHandlerClient = new ApiOnRequestHandlerClient({ @@ -57,7 +57,7 @@ describe("ApiResponseMapper", () => { const handlerResponse: ApiResponse = { status: 200, - body: { key: "value" }, + body: JSON.stringify({ key: "value" }), }; const requestHandlerClient = new ApiOnRequestHandlerClient({ handler: { @@ -130,7 +130,7 @@ describe("ApiResponseMapper", () => { const handlerResponse: ApiResponse = { status: 200, - body: { key: "value" }, + body: JSON.stringify({ key: "value" }), headers: { "Content-Type": "application/octet-stream", }, @@ -194,7 +194,7 @@ describe("ApiRequest", () => { // THEN expect(handlerMock).toHaveBeenCalledWith({ - body: { foo: "bar" }, + body: JSON.stringify({ foo: "bar" }), headers: { "header-1": "value-1" }, method: "GET", path: "/", @@ -289,7 +289,7 @@ describe("ApiRequest", () => { // THEN expect(handlerMock).toHaveBeenCalledWith({ - body: { foo: "bar", bar: "baz" }, + body: JSON.stringify({ foo: "bar", bar: "baz" }), headers: { "content-type": "application/x-www-form-urlencoded", }, diff --git a/libs/wingsdk/test/target-sim/__snapshots__/api.test.ts.snap b/libs/wingsdk/test/target-sim/__snapshots__/api.test.ts.snap index 84fa263c4d4..6dfa2e45577 100644 --- a/libs/wingsdk/test/target-sim/__snapshots__/api.test.ts.snap +++ b/libs/wingsdk/test/target-sim/__snapshots__/api.test.ts.snap @@ -1055,7 +1055,7 @@ exports[`api supports every method type 1`] = ` "Invoke (payload={\\"headers\\":{\\"host\\":\\"127.0.0.1:\\",\\"connection\\":\\"keep-alive\\",\\"accept\\":\\"*/*\\",\\"accept-language\\":\\"*\\",\\"sec-fetch-mode\\":\\"cors\\",\\"user-agent\\":\\"undici\\",\\"accept-encoding\\":\\"gzip, deflate\\"},\\"body\\":{},\\"method\\":\\"DELETE\\",\\"path\\":\\"/hello\\",\\"query\\":{},\\"vars\\":{}}).", "DELETE /hello - 200.", "Processing \\"GET /hello\\" params={}).", - "Invoke (payload={\\"headers\\":{\\"host\\":\\"127.0.0.1:\\",\\"connection\\":\\"keep-alive\\",\\"accept\\":\\"*/*\\",\\"accept-language\\":\\"*\\",\\"sec-fetch-mode\\":\\"cors\\",\\"user-agent\\":\\"undici\\",\\"accept-encoding\\":\\"gzip, deflate\\"},\\"body\\":{},\\"method\\":\\"HEAD\\",\\"path\\":\\"/hello\\",\\"query\\":{},\\"vars\\":{}}).", + "Invoke (payload={\\"headers\\":{\\"host\\":\\"127.0.0.1:\\",\\"connection\\":\\"close\\",\\"accept\\":\\"*/*\\",\\"accept-language\\":\\"*\\",\\"sec-fetch-mode\\":\\"cors\\",\\"user-agent\\":\\"undici\\",\\"accept-encoding\\":\\"gzip, deflate\\"},\\"body\\":{},\\"method\\":\\"HEAD\\",\\"path\\":\\"/hello\\",\\"query\\":{},\\"vars\\":{}}).", "GET /hello - 200.", "Processing \\"OPTIONS /hello\\" params={}).", "Invoke (payload={\\"headers\\":{\\"host\\":\\"127.0.0.1:\\",\\"connection\\":\\"keep-alive\\",\\"accept\\":\\"*/*\\",\\"accept-language\\":\\"*\\",\\"sec-fetch-mode\\":\\"cors\\",\\"user-agent\\":\\"undici\\",\\"accept-encoding\\":\\"gzip, deflate\\"},\\"body\\":{},\\"method\\":\\"OPTIONS\\",\\"path\\":\\"/hello\\",\\"query\\":{},\\"vars\\":{}}).", diff --git a/libs/wingsdk/test/target-sim/__snapshots__/table.test.ts.snap b/libs/wingsdk/test/target-sim/__snapshots__/table.test.ts.snap index 706cb6702a3..5793b4f9bc0 100644 --- a/libs/wingsdk/test/target-sim/__snapshots__/table.test.ts.snap +++ b/libs/wingsdk/test/target-sim/__snapshots__/table.test.ts.snap @@ -1,5 +1,97 @@ // Vitest Snapshot v1, https://vitest.dev/guide/snapshot.html +exports[`can add row in preflight 1`] = ` +[ + "wingsdk.cloud.TestRunner created.", + "Adding initial row (key=joe-id).", + "wingsdk.cloud.Table created.", + "get row joe-id from table my_addrow_table.", + "wingsdk.cloud.Table deleted.", + "wingsdk.cloud.TestRunner deleted.", +] +`; + +exports[`can add row in preflight 2`] = ` +{ + "simulator.json": { + "resources": [ + { + "attrs": {}, + "path": "root/cloud.TestRunner", + "props": { + "tests": {}, + }, + "type": "wingsdk.cloud.TestRunner", + }, + { + "attrs": {}, + "path": "root/my_table", + "props": { + "columns": { + "age": 1, + "name": 0, + }, + "initialRows": { + "joe-id": { + "age": 50, + "name": "Joe Doe", + }, + }, + "name": "my_addrow_table", + "primaryKey": "id", + }, + "type": "wingsdk.cloud.Table", + }, + ], + "sdkVersion": "0.0.0", + }, + "tree.json": { + "tree": { + "children": { + "cloud.TestRunner": { + "attributes": { + "wing:resource:connections": [], + }, + "constructInfo": { + "fqn": "constructs.Construct", + "version": "10.1.314", + }, + "display": { + "description": "A suite of APIs for running tests and collecting results.", + "hidden": true, + "title": "TestRunner", + }, + "id": "cloud.TestRunner", + "path": "root/cloud.TestRunner", + }, + "my_table": { + "attributes": { + "wing:resource:connections": [], + }, + "constructInfo": { + "fqn": "constructs.Construct", + "version": "10.1.314", + }, + "display": { + "description": "A cloud NoSQL database table that can be used to store and query data", + "title": "Table", + }, + "id": "my_table", + "path": "root/my_table", + }, + }, + "constructInfo": { + "fqn": "constructs.Construct", + "version": "10.1.314", + }, + "id": "root", + "path": "root", + }, + "version": "tree-0.1", + }, +} +`; + exports[`create a table 1`] = ` { "simulator.json": { @@ -20,6 +112,7 @@ exports[`create a table 1`] = ` "age": 1, "name": 0, }, + "initialRows": {}, "name": "new_table", "primaryKey": "id", }, @@ -107,6 +200,7 @@ exports[`get row 2`] = ` "age": 1, "name": 0, }, + "initialRows": {}, "name": "my_get_table", "primaryKey": "id", }, @@ -193,6 +287,7 @@ exports[`insert row 2`] = ` "age": 1, "name": 0, }, + "initialRows": {}, "name": "my_insert_table", "primaryKey": "id", }, @@ -282,6 +377,7 @@ exports[`list table 2`] = ` "age": 1, "name": 0, }, + "initialRows": {}, "name": "my_list_table", "primaryKey": "id", }, @@ -372,6 +468,7 @@ exports[`update row 2`] = ` "age": 1, "name": 0, }, + "initialRows": {}, "name": "my_update_table", "primaryKey": "id", }, diff --git a/libs/wingsdk/test/target-sim/table.test.ts b/libs/wingsdk/test/target-sim/table.test.ts index e688a377eb0..4c9f96ebccc 100644 --- a/libs/wingsdk/test/target-sim/table.test.ts +++ b/libs/wingsdk/test/target-sim/table.test.ts @@ -29,6 +29,7 @@ test("create a table", async () => { age: cloud.ColumnType.NUMBER, }, primaryKey: "id", + initialRows: {}, }, type: "wingsdk.cloud.Table", }); @@ -65,6 +66,7 @@ test("insert row", async () => { age: cloud.ColumnType.NUMBER, }, primaryKey: "id", + initialRows: {}, }, type: "wingsdk.cloud.Table", }); @@ -104,6 +106,7 @@ test("get row", async () => { age: cloud.ColumnType.NUMBER, }, primaryKey: "id", + initialRows: {}, }, type: "wingsdk.cloud.Table", }); @@ -146,6 +149,7 @@ test("update row", async () => { age: cloud.ColumnType.NUMBER, }, primaryKey: "id", + initialRows: {}, }, type: "wingsdk.cloud.Table", }); @@ -187,6 +191,7 @@ test("list table", async () => { age: cloud.ColumnType.NUMBER, }, primaryKey: "id", + initialRows: {}, }, type: "wingsdk.cloud.Table", }); @@ -254,3 +259,50 @@ test("deleting non-existent item", async () => { `The primary key "joe-id" not found in the "my_delete_non_existent_table" table.` ); }); + +test("can add row in preflight", async () => { + // GIVEN + const KEY = "joe-id"; + const ROW = { name: "Joe Doe", age: 50 }; + + const app = new SimApp(); + const table = cloud.Table._newTable(app, "my_table", { + name: "my_addrow_table", + columns: { + name: cloud.ColumnType.STRING, + age: cloud.ColumnType.NUMBER, + }, + primaryKey: "id", + initialRows: {}, + }); + table.addRow(KEY, ROW as any); + + const s = await app.startSimulator(); + const client = s.getResource("/my_table") as ITableClient; + + const joe = await client.get("joe-id"); + expect(joe).toEqual({ name: "Joe Doe", age: 50 }); + + expect(s.getResourceConfig("/my_table")).toEqual({ + attrs: { + handle: expect.any(String), + }, + path: "root/my_table", + props: { + name: "my_addrow_table", + columns: { + name: cloud.ColumnType.STRING, + age: cloud.ColumnType.NUMBER, + }, + primaryKey: "id", + initialRows: { + "joe-id": { name: "Joe Doe", age: 50 }, + }, + }, + type: "wingsdk.cloud.Table", + }); + await s.stop(); + + expect(listMessages(s)).toMatchSnapshot(); + expect(app.snapshot()).toMatchSnapshot(); +}); diff --git a/libs/wingsdk/test/testing/__snapshots__/simulator.test.ts.snap b/libs/wingsdk/test/testing/__snapshots__/simulator.test.ts.snap index bc6128bcec8..b882df4f85b 100644 --- a/libs/wingsdk/test/testing/__snapshots__/simulator.test.ts.snap +++ b/libs/wingsdk/test/testing/__snapshots__/simulator.test.ts.snap @@ -148,8 +148,8 @@ exports[`run single test > test failure 1`] = ` - at Script.runInContext (node:vm:141:12) - at Object.runInContext (node:vm:297:6) + at Script.runInContext (node:vm:) + at Object.runInContext (node:vm:) at new Promise () diff --git a/libs/wingsdk/test/testing/simulator.test.ts b/libs/wingsdk/test/testing/simulator.test.ts index 50ae979dbe5..3c3f5c708a0 100644 --- a/libs/wingsdk/test/testing/simulator.test.ts +++ b/libs/wingsdk/test/testing/simulator.test.ts @@ -140,10 +140,21 @@ function removePathsFromTraceLine(line?: string) { return line; } +function removeLineNumbers(line?: string) { + if (!line) { + return undefined; + } + + return line.replace(/:\d+:\d+/g, ":"); +} + function sanitizeResult(result: TestResult): TestResult { let error: string | undefined; if (result.error) { - let lines = result.error.split("\n").map(removePathsFromTraceLine); + let lines = result.error + .split("\n") + .map(removePathsFromTraceLine) + .map(removeLineNumbers); // remove all lines after "at Simulator.runTest" since they are platform-dependent let lastLine = lines.findIndex((line) => diff --git a/tools/bump-pack/src/pack.ts b/tools/bump-pack/src/pack.ts index 1068aa6a471..62ae26af12d 100644 --- a/tools/bump-pack/src/pack.ts +++ b/tools/bump-pack/src/pack.ts @@ -1,4 +1,5 @@ import { execSync } from "node:child_process"; +import { readFileSync, writeFileSync } from "node:fs"; export interface PackOptions { /** @@ -22,6 +23,38 @@ export async function pack(options: PackOptions) { if (dryRun) { console.log(`Would have run "npm pack" in ${packageDir}`); } else { - execSync("npm pack", { cwd: packageDir, stdio: "inherit" }); + preparePackageJsonAndRun(packageDir, () => { + execSync("npm pack", { cwd: packageDir, stdio: "inherit" }); + }); + } +} + +/** + * Transforms the package.json at `packageDir` to use the publishConfig field and remove other unnecessary fields such as devDependencies. + * @param packageDir The directory that contains the package.json to transform. + * @param callback The function called after the transformation, before reverting the package.json back to its original state. + */ +function preparePackageJsonAndRun(packageDir: string, callback: () => void) { + const packageJsonPath = `${packageDir}/package.json`; + const packageJsonString = readFileSync(packageJsonPath, "utf8"); + const packageJson = JSON.parse(packageJsonString); + try { + writeFileSync( + packageJsonPath, + `${JSON.stringify( + { + ...packageJson, + ...packageJson.publishConfig, + publishConfig: undefined, + devDependencies: undefined, + }, + undefined, + 2 + )}\n` + ); + + callback(); + } finally { + writeFileSync(packageJsonPath, packageJsonString); } } diff --git a/tools/hangar/README.md b/tools/hangar/README.md index 07a84e87c57..378b07ea3c5 100644 --- a/tools/hangar/README.md +++ b/tools/hangar/README.md @@ -1,6 +1,6 @@ # Hangar - Wing Toolchain Test Suite -[How to run E2E tests?](https://docs.winglang.io/contributors/development#-how-do-i-run-tests) +[How to run E2E tests?](https://docs.winglang.io/contributing/development#-how-do-i-run-tests) ### Ideas for later diff --git a/tools/hangar/__snapshots__/error.ts.snap b/tools/hangar/__snapshots__/error.ts.snap index 20ccc525fad..30acafb6401 100644 --- a/tools/hangar/__snapshots__/error.ts.snap +++ b/tools/hangar/__snapshots__/error.ts.snap @@ -11,13 +11,10 @@ exports[`bool_from_json.w 1`] = ` } - - - - -Tests 1 failed (1) -Duration -" + +Tests 1 failed (1) +Test Files 1 failed (1) +Duration " `; exports[`num_from_str.w 1`] = ` @@ -31,13 +28,10 @@ exports[`num_from_str.w 1`] = ` } - - - - -Tests 1 failed (1) -Duration -" + +Tests 1 failed (1) +Test Files 1 failed (1) +Duration " `; exports[`number_from_json.w 1`] = ` @@ -51,13 +45,10 @@ exports[`number_from_json.w 1`] = ` } - - - - -Tests 1 failed (1) -Duration -" + +Tests 1 failed (1) +Test Files 1 failed (1) +Duration " `; exports[`repeat_construct_id.w 1`] = ` @@ -77,13 +68,10 @@ For more information, see https://docs.winglang.io/concepts/resources } - - - - -Tests 1 failed (1) -Duration -" + +Tests 1 failed (1) +Test Files 1 failed (1) +Duration " `; exports[`repeat_construct_id2.w 1`] = ` @@ -97,19 +85,16 @@ For more information, see https://docs.winglang.io/concepts/resources ../../../examples/tests/error/target/test/repeat_construct_id2.wsim.[REDACTED].tmp/.wing/preflight.js:14 ; - const bucket1 = this.node.root.newAbstract(\\"@winglang/sdk.cloud.Bucket\\",this,\`\${(make_name())}\`); ->> const bucket2 = this.node.root.newAbstract(\\"@winglang/sdk.cloud.Bucket\\",this,\`\${(make_name())}\`); + const bucket1 = this.node.root.newAbstract(\\"@winglang/sdk.cloud.Bucket\\",this,String.raw({ raw: [\\"\\", \\"\\"] }, (make_name()))); +>> const bucket2 = this.node.root.newAbstract(\\"@winglang/sdk.cloud.Bucket\\",this,String.raw({ raw: [\\"\\", \\"\\"] }, (make_name()))); } } - - - - -Tests 1 failed (1) -Duration -" + +Tests 1 failed (1) +Test Files 1 failed (1) +Duration " `; exports[`string_from_json.w 1`] = ` @@ -123,31 +108,25 @@ exports[`string_from_json.w 1`] = ` } - - - - -Tests 1 failed (1) -Duration -" + +Tests 1 failed (1) +Test Files 1 failed (1) +Duration " `; exports[`utilities.w 1`] = ` -"ERROR: assertion failed: 'false' +"ERROR: assertion failed: false ../../../examples/tests/error/target/test/utilities.wsim.[REDACTED].tmp/.wing/preflight.js:8 constructor(scope, id) { super(scope, id); ->> {((cond) => {if (!cond) throw new Error(\`assertion failed: 'false'\`)})(false)}; +>> {((cond) => {if (!cond) throw new Error(\\"assertion failed: false\\")})(false)}; {console.log(\\"W\\")}; {((msg) => {throw new Error(msg)})(\\"me\\")}; - - - - -Tests 1 failed (1) -Duration -" + +Tests 1 failed (1) +Test Files 1 failed (1) +Duration " `; diff --git a/tools/hangar/__snapshots__/invalid.ts.snap b/tools/hangar/__snapshots__/invalid.ts.snap index 4a582b4ce49..4d2cec0b364 100644 --- a/tools/hangar/__snapshots__/invalid.ts.snap +++ b/tools/hangar/__snapshots__/invalid.ts.snap @@ -9,13 +9,10 @@ exports[`access_hidden_namespace.w 1`] = ` - - - - -Tests 1 failed (1) -Duration -" + +Tests 1 failed (1) +Test Files 1 failed (1) +Duration " `; exports[`access_static_from_instance.w 1`] = ` @@ -55,13 +52,10 @@ error: Unknown symbol \\"this\\" - - - - -Tests 1 failed (1) -Duration -" + +Tests 1 failed (1) +Test Files 1 failed (1) +Duration " `; exports[`bring.w 1`] = ` @@ -87,13 +81,10 @@ error: \\"fs\\" is not a built-in module - - - - -Tests 1 failed (1) -Duration -" + +Tests 1 failed (1) +Test Files 1 failed (1) +Duration " `; exports[`bring_jsii.w 1`] = ` @@ -112,70 +103,39 @@ error: Cannot find module \\"foobar\\" in source directory: Unable to load \\"fo - - - - -Tests 1 failed (1) -Duration -" + +Tests 1 failed (1) +Test Files 1 failed (1) +Duration " `; -exports[`capture_mutables.w 1`] = ` -"error: Cannot capture field 'a' with non-capturable type 'MutArray' - --> ../../../examples/tests/invalid/capture_mutables.w:8:10 +exports[`bring_non_std_construct.w 1`] = ` +"error: Expected 1 positional argument(s) but got 0 + --> ../../../examples/tests/invalid/bring_non_std_construct.w:8:1 | -8 | assert(a.length == 1); - | ^ Cannot capture field 'a' with non-capturable type 'MutArray' +8 | new cdktf.S3Backend(); + | ^^^^^^^^^^^^^^^^^^^^^ Expected 1 positional argument(s) but got 0 -error: Cannot capture field 's' with non-capturable type 'MutSet' - --> ../../../examples/tests/invalid/capture_mutables.w:10:10 +error: Cannot set id of non-standard preflight class \\"S3Backend\\" using \`as\` + --> ../../../examples/tests/invalid/bring_non_std_construct.w:13:85 | -10 | assert(s.size == 1); - | ^ Cannot capture field 's' with non-capturable type 'MutSet' +13 | new cdktf.S3Backend(this, cdktf.S3BackendConfig {bucket: \\"foo\\", key: \\"bar\\"}) as \\"s3_backend\\"; + | ^^^^^^^^^^^^ Cannot set id of non-standard preflight class \\"S3Backend\\" using \`as\` -error: Cannot capture field 'm' with non-capturable type 'MutMap' - --> ../../../examples/tests/invalid/capture_mutables.w:12:10 +error: Cannot set scope of non-standard preflight class \\"S3Backend\\" using \`in\` + --> ../../../examples/tests/invalid/bring_non_std_construct.w:15:85 | -12 | assert(m.size() == 1); - | ^ Cannot capture field 'm' with non-capturable type 'MutMap' - - -error: Cannot capture field 'aCloned' with non-capturable type 'MutArray' - --> ../../../examples/tests/invalid/capture_mutables.w:14:10 - | -14 | assert(aCloned.length == 1); - | ^^^^^^^ Cannot capture field 'aCloned' with non-capturable type 'MutArray' +15 | new cdktf.S3Backend(this, cdktf.S3BackendConfig {bucket: \\"foo\\", key: \\"bar\\"}) in this; + | ^^^^ Cannot set scope of non-standard preflight class \\"S3Backend\\" using \`in\` - - - - -Tests 1 failed (1) -Duration -" -`; - -exports[`capture_reassignable.w 1`] = ` -"error: Cannot capture reassignable field 'x' - --> ../../../examples/tests/invalid/capture_reassignable.w:6:15 - | -6 | log(\\"x: \${x}\\"); - | ^ Cannot capture reassignable field 'x' - - - - - - -Tests 1 failed (1) -Duration -" +Tests 1 failed (1) +Test Files 1 failed (1) +Duration " `; exports[`capture_redefinition.w 1`] = ` @@ -187,13 +147,10 @@ exports[`capture_redefinition.w 1`] = ` - - - - -Tests 1 failed (1) -Duration -" + +Tests 1 failed (1) +Test Files 1 failed (1) +Duration " `; exports[`class.w 1`] = ` @@ -380,13 +337,10 @@ error: Expected type to be \\"num\\", but got \\"str\\" instead - - - - -Tests 1 failed (1) -Duration -" + +Tests 1 failed (1) +Test Files 1 failed (1) +Duration " `; exports[`cloud_function_expects_inflight.w 1`] = ` @@ -404,13 +358,10 @@ error: Expected type to be \\"inflight (message: str): void\\", but got \\"$Clos - - - - -Tests 1 failed (1) -Duration -" + +Tests 1 failed (1) +Test Files 1 failed (1) +Duration " `; exports[`container_types.w 1`] = ` @@ -541,13 +492,10 @@ error: Expected type to be \\"Array\\", but got \\"MutArray\\" instead - - - - -Tests 1 failed (1) -Duration -" + +Tests 1 failed (1) +Test Files 1 failed (1) +Duration " `; exports[`diags_with_multibyte_chars.w 1`] = ` @@ -559,13 +507,10 @@ exports[`diags_with_multibyte_chars.w 1`] = ` - - - - -Tests 1 failed (1) -Duration -" + +Tests 1 failed (1) +Test Files 1 failed (1) +Duration " `; exports[`enums.w 1`] = ` @@ -584,13 +529,10 @@ error: Property access unsupported on type \\"SomeEnum\\" - - - - -Tests 1 failed (1) -Duration -" + +Tests 1 failed (1) +Test Files 1 failed (1) +Duration " `; exports[`extern.w 1`] = ` @@ -609,13 +551,10 @@ error: Failed to resolve extern \\"not-installed\\": Not Found - - - - -Tests 1 failed (1) -Duration -" + +Tests 1 failed (1) +Test Files 1 failed (1) +Duration " `; exports[`for_loop.w 1`] = ` @@ -627,13 +566,10 @@ exports[`for_loop.w 1`] = ` - - - - -Tests 1 failed (1) -Duration -" + +Tests 1 failed (1) +Test Files 1 failed (1) +Duration " `; exports[`function_type.w 1`] = ` @@ -652,13 +588,10 @@ error: Expected function return type - - - - -Tests 1 failed (1) -Duration -" + +Tests 1 failed (1) +Test Files 1 failed (1) +Duration " `; exports[`immutable_container_types.w 1`] = ` @@ -670,13 +603,10 @@ exports[`immutable_container_types.w 1`] = ` - - - - -Tests 1 failed (1) -Duration -" + +Tests 1 failed (1) +Test Files 1 failed (1) +Duration " `; exports[`impl_interface.w 1`] = ` @@ -723,38 +653,19 @@ error: Class \\"r\\" does not implement method \\"method3\\" of interface \\"I3\ - - - - -Tests 1 failed (1) -Duration -" + +Tests 1 failed (1) +Test Files 1 failed (1) +Duration " `; exports[`inflight_class_capture_mutable.w 1`] = ` -"error: Cannot capture field 'x' with non-capturable type 'MutArray' - --> ../../../examples/tests/invalid/inflight_class_capture_mutable.w:5:9 - | -5 | log(x.at(0)); - | ^ Cannot capture field 'x' with non-capturable type 'MutArray' - - -error: Cannot capture reassignable field 'foo' - --> ../../../examples/tests/invalid/inflight_class_capture_mutable.w:14:12 - | -14 | return foo; - | ^^^ Cannot capture reassignable field 'foo' - - +"pass โ”€ inflight_class_capture_mutable.wsim (no tests) - - - - -Tests 1 failed (1) -Duration -" + +Tests 1 passed (1) +Test Files 1 passed (1) +Duration " `; exports[`inflight_class_created_in_preflight.w 1`] = ` @@ -787,13 +698,10 @@ error: Cannot create preflight class \\"PreflightClass\\" in inflight phase - - - - -Tests 1 failed (1) -Duration -" + +Tests 1 failed (1) +Test Files 1 failed (1) +Duration " `; exports[`inflight_class_dup_init.w 1`] = ` @@ -807,13 +715,10 @@ exports[`inflight_class_dup_init.w 1`] = ` - - - - -Tests 1 failed (1) -Duration -" + +Tests 1 failed (1) +Test Files 1 failed (1) +Duration " `; exports[`inflight_class_in_preflight.w 1`] = ` @@ -825,13 +730,10 @@ exports[`inflight_class_in_preflight.w 1`] = ` - - - - -Tests 1 failed (1) -Duration -" + +Tests 1 failed (1) +Test Files 1 failed (1) +Duration " `; exports[`inflight_class_interface_structural_typing.w 1`] = ` @@ -843,13 +745,10 @@ exports[`inflight_class_interface_structural_typing.w 1`] = ` - - - - -Tests 1 failed (1) -Duration -" + +Tests 1 failed (1) +Test Files 1 failed (1) +Duration " `; exports[`inflight_ref_explicit_ops.w 1`] = ` @@ -875,13 +774,10 @@ error: Capturing collection of preflight classes is not supported yet (type is ' - - - - -Tests 1 failed (1) -Duration -" + +Tests 1 failed (1) +Test Files 1 failed (1) +Duration " `; exports[`inflight_ref_resource_sub_method.w 1`] = ` @@ -900,13 +796,10 @@ error: Unable to qualify which operations are performed on 'globalQueue' of type - - - - -Tests 1 failed (1) -Duration -" + +Tests 1 failed (1) +Test Files 1 failed (1) +Duration " `; exports[`inflight_ref_unknown_op.w 1`] = ` @@ -925,13 +818,10 @@ error: Unable to qualify which operations are performed on 'globalB' of type 'Bu - - - - -Tests 1 failed (1) -Duration -" + +Tests 1 failed (1) +Test Files 1 failed (1) +Duration " `; exports[`interface.w 1`] = ` @@ -978,13 +868,10 @@ error: Symbol \\"foo\\" already defined in this scope - - - - -Tests 1 failed (1) -Duration -" + +Tests 1 failed (1) +Test Files 1 failed (1) +Duration " `; exports[`json.w 1`] = ` @@ -1058,14 +945,32 @@ error: Expected \\"Json\\" elements to be Json values (https://www.json.org/json | ^^^ Expected \\"Json\\" elements to be Json values (https://www.json.org/json-en.html), but got \\"Bucket\\" which is not a Json value - +error: Expected type to be \\"num?\\", but got \\"str?\\" instead + --> ../../../examples/tests/invalid/json.w:33:20 + | +33 | let tryNum: num? = j.tryAsStr(); + | ^^^^^^^^^^^^ Expected type to be \\"num?\\", but got \\"str?\\" instead +error: Expected type to be \\"str?\\", but got \\"bool?\\" instead + --> ../../../examples/tests/invalid/json.w:36:20 + | +36 | let tryStr: str? = j.tryAsBool(); + | ^^^^^^^^^^^^^ Expected type to be \\"str?\\", but got \\"bool?\\" instead -Tests 1 failed (1) -Duration -" +error: Expected type to be \\"bool?\\", but got \\"num?\\" instead + --> ../../../examples/tests/invalid/json.w:39:22 + | +39 | let tryBool: bool? = j.tryAsNum(); + | ^^^^^^^^^^^^ Expected type to be \\"bool?\\", but got \\"num?\\" instead + + + + +Tests 1 failed (1) +Test Files 1 failed (1) +Duration " `; exports[`json_static.w 1`] = ` @@ -1077,13 +982,10 @@ exports[`json_static.w 1`] = ` - - - - -Tests 1 failed (1) -Duration -" + +Tests 1 failed (1) +Test Files 1 failed (1) +Duration " `; exports[`missing_semicolon.w 1`] = ` @@ -1109,13 +1011,10 @@ error: Expected '}' - - - - -Tests 1 failed (1) -Duration -" + +Tests 1 failed (1) +Test Files 1 failed (1) +Duration " `; exports[`mut_container_types.w 1`] = ` @@ -1218,13 +1117,10 @@ error: Expected type to be \\"MutMap\\", but got \\"MutMap\\" instead - - - - -Tests 1 failed (1) -Duration -" + +Tests 1 failed (1) +Test Files 1 failed (1) +Duration " `; exports[`nil.w 1`] = ` @@ -1264,13 +1160,10 @@ error: Expected type to be \\"num\\", but got \\"nil\\" instead (hint: to allow - - - - -Tests 1 failed (1) -Duration -" + +Tests 1 failed (1) +Test Files 1 failed (1) +Duration " `; exports[`optionals.w 1`] = ` @@ -1352,31 +1245,25 @@ error: Variable hi is not reassignable - - - - -Tests 1 failed (1) -Duration -" + +Tests 1 failed (1) +Test Files 1 failed (1) +Duration " `; exports[`panic.w 1`] = ` -"error: Compiler bug (panicked at 'User invoked panic', libs/wingc/src/type_check.rs:LINE:COL) during type-checking, please report at https://docs.winglang.io/contributors/bugs +"error: Compiler bug (panicked at 'User invoked panic', libs/wingc/src/type_check.rs:LINE:COL) during type-checking, please report at https://docs.winglang.io/contributing/bugs --> ../../../examples/tests/invalid/panic.w:6:1 | 6 | ๐Ÿ˜ฑ; - | ^^ Compiler bug (panicked at 'User invoked panic', libs/wingc/src/type_check.rs:LINE:COL) during type-checking, please report at https://docs.winglang.io/contributors/bugs + | ^^ Compiler bug (panicked at 'User invoked panic', libs/wingc/src/type_check.rs:LINE:COL) during type-checking, please report at https://docs.winglang.io/contributing/bugs - - - - -Tests 1 failed (1) -Duration -" + +Tests 1 failed (1) +Test Files 1 failed (1) +Duration " `; exports[`panic.w 2`] = `"Panicked, backtrace not captured: Unsupported"`; @@ -1390,13 +1277,10 @@ exports[`preflight_from_inflight.w 1`] = ` - - - - -Tests 1 failed (1) -Duration -" + +Tests 1 failed (1) +Test Files 1 failed (1) +Duration " `; exports[`primitives.w 1`] = ` @@ -1429,13 +1313,10 @@ error: Expected type to be \\"str\\", but got \\"num\\" instead - - - - -Tests 1 failed (1) -Duration -" + +Tests 1 failed (1) +Test Files 1 failed (1) +Duration " `; exports[`reassign_to_nonreassignable.w 1`] = ` @@ -1475,13 +1356,10 @@ error: Variable arg is not reassignable - - - - -Tests 1 failed (1) -Duration -" + +Tests 1 failed (1) +Test Files 1 failed (1) +Duration " `; exports[`resource_access_field_as_method.w 1`] = ` @@ -1493,31 +1371,14 @@ exports[`resource_access_field_as_method.w 1`] = ` - - - - -Tests 1 failed (1) -Duration -" + +Tests 1 failed (1) +Test Files 1 failed (1) +Duration " `; exports[`resource_captures.w 1`] = ` -"error: Cannot capture reassignable field 'reassignable' - --> ../../../examples/tests/invalid/resource_captures.w:18:17 - | -18 | log(\\"\${this.reassignable}\\"); - | ^^^^^^^^^^^^ Cannot capture reassignable field 'reassignable' - - -error: Cannot capture field 'mutArray' with non-capturable type 'MutArray' - --> ../../../examples/tests/invalid/resource_captures.w:20:14 - | -20 | log(this.mutArray.at(0)); - | ^^^^^^^^ Cannot capture field 'mutArray' with non-capturable type 'MutArray' - - -error: Unable to qualify which operations are performed on 'this.bucket' of type 'Bucket'. This is not supported yet. +"error: Unable to qualify which operations are performed on 'this.bucket' of type 'Bucket'. This is not supported yet. --> ../../../examples/tests/invalid/resource_captures.w:23:13 | 23 | let b = this.bucket; @@ -1532,13 +1393,10 @@ error: Capturing collection of preflight classes is not supported yet (type is ' - - - - -Tests 1 failed (1) -Duration -" + +Tests 1 failed (1) +Test Files 1 failed (1) +Duration " `; exports[`resource_inflight.w 1`] = ` @@ -1550,13 +1408,10 @@ exports[`resource_inflight.w 1`] = ` - - - - -Tests 1 failed (1) -Duration -" + +Tests 1 failed (1) +Test Files 1 failed (1) +Duration " `; exports[`resource_init.w 1`] = ` @@ -1589,13 +1444,53 @@ error: Inflight initializers cannot have parameters + +Tests 1 failed (1) +Test Files 1 failed (1) +Duration " +`; + +exports[`return_types.w 1`] = ` +"error: Return statement outside of function cannot return a value + --> ../../../examples/tests/invalid/return_types.w:1:5 + | +1 | return 9; + | ^^^^^^^^^ Return statement outside of function cannot return a value +error: Return statement outside of function cannot return a value + --> ../../../examples/tests/invalid/return_types.w:4:5 + | +4 | return 9; + | ^^^^^^^^^ Return statement outside of function cannot return a value + +error: Unexpected return value from void function + --> ../../../examples/tests/invalid/return_types.w:9:3 + | +9 | return 9; + | ^^^^^^^^^ Unexpected return value from void function -Tests 1 failed (1) -Duration -" + +error: Unexpected return value from void function + --> ../../../examples/tests/invalid/return_types.w:12:5 + | +12 | return 9; + | ^^^^^^^^^ Unexpected return value from void function + + +error: Unexpected return value from void function + --> ../../../examples/tests/invalid/return_types.w:19:5 + | +19 | return 9; + | ^^^^^^^^^ Unexpected return value from void function + + + + +Tests 1 failed (1) +Test Files 1 failed (1) +Duration " `; exports[`scope_and_id.w 1`] = ` @@ -1628,13 +1523,10 @@ error: Inflight classes cannot have a scope - - - - -Tests 1 failed (1) -Duration -" + +Tests 1 failed (1) +Test Files 1 failed (1) +Duration " `; exports[`sorted_errors_no_span.w 1`] = ` @@ -1667,13 +1559,10 @@ error: Expected \\"b\\" to be a type but it's a variable - - - - -Tests 1 failed (1) -Duration -" + +Tests 1 failed (1) +Test Files 1 failed (1) +Duration " `; exports[`statement_invalid_scope.w 1`] = ` @@ -1706,13 +1595,10 @@ error: Expected continue statement to be inside of a loop (while/for) - - - - -Tests 1 failed (1) -Duration -" + +Tests 1 failed (1) +Test Files 1 failed (1) +Duration " `; exports[`statements_if.w 1`] = ` @@ -1738,13 +1624,10 @@ error: Expected type to be \\"bool\\", but got \\"num\\" instead - - - - -Tests 1 failed (1) -Duration -" + +Tests 1 failed (1) +Test Files 1 failed (1) +Duration " `; exports[`std_containers.w 1`] = ` @@ -1756,13 +1639,10 @@ exports[`std_containers.w 1`] = ` - - - - -Tests 1 failed (1) -Duration -" + +Tests 1 failed (1) +Test Files 1 failed (1) +Duration " `; exports[`struct_expansion.w 1`] = ` @@ -1817,13 +1697,10 @@ error: Expected 2 positional argument(s) but got 1 - - - - -Tests 1 failed (1) -Duration -" + +Tests 1 failed (1) +Test Files 1 failed (1) +Duration " `; exports[`structs.w 1`] = ` @@ -1877,13 +1754,10 @@ error: Cannot instantiate type \\"BucketProps\\" because it is a struct and not - - - - -Tests 1 failed (1) -Duration -" + +Tests 1 failed (1) +Test Files 1 failed (1) +Duration " `; exports[`try_no_catch_or_finally.w 1`] = ` @@ -1897,13 +1771,10 @@ exports[`try_no_catch_or_finally.w 1`] = ` - - - - -Tests 1 failed (1) -Duration -" + +Tests 1 failed (1) +Test Files 1 failed (1) +Duration " `; exports[`types_strings_arithmetic.w 1`] = ` @@ -1929,13 +1800,10 @@ error: Expected type to be \\"num\\", but got \\"str\\" instead - - - - -Tests 1 failed (1) -Duration -" + +Tests 1 failed (1) +Test Files 1 failed (1) +Duration " `; exports[`unimplemented_grammar.w 1`] = ` @@ -1968,13 +1836,10 @@ error: expression \\"await_expression\\" is not supported yet see https://github - - - - -Tests 1 failed (1) -Duration -" + +Tests 1 failed (1) +Test Files 1 failed (1) +Duration " `; exports[`unknown_field.w 1`] = ` @@ -1986,13 +1851,10 @@ exports[`unknown_field.w 1`] = ` - - - - -Tests 1 failed (1) -Duration -" + +Tests 1 failed (1) +Test Files 1 failed (1) +Duration " `; exports[`unknown_submodule.w 1`] = ` @@ -2004,13 +1866,10 @@ exports[`unknown_submodule.w 1`] = ` - - - - -Tests 1 failed (1) -Duration -" + +Tests 1 failed (1) +Test Files 1 failed (1) +Duration " `; exports[`unknown_symbol.w 1`] = ` @@ -2071,13 +1930,10 @@ error: Unknown symbol \\"methodWhichIsNotPartOfBucketApi\\" - - - - -Tests 1 failed (1) -Duration -" + +Tests 1 failed (1) +Test Files 1 failed (1) +Duration " `; exports[`use_before_defined.w 1`] = ` @@ -2096,13 +1952,10 @@ error: Symbol \\"x\\" used before being defined - - - - -Tests 1 failed (1) -Duration -" + +Tests 1 failed (1) +Test Files 1 failed (1) +Duration " `; exports[`variable_scoping.w 1`] = ` @@ -2114,13 +1967,10 @@ exports[`variable_scoping.w 1`] = ` - - - - -Tests 1 failed (1) -Duration -" + +Tests 1 failed (1) +Test Files 1 failed (1) +Duration " `; exports[`void_in_expression_position.w 1`] = ` @@ -2146,11 +1996,8 @@ error: Cannot assign expression of type \\"void\\" to a variable - - - - -Tests 1 failed (1) -Duration -" + +Tests 1 failed (1) +Test Files 1 failed (1) +Duration " `; diff --git a/tools/hangar/__snapshots__/test_corpus/sdk_tests/api/delete.w_compile_tf-aws.md b/tools/hangar/__snapshots__/test_corpus/sdk_tests/api/delete.w_compile_tf-aws.md new file mode 100644 index 00000000000..e0e0b90647b --- /dev/null +++ b/tools/hangar/__snapshots__/test_corpus/sdk_tests/api/delete.w_compile_tf-aws.md @@ -0,0 +1,431 @@ +# [delete.w](../../../../../../examples/tests/sdk_tests/api/delete.w) | compile | tf-aws + +## inflight.$Closure1.js +```js +module.exports = function({ api_DELETE }) { + class $Closure1 { + constructor({ }) { + const $obj = (...args) => this.handle(...args); + Object.setPrototypeOf($obj, this); + return $obj; + } + async $inflight_init() { + } + async handle(req) { + {((cond) => {if (!cond) throw new Error("assertion failed: req.method == api_DELETE")})((req.method === api_DELETE))}; + {((cond) => {if (!cond) throw new Error("assertion failed: req.query?.get(\"all\") == \"true\"")})(((req.query)["all"] === "true"))}; + {((cond) => {if (!cond) throw new Error("assertion failed: req.query?.get(\"page\") == \"6\"")})(((req.query)["page"] === "6"))}; + {((cond) => {if (!cond) throw new Error("assertion failed: req.path == \"/path\"")})((req.path === "/path"))}; + return { + "status": 200, + "body": (req.query)["page"],} + ; + } + } + return $Closure1; +} + +``` + +## inflight.$Closure2.js +```js +module.exports = function({ api, http_DELETE, http_Util }) { + class $Closure2 { + constructor({ }) { + const $obj = (...args) => this.handle(...args); + Object.setPrototypeOf($obj, this); + return $obj; + } + async $inflight_init() { + } + async handle() { + const url = String.raw({ raw: ["", "/path?all=true&page=6"] }, api.url); + const response = (await http_Util.delete(url)); + const fetchResponse = (await http_Util.fetch(url,Object.freeze({"method":http_DELETE}))); + {((cond) => {if (!cond) throw new Error("assertion failed: response.body == \"6\"")})((response.body === "6"))}; + {((cond) => {if (!cond) throw new Error("assertion failed: response.status == 200")})((response.status === 200))}; + {((cond) => {if (!cond) throw new Error("assertion failed: response.url == url")})((response.url === url))}; + {((cond) => {if (!cond) throw new Error("assertion failed: fetchResponse.body == \"6\"")})((fetchResponse.body === "6"))}; + {((cond) => {if (!cond) throw new Error("assertion failed: fetchResponse.status == 200")})((fetchResponse.status === 200))}; + {((cond) => {if (!cond) throw new Error("assertion failed: fetchResponse.url == url")})((fetchResponse.url === url))}; + } + } + return $Closure2; +} + +``` + +## main.tf.json +```json +{ + "//": { + "metadata": { + "backend": "local", + "stackName": "root", + "version": "0.15.2" + }, + "outputs": { + "root": { + "Default": { + "cloud.TestRunner": { + "TestFunctionArns": "WING_TEST_RUNNER_FUNCTION_ARNS" + } + } + } + } + }, + "data": { + "aws_region": { + "root_Region_A2D17352": { + "//": { + "metadata": { + "path": "root/Default/Region", + "uniqueId": "root_Region_A2D17352" + } + } + } + } + }, + "output": { + "WING_TEST_RUNNER_FUNCTION_ARNS": { + "value": "[[\"root/Default/Default/test:http.delete and http.fetch can preform a call to an api\",\"${aws_lambda_function.root_testhttpdeleteandhttpfetchcanpreformacalltoanapi_Handler_0C9771D7.arn}\"]]" + } + }, + "provider": { + "aws": [ + {} + ] + }, + "resource": { + "aws_api_gateway_deployment": { + "root_cloudApi_api_deployment_E29F699A": { + "//": { + "metadata": { + "path": "root/Default/Default/cloud.Api/api/deployment", + "uniqueId": "root_cloudApi_api_deployment_E29F699A" + } + }, + "lifecycle": { + "create_before_destroy": true + }, + "rest_api_id": "${aws_api_gateway_rest_api.root_cloudApi_api_8C9FE51E.id}", + "triggers": { + "redeployment": "841e88388b5ba75d968430f607ebeffd3f39668c" + } + } + }, + "aws_api_gateway_rest_api": { + "root_cloudApi_api_8C9FE51E": { + "//": { + "metadata": { + "path": "root/Default/Default/cloud.Api/api/api", + "uniqueId": "root_cloudApi_api_8C9FE51E" + } + }, + "body": "{\"openapi\":\"3.0.3\",\"paths\":{\"/path\":{\"delete\":{\"operationId\":\"delete-path\",\"responses\":{\"200\":{\"description\":\"200 response\",\"content\":{}}},\"parameters\":[],\"x-amazon-apigateway-integration\":{\"uri\":\"arn:aws:apigateway:${data.aws_region.root_Region_A2D17352.name}:lambda:path/2015-03-31/functions/${aws_lambda_function.root_cloudApi_cloudApiOnRequestcdafee6e_582EA655.arn}/invocations\",\"type\":\"aws_proxy\",\"httpMethod\":\"POST\",\"responses\":{\"default\":{\"statusCode\":\"200\"}},\"passthroughBehavior\":\"when_no_match\",\"contentHandling\":\"CONVERT_TO_TEXT\"}}}}}", + "name": "api-c895068c" + } + }, + "aws_api_gateway_stage": { + "root_cloudApi_api_stage_57D6284A": { + "//": { + "metadata": { + "path": "root/Default/Default/cloud.Api/api/stage", + "uniqueId": "root_cloudApi_api_stage_57D6284A" + } + }, + "deployment_id": "${aws_api_gateway_deployment.root_cloudApi_api_deployment_E29F699A.id}", + "rest_api_id": "${aws_api_gateway_rest_api.root_cloudApi_api_8C9FE51E.id}", + "stage_name": "prod" + } + }, + "aws_iam_role": { + "root_cloudApi_cloudApiOnRequestcdafee6e_IamRole_2B8A04C3": { + "//": { + "metadata": { + "path": "root/Default/Default/cloud.Api/cloud.Api-OnRequest-cdafee6e/IamRole", + "uniqueId": "root_cloudApi_cloudApiOnRequestcdafee6e_IamRole_2B8A04C3" + } + }, + "assume_role_policy": "{\"Version\":\"2012-10-17\",\"Statement\":[{\"Action\":\"sts:AssumeRole\",\"Principal\":{\"Service\":\"lambda.amazonaws.com\"},\"Effect\":\"Allow\"}]}" + }, + "root_testhttpdeleteandhttpfetchcanpreformacalltoanapi_Handler_IamRole_CABDAAA1": { + "//": { + "metadata": { + "path": "root/Default/Default/test:http.delete and http.fetch can preform a call to an api/Handler/IamRole", + "uniqueId": "root_testhttpdeleteandhttpfetchcanpreformacalltoanapi_Handler_IamRole_CABDAAA1" + } + }, + "assume_role_policy": "{\"Version\":\"2012-10-17\",\"Statement\":[{\"Action\":\"sts:AssumeRole\",\"Principal\":{\"Service\":\"lambda.amazonaws.com\"},\"Effect\":\"Allow\"}]}" + } + }, + "aws_iam_role_policy": { + "root_cloudApi_cloudApiOnRequestcdafee6e_IamRolePolicy_E6B9BE66": { + "//": { + "metadata": { + "path": "root/Default/Default/cloud.Api/cloud.Api-OnRequest-cdafee6e/IamRolePolicy", + "uniqueId": "root_cloudApi_cloudApiOnRequestcdafee6e_IamRolePolicy_E6B9BE66" + } + }, + "policy": "{\"Version\":\"2012-10-17\",\"Statement\":[{\"Effect\":\"Allow\",\"Action\":\"none:null\",\"Resource\":\"*\"}]}", + "role": "${aws_iam_role.root_cloudApi_cloudApiOnRequestcdafee6e_IamRole_2B8A04C3.name}" + }, + "root_testhttpdeleteandhttpfetchcanpreformacalltoanapi_Handler_IamRolePolicy_A4D5F194": { + "//": { + "metadata": { + "path": "root/Default/Default/test:http.delete and http.fetch can preform a call to an api/Handler/IamRolePolicy", + "uniqueId": "root_testhttpdeleteandhttpfetchcanpreformacalltoanapi_Handler_IamRolePolicy_A4D5F194" + } + }, + "policy": "{\"Version\":\"2012-10-17\",\"Statement\":[{\"Effect\":\"Allow\",\"Action\":\"none:null\",\"Resource\":\"*\"}]}", + "role": "${aws_iam_role.root_testhttpdeleteandhttpfetchcanpreformacalltoanapi_Handler_IamRole_CABDAAA1.name}" + } + }, + "aws_iam_role_policy_attachment": { + "root_cloudApi_cloudApiOnRequestcdafee6e_IamRolePolicyAttachment_4A873879": { + "//": { + "metadata": { + "path": "root/Default/Default/cloud.Api/cloud.Api-OnRequest-cdafee6e/IamRolePolicyAttachment", + "uniqueId": "root_cloudApi_cloudApiOnRequestcdafee6e_IamRolePolicyAttachment_4A873879" + } + }, + "policy_arn": "arn:aws:iam::aws:policy/service-role/AWSLambdaBasicExecutionRole", + "role": "${aws_iam_role.root_cloudApi_cloudApiOnRequestcdafee6e_IamRole_2B8A04C3.name}" + }, + "root_testhttpdeleteandhttpfetchcanpreformacalltoanapi_Handler_IamRolePolicyAttachment_FED05D78": { + "//": { + "metadata": { + "path": "root/Default/Default/test:http.delete and http.fetch can preform a call to an api/Handler/IamRolePolicyAttachment", + "uniqueId": "root_testhttpdeleteandhttpfetchcanpreformacalltoanapi_Handler_IamRolePolicyAttachment_FED05D78" + } + }, + "policy_arn": "arn:aws:iam::aws:policy/service-role/AWSLambdaBasicExecutionRole", + "role": "${aws_iam_role.root_testhttpdeleteandhttpfetchcanpreformacalltoanapi_Handler_IamRole_CABDAAA1.name}" + } + }, + "aws_lambda_function": { + "root_cloudApi_cloudApiOnRequestcdafee6e_582EA655": { + "//": { + "metadata": { + "path": "root/Default/Default/cloud.Api/cloud.Api-OnRequest-cdafee6e/Default", + "uniqueId": "root_cloudApi_cloudApiOnRequestcdafee6e_582EA655" + } + }, + "environment": { + "variables": { + "WING_FUNCTION_NAME": "cloud-Api-OnRequest-cdafee6e-c8147384", + "WING_TARGET": "tf-aws" + } + }, + "function_name": "cloud-Api-OnRequest-cdafee6e-c8147384", + "handler": "index.handler", + "publish": true, + "role": "${aws_iam_role.root_cloudApi_cloudApiOnRequestcdafee6e_IamRole_2B8A04C3.arn}", + "runtime": "nodejs18.x", + "s3_bucket": "${aws_s3_bucket.root_Code_02F3C603.bucket}", + "s3_key": "${aws_s3_object.root_cloudApi_cloudApiOnRequestcdafee6e_S3Object_AA762041.key}", + "timeout": 30, + "vpc_config": { + "security_group_ids": [], + "subnet_ids": [] + } + }, + "root_testhttpdeleteandhttpfetchcanpreformacalltoanapi_Handler_0C9771D7": { + "//": { + "metadata": { + "path": "root/Default/Default/test:http.delete and http.fetch can preform a call to an api/Handler/Default", + "uniqueId": "root_testhttpdeleteandhttpfetchcanpreformacalltoanapi_Handler_0C9771D7" + } + }, + "environment": { + "variables": { + "CLOUD_API_C82DF3A5": "${aws_api_gateway_stage.root_cloudApi_api_stage_57D6284A.invoke_url}", + "WING_FUNCTION_NAME": "Handler-c897cd38", + "WING_TARGET": "tf-aws", + "WING_TOKEN_TFTOKEN_TOKEN_21": "${jsonencode(aws_api_gateway_stage.root_cloudApi_api_stage_57D6284A.invoke_url)}" + } + }, + "function_name": "Handler-c897cd38", + "handler": "index.handler", + "publish": true, + "role": "${aws_iam_role.root_testhttpdeleteandhttpfetchcanpreformacalltoanapi_Handler_IamRole_CABDAAA1.arn}", + "runtime": "nodejs18.x", + "s3_bucket": "${aws_s3_bucket.root_Code_02F3C603.bucket}", + "s3_key": "${aws_s3_object.root_testhttpdeleteandhttpfetchcanpreformacalltoanapi_Handler_S3Object_C56C2F7B.key}", + "timeout": 30, + "vpc_config": { + "security_group_ids": [], + "subnet_ids": [] + } + } + }, + "aws_lambda_permission": { + "root_cloudApi_api_permissionDELETEe2131352_670E7A12": { + "//": { + "metadata": { + "path": "root/Default/Default/cloud.Api/api/permission-DELETE-e2131352", + "uniqueId": "root_cloudApi_api_permissionDELETEe2131352_670E7A12" + } + }, + "action": "lambda:InvokeFunction", + "function_name": "${aws_lambda_function.root_cloudApi_cloudApiOnRequestcdafee6e_582EA655.function_name}", + "principal": "apigateway.amazonaws.com", + "source_arn": "${aws_api_gateway_rest_api.root_cloudApi_api_8C9FE51E.execution_arn}/*/DELETE/path", + "statement_id": "AllowExecutionFromAPIGateway-DELETE-e2131352" + } + }, + "aws_s3_bucket": { + "root_Code_02F3C603": { + "//": { + "metadata": { + "path": "root/Default/Code", + "uniqueId": "root_Code_02F3C603" + } + }, + "bucket_prefix": "code-c84a50b1-" + } + }, + "aws_s3_object": { + "root_cloudApi_cloudApiOnRequestcdafee6e_S3Object_AA762041": { + "//": { + "metadata": { + "path": "root/Default/Default/cloud.Api/cloud.Api-OnRequest-cdafee6e/S3Object", + "uniqueId": "root_cloudApi_cloudApiOnRequestcdafee6e_S3Object_AA762041" + } + }, + "bucket": "${aws_s3_bucket.root_Code_02F3C603.bucket}", + "key": "", + "source": "" + }, + "root_testhttpdeleteandhttpfetchcanpreformacalltoanapi_Handler_S3Object_C56C2F7B": { + "//": { + "metadata": { + "path": "root/Default/Default/test:http.delete and http.fetch can preform a call to an api/Handler/S3Object", + "uniqueId": "root_testhttpdeleteandhttpfetchcanpreformacalltoanapi_Handler_S3Object_C56C2F7B" + } + }, + "bucket": "${aws_s3_bucket.root_Code_02F3C603.bucket}", + "key": "", + "source": "" + } + } + } +} +``` + +## preflight.js +```js +const $stdlib = require('@winglang/sdk'); +const $outdir = process.env.WING_SYNTH_DIR ?? "."; +const std = $stdlib.std; +const $wing_is_test = process.env.WING_IS_TEST === "true"; +const $AppBase = $stdlib.core.App.for(process.env.WING_TARGET); +const cloud = require('@winglang/sdk').cloud; +const http = require('@winglang/sdk').http; +class $Root extends $stdlib.std.Resource { + constructor(scope, id) { + super(scope, id); + class $Closure1 extends $stdlib.std.Resource { + constructor(scope, id, ) { + super(scope, id); + this._addInflightOps("handle"); + this.display.hidden = true; + } + static _toInflightType(context) { + const self_client_path = "././inflight.$Closure1.js"; + const api_DELETE_client = context._lift(api_DELETE); + return $stdlib.core.NodeJsCode.fromInline(` + require("${self_client_path}")({ + api_DELETE: ${api_DELETE_client}, + }) + `); + } + _toInflight() { + return $stdlib.core.NodeJsCode.fromInline(` + (await (async () => { + const $Closure1Client = ${$Closure1._toInflightType(this).text}; + const client = new $Closure1Client({ + }); + if (client.$inflight_init) { await client.$inflight_init(); } + return client; + })()) + `); + } + _registerBind(host, ops) { + if (ops.includes("$inflight_init")) { + $Closure1._registerBindObject(api_DELETE, host, []); + } + if (ops.includes("handle")) { + $Closure1._registerBindObject(api_DELETE, host, []); + } + super._registerBind(host, ops); + } + } + class $Closure2 extends $stdlib.std.Resource { + constructor(scope, id, ) { + super(scope, id); + this._addInflightOps("handle"); + this.display.hidden = true; + } + static _toInflightType(context) { + const self_client_path = "././inflight.$Closure2.js"; + const api_client = context._lift(api); + const http_DELETE_client = context._lift(http_DELETE); + const http_UtilClient = http.Util._toInflightType(context); + return $stdlib.core.NodeJsCode.fromInline(` + require("${self_client_path}")({ + api: ${api_client}, + http_DELETE: ${http_DELETE_client}, + http_Util: ${http_UtilClient.text}, + }) + `); + } + _toInflight() { + return $stdlib.core.NodeJsCode.fromInline(` + (await (async () => { + const $Closure2Client = ${$Closure2._toInflightType(this).text}; + const client = new $Closure2Client({ + }); + if (client.$inflight_init) { await client.$inflight_init(); } + return client; + })()) + `); + } + _registerBind(host, ops) { + if (ops.includes("$inflight_init")) { + $Closure2._registerBindObject(api, host, []); + $Closure2._registerBindObject(http_DELETE, host, []); + } + if (ops.includes("handle")) { + $Closure2._registerBindObject(api.url, host, []); + $Closure2._registerBindObject(http_DELETE, host, []); + } + super._registerBind(host, ops); + } + } + const http_DELETE = http.HttpMethod.DELETE; + const api_DELETE = cloud.HttpMethod.DELETE; + const api = this.node.root.newAbstract("@winglang/sdk.cloud.Api",this,"cloud.Api"); + (api.delete("/path",new $Closure1(this,"$Closure1"))); + this.node.root.new("@winglang/sdk.std.Test",std.Test,this,"test:http.delete and http.fetch can preform a call to an api",new $Closure2(this,"$Closure2")); + } +} +class $App extends $AppBase { + constructor() { + super({ outdir: $outdir, name: "delete", plugins: $plugins, isTestEnvironment: $wing_is_test }); + if ($wing_is_test) { + new $Root(this, "env0"); + const $test_runner = this.testRunner; + const $tests = $test_runner.findTests(); + for (let $i = 1; $i < $tests.length; $i++) { + new $Root(this, "env" + $i); + } + } else { + new $Root(this, "Default"); + } + } +} +new $App().synth(); + +``` + diff --git a/tools/hangar/__snapshots__/test_corpus/sdk_tests/api/delete.w_test_sim.md b/tools/hangar/__snapshots__/test_corpus/sdk_tests/api/delete.w_test_sim.md new file mode 100644 index 00000000000..d2335cfddab --- /dev/null +++ b/tools/hangar/__snapshots__/test_corpus/sdk_tests/api/delete.w_test_sim.md @@ -0,0 +1,12 @@ +# [delete.w](../../../../../../examples/tests/sdk_tests/api/delete.w) | test | sim + +## stdout.log +```log +pass โ”€ delete.wsim ยป root/env0/test:http.delete and http.fetch can preform a call to an api + + +Tests 1 passed (1) +Test Files 1 passed (1) +Duration +``` + diff --git a/tools/hangar/__snapshots__/test_corpus/sdk_tests/api/get.w_compile_tf-aws.md b/tools/hangar/__snapshots__/test_corpus/sdk_tests/api/get.w_compile_tf-aws.md new file mode 100644 index 00000000000..604e14bce63 --- /dev/null +++ b/tools/hangar/__snapshots__/test_corpus/sdk_tests/api/get.w_compile_tf-aws.md @@ -0,0 +1,448 @@ +# [get.w](../../../../../../examples/tests/sdk_tests/api/get.w) | compile | tf-aws + +## inflight.$Closure1.js +```js +module.exports = function({ api_GET, body }) { + class $Closure1 { + constructor({ }) { + const $obj = (...args) => this.handle(...args); + Object.setPrototypeOf($obj, this); + return $obj; + } + async $inflight_init() { + } + async handle(req) { + {((cond) => {if (!cond) throw new Error("assertion failed: req.method == api_GET")})((req.method === api_GET))}; + {((cond) => {if (!cond) throw new Error("assertion failed: req.path == \"/path\"")})((req.path === "/path"))}; + {((cond) => {if (!cond) throw new Error("assertion failed: req.headers?.get(\"content-type\") == \"application/json\"")})(((req.headers)["content-type"] === "application/json"))}; + return { + "status": 200, + "body": body,} + ; + } + } + return $Closure1; +} + +``` + +## inflight.$Closure2.js +```js +module.exports = function({ api, http_GET, body, http_Util }) { + class $Closure2 { + constructor({ }) { + const $obj = (...args) => this.handle(...args); + Object.setPrototypeOf($obj, this); + return $obj; + } + async $inflight_init() { + } + async handle() { + const url = (api.url + "/path"); + const getResponse = (await http_Util.get(url,Object.freeze({"headers":Object.freeze({"content-type":"application/json"})}))); + const fetchResponse = (await http_Util.fetch(url,{ + "method": http_GET, + "headers": Object.freeze({"content-type":"application/json"}),} + )); + const fetchResponseNoMethod = (await http_Util.fetch(url,{ + "headers": Object.freeze({"content-type":"application/json"}),} + )); + {((cond) => {if (!cond) throw new Error("assertion failed: getResponse.body == body")})((getResponse.body === body))}; + {((cond) => {if (!cond) throw new Error("assertion failed: getResponse.status == 200")})((getResponse.status === 200))}; + {((cond) => {if (!cond) throw new Error("assertion failed: getResponse.url == url")})((getResponse.url === url))}; + {((cond) => {if (!cond) throw new Error("assertion failed: fetchResponse.body == body")})((fetchResponse.body === body))}; + {((cond) => {if (!cond) throw new Error("assertion failed: fetchResponse.status == 200")})((fetchResponse.status === 200))}; + {((cond) => {if (!cond) throw new Error("assertion failed: fetchResponse.url == url")})((fetchResponse.url === url))}; + {((cond) => {if (!cond) throw new Error("assertion failed: fetchResponseNoMethod.body == body")})((fetchResponseNoMethod.body === body))}; + {((cond) => {if (!cond) throw new Error("assertion failed: fetchResponseNoMethod.status == 200")})((fetchResponseNoMethod.status === 200))}; + {((cond) => {if (!cond) throw new Error("assertion failed: fetchResponseNoMethod.url == url")})((fetchResponseNoMethod.url === url))}; + } + } + return $Closure2; +} + +``` + +## main.tf.json +```json +{ + "//": { + "metadata": { + "backend": "local", + "stackName": "root", + "version": "0.15.2" + }, + "outputs": { + "root": { + "Default": { + "cloud.TestRunner": { + "TestFunctionArns": "WING_TEST_RUNNER_FUNCTION_ARNS" + } + } + } + } + }, + "data": { + "aws_region": { + "root_Region_A2D17352": { + "//": { + "metadata": { + "path": "root/Default/Region", + "uniqueId": "root_Region_A2D17352" + } + } + } + } + }, + "output": { + "WING_TEST_RUNNER_FUNCTION_ARNS": { + "value": "[[\"root/Default/Default/test:http.get and http.fetch can preform a call to an api\",\"${aws_lambda_function.root_testhttpgetandhttpfetchcanpreformacalltoanapi_Handler_543A78D5.arn}\"]]" + } + }, + "provider": { + "aws": [ + {} + ] + }, + "resource": { + "aws_api_gateway_deployment": { + "root_cloudApi_api_deployment_E29F699A": { + "//": { + "metadata": { + "path": "root/Default/Default/cloud.Api/api/deployment", + "uniqueId": "root_cloudApi_api_deployment_E29F699A" + } + }, + "lifecycle": { + "create_before_destroy": true + }, + "rest_api_id": "${aws_api_gateway_rest_api.root_cloudApi_api_8C9FE51E.id}", + "triggers": { + "redeployment": "c3461b0b0043b244acf509a72d2abc470b20cb05" + } + } + }, + "aws_api_gateway_rest_api": { + "root_cloudApi_api_8C9FE51E": { + "//": { + "metadata": { + "path": "root/Default/Default/cloud.Api/api/api", + "uniqueId": "root_cloudApi_api_8C9FE51E" + } + }, + "body": "{\"openapi\":\"3.0.3\",\"paths\":{\"/path\":{\"get\":{\"operationId\":\"get-path\",\"responses\":{\"200\":{\"description\":\"200 response\",\"content\":{}}},\"parameters\":[],\"x-amazon-apigateway-integration\":{\"uri\":\"arn:aws:apigateway:${data.aws_region.root_Region_A2D17352.name}:lambda:path/2015-03-31/functions/${aws_lambda_function.root_cloudApi_cloudApiOnRequestcdafee6e_582EA655.arn}/invocations\",\"type\":\"aws_proxy\",\"httpMethod\":\"POST\",\"responses\":{\"default\":{\"statusCode\":\"200\"}},\"passthroughBehavior\":\"when_no_match\",\"contentHandling\":\"CONVERT_TO_TEXT\"}}}}}", + "name": "api-c895068c" + } + }, + "aws_api_gateway_stage": { + "root_cloudApi_api_stage_57D6284A": { + "//": { + "metadata": { + "path": "root/Default/Default/cloud.Api/api/stage", + "uniqueId": "root_cloudApi_api_stage_57D6284A" + } + }, + "deployment_id": "${aws_api_gateway_deployment.root_cloudApi_api_deployment_E29F699A.id}", + "rest_api_id": "${aws_api_gateway_rest_api.root_cloudApi_api_8C9FE51E.id}", + "stage_name": "prod" + } + }, + "aws_iam_role": { + "root_cloudApi_cloudApiOnRequestcdafee6e_IamRole_2B8A04C3": { + "//": { + "metadata": { + "path": "root/Default/Default/cloud.Api/cloud.Api-OnRequest-cdafee6e/IamRole", + "uniqueId": "root_cloudApi_cloudApiOnRequestcdafee6e_IamRole_2B8A04C3" + } + }, + "assume_role_policy": "{\"Version\":\"2012-10-17\",\"Statement\":[{\"Action\":\"sts:AssumeRole\",\"Principal\":{\"Service\":\"lambda.amazonaws.com\"},\"Effect\":\"Allow\"}]}" + }, + "root_testhttpgetandhttpfetchcanpreformacalltoanapi_Handler_IamRole_09386838": { + "//": { + "metadata": { + "path": "root/Default/Default/test:http.get and http.fetch can preform a call to an api/Handler/IamRole", + "uniqueId": "root_testhttpgetandhttpfetchcanpreformacalltoanapi_Handler_IamRole_09386838" + } + }, + "assume_role_policy": "{\"Version\":\"2012-10-17\",\"Statement\":[{\"Action\":\"sts:AssumeRole\",\"Principal\":{\"Service\":\"lambda.amazonaws.com\"},\"Effect\":\"Allow\"}]}" + } + }, + "aws_iam_role_policy": { + "root_cloudApi_cloudApiOnRequestcdafee6e_IamRolePolicy_E6B9BE66": { + "//": { + "metadata": { + "path": "root/Default/Default/cloud.Api/cloud.Api-OnRequest-cdafee6e/IamRolePolicy", + "uniqueId": "root_cloudApi_cloudApiOnRequestcdafee6e_IamRolePolicy_E6B9BE66" + } + }, + "policy": "{\"Version\":\"2012-10-17\",\"Statement\":[{\"Effect\":\"Allow\",\"Action\":\"none:null\",\"Resource\":\"*\"}]}", + "role": "${aws_iam_role.root_cloudApi_cloudApiOnRequestcdafee6e_IamRole_2B8A04C3.name}" + }, + "root_testhttpgetandhttpfetchcanpreformacalltoanapi_Handler_IamRolePolicy_108210B3": { + "//": { + "metadata": { + "path": "root/Default/Default/test:http.get and http.fetch can preform a call to an api/Handler/IamRolePolicy", + "uniqueId": "root_testhttpgetandhttpfetchcanpreformacalltoanapi_Handler_IamRolePolicy_108210B3" + } + }, + "policy": "{\"Version\":\"2012-10-17\",\"Statement\":[{\"Effect\":\"Allow\",\"Action\":\"none:null\",\"Resource\":\"*\"}]}", + "role": "${aws_iam_role.root_testhttpgetandhttpfetchcanpreformacalltoanapi_Handler_IamRole_09386838.name}" + } + }, + "aws_iam_role_policy_attachment": { + "root_cloudApi_cloudApiOnRequestcdafee6e_IamRolePolicyAttachment_4A873879": { + "//": { + "metadata": { + "path": "root/Default/Default/cloud.Api/cloud.Api-OnRequest-cdafee6e/IamRolePolicyAttachment", + "uniqueId": "root_cloudApi_cloudApiOnRequestcdafee6e_IamRolePolicyAttachment_4A873879" + } + }, + "policy_arn": "arn:aws:iam::aws:policy/service-role/AWSLambdaBasicExecutionRole", + "role": "${aws_iam_role.root_cloudApi_cloudApiOnRequestcdafee6e_IamRole_2B8A04C3.name}" + }, + "root_testhttpgetandhttpfetchcanpreformacalltoanapi_Handler_IamRolePolicyAttachment_2F4F63AD": { + "//": { + "metadata": { + "path": "root/Default/Default/test:http.get and http.fetch can preform a call to an api/Handler/IamRolePolicyAttachment", + "uniqueId": "root_testhttpgetandhttpfetchcanpreformacalltoanapi_Handler_IamRolePolicyAttachment_2F4F63AD" + } + }, + "policy_arn": "arn:aws:iam::aws:policy/service-role/AWSLambdaBasicExecutionRole", + "role": "${aws_iam_role.root_testhttpgetandhttpfetchcanpreformacalltoanapi_Handler_IamRole_09386838.name}" + } + }, + "aws_lambda_function": { + "root_cloudApi_cloudApiOnRequestcdafee6e_582EA655": { + "//": { + "metadata": { + "path": "root/Default/Default/cloud.Api/cloud.Api-OnRequest-cdafee6e/Default", + "uniqueId": "root_cloudApi_cloudApiOnRequestcdafee6e_582EA655" + } + }, + "environment": { + "variables": { + "WING_FUNCTION_NAME": "cloud-Api-OnRequest-cdafee6e-c8147384", + "WING_TARGET": "tf-aws" + } + }, + "function_name": "cloud-Api-OnRequest-cdafee6e-c8147384", + "handler": "index.handler", + "publish": true, + "role": "${aws_iam_role.root_cloudApi_cloudApiOnRequestcdafee6e_IamRole_2B8A04C3.arn}", + "runtime": "nodejs18.x", + "s3_bucket": "${aws_s3_bucket.root_Code_02F3C603.bucket}", + "s3_key": "${aws_s3_object.root_cloudApi_cloudApiOnRequestcdafee6e_S3Object_AA762041.key}", + "timeout": 30, + "vpc_config": { + "security_group_ids": [], + "subnet_ids": [] + } + }, + "root_testhttpgetandhttpfetchcanpreformacalltoanapi_Handler_543A78D5": { + "//": { + "metadata": { + "path": "root/Default/Default/test:http.get and http.fetch can preform a call to an api/Handler/Default", + "uniqueId": "root_testhttpgetandhttpfetchcanpreformacalltoanapi_Handler_543A78D5" + } + }, + "environment": { + "variables": { + "CLOUD_API_C82DF3A5": "${aws_api_gateway_stage.root_cloudApi_api_stage_57D6284A.invoke_url}", + "WING_FUNCTION_NAME": "Handler-c838ce37", + "WING_TARGET": "tf-aws", + "WING_TOKEN_TFTOKEN_TOKEN_21": "${jsonencode(aws_api_gateway_stage.root_cloudApi_api_stage_57D6284A.invoke_url)}" + } + }, + "function_name": "Handler-c838ce37", + "handler": "index.handler", + "publish": true, + "role": "${aws_iam_role.root_testhttpgetandhttpfetchcanpreformacalltoanapi_Handler_IamRole_09386838.arn}", + "runtime": "nodejs18.x", + "s3_bucket": "${aws_s3_bucket.root_Code_02F3C603.bucket}", + "s3_key": "${aws_s3_object.root_testhttpgetandhttpfetchcanpreformacalltoanapi_Handler_S3Object_C6152827.key}", + "timeout": 30, + "vpc_config": { + "security_group_ids": [], + "subnet_ids": [] + } + } + }, + "aws_lambda_permission": { + "root_cloudApi_api_permissionGETe2131352_C536168C": { + "//": { + "metadata": { + "path": "root/Default/Default/cloud.Api/api/permission-GET-e2131352", + "uniqueId": "root_cloudApi_api_permissionGETe2131352_C536168C" + } + }, + "action": "lambda:InvokeFunction", + "function_name": "${aws_lambda_function.root_cloudApi_cloudApiOnRequestcdafee6e_582EA655.function_name}", + "principal": "apigateway.amazonaws.com", + "source_arn": "${aws_api_gateway_rest_api.root_cloudApi_api_8C9FE51E.execution_arn}/*/GET/path", + "statement_id": "AllowExecutionFromAPIGateway-GET-e2131352" + } + }, + "aws_s3_bucket": { + "root_Code_02F3C603": { + "//": { + "metadata": { + "path": "root/Default/Code", + "uniqueId": "root_Code_02F3C603" + } + }, + "bucket_prefix": "code-c84a50b1-" + } + }, + "aws_s3_object": { + "root_cloudApi_cloudApiOnRequestcdafee6e_S3Object_AA762041": { + "//": { + "metadata": { + "path": "root/Default/Default/cloud.Api/cloud.Api-OnRequest-cdafee6e/S3Object", + "uniqueId": "root_cloudApi_cloudApiOnRequestcdafee6e_S3Object_AA762041" + } + }, + "bucket": "${aws_s3_bucket.root_Code_02F3C603.bucket}", + "key": "", + "source": "" + }, + "root_testhttpgetandhttpfetchcanpreformacalltoanapi_Handler_S3Object_C6152827": { + "//": { + "metadata": { + "path": "root/Default/Default/test:http.get and http.fetch can preform a call to an api/Handler/S3Object", + "uniqueId": "root_testhttpgetandhttpfetchcanpreformacalltoanapi_Handler_S3Object_C6152827" + } + }, + "bucket": "${aws_s3_bucket.root_Code_02F3C603.bucket}", + "key": "", + "source": "" + } + } + } +} +``` + +## preflight.js +```js +const $stdlib = require('@winglang/sdk'); +const $outdir = process.env.WING_SYNTH_DIR ?? "."; +const std = $stdlib.std; +const $wing_is_test = process.env.WING_IS_TEST === "true"; +const $AppBase = $stdlib.core.App.for(process.env.WING_TARGET); +const cloud = require('@winglang/sdk').cloud; +const http = require('@winglang/sdk').http; +class $Root extends $stdlib.std.Resource { + constructor(scope, id) { + super(scope, id); + class $Closure1 extends $stdlib.std.Resource { + constructor(scope, id, ) { + super(scope, id); + this._addInflightOps("handle"); + this.display.hidden = true; + } + static _toInflightType(context) { + const self_client_path = "././inflight.$Closure1.js"; + const api_GET_client = context._lift(api_GET); + const body_client = context._lift(body); + return $stdlib.core.NodeJsCode.fromInline(` + require("${self_client_path}")({ + api_GET: ${api_GET_client}, + body: ${body_client}, + }) + `); + } + _toInflight() { + return $stdlib.core.NodeJsCode.fromInline(` + (await (async () => { + const $Closure1Client = ${$Closure1._toInflightType(this).text}; + const client = new $Closure1Client({ + }); + if (client.$inflight_init) { await client.$inflight_init(); } + return client; + })()) + `); + } + _registerBind(host, ops) { + if (ops.includes("$inflight_init")) { + $Closure1._registerBindObject(api_GET, host, []); + $Closure1._registerBindObject(body, host, []); + } + if (ops.includes("handle")) { + $Closure1._registerBindObject(api_GET, host, []); + $Closure1._registerBindObject(body, host, []); + } + super._registerBind(host, ops); + } + } + class $Closure2 extends $stdlib.std.Resource { + constructor(scope, id, ) { + super(scope, id); + this._addInflightOps("handle"); + this.display.hidden = true; + } + static _toInflightType(context) { + const self_client_path = "././inflight.$Closure2.js"; + const api_client = context._lift(api); + const http_GET_client = context._lift(http_GET); + const body_client = context._lift(body); + const http_UtilClient = http.Util._toInflightType(context); + return $stdlib.core.NodeJsCode.fromInline(` + require("${self_client_path}")({ + api: ${api_client}, + http_GET: ${http_GET_client}, + body: ${body_client}, + http_Util: ${http_UtilClient.text}, + }) + `); + } + _toInflight() { + return $stdlib.core.NodeJsCode.fromInline(` + (await (async () => { + const $Closure2Client = ${$Closure2._toInflightType(this).text}; + const client = new $Closure2Client({ + }); + if (client.$inflight_init) { await client.$inflight_init(); } + return client; + })()) + `); + } + _registerBind(host, ops) { + if (ops.includes("$inflight_init")) { + $Closure2._registerBindObject(api, host, []); + $Closure2._registerBindObject(body, host, []); + $Closure2._registerBindObject(http_GET, host, []); + } + if (ops.includes("handle")) { + $Closure2._registerBindObject(api.url, host, []); + $Closure2._registerBindObject(body, host, []); + $Closure2._registerBindObject(http_GET, host, []); + } + super._registerBind(host, ops); + } + } + const http_GET = http.HttpMethod.GET; + const api_GET = cloud.HttpMethod.GET; + const api = this.node.root.newAbstract("@winglang/sdk.cloud.Api",this,"cloud.Api"); + const body = "ok!"; + (api.get("/path",new $Closure1(this,"$Closure1"))); + this.node.root.new("@winglang/sdk.std.Test",std.Test,this,"test:http.get and http.fetch can preform a call to an api",new $Closure2(this,"$Closure2")); + } +} +class $App extends $AppBase { + constructor() { + super({ outdir: $outdir, name: "get", plugins: $plugins, isTestEnvironment: $wing_is_test }); + if ($wing_is_test) { + new $Root(this, "env0"); + const $test_runner = this.testRunner; + const $tests = $test_runner.findTests(); + for (let $i = 1; $i < $tests.length; $i++) { + new $Root(this, "env" + $i); + } + } else { + new $Root(this, "Default"); + } + } +} +new $App().synth(); + +``` + diff --git a/tools/hangar/__snapshots__/test_corpus/sdk_tests/api/get.w_test_sim.md b/tools/hangar/__snapshots__/test_corpus/sdk_tests/api/get.w_test_sim.md new file mode 100644 index 00000000000..9196bbe5e57 --- /dev/null +++ b/tools/hangar/__snapshots__/test_corpus/sdk_tests/api/get.w_test_sim.md @@ -0,0 +1,12 @@ +# [get.w](../../../../../../examples/tests/sdk_tests/api/get.w) | test | sim + +## stdout.log +```log +pass โ”€ get.wsim ยป root/env0/test:http.get and http.fetch can preform a call to an api + + +Tests 1 passed (1) +Test Files 1 passed (1) +Duration +``` + diff --git a/tools/hangar/__snapshots__/test_corpus/sdk_tests/api/patch.w_compile_tf-aws.md b/tools/hangar/__snapshots__/test_corpus/sdk_tests/api/patch.w_compile_tf-aws.md new file mode 100644 index 00000000000..4c6ce56bba9 --- /dev/null +++ b/tools/hangar/__snapshots__/test_corpus/sdk_tests/api/patch.w_compile_tf-aws.md @@ -0,0 +1,461 @@ +# [patch.w](../../../../../../examples/tests/sdk_tests/api/patch.w) | compile | tf-aws + +## inflight.$Closure1.js +```js +module.exports = function({ api_PATCH, _id, body, std_Json }) { + class $Closure1 { + constructor({ }) { + const $obj = (...args) => this.handle(...args); + Object.setPrototypeOf($obj, this); + return $obj; + } + async $inflight_init() { + } + async handle(req) { + {((cond) => {if (!cond) throw new Error("assertion failed: req.method == api_PATCH")})((req.method === api_PATCH))}; + {((cond) => {if (!cond) throw new Error("assertion failed: req.vars?.get(\"id\") == _id")})(((req.vars)["id"] === _id))}; + {((cond) => {if (!cond) throw new Error("assertion failed: req.path == \"/path/\"+ _id")})((req.path === ("/path/" + _id)))}; + {((cond) => {if (!cond) throw new Error("assertion failed: req.body == Json.stringify(body)")})((req.body === ((args) => { return JSON.stringify(args[0], null, args[1]) })([body])))}; + {((cond) => {if (!cond) throw new Error("assertion failed: req.headers?.get(\"content-type\") == \"application/json\"")})(((req.headers)["content-type"] === "application/json"))}; + return { + "status": 200, + "body": (req.vars)["id"],} + ; + } + } + return $Closure1; +} + +``` + +## inflight.$Closure2.js +```js +module.exports = function({ api, _id, body, http_PATCH, http_Util, std_Json }) { + class $Closure2 { + constructor({ }) { + const $obj = (...args) => this.handle(...args); + Object.setPrototypeOf($obj, this); + return $obj; + } + async $inflight_init() { + } + async handle() { + const url = String.raw({ raw: ["", "/path/", ""] }, api.url, _id); + const response = (await http_Util.patch(url,{ + "headers": Object.freeze({"content-type":"application/json"}), + "body": ((args) => { return JSON.stringify(args[0], null, args[1]) })([body]),} + )); + const fetchResponse = (await http_Util.patch(url,{ + "method": http_PATCH, + "headers": Object.freeze({"content-type":"application/json"}), + "body": ((args) => { return JSON.stringify(args[0], null, args[1]) })([body]),} + )); + {((cond) => {if (!cond) throw new Error("assertion failed: response.body == _id")})((response.body === _id))}; + {((cond) => {if (!cond) throw new Error("assertion failed: response.status == 200")})((response.status === 200))}; + {((cond) => {if (!cond) throw new Error("assertion failed: response.url == url")})((response.url === url))}; + {((cond) => {if (!cond) throw new Error("assertion failed: fetchResponse.body == _id")})((fetchResponse.body === _id))}; + {((cond) => {if (!cond) throw new Error("assertion failed: fetchResponse.status == 200")})((fetchResponse.status === 200))}; + {((cond) => {if (!cond) throw new Error("assertion failed: fetchResponse.url == url")})((fetchResponse.url === url))}; + } + } + return $Closure2; +} + +``` + +## main.tf.json +```json +{ + "//": { + "metadata": { + "backend": "local", + "stackName": "root", + "version": "0.15.2" + }, + "outputs": { + "root": { + "Default": { + "cloud.TestRunner": { + "TestFunctionArns": "WING_TEST_RUNNER_FUNCTION_ARNS" + } + } + } + } + }, + "data": { + "aws_region": { + "root_Region_A2D17352": { + "//": { + "metadata": { + "path": "root/Default/Region", + "uniqueId": "root_Region_A2D17352" + } + } + } + } + }, + "output": { + "WING_TEST_RUNNER_FUNCTION_ARNS": { + "value": "[[\"root/Default/Default/test:http.patch and http.fetch can preform a call to an api\",\"${aws_lambda_function.root_testhttppatchandhttpfetchcanpreformacalltoanapi_Handler_1C5BB2AB.arn}\"]]" + } + }, + "provider": { + "aws": [ + {} + ] + }, + "resource": { + "aws_api_gateway_deployment": { + "root_cloudApi_api_deployment_E29F699A": { + "//": { + "metadata": { + "path": "root/Default/Default/cloud.Api/api/deployment", + "uniqueId": "root_cloudApi_api_deployment_E29F699A" + } + }, + "lifecycle": { + "create_before_destroy": true + }, + "rest_api_id": "${aws_api_gateway_rest_api.root_cloudApi_api_8C9FE51E.id}", + "triggers": { + "redeployment": "fea7e9f182aa5daf0c90efdf632bb2737c4ef5c4" + } + } + }, + "aws_api_gateway_rest_api": { + "root_cloudApi_api_8C9FE51E": { + "//": { + "metadata": { + "path": "root/Default/Default/cloud.Api/api/api", + "uniqueId": "root_cloudApi_api_8C9FE51E" + } + }, + "body": "{\"openapi\":\"3.0.3\",\"paths\":{\"/path/{id}\":{\"patch\":{\"operationId\":\"patch-path/{id}\",\"responses\":{\"200\":{\"description\":\"200 response\",\"content\":{}}},\"parameters\":[{\"name\":\"id\",\"in\":\"path\",\"required\":true,\"schema\":{\"type\":\"string\"}}],\"x-amazon-apigateway-integration\":{\"uri\":\"arn:aws:apigateway:${data.aws_region.root_Region_A2D17352.name}:lambda:path/2015-03-31/functions/${aws_lambda_function.root_cloudApi_cloudApiOnRequestcdafee6e_582EA655.arn}/invocations\",\"type\":\"aws_proxy\",\"httpMethod\":\"POST\",\"responses\":{\"default\":{\"statusCode\":\"200\"}},\"passthroughBehavior\":\"when_no_match\",\"contentHandling\":\"CONVERT_TO_TEXT\"}}}}}", + "name": "api-c895068c" + } + }, + "aws_api_gateway_stage": { + "root_cloudApi_api_stage_57D6284A": { + "//": { + "metadata": { + "path": "root/Default/Default/cloud.Api/api/stage", + "uniqueId": "root_cloudApi_api_stage_57D6284A" + } + }, + "deployment_id": "${aws_api_gateway_deployment.root_cloudApi_api_deployment_E29F699A.id}", + "rest_api_id": "${aws_api_gateway_rest_api.root_cloudApi_api_8C9FE51E.id}", + "stage_name": "prod" + } + }, + "aws_iam_role": { + "root_cloudApi_cloudApiOnRequestcdafee6e_IamRole_2B8A04C3": { + "//": { + "metadata": { + "path": "root/Default/Default/cloud.Api/cloud.Api-OnRequest-cdafee6e/IamRole", + "uniqueId": "root_cloudApi_cloudApiOnRequestcdafee6e_IamRole_2B8A04C3" + } + }, + "assume_role_policy": "{\"Version\":\"2012-10-17\",\"Statement\":[{\"Action\":\"sts:AssumeRole\",\"Principal\":{\"Service\":\"lambda.amazonaws.com\"},\"Effect\":\"Allow\"}]}" + }, + "root_testhttppatchandhttpfetchcanpreformacalltoanapi_Handler_IamRole_D7C5DEEB": { + "//": { + "metadata": { + "path": "root/Default/Default/test:http.patch and http.fetch can preform a call to an api/Handler/IamRole", + "uniqueId": "root_testhttppatchandhttpfetchcanpreformacalltoanapi_Handler_IamRole_D7C5DEEB" + } + }, + "assume_role_policy": "{\"Version\":\"2012-10-17\",\"Statement\":[{\"Action\":\"sts:AssumeRole\",\"Principal\":{\"Service\":\"lambda.amazonaws.com\"},\"Effect\":\"Allow\"}]}" + } + }, + "aws_iam_role_policy": { + "root_cloudApi_cloudApiOnRequestcdafee6e_IamRolePolicy_E6B9BE66": { + "//": { + "metadata": { + "path": "root/Default/Default/cloud.Api/cloud.Api-OnRequest-cdafee6e/IamRolePolicy", + "uniqueId": "root_cloudApi_cloudApiOnRequestcdafee6e_IamRolePolicy_E6B9BE66" + } + }, + "policy": "{\"Version\":\"2012-10-17\",\"Statement\":[{\"Effect\":\"Allow\",\"Action\":\"none:null\",\"Resource\":\"*\"}]}", + "role": "${aws_iam_role.root_cloudApi_cloudApiOnRequestcdafee6e_IamRole_2B8A04C3.name}" + }, + "root_testhttppatchandhttpfetchcanpreformacalltoanapi_Handler_IamRolePolicy_1172AA12": { + "//": { + "metadata": { + "path": "root/Default/Default/test:http.patch and http.fetch can preform a call to an api/Handler/IamRolePolicy", + "uniqueId": "root_testhttppatchandhttpfetchcanpreformacalltoanapi_Handler_IamRolePolicy_1172AA12" + } + }, + "policy": "{\"Version\":\"2012-10-17\",\"Statement\":[{\"Effect\":\"Allow\",\"Action\":\"none:null\",\"Resource\":\"*\"}]}", + "role": "${aws_iam_role.root_testhttppatchandhttpfetchcanpreformacalltoanapi_Handler_IamRole_D7C5DEEB.name}" + } + }, + "aws_iam_role_policy_attachment": { + "root_cloudApi_cloudApiOnRequestcdafee6e_IamRolePolicyAttachment_4A873879": { + "//": { + "metadata": { + "path": "root/Default/Default/cloud.Api/cloud.Api-OnRequest-cdafee6e/IamRolePolicyAttachment", + "uniqueId": "root_cloudApi_cloudApiOnRequestcdafee6e_IamRolePolicyAttachment_4A873879" + } + }, + "policy_arn": "arn:aws:iam::aws:policy/service-role/AWSLambdaBasicExecutionRole", + "role": "${aws_iam_role.root_cloudApi_cloudApiOnRequestcdafee6e_IamRole_2B8A04C3.name}" + }, + "root_testhttppatchandhttpfetchcanpreformacalltoanapi_Handler_IamRolePolicyAttachment_93E80B8C": { + "//": { + "metadata": { + "path": "root/Default/Default/test:http.patch and http.fetch can preform a call to an api/Handler/IamRolePolicyAttachment", + "uniqueId": "root_testhttppatchandhttpfetchcanpreformacalltoanapi_Handler_IamRolePolicyAttachment_93E80B8C" + } + }, + "policy_arn": "arn:aws:iam::aws:policy/service-role/AWSLambdaBasicExecutionRole", + "role": "${aws_iam_role.root_testhttppatchandhttpfetchcanpreformacalltoanapi_Handler_IamRole_D7C5DEEB.name}" + } + }, + "aws_lambda_function": { + "root_cloudApi_cloudApiOnRequestcdafee6e_582EA655": { + "//": { + "metadata": { + "path": "root/Default/Default/cloud.Api/cloud.Api-OnRequest-cdafee6e/Default", + "uniqueId": "root_cloudApi_cloudApiOnRequestcdafee6e_582EA655" + } + }, + "environment": { + "variables": { + "WING_FUNCTION_NAME": "cloud-Api-OnRequest-cdafee6e-c8147384", + "WING_TARGET": "tf-aws" + } + }, + "function_name": "cloud-Api-OnRequest-cdafee6e-c8147384", + "handler": "index.handler", + "publish": true, + "role": "${aws_iam_role.root_cloudApi_cloudApiOnRequestcdafee6e_IamRole_2B8A04C3.arn}", + "runtime": "nodejs18.x", + "s3_bucket": "${aws_s3_bucket.root_Code_02F3C603.bucket}", + "s3_key": "${aws_s3_object.root_cloudApi_cloudApiOnRequestcdafee6e_S3Object_AA762041.key}", + "timeout": 30, + "vpc_config": { + "security_group_ids": [], + "subnet_ids": [] + } + }, + "root_testhttppatchandhttpfetchcanpreformacalltoanapi_Handler_1C5BB2AB": { + "//": { + "metadata": { + "path": "root/Default/Default/test:http.patch and http.fetch can preform a call to an api/Handler/Default", + "uniqueId": "root_testhttppatchandhttpfetchcanpreformacalltoanapi_Handler_1C5BB2AB" + } + }, + "environment": { + "variables": { + "CLOUD_API_C82DF3A5": "${aws_api_gateway_stage.root_cloudApi_api_stage_57D6284A.invoke_url}", + "WING_FUNCTION_NAME": "Handler-c89df580", + "WING_TARGET": "tf-aws", + "WING_TOKEN_TFTOKEN_TOKEN_21": "${jsonencode(aws_api_gateway_stage.root_cloudApi_api_stage_57D6284A.invoke_url)}" + } + }, + "function_name": "Handler-c89df580", + "handler": "index.handler", + "publish": true, + "role": "${aws_iam_role.root_testhttppatchandhttpfetchcanpreformacalltoanapi_Handler_IamRole_D7C5DEEB.arn}", + "runtime": "nodejs18.x", + "s3_bucket": "${aws_s3_bucket.root_Code_02F3C603.bucket}", + "s3_key": "${aws_s3_object.root_testhttppatchandhttpfetchcanpreformacalltoanapi_Handler_S3Object_7BA45804.key}", + "timeout": 30, + "vpc_config": { + "security_group_ids": [], + "subnet_ids": [] + } + } + }, + "aws_lambda_permission": { + "root_cloudApi_api_permissionPATCH4d67c9d8_FFD02B88": { + "//": { + "metadata": { + "path": "root/Default/Default/cloud.Api/api/permission-PATCH-4d67c9d8", + "uniqueId": "root_cloudApi_api_permissionPATCH4d67c9d8_FFD02B88" + } + }, + "action": "lambda:InvokeFunction", + "function_name": "${aws_lambda_function.root_cloudApi_cloudApiOnRequestcdafee6e_582EA655.function_name}", + "principal": "apigateway.amazonaws.com", + "source_arn": "${aws_api_gateway_rest_api.root_cloudApi_api_8C9FE51E.execution_arn}/*/PATCH/path/{id}", + "statement_id": "AllowExecutionFromAPIGateway-PATCH-4d67c9d8" + } + }, + "aws_s3_bucket": { + "root_Code_02F3C603": { + "//": { + "metadata": { + "path": "root/Default/Code", + "uniqueId": "root_Code_02F3C603" + } + }, + "bucket_prefix": "code-c84a50b1-" + } + }, + "aws_s3_object": { + "root_cloudApi_cloudApiOnRequestcdafee6e_S3Object_AA762041": { + "//": { + "metadata": { + "path": "root/Default/Default/cloud.Api/cloud.Api-OnRequest-cdafee6e/S3Object", + "uniqueId": "root_cloudApi_cloudApiOnRequestcdafee6e_S3Object_AA762041" + } + }, + "bucket": "${aws_s3_bucket.root_Code_02F3C603.bucket}", + "key": "", + "source": "" + }, + "root_testhttppatchandhttpfetchcanpreformacalltoanapi_Handler_S3Object_7BA45804": { + "//": { + "metadata": { + "path": "root/Default/Default/test:http.patch and http.fetch can preform a call to an api/Handler/S3Object", + "uniqueId": "root_testhttppatchandhttpfetchcanpreformacalltoanapi_Handler_S3Object_7BA45804" + } + }, + "bucket": "${aws_s3_bucket.root_Code_02F3C603.bucket}", + "key": "", + "source": "" + } + } + } +} +``` + +## preflight.js +```js +const $stdlib = require('@winglang/sdk'); +const $outdir = process.env.WING_SYNTH_DIR ?? "."; +const std = $stdlib.std; +const $wing_is_test = process.env.WING_IS_TEST === "true"; +const $AppBase = $stdlib.core.App.for(process.env.WING_TARGET); +const cloud = require('@winglang/sdk').cloud; +const http = require('@winglang/sdk').http; +class $Root extends $stdlib.std.Resource { + constructor(scope, id) { + super(scope, id); + class $Closure1 extends $stdlib.std.Resource { + constructor(scope, id, ) { + super(scope, id); + this._addInflightOps("handle"); + this.display.hidden = true; + } + static _toInflightType(context) { + const self_client_path = "././inflight.$Closure1.js"; + const api_PATCH_client = context._lift(api_PATCH); + const _id_client = context._lift(_id); + const body_client = context._lift(body); + const std_JsonClient = std.Json._toInflightType(context); + return $stdlib.core.NodeJsCode.fromInline(` + require("${self_client_path}")({ + api_PATCH: ${api_PATCH_client}, + _id: ${_id_client}, + body: ${body_client}, + std_Json: ${std_JsonClient.text}, + }) + `); + } + _toInflight() { + return $stdlib.core.NodeJsCode.fromInline(` + (await (async () => { + const $Closure1Client = ${$Closure1._toInflightType(this).text}; + const client = new $Closure1Client({ + }); + if (client.$inflight_init) { await client.$inflight_init(); } + return client; + })()) + `); + } + _registerBind(host, ops) { + if (ops.includes("$inflight_init")) { + $Closure1._registerBindObject(_id, host, []); + $Closure1._registerBindObject(api_PATCH, host, []); + $Closure1._registerBindObject(body, host, []); + } + if (ops.includes("handle")) { + $Closure1._registerBindObject(_id, host, []); + $Closure1._registerBindObject(api_PATCH, host, []); + $Closure1._registerBindObject(body, host, []); + } + super._registerBind(host, ops); + } + } + class $Closure2 extends $stdlib.std.Resource { + constructor(scope, id, ) { + super(scope, id); + this._addInflightOps("handle"); + this.display.hidden = true; + } + static _toInflightType(context) { + const self_client_path = "././inflight.$Closure2.js"; + const api_client = context._lift(api); + const _id_client = context._lift(_id); + const body_client = context._lift(body); + const http_PATCH_client = context._lift(http_PATCH); + const http_UtilClient = http.Util._toInflightType(context); + const std_JsonClient = std.Json._toInflightType(context); + return $stdlib.core.NodeJsCode.fromInline(` + require("${self_client_path}")({ + api: ${api_client}, + _id: ${_id_client}, + body: ${body_client}, + http_PATCH: ${http_PATCH_client}, + http_Util: ${http_UtilClient.text}, + std_Json: ${std_JsonClient.text}, + }) + `); + } + _toInflight() { + return $stdlib.core.NodeJsCode.fromInline(` + (await (async () => { + const $Closure2Client = ${$Closure2._toInflightType(this).text}; + const client = new $Closure2Client({ + }); + if (client.$inflight_init) { await client.$inflight_init(); } + return client; + })()) + `); + } + _registerBind(host, ops) { + if (ops.includes("$inflight_init")) { + $Closure2._registerBindObject(_id, host, []); + $Closure2._registerBindObject(api, host, []); + $Closure2._registerBindObject(body, host, []); + $Closure2._registerBindObject(http_PATCH, host, []); + } + if (ops.includes("handle")) { + $Closure2._registerBindObject(_id, host, []); + $Closure2._registerBindObject(api.url, host, []); + $Closure2._registerBindObject(body, host, []); + $Closure2._registerBindObject(http_PATCH, host, []); + } + super._registerBind(host, ops); + } + } + const http_PATCH = http.HttpMethod.PATCH; + const api_PATCH = cloud.HttpMethod.PATCH; + const api = this.node.root.newAbstract("@winglang/sdk.cloud.Api",this,"cloud.Api"); + const body = Object.freeze({"cat":"Tion"}); + const _id = "12345"; + (api.patch("/path/{id}",new $Closure1(this,"$Closure1"))); + this.node.root.new("@winglang/sdk.std.Test",std.Test,this,"test:http.patch and http.fetch can preform a call to an api",new $Closure2(this,"$Closure2")); + } +} +class $App extends $AppBase { + constructor() { + super({ outdir: $outdir, name: "patch", plugins: $plugins, isTestEnvironment: $wing_is_test }); + if ($wing_is_test) { + new $Root(this, "env0"); + const $test_runner = this.testRunner; + const $tests = $test_runner.findTests(); + for (let $i = 1; $i < $tests.length; $i++) { + new $Root(this, "env" + $i); + } + } else { + new $Root(this, "Default"); + } + } +} +new $App().synth(); + +``` + diff --git a/tools/hangar/__snapshots__/test_corpus/sdk_tests/api/patch.w_test_sim.md b/tools/hangar/__snapshots__/test_corpus/sdk_tests/api/patch.w_test_sim.md new file mode 100644 index 00000000000..65b33f03a26 --- /dev/null +++ b/tools/hangar/__snapshots__/test_corpus/sdk_tests/api/patch.w_test_sim.md @@ -0,0 +1,12 @@ +# [patch.w](../../../../../../examples/tests/sdk_tests/api/patch.w) | test | sim + +## stdout.log +```log +pass โ”€ patch.wsim ยป root/env0/test:http.patch and http.fetch can preform a call to an api + + +Tests 1 passed (1) +Test Files 1 passed (1) +Duration +``` + diff --git a/tools/hangar/__snapshots__/test_corpus/sdk_tests/api/post.w_compile_tf-aws.md b/tools/hangar/__snapshots__/test_corpus/sdk_tests/api/post.w_compile_tf-aws.md new file mode 100644 index 00000000000..860de43490e --- /dev/null +++ b/tools/hangar/__snapshots__/test_corpus/sdk_tests/api/post.w_compile_tf-aws.md @@ -0,0 +1,451 @@ +# [post.w](../../../../../../examples/tests/sdk_tests/api/post.w) | compile | tf-aws + +## inflight.$Closure1.js +```js +module.exports = function({ api_POST, body, std_Json }) { + class $Closure1 { + constructor({ }) { + const $obj = (...args) => this.handle(...args); + Object.setPrototypeOf($obj, this); + return $obj; + } + async $inflight_init() { + } + async handle(req) { + {((cond) => {if (!cond) throw new Error("assertion failed: req.method == api_POST")})((req.method === api_POST))}; + {((cond) => {if (!cond) throw new Error("assertion failed: req.path == \"/path\"")})((req.path === "/path"))}; + {((cond) => {if (!cond) throw new Error("assertion failed: req.body == Json.stringify(body)")})((req.body === ((args) => { return JSON.stringify(args[0], null, args[1]) })([body])))}; + {((cond) => {if (!cond) throw new Error("assertion failed: req.headers?.get(\"content-type\") == \"application/json\"")})(((req.headers)["content-type"] === "application/json"))}; + return { + "status": 200, + "body": req.body,} + ; + } + } + return $Closure1; +} + +``` + +## inflight.$Closure2.js +```js +module.exports = function({ api, body, http_POST, http_Util, std_Json }) { + class $Closure2 { + constructor({ }) { + const $obj = (...args) => this.handle(...args); + Object.setPrototypeOf($obj, this); + return $obj; + } + async $inflight_init() { + } + async handle() { + const url = (api.url + "/path"); + const response = (await http_Util.post(url,{ + "headers": Object.freeze({"content-type":"application/json"}), + "body": ((args) => { return JSON.stringify(args[0], null, args[1]) })([body]),} + )); + const fetchResponse = (await http_Util.post(url,{ + "method": http_POST, + "headers": Object.freeze({"content-type":"application/json"}), + "body": ((args) => { return JSON.stringify(args[0], null, args[1]) })([body]),} + )); + {((cond) => {if (!cond) throw new Error("assertion failed: response.body == Json.stringify(body)")})((response.body === ((args) => { return JSON.stringify(args[0], null, args[1]) })([body])))}; + {((cond) => {if (!cond) throw new Error("assertion failed: response.status == 200")})((response.status === 200))}; + {((cond) => {if (!cond) throw new Error("assertion failed: response.url == url")})((response.url === url))}; + {((cond) => {if (!cond) throw new Error("assertion failed: fetchResponse.body == Json.stringify(body)")})((fetchResponse.body === ((args) => { return JSON.stringify(args[0], null, args[1]) })([body])))}; + {((cond) => {if (!cond) throw new Error("assertion failed: fetchResponse.status == 200")})((fetchResponse.status === 200))}; + {((cond) => {if (!cond) throw new Error("assertion failed: fetchResponse.url == url")})((fetchResponse.url === url))}; + } + } + return $Closure2; +} + +``` + +## main.tf.json +```json +{ + "//": { + "metadata": { + "backend": "local", + "stackName": "root", + "version": "0.15.2" + }, + "outputs": { + "root": { + "Default": { + "cloud.TestRunner": { + "TestFunctionArns": "WING_TEST_RUNNER_FUNCTION_ARNS" + } + } + } + } + }, + "data": { + "aws_region": { + "root_Region_A2D17352": { + "//": { + "metadata": { + "path": "root/Default/Region", + "uniqueId": "root_Region_A2D17352" + } + } + } + } + }, + "output": { + "WING_TEST_RUNNER_FUNCTION_ARNS": { + "value": "[[\"root/Default/Default/test:http.post and http.fetch can preform a call to an api\",\"${aws_lambda_function.root_testhttppostandhttpfetchcanpreformacalltoanapi_Handler_918D65BA.arn}\"]]" + } + }, + "provider": { + "aws": [ + {} + ] + }, + "resource": { + "aws_api_gateway_deployment": { + "root_cloudApi_api_deployment_E29F699A": { + "//": { + "metadata": { + "path": "root/Default/Default/cloud.Api/api/deployment", + "uniqueId": "root_cloudApi_api_deployment_E29F699A" + } + }, + "lifecycle": { + "create_before_destroy": true + }, + "rest_api_id": "${aws_api_gateway_rest_api.root_cloudApi_api_8C9FE51E.id}", + "triggers": { + "redeployment": "2e0d4578fa0f01cc502b493b801d616ab05c6da5" + } + } + }, + "aws_api_gateway_rest_api": { + "root_cloudApi_api_8C9FE51E": { + "//": { + "metadata": { + "path": "root/Default/Default/cloud.Api/api/api", + "uniqueId": "root_cloudApi_api_8C9FE51E" + } + }, + "body": "{\"openapi\":\"3.0.3\",\"paths\":{\"/path\":{\"post\":{\"operationId\":\"post-path\",\"responses\":{\"200\":{\"description\":\"200 response\",\"content\":{}}},\"parameters\":[],\"x-amazon-apigateway-integration\":{\"uri\":\"arn:aws:apigateway:${data.aws_region.root_Region_A2D17352.name}:lambda:path/2015-03-31/functions/${aws_lambda_function.root_cloudApi_cloudApiOnRequestcdafee6e_582EA655.arn}/invocations\",\"type\":\"aws_proxy\",\"httpMethod\":\"POST\",\"responses\":{\"default\":{\"statusCode\":\"200\"}},\"passthroughBehavior\":\"when_no_match\",\"contentHandling\":\"CONVERT_TO_TEXT\"}}}}}", + "name": "api-c895068c" + } + }, + "aws_api_gateway_stage": { + "root_cloudApi_api_stage_57D6284A": { + "//": { + "metadata": { + "path": "root/Default/Default/cloud.Api/api/stage", + "uniqueId": "root_cloudApi_api_stage_57D6284A" + } + }, + "deployment_id": "${aws_api_gateway_deployment.root_cloudApi_api_deployment_E29F699A.id}", + "rest_api_id": "${aws_api_gateway_rest_api.root_cloudApi_api_8C9FE51E.id}", + "stage_name": "prod" + } + }, + "aws_iam_role": { + "root_cloudApi_cloudApiOnRequestcdafee6e_IamRole_2B8A04C3": { + "//": { + "metadata": { + "path": "root/Default/Default/cloud.Api/cloud.Api-OnRequest-cdafee6e/IamRole", + "uniqueId": "root_cloudApi_cloudApiOnRequestcdafee6e_IamRole_2B8A04C3" + } + }, + "assume_role_policy": "{\"Version\":\"2012-10-17\",\"Statement\":[{\"Action\":\"sts:AssumeRole\",\"Principal\":{\"Service\":\"lambda.amazonaws.com\"},\"Effect\":\"Allow\"}]}" + }, + "root_testhttppostandhttpfetchcanpreformacalltoanapi_Handler_IamRole_C385115A": { + "//": { + "metadata": { + "path": "root/Default/Default/test:http.post and http.fetch can preform a call to an api/Handler/IamRole", + "uniqueId": "root_testhttppostandhttpfetchcanpreformacalltoanapi_Handler_IamRole_C385115A" + } + }, + "assume_role_policy": "{\"Version\":\"2012-10-17\",\"Statement\":[{\"Action\":\"sts:AssumeRole\",\"Principal\":{\"Service\":\"lambda.amazonaws.com\"},\"Effect\":\"Allow\"}]}" + } + }, + "aws_iam_role_policy": { + "root_cloudApi_cloudApiOnRequestcdafee6e_IamRolePolicy_E6B9BE66": { + "//": { + "metadata": { + "path": "root/Default/Default/cloud.Api/cloud.Api-OnRequest-cdafee6e/IamRolePolicy", + "uniqueId": "root_cloudApi_cloudApiOnRequestcdafee6e_IamRolePolicy_E6B9BE66" + } + }, + "policy": "{\"Version\":\"2012-10-17\",\"Statement\":[{\"Effect\":\"Allow\",\"Action\":\"none:null\",\"Resource\":\"*\"}]}", + "role": "${aws_iam_role.root_cloudApi_cloudApiOnRequestcdafee6e_IamRole_2B8A04C3.name}" + }, + "root_testhttppostandhttpfetchcanpreformacalltoanapi_Handler_IamRolePolicy_B6CDFDB0": { + "//": { + "metadata": { + "path": "root/Default/Default/test:http.post and http.fetch can preform a call to an api/Handler/IamRolePolicy", + "uniqueId": "root_testhttppostandhttpfetchcanpreformacalltoanapi_Handler_IamRolePolicy_B6CDFDB0" + } + }, + "policy": "{\"Version\":\"2012-10-17\",\"Statement\":[{\"Effect\":\"Allow\",\"Action\":\"none:null\",\"Resource\":\"*\"}]}", + "role": "${aws_iam_role.root_testhttppostandhttpfetchcanpreformacalltoanapi_Handler_IamRole_C385115A.name}" + } + }, + "aws_iam_role_policy_attachment": { + "root_cloudApi_cloudApiOnRequestcdafee6e_IamRolePolicyAttachment_4A873879": { + "//": { + "metadata": { + "path": "root/Default/Default/cloud.Api/cloud.Api-OnRequest-cdafee6e/IamRolePolicyAttachment", + "uniqueId": "root_cloudApi_cloudApiOnRequestcdafee6e_IamRolePolicyAttachment_4A873879" + } + }, + "policy_arn": "arn:aws:iam::aws:policy/service-role/AWSLambdaBasicExecutionRole", + "role": "${aws_iam_role.root_cloudApi_cloudApiOnRequestcdafee6e_IamRole_2B8A04C3.name}" + }, + "root_testhttppostandhttpfetchcanpreformacalltoanapi_Handler_IamRolePolicyAttachment_581A9E7B": { + "//": { + "metadata": { + "path": "root/Default/Default/test:http.post and http.fetch can preform a call to an api/Handler/IamRolePolicyAttachment", + "uniqueId": "root_testhttppostandhttpfetchcanpreformacalltoanapi_Handler_IamRolePolicyAttachment_581A9E7B" + } + }, + "policy_arn": "arn:aws:iam::aws:policy/service-role/AWSLambdaBasicExecutionRole", + "role": "${aws_iam_role.root_testhttppostandhttpfetchcanpreformacalltoanapi_Handler_IamRole_C385115A.name}" + } + }, + "aws_lambda_function": { + "root_cloudApi_cloudApiOnRequestcdafee6e_582EA655": { + "//": { + "metadata": { + "path": "root/Default/Default/cloud.Api/cloud.Api-OnRequest-cdafee6e/Default", + "uniqueId": "root_cloudApi_cloudApiOnRequestcdafee6e_582EA655" + } + }, + "environment": { + "variables": { + "WING_FUNCTION_NAME": "cloud-Api-OnRequest-cdafee6e-c8147384", + "WING_TARGET": "tf-aws" + } + }, + "function_name": "cloud-Api-OnRequest-cdafee6e-c8147384", + "handler": "index.handler", + "publish": true, + "role": "${aws_iam_role.root_cloudApi_cloudApiOnRequestcdafee6e_IamRole_2B8A04C3.arn}", + "runtime": "nodejs18.x", + "s3_bucket": "${aws_s3_bucket.root_Code_02F3C603.bucket}", + "s3_key": "${aws_s3_object.root_cloudApi_cloudApiOnRequestcdafee6e_S3Object_AA762041.key}", + "timeout": 30, + "vpc_config": { + "security_group_ids": [], + "subnet_ids": [] + } + }, + "root_testhttppostandhttpfetchcanpreformacalltoanapi_Handler_918D65BA": { + "//": { + "metadata": { + "path": "root/Default/Default/test:http.post and http.fetch can preform a call to an api/Handler/Default", + "uniqueId": "root_testhttppostandhttpfetchcanpreformacalltoanapi_Handler_918D65BA" + } + }, + "environment": { + "variables": { + "CLOUD_API_C82DF3A5": "${aws_api_gateway_stage.root_cloudApi_api_stage_57D6284A.invoke_url}", + "WING_FUNCTION_NAME": "Handler-c88947b5", + "WING_TARGET": "tf-aws", + "WING_TOKEN_TFTOKEN_TOKEN_21": "${jsonencode(aws_api_gateway_stage.root_cloudApi_api_stage_57D6284A.invoke_url)}" + } + }, + "function_name": "Handler-c88947b5", + "handler": "index.handler", + "publish": true, + "role": "${aws_iam_role.root_testhttppostandhttpfetchcanpreformacalltoanapi_Handler_IamRole_C385115A.arn}", + "runtime": "nodejs18.x", + "s3_bucket": "${aws_s3_bucket.root_Code_02F3C603.bucket}", + "s3_key": "${aws_s3_object.root_testhttppostandhttpfetchcanpreformacalltoanapi_Handler_S3Object_96BCFB2A.key}", + "timeout": 30, + "vpc_config": { + "security_group_ids": [], + "subnet_ids": [] + } + } + }, + "aws_lambda_permission": { + "root_cloudApi_api_permissionPOSTe2131352_C8B2E17B": { + "//": { + "metadata": { + "path": "root/Default/Default/cloud.Api/api/permission-POST-e2131352", + "uniqueId": "root_cloudApi_api_permissionPOSTe2131352_C8B2E17B" + } + }, + "action": "lambda:InvokeFunction", + "function_name": "${aws_lambda_function.root_cloudApi_cloudApiOnRequestcdafee6e_582EA655.function_name}", + "principal": "apigateway.amazonaws.com", + "source_arn": "${aws_api_gateway_rest_api.root_cloudApi_api_8C9FE51E.execution_arn}/*/POST/path", + "statement_id": "AllowExecutionFromAPIGateway-POST-e2131352" + } + }, + "aws_s3_bucket": { + "root_Code_02F3C603": { + "//": { + "metadata": { + "path": "root/Default/Code", + "uniqueId": "root_Code_02F3C603" + } + }, + "bucket_prefix": "code-c84a50b1-" + } + }, + "aws_s3_object": { + "root_cloudApi_cloudApiOnRequestcdafee6e_S3Object_AA762041": { + "//": { + "metadata": { + "path": "root/Default/Default/cloud.Api/cloud.Api-OnRequest-cdafee6e/S3Object", + "uniqueId": "root_cloudApi_cloudApiOnRequestcdafee6e_S3Object_AA762041" + } + }, + "bucket": "${aws_s3_bucket.root_Code_02F3C603.bucket}", + "key": "", + "source": "" + }, + "root_testhttppostandhttpfetchcanpreformacalltoanapi_Handler_S3Object_96BCFB2A": { + "//": { + "metadata": { + "path": "root/Default/Default/test:http.post and http.fetch can preform a call to an api/Handler/S3Object", + "uniqueId": "root_testhttppostandhttpfetchcanpreformacalltoanapi_Handler_S3Object_96BCFB2A" + } + }, + "bucket": "${aws_s3_bucket.root_Code_02F3C603.bucket}", + "key": "", + "source": "" + } + } + } +} +``` + +## preflight.js +```js +const $stdlib = require('@winglang/sdk'); +const $outdir = process.env.WING_SYNTH_DIR ?? "."; +const std = $stdlib.std; +const $wing_is_test = process.env.WING_IS_TEST === "true"; +const $AppBase = $stdlib.core.App.for(process.env.WING_TARGET); +const cloud = require('@winglang/sdk').cloud; +const http = require('@winglang/sdk').http; +class $Root extends $stdlib.std.Resource { + constructor(scope, id) { + super(scope, id); + class $Closure1 extends $stdlib.std.Resource { + constructor(scope, id, ) { + super(scope, id); + this._addInflightOps("handle"); + this.display.hidden = true; + } + static _toInflightType(context) { + const self_client_path = "././inflight.$Closure1.js"; + const api_POST_client = context._lift(api_POST); + const body_client = context._lift(body); + const std_JsonClient = std.Json._toInflightType(context); + return $stdlib.core.NodeJsCode.fromInline(` + require("${self_client_path}")({ + api_POST: ${api_POST_client}, + body: ${body_client}, + std_Json: ${std_JsonClient.text}, + }) + `); + } + _toInflight() { + return $stdlib.core.NodeJsCode.fromInline(` + (await (async () => { + const $Closure1Client = ${$Closure1._toInflightType(this).text}; + const client = new $Closure1Client({ + }); + if (client.$inflight_init) { await client.$inflight_init(); } + return client; + })()) + `); + } + _registerBind(host, ops) { + if (ops.includes("$inflight_init")) { + $Closure1._registerBindObject(api_POST, host, []); + $Closure1._registerBindObject(body, host, []); + } + if (ops.includes("handle")) { + $Closure1._registerBindObject(api_POST, host, []); + $Closure1._registerBindObject(body, host, []); + } + super._registerBind(host, ops); + } + } + class $Closure2 extends $stdlib.std.Resource { + constructor(scope, id, ) { + super(scope, id); + this._addInflightOps("handle"); + this.display.hidden = true; + } + static _toInflightType(context) { + const self_client_path = "././inflight.$Closure2.js"; + const api_client = context._lift(api); + const body_client = context._lift(body); + const http_POST_client = context._lift(http_POST); + const http_UtilClient = http.Util._toInflightType(context); + const std_JsonClient = std.Json._toInflightType(context); + return $stdlib.core.NodeJsCode.fromInline(` + require("${self_client_path}")({ + api: ${api_client}, + body: ${body_client}, + http_POST: ${http_POST_client}, + http_Util: ${http_UtilClient.text}, + std_Json: ${std_JsonClient.text}, + }) + `); + } + _toInflight() { + return $stdlib.core.NodeJsCode.fromInline(` + (await (async () => { + const $Closure2Client = ${$Closure2._toInflightType(this).text}; + const client = new $Closure2Client({ + }); + if (client.$inflight_init) { await client.$inflight_init(); } + return client; + })()) + `); + } + _registerBind(host, ops) { + if (ops.includes("$inflight_init")) { + $Closure2._registerBindObject(api, host, []); + $Closure2._registerBindObject(body, host, []); + $Closure2._registerBindObject(http_POST, host, []); + } + if (ops.includes("handle")) { + $Closure2._registerBindObject(api.url, host, []); + $Closure2._registerBindObject(body, host, []); + $Closure2._registerBindObject(http_POST, host, []); + } + super._registerBind(host, ops); + } + } + const http_POST = http.HttpMethod.POST; + const api_POST = cloud.HttpMethod.POST; + const api = this.node.root.newAbstract("@winglang/sdk.cloud.Api",this,"cloud.Api"); + const body = Object.freeze({"cat":"Tion"}); + (api.post("/path",new $Closure1(this,"$Closure1"))); + this.node.root.new("@winglang/sdk.std.Test",std.Test,this,"test:http.post and http.fetch can preform a call to an api",new $Closure2(this,"$Closure2")); + } +} +class $App extends $AppBase { + constructor() { + super({ outdir: $outdir, name: "post", plugins: $plugins, isTestEnvironment: $wing_is_test }); + if ($wing_is_test) { + new $Root(this, "env0"); + const $test_runner = this.testRunner; + const $tests = $test_runner.findTests(); + for (let $i = 1; $i < $tests.length; $i++) { + new $Root(this, "env" + $i); + } + } else { + new $Root(this, "Default"); + } + } +} +new $App().synth(); + +``` + diff --git a/tools/hangar/__snapshots__/test_corpus/sdk_tests/api/post.w_test_sim.md b/tools/hangar/__snapshots__/test_corpus/sdk_tests/api/post.w_test_sim.md new file mode 100644 index 00000000000..6102bd1039a --- /dev/null +++ b/tools/hangar/__snapshots__/test_corpus/sdk_tests/api/post.w_test_sim.md @@ -0,0 +1,12 @@ +# [post.w](../../../../../../examples/tests/sdk_tests/api/post.w) | test | sim + +## stdout.log +```log +pass โ”€ post.wsim ยป root/env0/test:http.post and http.fetch can preform a call to an api + + +Tests 1 passed (1) +Test Files 1 passed (1) +Duration +``` + diff --git a/tools/hangar/__snapshots__/test_corpus/sdk_tests/api/put.w_compile_tf-aws.md b/tools/hangar/__snapshots__/test_corpus/sdk_tests/api/put.w_compile_tf-aws.md new file mode 100644 index 00000000000..1722c32aa60 --- /dev/null +++ b/tools/hangar/__snapshots__/test_corpus/sdk_tests/api/put.w_compile_tf-aws.md @@ -0,0 +1,472 @@ +# [put.w](../../../../../../examples/tests/sdk_tests/api/put.w) | compile | tf-aws + +## inflight.$Closure1.js +```js +module.exports = function({ _id, user, api_PUT, body, std_Json }) { + class $Closure1 { + constructor({ }) { + const $obj = (...args) => this.handle(...args); + Object.setPrototypeOf($obj, this); + return $obj; + } + async $inflight_init() { + } + async handle(req) { + const path = String.raw({ raw: ["/path/", "/nn/", ""] }, _id, user); + {((cond) => {if (!cond) throw new Error("assertion failed: req.method == api_PUT")})((req.method === api_PUT))}; + {((cond) => {if (!cond) throw new Error("assertion failed: req.vars?.get(\"id\") == _id")})(((req.vars)["id"] === _id))}; + {((cond) => {if (!cond) throw new Error("assertion failed: req.vars?.get(\"user\") == user")})(((req.vars)["user"] === user))}; + {((cond) => {if (!cond) throw new Error("assertion failed: req.path == path")})((req.path === path))}; + {((cond) => {if (!cond) throw new Error("assertion failed: req.body == Json.stringify(body)")})((req.body === ((args) => { return JSON.stringify(args[0], null, args[1]) })([body])))}; + {((cond) => {if (!cond) throw new Error("assertion failed: req.headers?.get(\"content-type\") == \"application/json\"")})(((req.headers)["content-type"] === "application/json"))}; + return { + "status": 200, + "body": (req.vars)["id"],} + ; + } + } + return $Closure1; +} + +``` + +## inflight.$Closure2.js +```js +module.exports = function({ api, _id, user, body, http_PUT, http_Util, std_Json }) { + class $Closure2 { + constructor({ }) { + const $obj = (...args) => this.handle(...args); + Object.setPrototypeOf($obj, this); + return $obj; + } + async $inflight_init() { + } + async handle() { + const url = String.raw({ raw: ["", "/path/", "/nn/", ""] }, api.url, _id, user); + const response = (await http_Util.put(url,{ + "headers": Object.freeze({"content-type":"application/json"}), + "body": ((args) => { return JSON.stringify(args[0], null, args[1]) })([body]),} + )); + const fetchResponse = (await http_Util.put(url,{ + "method": http_PUT, + "headers": Object.freeze({"content-type":"application/json"}), + "body": ((args) => { return JSON.stringify(args[0], null, args[1]) })([body]),} + )); + {((cond) => {if (!cond) throw new Error("assertion failed: response.body == _id")})((response.body === _id))}; + {((cond) => {if (!cond) throw new Error("assertion failed: response.status == 200")})((response.status === 200))}; + {((cond) => {if (!cond) throw new Error("assertion failed: response.url == url")})((response.url === url))}; + {((cond) => {if (!cond) throw new Error("assertion failed: fetchResponse.body == _id")})((fetchResponse.body === _id))}; + {((cond) => {if (!cond) throw new Error("assertion failed: fetchResponse.status == 200")})((fetchResponse.status === 200))}; + {((cond) => {if (!cond) throw new Error("assertion failed: fetchResponse.url == url")})((fetchResponse.url === url))}; + } + } + return $Closure2; +} + +``` + +## main.tf.json +```json +{ + "//": { + "metadata": { + "backend": "local", + "stackName": "root", + "version": "0.15.2" + }, + "outputs": { + "root": { + "Default": { + "cloud.TestRunner": { + "TestFunctionArns": "WING_TEST_RUNNER_FUNCTION_ARNS" + } + } + } + } + }, + "data": { + "aws_region": { + "root_Region_A2D17352": { + "//": { + "metadata": { + "path": "root/Default/Region", + "uniqueId": "root_Region_A2D17352" + } + } + } + } + }, + "output": { + "WING_TEST_RUNNER_FUNCTION_ARNS": { + "value": "[[\"root/Default/Default/test:http.put and http.fetch can preform a call to an api\",\"${aws_lambda_function.root_testhttpputandhttpfetchcanpreformacalltoanapi_Handler_D6DD411B.arn}\"]]" + } + }, + "provider": { + "aws": [ + {} + ] + }, + "resource": { + "aws_api_gateway_deployment": { + "root_cloudApi_api_deployment_E29F699A": { + "//": { + "metadata": { + "path": "root/Default/Default/cloud.Api/api/deployment", + "uniqueId": "root_cloudApi_api_deployment_E29F699A" + } + }, + "lifecycle": { + "create_before_destroy": true + }, + "rest_api_id": "${aws_api_gateway_rest_api.root_cloudApi_api_8C9FE51E.id}", + "triggers": { + "redeployment": "a67fe6988218a80a1321d2cf04424fe744273dd4" + } + } + }, + "aws_api_gateway_rest_api": { + "root_cloudApi_api_8C9FE51E": { + "//": { + "metadata": { + "path": "root/Default/Default/cloud.Api/api/api", + "uniqueId": "root_cloudApi_api_8C9FE51E" + } + }, + "body": "{\"openapi\":\"3.0.3\",\"paths\":{\"/path/{id}/nn/{user}\":{\"put\":{\"operationId\":\"put-path/{id}/nn/{user}\",\"responses\":{\"200\":{\"description\":\"200 response\",\"content\":{}}},\"parameters\":[{\"name\":\"id\",\"in\":\"path\",\"required\":true,\"schema\":{\"type\":\"string\"}},{\"name\":\"user\",\"in\":\"path\",\"required\":true,\"schema\":{\"type\":\"string\"}}],\"x-amazon-apigateway-integration\":{\"uri\":\"arn:aws:apigateway:${data.aws_region.root_Region_A2D17352.name}:lambda:path/2015-03-31/functions/${aws_lambda_function.root_cloudApi_cloudApiOnRequestcdafee6e_582EA655.arn}/invocations\",\"type\":\"aws_proxy\",\"httpMethod\":\"POST\",\"responses\":{\"default\":{\"statusCode\":\"200\"}},\"passthroughBehavior\":\"when_no_match\",\"contentHandling\":\"CONVERT_TO_TEXT\"}}}}}", + "name": "api-c895068c" + } + }, + "aws_api_gateway_stage": { + "root_cloudApi_api_stage_57D6284A": { + "//": { + "metadata": { + "path": "root/Default/Default/cloud.Api/api/stage", + "uniqueId": "root_cloudApi_api_stage_57D6284A" + } + }, + "deployment_id": "${aws_api_gateway_deployment.root_cloudApi_api_deployment_E29F699A.id}", + "rest_api_id": "${aws_api_gateway_rest_api.root_cloudApi_api_8C9FE51E.id}", + "stage_name": "prod" + } + }, + "aws_iam_role": { + "root_cloudApi_cloudApiOnRequestcdafee6e_IamRole_2B8A04C3": { + "//": { + "metadata": { + "path": "root/Default/Default/cloud.Api/cloud.Api-OnRequest-cdafee6e/IamRole", + "uniqueId": "root_cloudApi_cloudApiOnRequestcdafee6e_IamRole_2B8A04C3" + } + }, + "assume_role_policy": "{\"Version\":\"2012-10-17\",\"Statement\":[{\"Action\":\"sts:AssumeRole\",\"Principal\":{\"Service\":\"lambda.amazonaws.com\"},\"Effect\":\"Allow\"}]}" + }, + "root_testhttpputandhttpfetchcanpreformacalltoanapi_Handler_IamRole_613C5C88": { + "//": { + "metadata": { + "path": "root/Default/Default/test:http.put and http.fetch can preform a call to an api/Handler/IamRole", + "uniqueId": "root_testhttpputandhttpfetchcanpreformacalltoanapi_Handler_IamRole_613C5C88" + } + }, + "assume_role_policy": "{\"Version\":\"2012-10-17\",\"Statement\":[{\"Action\":\"sts:AssumeRole\",\"Principal\":{\"Service\":\"lambda.amazonaws.com\"},\"Effect\":\"Allow\"}]}" + } + }, + "aws_iam_role_policy": { + "root_cloudApi_cloudApiOnRequestcdafee6e_IamRolePolicy_E6B9BE66": { + "//": { + "metadata": { + "path": "root/Default/Default/cloud.Api/cloud.Api-OnRequest-cdafee6e/IamRolePolicy", + "uniqueId": "root_cloudApi_cloudApiOnRequestcdafee6e_IamRolePolicy_E6B9BE66" + } + }, + "policy": "{\"Version\":\"2012-10-17\",\"Statement\":[{\"Effect\":\"Allow\",\"Action\":\"none:null\",\"Resource\":\"*\"}]}", + "role": "${aws_iam_role.root_cloudApi_cloudApiOnRequestcdafee6e_IamRole_2B8A04C3.name}" + }, + "root_testhttpputandhttpfetchcanpreformacalltoanapi_Handler_IamRolePolicy_5A1B9B24": { + "//": { + "metadata": { + "path": "root/Default/Default/test:http.put and http.fetch can preform a call to an api/Handler/IamRolePolicy", + "uniqueId": "root_testhttpputandhttpfetchcanpreformacalltoanapi_Handler_IamRolePolicy_5A1B9B24" + } + }, + "policy": "{\"Version\":\"2012-10-17\",\"Statement\":[{\"Effect\":\"Allow\",\"Action\":\"none:null\",\"Resource\":\"*\"}]}", + "role": "${aws_iam_role.root_testhttpputandhttpfetchcanpreformacalltoanapi_Handler_IamRole_613C5C88.name}" + } + }, + "aws_iam_role_policy_attachment": { + "root_cloudApi_cloudApiOnRequestcdafee6e_IamRolePolicyAttachment_4A873879": { + "//": { + "metadata": { + "path": "root/Default/Default/cloud.Api/cloud.Api-OnRequest-cdafee6e/IamRolePolicyAttachment", + "uniqueId": "root_cloudApi_cloudApiOnRequestcdafee6e_IamRolePolicyAttachment_4A873879" + } + }, + "policy_arn": "arn:aws:iam::aws:policy/service-role/AWSLambdaBasicExecutionRole", + "role": "${aws_iam_role.root_cloudApi_cloudApiOnRequestcdafee6e_IamRole_2B8A04C3.name}" + }, + "root_testhttpputandhttpfetchcanpreformacalltoanapi_Handler_IamRolePolicyAttachment_61C9C7F7": { + "//": { + "metadata": { + "path": "root/Default/Default/test:http.put and http.fetch can preform a call to an api/Handler/IamRolePolicyAttachment", + "uniqueId": "root_testhttpputandhttpfetchcanpreformacalltoanapi_Handler_IamRolePolicyAttachment_61C9C7F7" + } + }, + "policy_arn": "arn:aws:iam::aws:policy/service-role/AWSLambdaBasicExecutionRole", + "role": "${aws_iam_role.root_testhttpputandhttpfetchcanpreformacalltoanapi_Handler_IamRole_613C5C88.name}" + } + }, + "aws_lambda_function": { + "root_cloudApi_cloudApiOnRequestcdafee6e_582EA655": { + "//": { + "metadata": { + "path": "root/Default/Default/cloud.Api/cloud.Api-OnRequest-cdafee6e/Default", + "uniqueId": "root_cloudApi_cloudApiOnRequestcdafee6e_582EA655" + } + }, + "environment": { + "variables": { + "WING_FUNCTION_NAME": "cloud-Api-OnRequest-cdafee6e-c8147384", + "WING_TARGET": "tf-aws" + } + }, + "function_name": "cloud-Api-OnRequest-cdafee6e-c8147384", + "handler": "index.handler", + "publish": true, + "role": "${aws_iam_role.root_cloudApi_cloudApiOnRequestcdafee6e_IamRole_2B8A04C3.arn}", + "runtime": "nodejs18.x", + "s3_bucket": "${aws_s3_bucket.root_Code_02F3C603.bucket}", + "s3_key": "${aws_s3_object.root_cloudApi_cloudApiOnRequestcdafee6e_S3Object_AA762041.key}", + "timeout": 30, + "vpc_config": { + "security_group_ids": [], + "subnet_ids": [] + } + }, + "root_testhttpputandhttpfetchcanpreformacalltoanapi_Handler_D6DD411B": { + "//": { + "metadata": { + "path": "root/Default/Default/test:http.put and http.fetch can preform a call to an api/Handler/Default", + "uniqueId": "root_testhttpputandhttpfetchcanpreformacalltoanapi_Handler_D6DD411B" + } + }, + "environment": { + "variables": { + "CLOUD_API_C82DF3A5": "${aws_api_gateway_stage.root_cloudApi_api_stage_57D6284A.invoke_url}", + "WING_FUNCTION_NAME": "Handler-c8e4b12f", + "WING_TARGET": "tf-aws", + "WING_TOKEN_TFTOKEN_TOKEN_21": "${jsonencode(aws_api_gateway_stage.root_cloudApi_api_stage_57D6284A.invoke_url)}" + } + }, + "function_name": "Handler-c8e4b12f", + "handler": "index.handler", + "publish": true, + "role": "${aws_iam_role.root_testhttpputandhttpfetchcanpreformacalltoanapi_Handler_IamRole_613C5C88.arn}", + "runtime": "nodejs18.x", + "s3_bucket": "${aws_s3_bucket.root_Code_02F3C603.bucket}", + "s3_key": "${aws_s3_object.root_testhttpputandhttpfetchcanpreformacalltoanapi_Handler_S3Object_824D58B7.key}", + "timeout": 30, + "vpc_config": { + "security_group_ids": [], + "subnet_ids": [] + } + } + }, + "aws_lambda_permission": { + "root_cloudApi_api_permissionPUTdcff9e9b_98D846ED": { + "//": { + "metadata": { + "path": "root/Default/Default/cloud.Api/api/permission-PUT-dcff9e9b", + "uniqueId": "root_cloudApi_api_permissionPUTdcff9e9b_98D846ED" + } + }, + "action": "lambda:InvokeFunction", + "function_name": "${aws_lambda_function.root_cloudApi_cloudApiOnRequestcdafee6e_582EA655.function_name}", + "principal": "apigateway.amazonaws.com", + "source_arn": "${aws_api_gateway_rest_api.root_cloudApi_api_8C9FE51E.execution_arn}/*/PUT/path/{id}/nn/{user}", + "statement_id": "AllowExecutionFromAPIGateway-PUT-dcff9e9b" + } + }, + "aws_s3_bucket": { + "root_Code_02F3C603": { + "//": { + "metadata": { + "path": "root/Default/Code", + "uniqueId": "root_Code_02F3C603" + } + }, + "bucket_prefix": "code-c84a50b1-" + } + }, + "aws_s3_object": { + "root_cloudApi_cloudApiOnRequestcdafee6e_S3Object_AA762041": { + "//": { + "metadata": { + "path": "root/Default/Default/cloud.Api/cloud.Api-OnRequest-cdafee6e/S3Object", + "uniqueId": "root_cloudApi_cloudApiOnRequestcdafee6e_S3Object_AA762041" + } + }, + "bucket": "${aws_s3_bucket.root_Code_02F3C603.bucket}", + "key": "", + "source": "" + }, + "root_testhttpputandhttpfetchcanpreformacalltoanapi_Handler_S3Object_824D58B7": { + "//": { + "metadata": { + "path": "root/Default/Default/test:http.put and http.fetch can preform a call to an api/Handler/S3Object", + "uniqueId": "root_testhttpputandhttpfetchcanpreformacalltoanapi_Handler_S3Object_824D58B7" + } + }, + "bucket": "${aws_s3_bucket.root_Code_02F3C603.bucket}", + "key": "", + "source": "" + } + } + } +} +``` + +## preflight.js +```js +const $stdlib = require('@winglang/sdk'); +const $outdir = process.env.WING_SYNTH_DIR ?? "."; +const std = $stdlib.std; +const $wing_is_test = process.env.WING_IS_TEST === "true"; +const $AppBase = $stdlib.core.App.for(process.env.WING_TARGET); +const cloud = require('@winglang/sdk').cloud; +const http = require('@winglang/sdk').http; +class $Root extends $stdlib.std.Resource { + constructor(scope, id) { + super(scope, id); + class $Closure1 extends $stdlib.std.Resource { + constructor(scope, id, ) { + super(scope, id); + this._addInflightOps("handle"); + this.display.hidden = true; + } + static _toInflightType(context) { + const self_client_path = "././inflight.$Closure1.js"; + const _id_client = context._lift(_id); + const user_client = context._lift(user); + const api_PUT_client = context._lift(api_PUT); + const body_client = context._lift(body); + const std_JsonClient = std.Json._toInflightType(context); + return $stdlib.core.NodeJsCode.fromInline(` + require("${self_client_path}")({ + _id: ${_id_client}, + user: ${user_client}, + api_PUT: ${api_PUT_client}, + body: ${body_client}, + std_Json: ${std_JsonClient.text}, + }) + `); + } + _toInflight() { + return $stdlib.core.NodeJsCode.fromInline(` + (await (async () => { + const $Closure1Client = ${$Closure1._toInflightType(this).text}; + const client = new $Closure1Client({ + }); + if (client.$inflight_init) { await client.$inflight_init(); } + return client; + })()) + `); + } + _registerBind(host, ops) { + if (ops.includes("$inflight_init")) { + $Closure1._registerBindObject(_id, host, []); + $Closure1._registerBindObject(api_PUT, host, []); + $Closure1._registerBindObject(body, host, []); + $Closure1._registerBindObject(user, host, []); + } + if (ops.includes("handle")) { + $Closure1._registerBindObject(_id, host, []); + $Closure1._registerBindObject(api_PUT, host, []); + $Closure1._registerBindObject(body, host, []); + $Closure1._registerBindObject(user, host, []); + } + super._registerBind(host, ops); + } + } + class $Closure2 extends $stdlib.std.Resource { + constructor(scope, id, ) { + super(scope, id); + this._addInflightOps("handle"); + this.display.hidden = true; + } + static _toInflightType(context) { + const self_client_path = "././inflight.$Closure2.js"; + const api_client = context._lift(api); + const _id_client = context._lift(_id); + const user_client = context._lift(user); + const body_client = context._lift(body); + const http_PUT_client = context._lift(http_PUT); + const http_UtilClient = http.Util._toInflightType(context); + const std_JsonClient = std.Json._toInflightType(context); + return $stdlib.core.NodeJsCode.fromInline(` + require("${self_client_path}")({ + api: ${api_client}, + _id: ${_id_client}, + user: ${user_client}, + body: ${body_client}, + http_PUT: ${http_PUT_client}, + http_Util: ${http_UtilClient.text}, + std_Json: ${std_JsonClient.text}, + }) + `); + } + _toInflight() { + return $stdlib.core.NodeJsCode.fromInline(` + (await (async () => { + const $Closure2Client = ${$Closure2._toInflightType(this).text}; + const client = new $Closure2Client({ + }); + if (client.$inflight_init) { await client.$inflight_init(); } + return client; + })()) + `); + } + _registerBind(host, ops) { + if (ops.includes("$inflight_init")) { + $Closure2._registerBindObject(_id, host, []); + $Closure2._registerBindObject(api, host, []); + $Closure2._registerBindObject(body, host, []); + $Closure2._registerBindObject(http_PUT, host, []); + $Closure2._registerBindObject(user, host, []); + } + if (ops.includes("handle")) { + $Closure2._registerBindObject(_id, host, []); + $Closure2._registerBindObject(api.url, host, []); + $Closure2._registerBindObject(body, host, []); + $Closure2._registerBindObject(http_PUT, host, []); + $Closure2._registerBindObject(user, host, []); + } + super._registerBind(host, ops); + } + } + const http_PUT = http.HttpMethod.PUT; + const api_PUT = cloud.HttpMethod.PUT; + const api = this.node.root.newAbstract("@winglang/sdk.cloud.Api",this,"cloud.Api"); + const body = Object.freeze({"cat":"Tion"}); + const user = "guy"; + const _id = "12345"; + (api.put("/path/{id}/nn/{user}",new $Closure1(this,"$Closure1"))); + this.node.root.new("@winglang/sdk.std.Test",std.Test,this,"test:http.put and http.fetch can preform a call to an api",new $Closure2(this,"$Closure2")); + } +} +class $App extends $AppBase { + constructor() { + super({ outdir: $outdir, name: "put", plugins: $plugins, isTestEnvironment: $wing_is_test }); + if ($wing_is_test) { + new $Root(this, "env0"); + const $test_runner = this.testRunner; + const $tests = $test_runner.findTests(); + for (let $i = 1; $i < $tests.length; $i++) { + new $Root(this, "env" + $i); + } + } else { + new $Root(this, "Default"); + } + } +} +new $App().synth(); + +``` + diff --git a/tools/hangar/__snapshots__/test_corpus/sdk_tests/api/put.w_test_sim.md b/tools/hangar/__snapshots__/test_corpus/sdk_tests/api/put.w_test_sim.md new file mode 100644 index 00000000000..a0377e5d3a5 --- /dev/null +++ b/tools/hangar/__snapshots__/test_corpus/sdk_tests/api/put.w_test_sim.md @@ -0,0 +1,12 @@ +# [put.w](../../../../../../examples/tests/sdk_tests/api/put.w) | test | sim + +## stdout.log +```log +pass โ”€ put.wsim ยป root/env0/test:http.put and http.fetch can preform a call to an api + + +Tests 1 passed (1) +Test Files 1 passed (1) +Duration +``` + diff --git a/tools/hangar/__snapshots__/test_corpus/sdk_tests/bucket/add_object.w_compile_tf-aws.md b/tools/hangar/__snapshots__/test_corpus/sdk_tests/bucket/add_object.w_compile_tf-aws.md index c2142005d0c..cb8dd03c1b9 100644 --- a/tools/hangar/__snapshots__/test_corpus/sdk_tests/bucket/add_object.w_compile_tf-aws.md +++ b/tools/hangar/__snapshots__/test_corpus/sdk_tests/bucket/add_object.w_compile_tf-aws.md @@ -12,9 +12,9 @@ module.exports = function({ b, jsonObj1, std_Json }) { async $inflight_init() { } async handle() { - {((cond) => {if (!cond) throw new Error(`assertion failed: '((await b.list()).length === 2)'`)})(((await b.list()).length === 2))}; - {((cond) => {if (!cond) throw new Error(`assertion failed: '(((args) => { return JSON.stringify(args[0], null, args[1]) })([(await b.getJson("file1.json"))]) === ((args) => { return JSON.stringify(args[0], null, args[1]) })([jsonObj1]))'`)})((((args) => { return JSON.stringify(args[0], null, args[1]) })([(await b.getJson("file1.json"))]) === ((args) => { return JSON.stringify(args[0], null, args[1]) })([jsonObj1])))}; - {((cond) => {if (!cond) throw new Error(`assertion failed: '((await b.get("file2.txt")) === "Bar")'`)})(((await b.get("file2.txt")) === "Bar"))}; + {((cond) => {if (!cond) throw new Error("assertion failed: b.list().length == 2")})(((await b.list()).length === 2))}; + {((cond) => {if (!cond) throw new Error("assertion failed: Json.stringify(b.getJson(\"file1.json\")) == Json.stringify(jsonObj1)")})((((args) => { return JSON.stringify(args[0], null, args[1]) })([(await b.getJson("file1.json"))]) === ((args) => { return JSON.stringify(args[0], null, args[1]) })([jsonObj1])))}; + {((cond) => {if (!cond) throw new Error("assertion failed: b.get(\"file2.txt\") == \"Bar\"")})(((await b.get("file2.txt")) === "Bar"))}; } } return $Closure1; diff --git a/tools/hangar/__snapshots__/test_corpus/sdk_tests/bucket/add_object.w_test_sim.md b/tools/hangar/__snapshots__/test_corpus/sdk_tests/bucket/add_object.w_test_sim.md index 860a979ed2b..f0f63c02ac9 100644 --- a/tools/hangar/__snapshots__/test_corpus/sdk_tests/bucket/add_object.w_test_sim.md +++ b/tools/hangar/__snapshots__/test_corpus/sdk_tests/bucket/add_object.w_test_sim.md @@ -4,12 +4,9 @@ ```log pass โ”€ add_object.wsim ยป root/env0/test:addObject - - - - -Tests 1 passed (1) + +Tests 1 passed (1) +Test Files 1 passed (1) Duration - ``` diff --git a/tools/hangar/__snapshots__/test_corpus/sdk_tests/bucket/bucket_list.w_compile_tf-aws.md b/tools/hangar/__snapshots__/test_corpus/sdk_tests/bucket/bucket_list.w_compile_tf-aws.md index 13ea7d684b9..f834f35986b 100644 --- a/tools/hangar/__snapshots__/test_corpus/sdk_tests/bucket/bucket_list.w_compile_tf-aws.md +++ b/tools/hangar/__snapshots__/test_corpus/sdk_tests/bucket/bucket_list.w_compile_tf-aws.md @@ -13,22 +13,22 @@ module.exports = function({ b }) { } async handle() { const jsonObj1 = Object.freeze({"key1":"value1"}); - {((cond) => {if (!cond) throw new Error(`assertion failed: '((await b.list()).length === 1)'`)})(((await b.list()).length === 1))}; + {((cond) => {if (!cond) throw new Error("assertion failed: b.list().length == 1")})(((await b.list()).length === 1))}; (await b.putJson("file1.json",jsonObj1)); (await b.put("file2.txt","Bar")); (await b.put("random","Buz")); const objs = (await b.list()); const objs2 = (await b.list("file")); - {((cond) => {if (!cond) throw new Error(`assertion failed: 'objs.includes("file1.json")'`)})(objs.includes("file1.json"))}; - {((cond) => {if (!cond) throw new Error(`assertion failed: 'objs.includes("file2.txt")'`)})(objs.includes("file2.txt"))}; - {((cond) => {if (!cond) throw new Error(`assertion failed: 'objs.includes("file3.txt")'`)})(objs.includes("file3.txt"))}; - {((cond) => {if (!cond) throw new Error(`assertion failed: 'objs.includes("random")'`)})(objs.includes("random"))}; - {((cond) => {if (!cond) throw new Error(`assertion failed: 'objs2.includes("file1.json")'`)})(objs2.includes("file1.json"))}; - {((cond) => {if (!cond) throw new Error(`assertion failed: 'objs2.includes("file2.txt")'`)})(objs2.includes("file2.txt"))}; - {((cond) => {if (!cond) throw new Error(`assertion failed: 'objs2.includes("file3.txt")'`)})(objs2.includes("file3.txt"))}; - {((cond) => {if (!cond) throw new Error(`assertion failed: '(!objs2.includes("random"))'`)})((!objs2.includes("random")))}; - {((cond) => {if (!cond) throw new Error(`assertion failed: '(objs.length === 4)'`)})((objs.length === 4))}; - {((cond) => {if (!cond) throw new Error(`assertion failed: '(objs2.length === 3)'`)})((objs2.length === 3))}; + {((cond) => {if (!cond) throw new Error("assertion failed: objs.contains(\"file1.json\")")})(objs.includes("file1.json"))}; + {((cond) => {if (!cond) throw new Error("assertion failed: objs.contains(\"file2.txt\")")})(objs.includes("file2.txt"))}; + {((cond) => {if (!cond) throw new Error("assertion failed: objs.contains(\"file3.txt\")")})(objs.includes("file3.txt"))}; + {((cond) => {if (!cond) throw new Error("assertion failed: objs.contains(\"random\")")})(objs.includes("random"))}; + {((cond) => {if (!cond) throw new Error("assertion failed: objs2.contains(\"file1.json\")")})(objs2.includes("file1.json"))}; + {((cond) => {if (!cond) throw new Error("assertion failed: objs2.contains(\"file2.txt\")")})(objs2.includes("file2.txt"))}; + {((cond) => {if (!cond) throw new Error("assertion failed: objs2.contains(\"file3.txt\")")})(objs2.includes("file3.txt"))}; + {((cond) => {if (!cond) throw new Error("assertion failed: !objs2.contains(\"random\")")})((!objs2.includes("random")))}; + {((cond) => {if (!cond) throw new Error("assertion failed: objs.length == 4")})((objs.length === 4))}; + {((cond) => {if (!cond) throw new Error("assertion failed: objs2.length == 3")})((objs2.length === 3))}; } } return $Closure1; diff --git a/tools/hangar/__snapshots__/test_corpus/sdk_tests/bucket/bucket_list.w_test_sim.md b/tools/hangar/__snapshots__/test_corpus/sdk_tests/bucket/bucket_list.w_test_sim.md index 8ee0ed5f7df..6d0f90a8896 100644 --- a/tools/hangar/__snapshots__/test_corpus/sdk_tests/bucket/bucket_list.w_test_sim.md +++ b/tools/hangar/__snapshots__/test_corpus/sdk_tests/bucket/bucket_list.w_test_sim.md @@ -4,12 +4,9 @@ ```log pass โ”€ bucket_list.wsim ยป root/env0/test:list - - - - -Tests 1 passed (1) + +Tests 1 passed (1) +Test Files 1 passed (1) Duration - ``` diff --git a/tools/hangar/__snapshots__/test_corpus/sdk_tests/bucket/delete.w_compile_tf-aws.md b/tools/hangar/__snapshots__/test_corpus/sdk_tests/bucket/delete.w_compile_tf-aws.md index 74e4362bb38..4f9d13c9dd9 100644 --- a/tools/hangar/__snapshots__/test_corpus/sdk_tests/bucket/delete.w_compile_tf-aws.md +++ b/tools/hangar/__snapshots__/test_corpus/sdk_tests/bucket/delete.w_compile_tf-aws.md @@ -16,8 +16,8 @@ module.exports = function({ b }) { const jsonObj1 = Object.freeze({"key1":"value1"}); (await b.putJson("file1.json",jsonObj1)); (await b.delete("file1.txt")); - {((cond) => {if (!cond) throw new Error(`assertion failed: '(await b.exists("file1.json"))'`)})((await b.exists("file1.json")))}; - {((cond) => {if (!cond) throw new Error(`assertion failed: '(await b.exists("file2.txt"))'`)})((await b.exists("file2.txt")))}; + {((cond) => {if (!cond) throw new Error("assertion failed: b.exists(\"file1.json\")")})((await b.exists("file1.json")))}; + {((cond) => {if (!cond) throw new Error("assertion failed: b.exists(\"file2.txt\")")})((await b.exists("file2.txt")))}; (await b.delete("file1.json",Object.freeze({"mustExist":true}))); try { (await b.delete("file1.json",Object.freeze({"mustExist":true}))); @@ -26,10 +26,10 @@ module.exports = function({ b }) { const e = $error_e.message; error = e; } - {((cond) => {if (!cond) throw new Error(`assertion failed: '(error === "Object does not exist (key=file1.json).")'`)})((error === "Object does not exist (key=file1.json)."))}; - {((cond) => {if (!cond) throw new Error(`assertion failed: '(await b.exists("file2.txt"))'`)})((await b.exists("file2.txt")))}; + {((cond) => {if (!cond) throw new Error("assertion failed: error == \"Object does not exist (key=file1.json).\"")})((error === "Object does not exist (key=file1.json)."))}; + {((cond) => {if (!cond) throw new Error("assertion failed: b.exists(\"file2.txt\")")})((await b.exists("file2.txt")))}; (await b.delete("file2.txt")); - {((cond) => {if (!cond) throw new Error(`assertion failed: '(!(await b.exists("file2.txt")))'`)})((!(await b.exists("file2.txt"))))}; + {((cond) => {if (!cond) throw new Error("assertion failed: !b.exists(\"file2.txt\")")})((!(await b.exists("file2.txt"))))}; } } return $Closure1; diff --git a/tools/hangar/__snapshots__/test_corpus/sdk_tests/bucket/delete.w_test_sim.md b/tools/hangar/__snapshots__/test_corpus/sdk_tests/bucket/delete.w_test_sim.md index 64bb711e2ea..98a7dd4cd87 100644 --- a/tools/hangar/__snapshots__/test_corpus/sdk_tests/bucket/delete.w_test_sim.md +++ b/tools/hangar/__snapshots__/test_corpus/sdk_tests/bucket/delete.w_test_sim.md @@ -4,12 +4,9 @@ ```log pass โ”€ delete.wsim ยป root/env0/test:delete - - - - -Tests 1 passed (1) + +Tests 1 passed (1) +Test Files 1 passed (1) Duration - ``` diff --git a/tools/hangar/__snapshots__/test_corpus/sdk_tests/bucket/events.w_compile_tf-aws.md b/tools/hangar/__snapshots__/test_corpus/sdk_tests/bucket/events.w_compile_tf-aws.md index e7af1f036b4..a69a5e4f4c9 100644 --- a/tools/hangar/__snapshots__/test_corpus/sdk_tests/bucket/events.w_compile_tf-aws.md +++ b/tools/hangar/__snapshots__/test_corpus/sdk_tests/bucket/events.w_compile_tf-aws.md @@ -12,7 +12,7 @@ module.exports = function({ table, idsCounter }) { async $inflight_init() { } async handle(key, operation, source) { - (await table.insert(`${(await idsCounter.inc())}`,Object.freeze({"key":key,"operation":operation,"source":`${source}`}))); + (await table.insert(String.raw({ raw: ["", ""] }, (await idsCounter.inc())),Object.freeze({"key":key,"operation":operation,"source":String.raw({ raw: ["", ""] }, source)}))); } } return $Closure1; @@ -92,7 +92,7 @@ module.exports = function({ logHistory, Source }) { async $inflight_init() { } async handle(key, event) { - (await logHistory(key,`${event}`,Source.onEvent)); + (await logHistory(key,String.raw({ raw: ["", ""] }, event),Source.onEvent)); } } return $Closure5; @@ -143,7 +143,7 @@ module.exports = function({ table }) { return async () => { let count = 0; for (const u of (await table.list())) { - if (((((u)["key"] === opts.key) && ((u)["operation"] === opts.type)) && ((u)["source"] === `${opts.source}`))) { + if (((((u)["key"] === opts.key) && ((u)["operation"] === opts.type)) && ((u)["source"] === String.raw({ raw: ["", ""] }, opts.source)))) { count = (count + 1); } } @@ -174,16 +174,16 @@ module.exports = function({ b, wait, checkHitCount, Source }) { (await b.put("c","1")); (await b.put("b","100")); (await b.delete("c")); - {((cond) => {if (!cond) throw new Error(`assertion failed: '(await wait((await checkHitCount({ key: "a", type: "CREATE", source: Source.anyEvent, count: 1 }))))'`)})((await wait((await checkHitCount({ key: "a", type: "CREATE", source: Source.anyEvent, count: 1 })))))}; - {((cond) => {if (!cond) throw new Error(`assertion failed: '(await wait((await checkHitCount({ key: "b", type: "CREATE", source: Source.anyEvent, count: 1 }))))'`)})((await wait((await checkHitCount({ key: "b", type: "CREATE", source: Source.anyEvent, count: 1 })))))}; - {((cond) => {if (!cond) throw new Error(`assertion failed: '(await wait((await checkHitCount({ key: "c", type: "CREATE", source: Source.anyEvent, count: 1 }))))'`)})((await wait((await checkHitCount({ key: "c", type: "CREATE", source: Source.anyEvent, count: 1 })))))}; - {((cond) => {if (!cond) throw new Error(`assertion failed: '(await wait((await checkHitCount({ key: "a", type: "CREATE", source: Source.onEvent, count: 1 }))))'`)})((await wait((await checkHitCount({ key: "a", type: "CREATE", source: Source.onEvent, count: 1 })))))}; - {((cond) => {if (!cond) throw new Error(`assertion failed: '(await wait((await checkHitCount({ key: "b", type: "CREATE", source: Source.onEvent, count: 1 }))))'`)})((await wait((await checkHitCount({ key: "b", type: "CREATE", source: Source.onEvent, count: 1 })))))}; - {((cond) => {if (!cond) throw new Error(`assertion failed: '(await wait((await checkHitCount({ key: "c", type: "CREATE", source: Source.onEvent, count: 1 }))))'`)})((await wait((await checkHitCount({ key: "c", type: "CREATE", source: Source.onEvent, count: 1 })))))}; - {((cond) => {if (!cond) throw new Error(`assertion failed: '(await wait((await checkHitCount({ key: "b", type: "UPDATE", source: Source.anyEvent, count: 1 }))))'`)})((await wait((await checkHitCount({ key: "b", type: "UPDATE", source: Source.anyEvent, count: 1 })))))}; - {((cond) => {if (!cond) throw new Error(`assertion failed: '(await wait((await checkHitCount({ key: "c", type: "DELETE", source: Source.anyEvent, count: 1 }))))'`)})((await wait((await checkHitCount({ key: "c", type: "DELETE", source: Source.anyEvent, count: 1 })))))}; - {((cond) => {if (!cond) throw new Error(`assertion failed: '(await wait((await checkHitCount({ key: "b", type: "UPDATE", source: Source.onEvent, count: 1 }))))'`)})((await wait((await checkHitCount({ key: "b", type: "UPDATE", source: Source.onEvent, count: 1 })))))}; - {((cond) => {if (!cond) throw new Error(`assertion failed: '(await wait((await checkHitCount({ key: "c", type: "DELETE", source: Source.onEvent, count: 1 }))))'`)})((await wait((await checkHitCount({ key: "c", type: "DELETE", source: Source.onEvent, count: 1 })))))}; + {((cond) => {if (!cond) throw new Error("assertion failed: wait(checkHitCount(key: \"a\", type: \"CREATE\", source: Source.anyEvent, count: 1))")})((await wait((await checkHitCount({ key: "a", type: "CREATE", source: Source.anyEvent, count: 1 })))))}; + {((cond) => {if (!cond) throw new Error("assertion failed: wait(checkHitCount(key: \"b\", type: \"CREATE\", source: Source.anyEvent, count: 1))")})((await wait((await checkHitCount({ key: "b", type: "CREATE", source: Source.anyEvent, count: 1 })))))}; + {((cond) => {if (!cond) throw new Error("assertion failed: wait(checkHitCount(key: \"c\", type: \"CREATE\", source: Source.anyEvent, count: 1))")})((await wait((await checkHitCount({ key: "c", type: "CREATE", source: Source.anyEvent, count: 1 })))))}; + {((cond) => {if (!cond) throw new Error("assertion failed: wait(checkHitCount(key: \"a\", type: \"CREATE\", source: Source.onEvent, count: 1))")})((await wait((await checkHitCount({ key: "a", type: "CREATE", source: Source.onEvent, count: 1 })))))}; + {((cond) => {if (!cond) throw new Error("assertion failed: wait(checkHitCount(key: \"b\", type: \"CREATE\", source: Source.onEvent, count: 1))")})((await wait((await checkHitCount({ key: "b", type: "CREATE", source: Source.onEvent, count: 1 })))))}; + {((cond) => {if (!cond) throw new Error("assertion failed: wait(checkHitCount(key: \"c\", type: \"CREATE\", source: Source.onEvent, count: 1))")})((await wait((await checkHitCount({ key: "c", type: "CREATE", source: Source.onEvent, count: 1 })))))}; + {((cond) => {if (!cond) throw new Error("assertion failed: wait(checkHitCount(key: \"b\", type: \"UPDATE\", source: Source.anyEvent, count: 1))")})((await wait((await checkHitCount({ key: "b", type: "UPDATE", source: Source.anyEvent, count: 1 })))))}; + {((cond) => {if (!cond) throw new Error("assertion failed: wait(checkHitCount(key: \"c\", type: \"DELETE\", source: Source.anyEvent, count: 1))")})((await wait((await checkHitCount({ key: "c", type: "DELETE", source: Source.anyEvent, count: 1 })))))}; + {((cond) => {if (!cond) throw new Error("assertion failed: wait(checkHitCount(key: \"b\", type: \"UPDATE\", source: Source.onEvent, count: 1))")})((await wait((await checkHitCount({ key: "b", type: "UPDATE", source: Source.onEvent, count: 1 })))))}; + {((cond) => {if (!cond) throw new Error("assertion failed: wait(checkHitCount(key: \"c\", type: \"DELETE\", source: Source.onEvent, count: 1))")})((await wait((await checkHitCount({ key: "c", type: "DELETE", source: Source.onEvent, count: 1 })))))}; } } return $Closure8; diff --git a/tools/hangar/__snapshots__/test_corpus/sdk_tests/bucket/events.w_test_sim.md b/tools/hangar/__snapshots__/test_corpus/sdk_tests/bucket/events.w_test_sim.md index 4e6c42600e6..f1b5254d10d 100644 --- a/tools/hangar/__snapshots__/test_corpus/sdk_tests/bucket/events.w_test_sim.md +++ b/tools/hangar/__snapshots__/test_corpus/sdk_tests/bucket/events.w_test_sim.md @@ -4,12 +4,9 @@ ```log pass โ”€ events.wsim ยป root/env0/hitCount is incremented according to the bucket event - - - - -Tests 1 passed (1) + +Tests 1 passed (1) +Test Files 1 passed (1) Duration - ``` diff --git a/tools/hangar/__snapshots__/test_corpus/sdk_tests/bucket/exists.w_compile_tf-aws.md b/tools/hangar/__snapshots__/test_corpus/sdk_tests/bucket/exists.w_compile_tf-aws.md index a2926e54115..ba6991e56e4 100644 --- a/tools/hangar/__snapshots__/test_corpus/sdk_tests/bucket/exists.w_compile_tf-aws.md +++ b/tools/hangar/__snapshots__/test_corpus/sdk_tests/bucket/exists.w_compile_tf-aws.md @@ -13,12 +13,12 @@ module.exports = function({ b }) { } async handle() { (await b.put("test1.txt","Foo")); - {((cond) => {if (!cond) throw new Error(`assertion failed: '(await b.exists("test1.txt"))'`)})((await b.exists("test1.txt")))}; - {((cond) => {if (!cond) throw new Error(`assertion failed: '(!(await b.exists("test2.txt")))'`)})((!(await b.exists("test2.txt"))))}; + {((cond) => {if (!cond) throw new Error("assertion failed: b.exists(\"test1.txt\")")})((await b.exists("test1.txt")))}; + {((cond) => {if (!cond) throw new Error("assertion failed: !b.exists(\"test2.txt\")")})((!(await b.exists("test2.txt"))))}; (await b.put("test2.txt","Bar")); - {((cond) => {if (!cond) throw new Error(`assertion failed: '(await b.exists("test2.txt"))'`)})((await b.exists("test2.txt")))}; + {((cond) => {if (!cond) throw new Error("assertion failed: b.exists(\"test2.txt\")")})((await b.exists("test2.txt")))}; (await b.delete("test1.txt")); - {((cond) => {if (!cond) throw new Error(`assertion failed: '(!(await b.exists("test1.txt")))'`)})((!(await b.exists("test1.txt"))))}; + {((cond) => {if (!cond) throw new Error("assertion failed: !b.exists(\"test1.txt\")")})((!(await b.exists("test1.txt"))))}; } } return $Closure1; diff --git a/tools/hangar/__snapshots__/test_corpus/sdk_tests/bucket/exists.w_test_sim.md b/tools/hangar/__snapshots__/test_corpus/sdk_tests/bucket/exists.w_test_sim.md index e8b07a952ae..bb6ab9a048f 100644 --- a/tools/hangar/__snapshots__/test_corpus/sdk_tests/bucket/exists.w_test_sim.md +++ b/tools/hangar/__snapshots__/test_corpus/sdk_tests/bucket/exists.w_test_sim.md @@ -4,12 +4,9 @@ ```log pass โ”€ exists.wsim ยป root/env0/test:exists - - - - -Tests 1 passed (1) + +Tests 1 passed (1) +Test Files 1 passed (1) Duration - ``` diff --git a/tools/hangar/__snapshots__/test_corpus/sdk_tests/bucket/public_url.w_compile_tf-aws.md b/tools/hangar/__snapshots__/test_corpus/sdk_tests/bucket/public_url.w_compile_tf-aws.md index 14ee94ca5bc..5d663a60c58 100644 --- a/tools/hangar/__snapshots__/test_corpus/sdk_tests/bucket/public_url.w_compile_tf-aws.md +++ b/tools/hangar/__snapshots__/test_corpus/sdk_tests/bucket/public_url.w_compile_tf-aws.md @@ -15,7 +15,7 @@ module.exports = function({ publicBucket, privateBucket }) { let error = ""; (await publicBucket.put("file1.txt","Foo")); (await privateBucket.put("file2.txt","Bar")); - {((cond) => {if (!cond) throw new Error(`assertion failed: '((await publicBucket.publicUrl("file1.txt")) !== "")'`)})(((await publicBucket.publicUrl("file1.txt")) !== ""))}; + {((cond) => {if (!cond) throw new Error("assertion failed: publicBucket.publicUrl(\"file1.txt\") != \"\"")})(((await publicBucket.publicUrl("file1.txt")) !== ""))}; try { (await privateBucket.publicUrl("file2.txt")); } @@ -23,7 +23,7 @@ module.exports = function({ publicBucket, privateBucket }) { const e = $error_e.message; error = e; } - {((cond) => {if (!cond) throw new Error(`assertion failed: '(error === "Cannot provide public url for a non-public bucket")'`)})((error === "Cannot provide public url for a non-public bucket"))}; + {((cond) => {if (!cond) throw new Error("assertion failed: error == \"Cannot provide public url for a non-public bucket\"")})((error === "Cannot provide public url for a non-public bucket"))}; } } return $Closure1; diff --git a/tools/hangar/__snapshots__/test_corpus/sdk_tests/bucket/public_url.w_test_sim.md b/tools/hangar/__snapshots__/test_corpus/sdk_tests/bucket/public_url.w_test_sim.md index a594d08eb29..d4db06f0a78 100644 --- a/tools/hangar/__snapshots__/test_corpus/sdk_tests/bucket/public_url.w_test_sim.md +++ b/tools/hangar/__snapshots__/test_corpus/sdk_tests/bucket/public_url.w_test_sim.md @@ -4,12 +4,9 @@ ```log pass โ”€ public_url.wsim ยป root/env0/test:publicUrl - - - - -Tests 1 passed (1) + +Tests 1 passed (1) +Test Files 1 passed (1) Duration - ``` diff --git a/tools/hangar/__snapshots__/test_corpus/sdk_tests/bucket/put.w_compile_tf-aws.md b/tools/hangar/__snapshots__/test_corpus/sdk_tests/bucket/put.w_compile_tf-aws.md index 9f2c802d670..e5881bd3f16 100644 --- a/tools/hangar/__snapshots__/test_corpus/sdk_tests/bucket/put.w_compile_tf-aws.md +++ b/tools/hangar/__snapshots__/test_corpus/sdk_tests/bucket/put.w_compile_tf-aws.md @@ -16,15 +16,15 @@ module.exports = function({ b }) { (await b.put("test2.txt","Bar")); const first = (await b.get("test1.txt")); const second = (await b.get("test2.txt")); - {((cond) => {if (!cond) throw new Error(`assertion failed: '(first === "Foo")'`)})((first === "Foo"))}; - {((cond) => {if (!cond) throw new Error(`assertion failed: '(second === "Bar")'`)})((second === "Bar"))}; + {((cond) => {if (!cond) throw new Error("assertion failed: first == \"Foo\"")})((first === "Foo"))}; + {((cond) => {if (!cond) throw new Error("assertion failed: second == \"Bar\"")})((second === "Bar"))}; (await b.delete("test1.txt")); const files = (await b.list()); - {((cond) => {if (!cond) throw new Error(`assertion failed: '(files.includes("test1.txt") === false)'`)})((files.includes("test1.txt") === false))}; - {((cond) => {if (!cond) throw new Error(`assertion failed: '(files.includes("test2.txt") === true)'`)})((files.includes("test2.txt") === true))}; + {((cond) => {if (!cond) throw new Error("assertion failed: files.contains(\"test1.txt\") == false")})((files.includes("test1.txt") === false))}; + {((cond) => {if (!cond) throw new Error("assertion failed: files.contains(\"test2.txt\") == true")})((files.includes("test2.txt") === true))}; (await b.put("test2.txt","Baz")); const third = (await b.get("test2.txt")); - {((cond) => {if (!cond) throw new Error(`assertion failed: '(third === "Baz")'`)})((third === "Baz"))}; + {((cond) => {if (!cond) throw new Error("assertion failed: third == \"Baz\"")})((third === "Baz"))}; } } return $Closure1; diff --git a/tools/hangar/__snapshots__/test_corpus/sdk_tests/bucket/put.w_test_sim.md b/tools/hangar/__snapshots__/test_corpus/sdk_tests/bucket/put.w_test_sim.md index dd1a1560f33..36c34fb4d5c 100644 --- a/tools/hangar/__snapshots__/test_corpus/sdk_tests/bucket/put.w_test_sim.md +++ b/tools/hangar/__snapshots__/test_corpus/sdk_tests/bucket/put.w_test_sim.md @@ -4,12 +4,9 @@ ```log pass โ”€ put.wsim ยป root/env0/test:put - - - - -Tests 1 passed (1) + +Tests 1 passed (1) +Test Files 1 passed (1) Duration - ``` diff --git a/tools/hangar/__snapshots__/test_corpus/sdk_tests/bucket/put_json.w_compile_tf-aws.md b/tools/hangar/__snapshots__/test_corpus/sdk_tests/bucket/put_json.w_compile_tf-aws.md index 1efc531af0d..1c5e26a9faa 100644 --- a/tools/hangar/__snapshots__/test_corpus/sdk_tests/bucket/put_json.w_compile_tf-aws.md +++ b/tools/hangar/__snapshots__/test_corpus/sdk_tests/bucket/put_json.w_compile_tf-aws.md @@ -18,16 +18,16 @@ module.exports = function({ b }) { (await b.putJson("test2.txt",jsonObj2)); const testJson1 = (await b.getJson("test1.txt")); const testJson2 = (await b.getJson("test2.txt")); - {((cond) => {if (!cond) throw new Error(`assertion failed: '((testJson1)["test"] === (jsonObj1)["test"])'`)})(((testJson1)["test"] === (jsonObj1)["test"]))}; - {((cond) => {if (!cond) throw new Error(`assertion failed: '((testJson2)["test"] === (jsonObj2)["test"])'`)})(((testJson2)["test"] === (jsonObj2)["test"]))}; + {((cond) => {if (!cond) throw new Error("assertion failed: testJson1.get(\"test\") == jsonObj1.get(\"test\")")})(((testJson1)["test"] === (jsonObj1)["test"]))}; + {((cond) => {if (!cond) throw new Error("assertion failed: testJson2.get(\"test\") == jsonObj2.get(\"test\")")})(((testJson2)["test"] === (jsonObj2)["test"]))}; const jsonObj3 = Object.freeze({"test":"test3"}); (await b.putJson("test3.txt",jsonObj3)); const testJson3 = (await b.getJson("test3.txt")); - {((cond) => {if (!cond) throw new Error(`assertion failed: '((testJson3)["test"] === (jsonObj3)["test"])'`)})(((testJson3)["test"] === (jsonObj3)["test"]))}; + {((cond) => {if (!cond) throw new Error("assertion failed: testJson3.get(\"test\") == jsonObj3.get(\"test\")")})(((testJson3)["test"] === (jsonObj3)["test"]))}; (await b.delete("test1.txt")); const files = (await b.list()); - {((cond) => {if (!cond) throw new Error(`assertion failed: '(files.includes("test1.txt") === false)'`)})((files.includes("test1.txt") === false))}; - {((cond) => {if (!cond) throw new Error(`assertion failed: '(files.includes("test2.txt") === true)'`)})((files.includes("test2.txt") === true))}; + {((cond) => {if (!cond) throw new Error("assertion failed: files.contains(\"test1.txt\") == false")})((files.includes("test1.txt") === false))}; + {((cond) => {if (!cond) throw new Error("assertion failed: files.contains(\"test2.txt\") == true")})((files.includes("test2.txt") === true))}; } } return $Closure1; diff --git a/tools/hangar/__snapshots__/test_corpus/sdk_tests/bucket/put_json.w_test_sim.md b/tools/hangar/__snapshots__/test_corpus/sdk_tests/bucket/put_json.w_test_sim.md index a9638a9c1ca..1d14e5665db 100644 --- a/tools/hangar/__snapshots__/test_corpus/sdk_tests/bucket/put_json.w_test_sim.md +++ b/tools/hangar/__snapshots__/test_corpus/sdk_tests/bucket/put_json.w_test_sim.md @@ -4,12 +4,9 @@ ```log pass โ”€ put_json.wsim ยป root/env0/test:putJson - - - - -Tests 1 passed (1) + +Tests 1 passed (1) +Test Files 1 passed (1) Duration - ``` diff --git a/tools/hangar/__snapshots__/test_corpus/sdk_tests/bucket/try_delete.w_compile_tf-aws.md b/tools/hangar/__snapshots__/test_corpus/sdk_tests/bucket/try_delete.w_compile_tf-aws.md index 4cdff8ecd82..38bf8116e9a 100644 --- a/tools/hangar/__snapshots__/test_corpus/sdk_tests/bucket/try_delete.w_compile_tf-aws.md +++ b/tools/hangar/__snapshots__/test_corpus/sdk_tests/bucket/try_delete.w_compile_tf-aws.md @@ -14,15 +14,15 @@ module.exports = function({ b }) { async handle() { const jsonObj2 = Object.freeze({"key2":"value2"}); (await b.put("file1.txt","Foo")); - {((cond) => {if (!cond) throw new Error(`assertion failed: '((await b.tryDelete("file1.txt")) === true)'`)})(((await b.tryDelete("file1.txt")) === true))}; - {((cond) => {if (!cond) throw new Error(`assertion failed: '((await b.tryDelete("file1.txt")) === false)'`)})(((await b.tryDelete("file1.txt")) === false))}; - {((cond) => {if (!cond) throw new Error(`assertion failed: '((await b.tryDelete("random")) === false)'`)})(((await b.tryDelete("random")) === false))}; + {((cond) => {if (!cond) throw new Error("assertion failed: b.tryDelete(\"file1.txt\") == true")})(((await b.tryDelete("file1.txt")) === true))}; + {((cond) => {if (!cond) throw new Error("assertion failed: b.tryDelete(\"file1.txt\") == false")})(((await b.tryDelete("file1.txt")) === false))}; + {((cond) => {if (!cond) throw new Error("assertion failed: b.tryDelete(\"random\") == false")})(((await b.tryDelete("random")) === false))}; (await b.put("file2.txt","Bar")); (await b.putJson("file2.json",jsonObj2)); - {((cond) => {if (!cond) throw new Error(`assertion failed: '((await b.tryDelete("file2.txt")) === true)'`)})(((await b.tryDelete("file2.txt")) === true))}; - {((cond) => {if (!cond) throw new Error(`assertion failed: '((await b.tryDelete("file2.json")) === true)'`)})(((await b.tryDelete("file2.json")) === true))}; - {((cond) => {if (!cond) throw new Error(`assertion failed: '((await b.tryDelete("file2.txt")) === false)'`)})(((await b.tryDelete("file2.txt")) === false))}; - {((cond) => {if (!cond) throw new Error(`assertion failed: '((await b.tryDelete("file2.json")) === false)'`)})(((await b.tryDelete("file2.json")) === false))}; + {((cond) => {if (!cond) throw new Error("assertion failed: b.tryDelete(\"file2.txt\") == true")})(((await b.tryDelete("file2.txt")) === true))}; + {((cond) => {if (!cond) throw new Error("assertion failed: b.tryDelete(\"file2.json\") == true")})(((await b.tryDelete("file2.json")) === true))}; + {((cond) => {if (!cond) throw new Error("assertion failed: b.tryDelete(\"file2.txt\") == false")})(((await b.tryDelete("file2.txt")) === false))}; + {((cond) => {if (!cond) throw new Error("assertion failed: b.tryDelete(\"file2.json\") == false")})(((await b.tryDelete("file2.json")) === false))}; } } return $Closure1; diff --git a/tools/hangar/__snapshots__/test_corpus/sdk_tests/bucket/try_delete.w_test_sim.md b/tools/hangar/__snapshots__/test_corpus/sdk_tests/bucket/try_delete.w_test_sim.md index 1d8ec4a8339..643e3afab51 100644 --- a/tools/hangar/__snapshots__/test_corpus/sdk_tests/bucket/try_delete.w_test_sim.md +++ b/tools/hangar/__snapshots__/test_corpus/sdk_tests/bucket/try_delete.w_test_sim.md @@ -4,12 +4,9 @@ ```log pass โ”€ try_delete.wsim ยป root/env0/test:tryDelete - - - - -Tests 1 passed (1) + +Tests 1 passed (1) +Test Files 1 passed (1) Duration - ``` diff --git a/tools/hangar/__snapshots__/test_corpus/sdk_tests/bucket/try_get.w_compile_tf-aws.md b/tools/hangar/__snapshots__/test_corpus/sdk_tests/bucket/try_get.w_compile_tf-aws.md index c15c7d09457..5e3f1847c37 100644 --- a/tools/hangar/__snapshots__/test_corpus/sdk_tests/bucket/try_get.w_compile_tf-aws.md +++ b/tools/hangar/__snapshots__/test_corpus/sdk_tests/bucket/try_get.w_compile_tf-aws.md @@ -13,12 +13,12 @@ module.exports = function({ b }) { } async handle() { (await b.put("test1.txt","Foo")); - {((cond) => {if (!cond) throw new Error(`assertion failed: '((await b.tryGet("test1.txt")) === "Foo")'`)})(((await b.tryGet("test1.txt")) === "Foo"))}; - {((cond) => {if (!cond) throw new Error(`assertion failed: '((await b.tryGet("test2.txt")) === undefined)'`)})(((await b.tryGet("test2.txt")) === undefined))}; + {((cond) => {if (!cond) throw new Error("assertion failed: b.tryGet(\"test1.txt\") == \"Foo\"")})(((await b.tryGet("test1.txt")) === "Foo"))}; + {((cond) => {if (!cond) throw new Error("assertion failed: b.tryGet(\"test2.txt\") == nil")})(((await b.tryGet("test2.txt")) === undefined))}; (await b.put("test2.txt","Bar")); - {((cond) => {if (!cond) throw new Error(`assertion failed: '((await b.tryGet("test2.txt")) === "Bar")'`)})(((await b.tryGet("test2.txt")) === "Bar"))}; + {((cond) => {if (!cond) throw new Error("assertion failed: b.tryGet(\"test2.txt\") == \"Bar\"")})(((await b.tryGet("test2.txt")) === "Bar"))}; (await b.delete("test1.txt")); - {((cond) => {if (!cond) throw new Error(`assertion failed: '((await b.tryGet("test1.txt")) === undefined)'`)})(((await b.tryGet("test1.txt")) === undefined))}; + {((cond) => {if (!cond) throw new Error("assertion failed: b.tryGet(\"test1.txt\") == nil")})(((await b.tryGet("test1.txt")) === undefined))}; } } return $Closure1; diff --git a/tools/hangar/__snapshots__/test_corpus/sdk_tests/bucket/try_get.w_test_sim.md b/tools/hangar/__snapshots__/test_corpus/sdk_tests/bucket/try_get.w_test_sim.md index de5bb9112c3..a7784b5c506 100644 --- a/tools/hangar/__snapshots__/test_corpus/sdk_tests/bucket/try_get.w_test_sim.md +++ b/tools/hangar/__snapshots__/test_corpus/sdk_tests/bucket/try_get.w_test_sim.md @@ -4,12 +4,9 @@ ```log pass โ”€ try_get.wsim ยป root/env0/test:tryGet - - - - -Tests 1 passed (1) + +Tests 1 passed (1) +Test Files 1 passed (1) Duration - ``` diff --git a/tools/hangar/__snapshots__/test_corpus/sdk_tests/bucket/try_get_json.w_compile_tf-aws.md b/tools/hangar/__snapshots__/test_corpus/sdk_tests/bucket/try_get_json.w_compile_tf-aws.md index 97ea8c168eb..931193026ea 100644 --- a/tools/hangar/__snapshots__/test_corpus/sdk_tests/bucket/try_get_json.w_compile_tf-aws.md +++ b/tools/hangar/__snapshots__/test_corpus/sdk_tests/bucket/try_get_json.w_compile_tf-aws.md @@ -15,14 +15,14 @@ module.exports = function({ b, std_Json }) { const jsonObj1 = Object.freeze({"key1":"value1"}); const jsonObj2 = Object.freeze({"key2":"value2"}); (await b.putJson("file1.json",jsonObj1)); - {((cond) => {if (!cond) throw new Error(`assertion failed: '(((args) => { return JSON.stringify(args[0], null, args[1]) })([(await b.tryGetJson("file1.json"))]) === ((args) => { return JSON.stringify(args[0], null, args[1]) })([jsonObj1]))'`)})((((args) => { return JSON.stringify(args[0], null, args[1]) })([(await b.tryGetJson("file1.json"))]) === ((args) => { return JSON.stringify(args[0], null, args[1]) })([jsonObj1])))}; - {((cond) => {if (!cond) throw new Error(`assertion failed: '((await b.tryGetJson("file2.json")) === undefined)'`)})(((await b.tryGetJson("file2.json")) === undefined))}; + {((cond) => {if (!cond) throw new Error("assertion failed: Json.stringify(b.tryGetJson(\"file1.json\")) == Json.stringify(jsonObj1)")})((((args) => { return JSON.stringify(args[0], null, args[1]) })([(await b.tryGetJson("file1.json"))]) === ((args) => { return JSON.stringify(args[0], null, args[1]) })([jsonObj1])))}; + {((cond) => {if (!cond) throw new Error("assertion failed: b.tryGetJson(\"file2.json\") == nil")})(((await b.tryGetJson("file2.json")) === undefined))}; (await b.putJson("file2.json",jsonObj2)); - {((cond) => {if (!cond) throw new Error(`assertion failed: '(((args) => { return JSON.stringify(args[0], null, args[1]) })([(await b.tryGetJson("file2.json"))]) === ((args) => { return JSON.stringify(args[0], null, args[1]) })([jsonObj2]))'`)})((((args) => { return JSON.stringify(args[0], null, args[1]) })([(await b.tryGetJson("file2.json"))]) === ((args) => { return JSON.stringify(args[0], null, args[1]) })([jsonObj2])))}; + {((cond) => {if (!cond) throw new Error("assertion failed: Json.stringify(b.tryGetJson(\"file2.json\")) == Json.stringify(jsonObj2)")})((((args) => { return JSON.stringify(args[0], null, args[1]) })([(await b.tryGetJson("file2.json"))]) === ((args) => { return JSON.stringify(args[0], null, args[1]) })([jsonObj2])))}; (await b.delete("file1.json")); (await b.delete("file2.json")); - {((cond) => {if (!cond) throw new Error(`assertion failed: '((await b.tryGetJson("file1.json")) === undefined)'`)})(((await b.tryGetJson("file1.json")) === undefined))}; - {((cond) => {if (!cond) throw new Error(`assertion failed: '((await b.tryGetJson("file2.json")) === undefined)'`)})(((await b.tryGetJson("file2.json")) === undefined))}; + {((cond) => {if (!cond) throw new Error("assertion failed: b.tryGetJson(\"file1.json\") == nil")})(((await b.tryGetJson("file1.json")) === undefined))}; + {((cond) => {if (!cond) throw new Error("assertion failed: b.tryGetJson(\"file2.json\") == nil")})(((await b.tryGetJson("file2.json")) === undefined))}; } } return $Closure1; diff --git a/tools/hangar/__snapshots__/test_corpus/sdk_tests/bucket/try_get_json.w_test_sim.md b/tools/hangar/__snapshots__/test_corpus/sdk_tests/bucket/try_get_json.w_test_sim.md index 70b4b7f7335..f0a2f232f36 100644 --- a/tools/hangar/__snapshots__/test_corpus/sdk_tests/bucket/try_get_json.w_test_sim.md +++ b/tools/hangar/__snapshots__/test_corpus/sdk_tests/bucket/try_get_json.w_test_sim.md @@ -4,12 +4,9 @@ ```log pass โ”€ try_get_json.wsim ยป root/env0/test:tryGetJson - - - - -Tests 1 passed (1) + +Tests 1 passed (1) +Test Files 1 passed (1) Duration - ``` diff --git a/tools/hangar/__snapshots__/test_corpus/sdk_tests/counter/dec.w_compile_tf-aws.md b/tools/hangar/__snapshots__/test_corpus/sdk_tests/counter/dec.w_compile_tf-aws.md index b74b5b7ae69..33964c79c7a 100644 --- a/tools/hangar/__snapshots__/test_corpus/sdk_tests/counter/dec.w_compile_tf-aws.md +++ b/tools/hangar/__snapshots__/test_corpus/sdk_tests/counter/dec.w_compile_tf-aws.md @@ -12,13 +12,13 @@ module.exports = function({ counter }) { async $inflight_init() { } async handle() { - {((cond) => {if (!cond) throw new Error(`assertion failed: '((await counter.peek()) === 1)'`)})(((await counter.peek()) === 1))}; + {((cond) => {if (!cond) throw new Error("assertion failed: counter.peek() == 1")})(((await counter.peek()) === 1))}; const dec1 = (await counter.dec()); - {((cond) => {if (!cond) throw new Error(`assertion failed: '((await counter.peek()) === 0)'`)})(((await counter.peek()) === 0))}; - {((cond) => {if (!cond) throw new Error(`assertion failed: '(dec1 === 1)'`)})((dec1 === 1))}; + {((cond) => {if (!cond) throw new Error("assertion failed: counter.peek() == 0")})(((await counter.peek()) === 0))}; + {((cond) => {if (!cond) throw new Error("assertion failed: dec1 == 1")})((dec1 === 1))}; const dec2 = (await counter.dec(2)); - {((cond) => {if (!cond) throw new Error(`assertion failed: '((await counter.peek()) === (-2))'`)})(((await counter.peek()) === (-2)))}; - {((cond) => {if (!cond) throw new Error(`assertion failed: '(dec2 === 0)'`)})((dec2 === 0))}; + {((cond) => {if (!cond) throw new Error("assertion failed: counter.peek() == -2")})(((await counter.peek()) === (-2)))}; + {((cond) => {if (!cond) throw new Error("assertion failed: dec2 == 0")})((dec2 === 0))}; } } return $Closure1; @@ -39,13 +39,13 @@ module.exports = function({ counter }) { } async handle() { const key = "my-key"; - {((cond) => {if (!cond) throw new Error(`assertion failed: '((await counter.peek(key)) === 0)'`)})(((await counter.peek(key)) === 0))}; + {((cond) => {if (!cond) throw new Error("assertion failed: counter.peek(key) == 0")})(((await counter.peek(key)) === 0))}; const dec1 = (await counter.dec(undefined,key)); - {((cond) => {if (!cond) throw new Error(`assertion failed: '((await counter.peek(key)) === (-1))'`)})(((await counter.peek(key)) === (-1)))}; - {((cond) => {if (!cond) throw new Error(`assertion failed: '(dec1 === 0)'`)})((dec1 === 0))}; + {((cond) => {if (!cond) throw new Error("assertion failed: counter.peek(key) == -1")})(((await counter.peek(key)) === (-1)))}; + {((cond) => {if (!cond) throw new Error("assertion failed: dec1 == 0")})((dec1 === 0))}; const dec2 = (await counter.dec(2,key)); - {((cond) => {if (!cond) throw new Error(`assertion failed: '((await counter.peek(key)) === (-3))'`)})(((await counter.peek(key)) === (-3)))}; - {((cond) => {if (!cond) throw new Error(`assertion failed: '(dec2 === (-1))'`)})((dec2 === (-1)))}; + {((cond) => {if (!cond) throw new Error("assertion failed: counter.peek(key) == -3")})(((await counter.peek(key)) === (-3)))}; + {((cond) => {if (!cond) throw new Error("assertion failed: dec2 == -1")})((dec2 === (-1)))}; } } return $Closure2; diff --git a/tools/hangar/__snapshots__/test_corpus/sdk_tests/counter/dec.w_test_sim.md b/tools/hangar/__snapshots__/test_corpus/sdk_tests/counter/dec.w_test_sim.md index 83eb0c5f8dd..39421d2e0b7 100644 --- a/tools/hangar/__snapshots__/test_corpus/sdk_tests/counter/dec.w_test_sim.md +++ b/tools/hangar/__snapshots__/test_corpus/sdk_tests/counter/dec.w_test_sim.md @@ -5,12 +5,9 @@ pass โ”€ dec.wsim ยป root/env0/test:dec pass โ”€ dec.wsim ยป root/env1/test:key dec - - - - -Tests 1 passed (1) + +Tests 2 passed (2) +Test Files 1 passed (1) Duration - ``` diff --git a/tools/hangar/__snapshots__/test_corpus/sdk_tests/counter/inc.w_compile_tf-aws.md b/tools/hangar/__snapshots__/test_corpus/sdk_tests/counter/inc.w_compile_tf-aws.md index 20bb9d85e39..c4bea80667e 100644 --- a/tools/hangar/__snapshots__/test_corpus/sdk_tests/counter/inc.w_compile_tf-aws.md +++ b/tools/hangar/__snapshots__/test_corpus/sdk_tests/counter/inc.w_compile_tf-aws.md @@ -12,18 +12,18 @@ module.exports = function({ counter }) { async $inflight_init() { } async handle() { - {((cond) => {if (!cond) throw new Error(`assertion failed: '((await counter.peek()) === 0)'`)})(((await counter.peek()) === 0))}; + {((cond) => {if (!cond) throw new Error("assertion failed: counter.peek() == 0")})(((await counter.peek()) === 0))}; const r0 = (await counter.inc()); - {((cond) => {if (!cond) throw new Error(`assertion failed: '(r0 === 0)'`)})((r0 === 0))}; - {((cond) => {if (!cond) throw new Error(`assertion failed: '((await counter.peek()) === 1)'`)})(((await counter.peek()) === 1))}; + {((cond) => {if (!cond) throw new Error("assertion failed: r0 == 0")})((r0 === 0))}; + {((cond) => {if (!cond) throw new Error("assertion failed: counter.peek() == 1")})(((await counter.peek()) === 1))}; const r1 = (await counter.inc()); - {((cond) => {if (!cond) throw new Error(`assertion failed: '(r1 === 1)'`)})((r1 === 1))}; - {((cond) => {if (!cond) throw new Error(`assertion failed: '((await counter.peek()) === 2)'`)})(((await counter.peek()) === 2))}; + {((cond) => {if (!cond) throw new Error("assertion failed: r1 == 1")})((r1 === 1))}; + {((cond) => {if (!cond) throw new Error("assertion failed: counter.peek() == 2")})(((await counter.peek()) === 2))}; const r2 = (await counter.inc(10)); - {((cond) => {if (!cond) throw new Error(`assertion failed: '(r2 === 2)'`)})((r2 === 2))}; - {((cond) => {if (!cond) throw new Error(`assertion failed: '((await counter.peek()) === 12)'`)})(((await counter.peek()) === 12))}; + {((cond) => {if (!cond) throw new Error("assertion failed: r2 == 2")})((r2 === 2))}; + {((cond) => {if (!cond) throw new Error("assertion failed: counter.peek() == 12")})(((await counter.peek()) === 12))}; const r3 = (await counter.inc()); - {((cond) => {if (!cond) throw new Error(`assertion failed: '(r3 === 12)'`)})((r3 === 12))}; + {((cond) => {if (!cond) throw new Error("assertion failed: r3 == 12")})((r3 === 12))}; } } return $Closure1; @@ -44,18 +44,18 @@ module.exports = function({ counter }) { } async handle() { const key = "my-key"; - {((cond) => {if (!cond) throw new Error(`assertion failed: '((await counter.peek(key)) === 0)'`)})(((await counter.peek(key)) === 0))}; + {((cond) => {if (!cond) throw new Error("assertion failed: counter.peek(key) == 0")})(((await counter.peek(key)) === 0))}; const r0 = (await counter.inc(undefined,key)); - {((cond) => {if (!cond) throw new Error(`assertion failed: '(r0 === 0)'`)})((r0 === 0))}; - {((cond) => {if (!cond) throw new Error(`assertion failed: '((await counter.peek(key)) === 1)'`)})(((await counter.peek(key)) === 1))}; + {((cond) => {if (!cond) throw new Error("assertion failed: r0 == 0")})((r0 === 0))}; + {((cond) => {if (!cond) throw new Error("assertion failed: counter.peek(key) == 1")})(((await counter.peek(key)) === 1))}; const r1 = (await counter.inc(undefined,key)); - {((cond) => {if (!cond) throw new Error(`assertion failed: '(r1 === 1)'`)})((r1 === 1))}; - {((cond) => {if (!cond) throw new Error(`assertion failed: '((await counter.peek(key)) === 2)'`)})(((await counter.peek(key)) === 2))}; + {((cond) => {if (!cond) throw new Error("assertion failed: r1 == 1")})((r1 === 1))}; + {((cond) => {if (!cond) throw new Error("assertion failed: counter.peek(key) == 2")})(((await counter.peek(key)) === 2))}; const r2 = (await counter.inc(10,key)); - {((cond) => {if (!cond) throw new Error(`assertion failed: '(r2 === 2)'`)})((r2 === 2))}; - {((cond) => {if (!cond) throw new Error(`assertion failed: '((await counter.peek(key)) === 12)'`)})(((await counter.peek(key)) === 12))}; + {((cond) => {if (!cond) throw new Error("assertion failed: r2 == 2")})((r2 === 2))}; + {((cond) => {if (!cond) throw new Error("assertion failed: counter.peek(key) == 12")})(((await counter.peek(key)) === 12))}; const r3 = (await counter.inc(undefined,key)); - {((cond) => {if (!cond) throw new Error(`assertion failed: '(r3 === 12)'`)})((r3 === 12))}; + {((cond) => {if (!cond) throw new Error("assertion failed: r3 == 12")})((r3 === 12))}; } } return $Closure2; diff --git a/tools/hangar/__snapshots__/test_corpus/sdk_tests/counter/inc.w_test_sim.md b/tools/hangar/__snapshots__/test_corpus/sdk_tests/counter/inc.w_test_sim.md index d4f33a57d90..f4842854f85 100644 --- a/tools/hangar/__snapshots__/test_corpus/sdk_tests/counter/inc.w_test_sim.md +++ b/tools/hangar/__snapshots__/test_corpus/sdk_tests/counter/inc.w_test_sim.md @@ -5,12 +5,9 @@ pass โ”€ inc.wsim ยป root/env0/test:inc pass โ”€ inc.wsim ยป root/env1/test:key inc - - - - -Tests 1 passed (1) + +Tests 2 passed (2) +Test Files 1 passed (1) Duration - ``` diff --git a/tools/hangar/__snapshots__/test_corpus/sdk_tests/counter/initial.w_compile_tf-aws.md b/tools/hangar/__snapshots__/test_corpus/sdk_tests/counter/initial.w_compile_tf-aws.md index 27b297f25fe..c11597280bb 100644 --- a/tools/hangar/__snapshots__/test_corpus/sdk_tests/counter/initial.w_compile_tf-aws.md +++ b/tools/hangar/__snapshots__/test_corpus/sdk_tests/counter/initial.w_compile_tf-aws.md @@ -12,7 +12,7 @@ module.exports = function({ counterA }) { async $inflight_init() { } async handle() { - {((cond) => {if (!cond) throw new Error(`assertion failed: '((await counterA.peek()) === 0)'`)})(((await counterA.peek()) === 0))}; + {((cond) => {if (!cond) throw new Error("assertion failed: counterA.peek() == 0")})(((await counterA.peek()) === 0))}; } } return $Closure1; @@ -32,7 +32,7 @@ module.exports = function({ counterB }) { async $inflight_init() { } async handle() { - {((cond) => {if (!cond) throw new Error(`assertion failed: '((await counterB.peek()) === 500)'`)})(((await counterB.peek()) === 500))}; + {((cond) => {if (!cond) throw new Error("assertion failed: counterB.peek() == 500")})(((await counterB.peek()) === 500))}; } } return $Closure2; @@ -52,7 +52,7 @@ module.exports = function({ counterC }) { async $inflight_init() { } async handle() { - {((cond) => {if (!cond) throw new Error(`assertion failed: '((await counterC.peek()) === (-198))'`)})(((await counterC.peek()) === (-198)))}; + {((cond) => {if (!cond) throw new Error("assertion failed: counterC.peek() == -198")})(((await counterC.peek()) === (-198)))}; } } return $Closure3; diff --git a/tools/hangar/__snapshots__/test_corpus/sdk_tests/counter/initial.w_test_sim.md b/tools/hangar/__snapshots__/test_corpus/sdk_tests/counter/initial.w_test_sim.md index 8fa297a61d2..048d9d6570a 100644 --- a/tools/hangar/__snapshots__/test_corpus/sdk_tests/counter/initial.w_test_sim.md +++ b/tools/hangar/__snapshots__/test_corpus/sdk_tests/counter/initial.w_test_sim.md @@ -6,12 +6,9 @@ pass โ”€ initial.wsim ยป root/env0/test:initial:default pass โ”€ initial.wsim ยป root/env1/test:initial:positive-value pass โ”€ initial.wsim ยป root/env2/test:initial:negative-value - - - - -Tests 1 passed (1) + +Tests 3 passed (3) +Test Files 1 passed (1) Duration - ``` diff --git a/tools/hangar/__snapshots__/test_corpus/sdk_tests/counter/peek.w_compile_tf-aws.md b/tools/hangar/__snapshots__/test_corpus/sdk_tests/counter/peek.w_compile_tf-aws.md index 2241aa56745..3a01e8dd653 100644 --- a/tools/hangar/__snapshots__/test_corpus/sdk_tests/counter/peek.w_compile_tf-aws.md +++ b/tools/hangar/__snapshots__/test_corpus/sdk_tests/counter/peek.w_compile_tf-aws.md @@ -12,10 +12,10 @@ module.exports = function({ c }) { async $inflight_init() { } async handle() { - {((cond) => {if (!cond) throw new Error(`assertion failed: '((await c.peek()) === 0)'`)})(((await c.peek()) === 0))}; - {((cond) => {if (!cond) throw new Error(`assertion failed: '((await c.peek()) === 0)'`)})(((await c.peek()) === 0))}; + {((cond) => {if (!cond) throw new Error("assertion failed: c.peek() == 0")})(((await c.peek()) === 0))}; + {((cond) => {if (!cond) throw new Error("assertion failed: c.peek() == 0")})(((await c.peek()) === 0))}; (await c.inc()); - {((cond) => {if (!cond) throw new Error(`assertion failed: '((await c.peek()) === 1)'`)})(((await c.peek()) === 1))}; + {((cond) => {if (!cond) throw new Error("assertion failed: c.peek() == 1")})(((await c.peek()) === 1))}; } } return $Closure1; @@ -36,10 +36,10 @@ module.exports = function({ c }) { } async handle() { const key = "my-key"; - {((cond) => {if (!cond) throw new Error(`assertion failed: '((await c.peek(key)) === 0)'`)})(((await c.peek(key)) === 0))}; - {((cond) => {if (!cond) throw new Error(`assertion failed: '((await c.peek(key)) === 0)'`)})(((await c.peek(key)) === 0))}; + {((cond) => {if (!cond) throw new Error("assertion failed: c.peek(key) == 0")})(((await c.peek(key)) === 0))}; + {((cond) => {if (!cond) throw new Error("assertion failed: c.peek(key) == 0")})(((await c.peek(key)) === 0))}; (await c.inc(undefined,key)); - {((cond) => {if (!cond) throw new Error(`assertion failed: '((await c.peek(key)) === 1)'`)})(((await c.peek(key)) === 1))}; + {((cond) => {if (!cond) throw new Error("assertion failed: c.peek(key) == 1")})(((await c.peek(key)) === 1))}; } } return $Closure2; diff --git a/tools/hangar/__snapshots__/test_corpus/sdk_tests/counter/peek.w_test_sim.md b/tools/hangar/__snapshots__/test_corpus/sdk_tests/counter/peek.w_test_sim.md index 28637c06b1c..e344b481cc0 100644 --- a/tools/hangar/__snapshots__/test_corpus/sdk_tests/counter/peek.w_test_sim.md +++ b/tools/hangar/__snapshots__/test_corpus/sdk_tests/counter/peek.w_test_sim.md @@ -5,12 +5,9 @@ pass โ”€ peek.wsim ยป root/env0/test:peek pass โ”€ peek.wsim ยป root/env1/test:key peek - - - - -Tests 1 passed (1) + +Tests 2 passed (2) +Test Files 1 passed (1) Duration - ``` diff --git a/tools/hangar/__snapshots__/test_corpus/sdk_tests/counter/set.w_compile_tf-aws.md b/tools/hangar/__snapshots__/test_corpus/sdk_tests/counter/set.w_compile_tf-aws.md index 6313a30d9e1..b15bac42f01 100644 --- a/tools/hangar/__snapshots__/test_corpus/sdk_tests/counter/set.w_compile_tf-aws.md +++ b/tools/hangar/__snapshots__/test_corpus/sdk_tests/counter/set.w_compile_tf-aws.md @@ -12,15 +12,15 @@ module.exports = function({ counter }) { async $inflight_init() { } async handle() { - {((cond) => {if (!cond) throw new Error(`assertion failed: '((await counter.peek()) === 0)'`)})(((await counter.peek()) === 0))}; + {((cond) => {if (!cond) throw new Error("assertion failed: counter.peek() == 0")})(((await counter.peek()) === 0))}; (await counter.inc()); - {((cond) => {if (!cond) throw new Error(`assertion failed: '((await counter.peek()) === 1)'`)})(((await counter.peek()) === 1))}; + {((cond) => {if (!cond) throw new Error("assertion failed: counter.peek() == 1")})(((await counter.peek()) === 1))}; (await counter.inc()); - {((cond) => {if (!cond) throw new Error(`assertion failed: '((await counter.peek()) === 2)'`)})(((await counter.peek()) === 2))}; + {((cond) => {if (!cond) throw new Error("assertion failed: counter.peek() == 2")})(((await counter.peek()) === 2))}; (await counter.inc(10)); - {((cond) => {if (!cond) throw new Error(`assertion failed: '((await counter.peek()) === 12)'`)})(((await counter.peek()) === 12))}; + {((cond) => {if (!cond) throw new Error("assertion failed: counter.peek() == 12")})(((await counter.peek()) === 12))}; (await counter.set(88)); - {((cond) => {if (!cond) throw new Error(`assertion failed: '((await counter.peek()) === 88)'`)})(((await counter.peek()) === 88))}; + {((cond) => {if (!cond) throw new Error("assertion failed: counter.peek() == 88")})(((await counter.peek()) === 88))}; } } return $Closure1; @@ -41,15 +41,15 @@ module.exports = function({ counter }) { } async handle() { const key = "my-key"; - {((cond) => {if (!cond) throw new Error(`assertion failed: '((await counter.peek(key)) === 0)'`)})(((await counter.peek(key)) === 0))}; + {((cond) => {if (!cond) throw new Error("assertion failed: counter.peek(key) == 0")})(((await counter.peek(key)) === 0))}; (await counter.inc(undefined,key)); - {((cond) => {if (!cond) throw new Error(`assertion failed: '((await counter.peek(key)) === 1)'`)})(((await counter.peek(key)) === 1))}; + {((cond) => {if (!cond) throw new Error("assertion failed: counter.peek(key) == 1")})(((await counter.peek(key)) === 1))}; (await counter.inc(undefined,key)); - {((cond) => {if (!cond) throw new Error(`assertion failed: '((await counter.peek(key)) === 2)'`)})(((await counter.peek(key)) === 2))}; + {((cond) => {if (!cond) throw new Error("assertion failed: counter.peek(key) == 2")})(((await counter.peek(key)) === 2))}; (await counter.inc(10,key)); - {((cond) => {if (!cond) throw new Error(`assertion failed: '((await counter.peek(key)) === 12)'`)})(((await counter.peek(key)) === 12))}; + {((cond) => {if (!cond) throw new Error("assertion failed: counter.peek(key) == 12")})(((await counter.peek(key)) === 12))}; (await counter.set(88,key)); - {((cond) => {if (!cond) throw new Error(`assertion failed: '((await counter.peek(key)) === 88)'`)})(((await counter.peek(key)) === 88))}; + {((cond) => {if (!cond) throw new Error("assertion failed: counter.peek(key) == 88")})(((await counter.peek(key)) === 88))}; } } return $Closure2; diff --git a/tools/hangar/__snapshots__/test_corpus/sdk_tests/counter/set.w_test_sim.md b/tools/hangar/__snapshots__/test_corpus/sdk_tests/counter/set.w_test_sim.md index f724e1aa7be..a1e30891814 100644 --- a/tools/hangar/__snapshots__/test_corpus/sdk_tests/counter/set.w_test_sim.md +++ b/tools/hangar/__snapshots__/test_corpus/sdk_tests/counter/set.w_test_sim.md @@ -5,12 +5,9 @@ pass โ”€ set.wsim ยป root/env0/test:set pass โ”€ set.wsim ยป root/env1/test:key set - - - - -Tests 1 passed (1) + +Tests 2 passed (2) +Test Files 1 passed (1) Duration - ``` diff --git a/tools/hangar/__snapshots__/test_corpus/sdk_tests/function/invoke.w_compile_tf-aws.md b/tools/hangar/__snapshots__/test_corpus/sdk_tests/function/invoke.w_compile_tf-aws.md index 2dccb569497..c9b18ea34d7 100644 --- a/tools/hangar/__snapshots__/test_corpus/sdk_tests/function/invoke.w_compile_tf-aws.md +++ b/tools/hangar/__snapshots__/test_corpus/sdk_tests/function/invoke.w_compile_tf-aws.md @@ -13,8 +13,8 @@ module.exports = function({ util_Util }) { } async handle(input) { const target = (await util_Util.tryEnv("WING_TARGET")); - {((cond) => {if (!cond) throw new Error(`assertion failed: '((target) != null)'`)})(((target) != null))}; - return `${input}-response`; + {((cond) => {if (!cond) throw new Error("assertion failed: target?")})(((target) != null))}; + return String.raw({ raw: ["", "-response"] }, input); } } return $Closure1; @@ -35,7 +35,7 @@ module.exports = function({ f }) { } async handle() { const x = (await f.invoke("hello")); - {((cond) => {if (!cond) throw new Error(`assertion failed: '(x === "hello-response")'`)})((x === "hello-response"))}; + {((cond) => {if (!cond) throw new Error("assertion failed: x == \"hello-response\"")})((x === "hello-response"))}; } } return $Closure2; diff --git a/tools/hangar/__snapshots__/test_corpus/sdk_tests/function/invoke.w_test_sim.md b/tools/hangar/__snapshots__/test_corpus/sdk_tests/function/invoke.w_test_sim.md index 6059d0138dd..d867c3040ce 100644 --- a/tools/hangar/__snapshots__/test_corpus/sdk_tests/function/invoke.w_test_sim.md +++ b/tools/hangar/__snapshots__/test_corpus/sdk_tests/function/invoke.w_test_sim.md @@ -4,12 +4,9 @@ ```log pass โ”€ invoke.wsim ยป root/env0/test:invoke - - - - -Tests 1 passed (1) + +Tests 1 passed (1) +Test Files 1 passed (1) Duration - ``` diff --git a/tools/hangar/__snapshots__/test_corpus/sdk_tests/function/memory_and_env.w_compile_tf-aws.md b/tools/hangar/__snapshots__/test_corpus/sdk_tests/function/memory_and_env.w_compile_tf-aws.md index 563aafc3ce4..1f4c9e6a66d 100644 --- a/tools/hangar/__snapshots__/test_corpus/sdk_tests/function/memory_and_env.w_compile_tf-aws.md +++ b/tools/hangar/__snapshots__/test_corpus/sdk_tests/function/memory_and_env.w_compile_tf-aws.md @@ -52,11 +52,11 @@ module.exports = function({ c, f1, f2 }) { async $inflight_init() { } async handle() { - {((cond) => {if (!cond) throw new Error(`assertion failed: '((await c.peek()) === 0)'`)})(((await c.peek()) === 0))}; + {((cond) => {if (!cond) throw new Error("assertion failed: c.peek() == 0")})(((await c.peek()) === 0))}; (await f1.invoke("")); - {((cond) => {if (!cond) throw new Error(`assertion failed: '((await c.peek()) === 1)'`)})(((await c.peek()) === 1))}; + {((cond) => {if (!cond) throw new Error("assertion failed: c.peek() == 1")})(((await c.peek()) === 1))}; (await f2.invoke("")); - {((cond) => {if (!cond) throw new Error(`assertion failed: '((await c.peek()) === 2)'`)})(((await c.peek()) === 2))}; + {((cond) => {if (!cond) throw new Error("assertion failed: c.peek() == 2")})(((await c.peek()) === 2))}; } } return $Closure3; @@ -524,8 +524,8 @@ class $Root extends $stdlib.std.Resource { "env": Object.freeze({"catName":"Tion"}),} ); (f2.addEnvironment("catAge","2")); - {((cond) => {if (!cond) throw new Error(`assertion failed: '((f2.env)["catAge"] === "2")'`)})(((f2.env)["catAge"] === "2"))}; - {((cond) => {if (!cond) throw new Error(`assertion failed: '((f2.env)["catName"] === "Tion")'`)})(((f2.env)["catName"] === "Tion"))}; + {((cond) => {if (!cond) throw new Error("assertion failed: f2.env.get(\"catAge\") == \"2\"")})(((f2.env)["catAge"] === "2"))}; + {((cond) => {if (!cond) throw new Error("assertion failed: f2.env.get(\"catName\") == \"Tion\"")})(((f2.env)["catName"] === "Tion"))}; this.node.root.new("@winglang/sdk.std.Test",std.Test,this,"test:function with memory and function with env can be invoked",new $Closure3(this,"$Closure3")); } } diff --git a/tools/hangar/__snapshots__/test_corpus/sdk_tests/function/memory_and_env.w_test_sim.md b/tools/hangar/__snapshots__/test_corpus/sdk_tests/function/memory_and_env.w_test_sim.md index c9b81ff3cbc..e6e92d16b6b 100644 --- a/tools/hangar/__snapshots__/test_corpus/sdk_tests/function/memory_and_env.w_test_sim.md +++ b/tools/hangar/__snapshots__/test_corpus/sdk_tests/function/memory_and_env.w_test_sim.md @@ -4,12 +4,9 @@ ```log pass โ”€ memory_and_env.wsim ยป root/env0/test:function with memory and function with env can be invoked - - - - -Tests 1 passed (1) + +Tests 1 passed (1) +Test Files 1 passed (1) Duration - ``` diff --git a/tools/hangar/__snapshots__/test_corpus/sdk_tests/queue/pop.w_compile_tf-aws.md b/tools/hangar/__snapshots__/test_corpus/sdk_tests/queue/pop.w_compile_tf-aws.md index a16217a6780..5ba5dc49797 100644 --- a/tools/hangar/__snapshots__/test_corpus/sdk_tests/queue/pop.w_compile_tf-aws.md +++ b/tools/hangar/__snapshots__/test_corpus/sdk_tests/queue/pop.w_compile_tf-aws.md @@ -19,9 +19,9 @@ module.exports = function({ q, NIL }) { const first = ((await q.pop()) ?? NIL); const second = ((await q.pop()) ?? NIL); const third = ((await q.pop()) ?? NIL); - {((cond) => {if (!cond) throw new Error(`assertion failed: 'msgs.includes(first)'`)})(msgs.includes(first))}; - {((cond) => {if (!cond) throw new Error(`assertion failed: 'msgs.includes(second)'`)})(msgs.includes(second))}; - {((cond) => {if (!cond) throw new Error(`assertion failed: '(third === NIL)'`)})((third === NIL))}; + {((cond) => {if (!cond) throw new Error("assertion failed: msgs.contains(first)")})(msgs.includes(first))}; + {((cond) => {if (!cond) throw new Error("assertion failed: msgs.contains(second)")})(msgs.includes(second))}; + {((cond) => {if (!cond) throw new Error("assertion failed: third == NIL")})((third === NIL))}; } } return $Closure1; diff --git a/tools/hangar/__snapshots__/test_corpus/sdk_tests/queue/pop.w_test_sim.md b/tools/hangar/__snapshots__/test_corpus/sdk_tests/queue/pop.w_test_sim.md index 52c352c919f..904c1b0cb31 100644 --- a/tools/hangar/__snapshots__/test_corpus/sdk_tests/queue/pop.w_test_sim.md +++ b/tools/hangar/__snapshots__/test_corpus/sdk_tests/queue/pop.w_test_sim.md @@ -4,12 +4,9 @@ ```log pass โ”€ pop.wsim ยป root/env0/test:pop - - - - -Tests 1 passed (1) + +Tests 1 passed (1) +Test Files 1 passed (1) Duration - ``` diff --git a/tools/hangar/__snapshots__/test_corpus/sdk_tests/queue/purge.w_compile_tf-aws.md b/tools/hangar/__snapshots__/test_corpus/sdk_tests/queue/purge.w_compile_tf-aws.md index cdecc400084..ca3c034cec5 100644 --- a/tools/hangar/__snapshots__/test_corpus/sdk_tests/queue/purge.w_compile_tf-aws.md +++ b/tools/hangar/__snapshots__/test_corpus/sdk_tests/queue/purge.w_compile_tf-aws.md @@ -27,18 +27,12 @@ module.exports = function({ q, js }) { return false; } ; - {((cond) => {if (!cond) throw new Error(`assertion failed: '(await wait(async () => { - return ((await q.approxSize()) === 3); - } - ))'`)})((await wait(async () => { + {((cond) => {if (!cond) throw new Error("assertion failed: wait(inflight (): bool => { \n return q.approxSize() == 3;\n })")})((await wait(async () => { return ((await q.approxSize()) === 3); } )))}; (await q.purge()); - {((cond) => {if (!cond) throw new Error(`assertion failed: '(await wait(async () => { - return ((await q.approxSize()) === 0); - } - ))'`)})((await wait(async () => { + {((cond) => {if (!cond) throw new Error("assertion failed: wait(inflight (): bool => {\n return q.approxSize() == 0;\n })")})((await wait(async () => { return ((await q.approxSize()) === 0); } )))}; diff --git a/tools/hangar/__snapshots__/test_corpus/sdk_tests/queue/purge.w_test_sim.md b/tools/hangar/__snapshots__/test_corpus/sdk_tests/queue/purge.w_test_sim.md index c1daac65362..7e9b0e37a3d 100644 --- a/tools/hangar/__snapshots__/test_corpus/sdk_tests/queue/purge.w_test_sim.md +++ b/tools/hangar/__snapshots__/test_corpus/sdk_tests/queue/purge.w_test_sim.md @@ -4,12 +4,9 @@ ```log pass โ”€ purge.wsim ยป root/env0/test:purge - - - - -Tests 1 passed (1) + +Tests 1 passed (1) +Test Files 1 passed (1) Duration - ``` diff --git a/tools/hangar/__snapshots__/test_corpus/sdk_tests/queue/set_consumer.w_compile_tf-aws.md b/tools/hangar/__snapshots__/test_corpus/sdk_tests/queue/set_consumer.w_compile_tf-aws.md index 9f74d24aa6c..58b659d556d 100644 --- a/tools/hangar/__snapshots__/test_corpus/sdk_tests/queue/set_consumer.w_compile_tf-aws.md +++ b/tools/hangar/__snapshots__/test_corpus/sdk_tests/queue/set_consumer.w_compile_tf-aws.md @@ -38,12 +38,12 @@ module.exports = function({ q, predicate, js }) { while ((i < 600)) { i = (i + 1); if ((await predicate.test())) { - {((cond) => {if (!cond) throw new Error(`assertion failed: '(await predicate.test())'`)})((await predicate.test()))}; + {((cond) => {if (!cond) throw new Error("assertion failed: predicate.test()")})((await predicate.test()))}; return; } (await js.sleep(100)); } - {((cond) => {if (!cond) throw new Error(`assertion failed: '(await predicate.test())'`)})((await predicate.test()))}; + {((cond) => {if (!cond) throw new Error("assertion failed: predicate.test()")})((await predicate.test()))}; } } return $Closure2; diff --git a/tools/hangar/__snapshots__/test_corpus/sdk_tests/queue/set_consumer.w_test_sim.md b/tools/hangar/__snapshots__/test_corpus/sdk_tests/queue/set_consumer.w_test_sim.md index 63c15a154ca..d6dac5a2c95 100644 --- a/tools/hangar/__snapshots__/test_corpus/sdk_tests/queue/set_consumer.w_test_sim.md +++ b/tools/hangar/__snapshots__/test_corpus/sdk_tests/queue/set_consumer.w_test_sim.md @@ -4,12 +4,9 @@ ```log pass โ”€ set_consumer.wsim ยป root/env0/test:setConsumer - - - - -Tests 1 passed (1) + +Tests 1 passed (1) +Test Files 1 passed (1) Duration - ``` diff --git a/tools/hangar/__snapshots__/test_corpus/sdk_tests/schedule/on_tick.w_compile_tf-aws.md b/tools/hangar/__snapshots__/test_corpus/sdk_tests/schedule/on_tick.w_compile_tf-aws.md index bb15e501668..9bd29c9c5b7 100644 --- a/tools/hangar/__snapshots__/test_corpus/sdk_tests/schedule/on_tick.w_compile_tf-aws.md +++ b/tools/hangar/__snapshots__/test_corpus/sdk_tests/schedule/on_tick.w_compile_tf-aws.md @@ -52,11 +52,11 @@ module.exports = function({ c1, c2, Utils }) { async $inflight_init() { } async handle() { - {((cond) => {if (!cond) throw new Error(`assertion failed: '((await c1.peek()) === 0)'`)})(((await c1.peek()) === 0))}; - {((cond) => {if (!cond) throw new Error(`assertion failed: '((await c2.peek()) === 0)'`)})(((await c2.peek()) === 0))}; + {((cond) => {if (!cond) throw new Error("assertion failed: c1.peek() == 0")})(((await c1.peek()) === 0))}; + {((cond) => {if (!cond) throw new Error("assertion failed: c2.peek() == 0")})(((await c2.peek()) === 0))}; (await Utils.sleep(((60 * 1000) * 1.1))); - {((cond) => {if (!cond) throw new Error(`assertion failed: '((await c1.peek()) >= 1)'`)})(((await c1.peek()) >= 1))}; - {((cond) => {if (!cond) throw new Error(`assertion failed: '((await c2.peek()) >= 1)'`)})(((await c2.peek()) >= 1))}; + {((cond) => {if (!cond) throw new Error("assertion failed: c1.peek() >= 1")})(((await c1.peek()) >= 1))}; + {((cond) => {if (!cond) throw new Error("assertion failed: c2.peek() >= 1")})(((await c2.peek()) >= 1))}; } } return $Closure3; diff --git a/tools/hangar/__snapshots__/test_corpus/sdk_tests/schedule/on_tick.w_test_sim.md b/tools/hangar/__snapshots__/test_corpus/sdk_tests/schedule/on_tick.w_test_sim.md index fe508378a81..a738e311968 100644 --- a/tools/hangar/__snapshots__/test_corpus/sdk_tests/schedule/on_tick.w_test_sim.md +++ b/tools/hangar/__snapshots__/test_corpus/sdk_tests/schedule/on_tick.w_test_sim.md @@ -4,12 +4,9 @@ ```log pass โ”€ on_tick.wsim ยป root/env0/on tick is called both for rate and cron schedules - - - - -Tests 1 passed (1) + +Tests 1 passed (1) +Test Files 1 passed (1) Duration - ``` diff --git a/tools/hangar/__snapshots__/test_corpus/sdk_tests/std/array.w_compile_tf-aws.md b/tools/hangar/__snapshots__/test_corpus/sdk_tests/std/array.w_compile_tf-aws.md index 97c86dbf368..d94b865714d 100644 --- a/tools/hangar/__snapshots__/test_corpus/sdk_tests/std/array.w_compile_tf-aws.md +++ b/tools/hangar/__snapshots__/test_corpus/sdk_tests/std/array.w_compile_tf-aws.md @@ -12,8 +12,8 @@ module.exports = function({ }) { async $inflight_init() { } async handle() { - {((cond) => {if (!cond) throw new Error(`assertion failed: '(Object.freeze(["hello"]).length === 1)'`)})((Object.freeze(["hello"]).length === 1))}; - {((cond) => {if (!cond) throw new Error(`assertion failed: '(["hello"].length === 1)'`)})((["hello"].length === 1))}; + {((cond) => {if (!cond) throw new Error("assertion failed: [\"hello\"].length == 1")})((Object.freeze(["hello"]).length === 1))}; + {((cond) => {if (!cond) throw new Error("assertion failed: MutArray[\"hello\"].length == 1")})((["hello"].length === 1))}; } } return $Closure1; @@ -21,6 +21,99 @@ module.exports = function({ }) { ``` +## inflight.$Closure10.js +```js +module.exports = function({ }) { + class $Closure10 { + constructor({ }) { + const $obj = (...args) => this.handle(...args); + Object.setPrototypeOf($obj, this); + return $obj; + } + async $inflight_init() { + } + async handle() { + const i = ["hello", "wing"]; + const separator = ","; + const joinedString = (await i.join()); + const expectedString = (((await i.at(0)) + separator) + (await i.at(1))); + {((cond) => {if (!cond) throw new Error("assertion failed: joinedString == expectedString")})((joinedString === expectedString))}; + } + } + return $Closure10; +} + +``` + +## inflight.$Closure11.js +```js +module.exports = function({ }) { + class $Closure11 { + constructor({ }) { + const $obj = (...args) => this.handle(...args); + Object.setPrototypeOf($obj, this); + return $obj; + } + async $inflight_init() { + } + async handle() { + const o = ["hello", "wing"]; + const p = Object.freeze([...(o)]); + {((cond) => {if (!cond) throw new Error("assertion failed: o.length == p.length")})((o.length === p.length))}; + {((cond) => {if (!cond) throw new Error("assertion failed: o.at(0) == p.at(0)")})(((await o.at(0)) === (await p.at(0))))}; + } + } + return $Closure11; +} + +``` + +## inflight.$Closure12.js +```js +module.exports = function({ }) { + class $Closure12 { + constructor({ }) { + const $obj = (...args) => this.handle(...args); + Object.setPrototypeOf($obj, this); + return $obj; + } + async $inflight_init() { + } + async handle() { + const q = Object.freeze(["hello", "wing"]); + const r = [...(q)]; + {((cond) => {if (!cond) throw new Error("assertion failed: q.length == r.length")})((q.length === r.length))}; + {((cond) => {if (!cond) throw new Error("assertion failed: q.at(0) == r.at(0)")})(((await q.at(0)) === (await r.at(0))))}; + } + } + return $Closure12; +} + +``` + +## inflight.$Closure13.js +```js +module.exports = function({ }) { + class $Closure13 { + constructor({ }) { + const $obj = (...args) => this.handle(...args); + Object.setPrototypeOf($obj, this); + return $obj; + } + async $inflight_init() { + } + async handle() { + const lastStr = "wing"; + const s = ["hello", lastStr, lastStr]; + {((cond) => {if (!cond) throw new Error("assertion failed: s.lastIndexOf(lastStr) == 2")})((s.lastIndexOf(lastStr) === 2))}; + {((cond) => {if (!cond) throw new Error("assertion failed: s.lastIndexOf(\"something\") == -1")})((s.lastIndexOf("something") === (-1)))}; + } + } + return $Closure13; +} + +``` + ## inflight.$Closure2.js ```js module.exports = function({ }) { @@ -33,8 +126,8 @@ module.exports = function({ }) { async $inflight_init() { } async handle() { - {((cond) => {if (!cond) throw new Error(`assertion failed: '((await Object.freeze(["hello"]).at(0)) === "hello")'`)})(((await Object.freeze(["hello"]).at(0)) === "hello"))}; - {((cond) => {if (!cond) throw new Error(`assertion failed: '((await ["hello", "world"].at(1)) === "world")'`)})(((await ["hello", "world"].at(1)) === "world"))}; + {((cond) => {if (!cond) throw new Error("assertion failed: [\"hello\"].at(0) == \"hello\"")})(((await Object.freeze(["hello"]).at(0)) === "hello"))}; + {((cond) => {if (!cond) throw new Error("assertion failed: MutArray[\"hello\", \"world\"].at(1) == \"world\"")})(((await ["hello", "world"].at(1)) === "world"))}; } } return $Closure2; @@ -55,11 +148,15 @@ module.exports = function({ }) { } async handle() { const a = ["hello"]; - {((cond) => {if (!cond) throw new Error(`assertion failed: '(a.length === 1)'`)})((a.length === 1))}; + {((cond) => {if (!cond) throw new Error("assertion failed: a.length == 1")})((a.length === 1))}; (await a.push("world")); - {((cond) => {if (!cond) throw new Error(`assertion failed: '(a.length === 2)'`)})((a.length === 2))}; - {((cond) => {if (!cond) throw new Error(`assertion failed: '((await a.at(0)) === "hello")'`)})(((await a.at(0)) === "hello"))}; - {((cond) => {if (!cond) throw new Error(`assertion failed: '((await a.at(1)) === "world")'`)})(((await a.at(1)) === "world"))}; + {((cond) => {if (!cond) throw new Error("assertion failed: a.length == 2")})((a.length === 2))}; + {((cond) => {if (!cond) throw new Error("assertion failed: a.at(0) == \"hello\"")})(((await a.at(0)) === "hello"))}; + {((cond) => {if (!cond) throw new Error("assertion failed: a.at(1) == \"world\"")})(((await a.at(1)) === "world"))}; + const item = (await a.pop()); + {((cond) => {if (!cond) throw new Error("assertion failed: item == \"world\"")})((item === "world"))}; + {((cond) => {if (!cond) throw new Error("assertion failed: a.length == 1")})((a.length === 1))}; + {((cond) => {if (!cond) throw new Error("assertion failed: a.at(0) == \"hello\"")})(((await a.at(0)) === "hello"))}; } } return $Closure3; @@ -67,6 +164,151 @@ module.exports = function({ }) { ``` +## inflight.$Closure4.js +```js +module.exports = function({ }) { + class $Closure4 { + constructor({ }) { + const $obj = (...args) => this.handle(...args); + Object.setPrototypeOf($obj, this); + return $obj; + } + async $inflight_init() { + } + async handle() { + const b = ["hello"]; + {((cond) => {if (!cond) throw new Error("assertion failed: b.length == 1")})((b.length === 1))}; + const d = (await b.concat(["wing"])); + {((cond) => {if (!cond) throw new Error("assertion failed: d.length == 2")})((d.length === 2))}; + {((cond) => {if (!cond) throw new Error("assertion failed: d.at(0) == \"hello\"")})(((await d.at(0)) === "hello"))}; + {((cond) => {if (!cond) throw new Error("assertion failed: d.at(1) == \"wing\"")})(((await d.at(1)) === "wing"))}; + } + } + return $Closure4; +} + +``` + +## inflight.$Closure5.js +```js +module.exports = function({ }) { + class $Closure5 { + constructor({ }) { + const $obj = (...args) => this.handle(...args); + Object.setPrototypeOf($obj, this); + return $obj; + } + async $inflight_init() { + } + async handle() { + const array = Object.freeze(["hello"]); + {((cond) => {if (!cond) throw new Error("assertion failed: array.length == 1")})((array.length === 1))}; + const anotherArray = Object.freeze(["wing"]); + {((cond) => {if (!cond) throw new Error("assertion failed: anotherArray.length == 1")})((anotherArray.length === 1))}; + const mergedArray = (await array.concat(anotherArray)); + {((cond) => {if (!cond) throw new Error("assertion failed: mergedArray.length == 2")})((mergedArray.length === 2))}; + {((cond) => {if (!cond) throw new Error("assertion failed: mergedArray.at(0) == \"hello\"")})(((await mergedArray.at(0)) === "hello"))}; + {((cond) => {if (!cond) throw new Error("assertion failed: mergedArray.at(1) == \"wing\"")})(((await mergedArray.at(1)) === "wing"))}; + } + } + return $Closure5; +} + +``` + +## inflight.$Closure6.js +```js +module.exports = function({ }) { + class $Closure6 { + constructor({ }) { + const $obj = (...args) => this.handle(...args); + Object.setPrototypeOf($obj, this); + return $obj; + } + async $inflight_init() { + } + async handle() { + const e = ["hello", "wing"]; + {((cond) => {if (!cond) throw new Error("assertion failed: e.contains(\"wing\")")})(e.includes("wing"))}; + {((cond) => {if (!cond) throw new Error("assertion failed: !e.contains(\"NotThere\")")})((!e.includes("NotThere")))}; + const h = Object.freeze(["hello", "wing"]); + {((cond) => {if (!cond) throw new Error("assertion failed: h.contains(\"wing\")")})(h.includes("wing"))}; + {((cond) => {if (!cond) throw new Error("assertion failed: !h.contains(\"NotThere\")")})((!h.includes("NotThere")))}; + } + } + return $Closure6; +} + +``` + +## inflight.$Closure7.js +```js +module.exports = function({ }) { + class $Closure7 { + constructor({ }) { + const $obj = (...args) => this.handle(...args); + Object.setPrototypeOf($obj, this); + return $obj; + } + async $inflight_init() { + } + async handle() { + const g = ["hello", "wing"]; + {((cond) => {if (!cond) throw new Error("assertion failed: g.indexOf(\"wing\") == 1")})((g.indexOf("wing") === 1))}; + {((cond) => {if (!cond) throw new Error("assertion failed: g.indexOf(\"notThere\") == -1")})((g.indexOf("notThere") === (-1)))}; + } + } + return $Closure7; +} + +``` + +## inflight.$Closure8.js +```js +module.exports = function({ }) { + class $Closure8 { + constructor({ }) { + const $obj = (...args) => this.handle(...args); + Object.setPrototypeOf($obj, this); + return $obj; + } + async $inflight_init() { + } + async handle() { + const g = Object.freeze(["hello", "wing"]); + {((cond) => {if (!cond) throw new Error("assertion failed: g.indexOf(\"wing\") == 1")})((g.indexOf("wing") === 1))}; + {((cond) => {if (!cond) throw new Error("assertion failed: g.indexOf(\"notThere\") == -1")})((g.indexOf("notThere") === (-1)))}; + } + } + return $Closure8; +} + +``` + +## inflight.$Closure9.js +```js +module.exports = function({ }) { + class $Closure9 { + constructor({ }) { + const $obj = (...args) => this.handle(...args); + Object.setPrototypeOf($obj, this); + return $obj; + } + async $inflight_init() { + } + async handle() { + const i = ["hello", "wing"]; + const separator = ";"; + const joinedString = (await i.join(separator)); + const expectedString = (((await i.at(0)) + separator) + (await i.at(1))); + {((cond) => {if (!cond) throw new Error("assertion failed: joinedString == expectedString")})((joinedString === expectedString))}; + } + } + return $Closure9; +} + +``` + ## main.tf.json ```json { @@ -88,7 +330,7 @@ module.exports = function({ }) { }, "output": { "WING_TEST_RUNNER_FUNCTION_ARNS": { - "value": "[[\"root/Default/Default/test:length\",\"${aws_lambda_function.root_testlength_Handler_7245E498.arn}\"],[\"root/Default/Default/test:at()\",\"${aws_lambda_function.root_testat_Handler_39FB3FA1.arn}\"],[\"root/Default/Default/test:push()\",\"${aws_lambda_function.root_testpush_Handler_1F462746.arn}\"]]" + "value": "[[\"root/Default/Default/test:length\",\"${aws_lambda_function.root_testlength_Handler_7245E498.arn}\"],[\"root/Default/Default/test:at()\",\"${aws_lambda_function.root_testat_Handler_39FB3FA1.arn}\"],[\"root/Default/Default/test:pushAndPop()\",\"${aws_lambda_function.root_testpushAndPop_Handler_20B4DAAB.arn}\"],[\"root/Default/Default/test:concatMutArray()\",\"${aws_lambda_function.root_testconcatMutArray_Handler_CCDA88F4.arn}\"],[\"root/Default/Default/test:concatArray()\",\"${aws_lambda_function.root_testconcatArray_Handler_BCC85120.arn}\"],[\"root/Default/Default/test:contains()\",\"${aws_lambda_function.root_testcontains_Handler_9F29A18C.arn}\"],[\"root/Default/Default/test:indexOf()\",\"${aws_lambda_function.root_testindexOf_Handler_6F5475B9.arn}\"],[\"root/Default/Default/test:indexOfArray()\",\"${aws_lambda_function.root_testindexOfArray_Handler_C5842150.arn}\"],[\"root/Default/Default/test:join()\",\"${aws_lambda_function.root_testjoin_Handler_CB9050B7.arn}\"],[\"root/Default/Default/test:joinWithDefaultSeparator()\",\"${aws_lambda_function.root_testjoinWithDefaultSeparator_Handler_D6A71109.arn}\"],[\"root/Default/Default/test:copy()\",\"${aws_lambda_function.root_testcopy_Handler_8004DED9.arn}\"],[\"root/Default/Default/test:copyMut()\",\"${aws_lambda_function.root_testcopyMut_Handler_40DBEE6F.arn}\"],[\"root/Default/Default/test:lastIndexOf()\",\"${aws_lambda_function.root_testlastIndexOf_Handler_6B91D55C.arn}\"]]" } }, "provider": { @@ -107,6 +349,96 @@ module.exports = function({ }) { }, "assume_role_policy": "{\"Version\":\"2012-10-17\",\"Statement\":[{\"Action\":\"sts:AssumeRole\",\"Principal\":{\"Service\":\"lambda.amazonaws.com\"},\"Effect\":\"Allow\"}]}" }, + "root_testconcatArray_Handler_IamRole_1305F7EF": { + "//": { + "metadata": { + "path": "root/Default/Default/test:concatArray()/Handler/IamRole", + "uniqueId": "root_testconcatArray_Handler_IamRole_1305F7EF" + } + }, + "assume_role_policy": "{\"Version\":\"2012-10-17\",\"Statement\":[{\"Action\":\"sts:AssumeRole\",\"Principal\":{\"Service\":\"lambda.amazonaws.com\"},\"Effect\":\"Allow\"}]}" + }, + "root_testconcatMutArray_Handler_IamRole_51074FC0": { + "//": { + "metadata": { + "path": "root/Default/Default/test:concatMutArray()/Handler/IamRole", + "uniqueId": "root_testconcatMutArray_Handler_IamRole_51074FC0" + } + }, + "assume_role_policy": "{\"Version\":\"2012-10-17\",\"Statement\":[{\"Action\":\"sts:AssumeRole\",\"Principal\":{\"Service\":\"lambda.amazonaws.com\"},\"Effect\":\"Allow\"}]}" + }, + "root_testcontains_Handler_IamRole_D838F461": { + "//": { + "metadata": { + "path": "root/Default/Default/test:contains()/Handler/IamRole", + "uniqueId": "root_testcontains_Handler_IamRole_D838F461" + } + }, + "assume_role_policy": "{\"Version\":\"2012-10-17\",\"Statement\":[{\"Action\":\"sts:AssumeRole\",\"Principal\":{\"Service\":\"lambda.amazonaws.com\"},\"Effect\":\"Allow\"}]}" + }, + "root_testcopyMut_Handler_IamRole_0420D757": { + "//": { + "metadata": { + "path": "root/Default/Default/test:copyMut()/Handler/IamRole", + "uniqueId": "root_testcopyMut_Handler_IamRole_0420D757" + } + }, + "assume_role_policy": "{\"Version\":\"2012-10-17\",\"Statement\":[{\"Action\":\"sts:AssumeRole\",\"Principal\":{\"Service\":\"lambda.amazonaws.com\"},\"Effect\":\"Allow\"}]}" + }, + "root_testcopy_Handler_IamRole_61CF9BB6": { + "//": { + "metadata": { + "path": "root/Default/Default/test:copy()/Handler/IamRole", + "uniqueId": "root_testcopy_Handler_IamRole_61CF9BB6" + } + }, + "assume_role_policy": "{\"Version\":\"2012-10-17\",\"Statement\":[{\"Action\":\"sts:AssumeRole\",\"Principal\":{\"Service\":\"lambda.amazonaws.com\"},\"Effect\":\"Allow\"}]}" + }, + "root_testindexOfArray_Handler_IamRole_83E668FB": { + "//": { + "metadata": { + "path": "root/Default/Default/test:indexOfArray()/Handler/IamRole", + "uniqueId": "root_testindexOfArray_Handler_IamRole_83E668FB" + } + }, + "assume_role_policy": "{\"Version\":\"2012-10-17\",\"Statement\":[{\"Action\":\"sts:AssumeRole\",\"Principal\":{\"Service\":\"lambda.amazonaws.com\"},\"Effect\":\"Allow\"}]}" + }, + "root_testindexOf_Handler_IamRole_7B64B0A4": { + "//": { + "metadata": { + "path": "root/Default/Default/test:indexOf()/Handler/IamRole", + "uniqueId": "root_testindexOf_Handler_IamRole_7B64B0A4" + } + }, + "assume_role_policy": "{\"Version\":\"2012-10-17\",\"Statement\":[{\"Action\":\"sts:AssumeRole\",\"Principal\":{\"Service\":\"lambda.amazonaws.com\"},\"Effect\":\"Allow\"}]}" + }, + "root_testjoinWithDefaultSeparator_Handler_IamRole_236D0F20": { + "//": { + "metadata": { + "path": "root/Default/Default/test:joinWithDefaultSeparator()/Handler/IamRole", + "uniqueId": "root_testjoinWithDefaultSeparator_Handler_IamRole_236D0F20" + } + }, + "assume_role_policy": "{\"Version\":\"2012-10-17\",\"Statement\":[{\"Action\":\"sts:AssumeRole\",\"Principal\":{\"Service\":\"lambda.amazonaws.com\"},\"Effect\":\"Allow\"}]}" + }, + "root_testjoin_Handler_IamRole_51CF02B8": { + "//": { + "metadata": { + "path": "root/Default/Default/test:join()/Handler/IamRole", + "uniqueId": "root_testjoin_Handler_IamRole_51CF02B8" + } + }, + "assume_role_policy": "{\"Version\":\"2012-10-17\",\"Statement\":[{\"Action\":\"sts:AssumeRole\",\"Principal\":{\"Service\":\"lambda.amazonaws.com\"},\"Effect\":\"Allow\"}]}" + }, + "root_testlastIndexOf_Handler_IamRole_79D10A99": { + "//": { + "metadata": { + "path": "root/Default/Default/test:lastIndexOf()/Handler/IamRole", + "uniqueId": "root_testlastIndexOf_Handler_IamRole_79D10A99" + } + }, + "assume_role_policy": "{\"Version\":\"2012-10-17\",\"Statement\":[{\"Action\":\"sts:AssumeRole\",\"Principal\":{\"Service\":\"lambda.amazonaws.com\"},\"Effect\":\"Allow\"}]}" + }, "root_testlength_Handler_IamRole_A8384051": { "//": { "metadata": { @@ -116,11 +448,11 @@ module.exports = function({ }) { }, "assume_role_policy": "{\"Version\":\"2012-10-17\",\"Statement\":[{\"Action\":\"sts:AssumeRole\",\"Principal\":{\"Service\":\"lambda.amazonaws.com\"},\"Effect\":\"Allow\"}]}" }, - "root_testpush_Handler_IamRole_3B5EB3DF": { + "root_testpushAndPop_Handler_IamRole_EC6118B7": { "//": { "metadata": { - "path": "root/Default/Default/test:push()/Handler/IamRole", - "uniqueId": "root_testpush_Handler_IamRole_3B5EB3DF" + "path": "root/Default/Default/test:pushAndPop()/Handler/IamRole", + "uniqueId": "root_testpushAndPop_Handler_IamRole_EC6118B7" } }, "assume_role_policy": "{\"Version\":\"2012-10-17\",\"Statement\":[{\"Action\":\"sts:AssumeRole\",\"Principal\":{\"Service\":\"lambda.amazonaws.com\"},\"Effect\":\"Allow\"}]}" @@ -137,74 +469,274 @@ module.exports = function({ }) { "policy": "{\"Version\":\"2012-10-17\",\"Statement\":[{\"Effect\":\"Allow\",\"Action\":\"none:null\",\"Resource\":\"*\"}]}", "role": "${aws_iam_role.root_testat_Handler_IamRole_EA5BD403.name}" }, - "root_testlength_Handler_IamRolePolicy_9DE70A2C": { + "root_testconcatArray_Handler_IamRolePolicy_ECEF2107": { "//": { "metadata": { - "path": "root/Default/Default/test:length/Handler/IamRolePolicy", - "uniqueId": "root_testlength_Handler_IamRolePolicy_9DE70A2C" + "path": "root/Default/Default/test:concatArray()/Handler/IamRolePolicy", + "uniqueId": "root_testconcatArray_Handler_IamRolePolicy_ECEF2107" } }, "policy": "{\"Version\":\"2012-10-17\",\"Statement\":[{\"Effect\":\"Allow\",\"Action\":\"none:null\",\"Resource\":\"*\"}]}", - "role": "${aws_iam_role.root_testlength_Handler_IamRole_A8384051.name}" + "role": "${aws_iam_role.root_testconcatArray_Handler_IamRole_1305F7EF.name}" }, - "root_testpush_Handler_IamRolePolicy_7691DE83": { + "root_testconcatMutArray_Handler_IamRolePolicy_3C7C25C2": { "//": { "metadata": { - "path": "root/Default/Default/test:push()/Handler/IamRolePolicy", - "uniqueId": "root_testpush_Handler_IamRolePolicy_7691DE83" + "path": "root/Default/Default/test:concatMutArray()/Handler/IamRolePolicy", + "uniqueId": "root_testconcatMutArray_Handler_IamRolePolicy_3C7C25C2" } }, "policy": "{\"Version\":\"2012-10-17\",\"Statement\":[{\"Effect\":\"Allow\",\"Action\":\"none:null\",\"Resource\":\"*\"}]}", - "role": "${aws_iam_role.root_testpush_Handler_IamRole_3B5EB3DF.name}" - } - }, - "aws_iam_role_policy_attachment": { - "root_testat_Handler_IamRolePolicyAttachment_13C52D1D": { + "role": "${aws_iam_role.root_testconcatMutArray_Handler_IamRole_51074FC0.name}" + }, + "root_testcontains_Handler_IamRolePolicy_98FEE2B9": { "//": { "metadata": { - "path": "root/Default/Default/test:at()/Handler/IamRolePolicyAttachment", - "uniqueId": "root_testat_Handler_IamRolePolicyAttachment_13C52D1D" + "path": "root/Default/Default/test:contains()/Handler/IamRolePolicy", + "uniqueId": "root_testcontains_Handler_IamRolePolicy_98FEE2B9" } }, - "policy_arn": "arn:aws:iam::aws:policy/service-role/AWSLambdaBasicExecutionRole", - "role": "${aws_iam_role.root_testat_Handler_IamRole_EA5BD403.name}" + "policy": "{\"Version\":\"2012-10-17\",\"Statement\":[{\"Effect\":\"Allow\",\"Action\":\"none:null\",\"Resource\":\"*\"}]}", + "role": "${aws_iam_role.root_testcontains_Handler_IamRole_D838F461.name}" }, - "root_testlength_Handler_IamRolePolicyAttachment_75515754": { + "root_testcopyMut_Handler_IamRolePolicy_0651D1C7": { "//": { "metadata": { - "path": "root/Default/Default/test:length/Handler/IamRolePolicyAttachment", - "uniqueId": "root_testlength_Handler_IamRolePolicyAttachment_75515754" + "path": "root/Default/Default/test:copyMut()/Handler/IamRolePolicy", + "uniqueId": "root_testcopyMut_Handler_IamRolePolicy_0651D1C7" } }, - "policy_arn": "arn:aws:iam::aws:policy/service-role/AWSLambdaBasicExecutionRole", - "role": "${aws_iam_role.root_testlength_Handler_IamRole_A8384051.name}" + "policy": "{\"Version\":\"2012-10-17\",\"Statement\":[{\"Effect\":\"Allow\",\"Action\":\"none:null\",\"Resource\":\"*\"}]}", + "role": "${aws_iam_role.root_testcopyMut_Handler_IamRole_0420D757.name}" }, - "root_testpush_Handler_IamRolePolicyAttachment_2F482395": { + "root_testcopy_Handler_IamRolePolicy_AED6FB45": { "//": { "metadata": { - "path": "root/Default/Default/test:push()/Handler/IamRolePolicyAttachment", - "uniqueId": "root_testpush_Handler_IamRolePolicyAttachment_2F482395" + "path": "root/Default/Default/test:copy()/Handler/IamRolePolicy", + "uniqueId": "root_testcopy_Handler_IamRolePolicy_AED6FB45" } }, - "policy_arn": "arn:aws:iam::aws:policy/service-role/AWSLambdaBasicExecutionRole", - "role": "${aws_iam_role.root_testpush_Handler_IamRole_3B5EB3DF.name}" - } - }, - "aws_lambda_function": { - "root_testat_Handler_39FB3FA1": { + "policy": "{\"Version\":\"2012-10-17\",\"Statement\":[{\"Effect\":\"Allow\",\"Action\":\"none:null\",\"Resource\":\"*\"}]}", + "role": "${aws_iam_role.root_testcopy_Handler_IamRole_61CF9BB6.name}" + }, + "root_testindexOfArray_Handler_IamRolePolicy_38DAB8BF": { "//": { "metadata": { - "path": "root/Default/Default/test:at()/Handler/Default", - "uniqueId": "root_testat_Handler_39FB3FA1" - } - }, - "environment": { - "variables": { - "WING_FUNCTION_NAME": "Handler-c858faac", - "WING_TARGET": "tf-aws" + "path": "root/Default/Default/test:indexOfArray()/Handler/IamRolePolicy", + "uniqueId": "root_testindexOfArray_Handler_IamRolePolicy_38DAB8BF" } }, - "function_name": "Handler-c858faac", + "policy": "{\"Version\":\"2012-10-17\",\"Statement\":[{\"Effect\":\"Allow\",\"Action\":\"none:null\",\"Resource\":\"*\"}]}", + "role": "${aws_iam_role.root_testindexOfArray_Handler_IamRole_83E668FB.name}" + }, + "root_testindexOf_Handler_IamRolePolicy_8E7A6391": { + "//": { + "metadata": { + "path": "root/Default/Default/test:indexOf()/Handler/IamRolePolicy", + "uniqueId": "root_testindexOf_Handler_IamRolePolicy_8E7A6391" + } + }, + "policy": "{\"Version\":\"2012-10-17\",\"Statement\":[{\"Effect\":\"Allow\",\"Action\":\"none:null\",\"Resource\":\"*\"}]}", + "role": "${aws_iam_role.root_testindexOf_Handler_IamRole_7B64B0A4.name}" + }, + "root_testjoinWithDefaultSeparator_Handler_IamRolePolicy_821C9484": { + "//": { + "metadata": { + "path": "root/Default/Default/test:joinWithDefaultSeparator()/Handler/IamRolePolicy", + "uniqueId": "root_testjoinWithDefaultSeparator_Handler_IamRolePolicy_821C9484" + } + }, + "policy": "{\"Version\":\"2012-10-17\",\"Statement\":[{\"Effect\":\"Allow\",\"Action\":\"none:null\",\"Resource\":\"*\"}]}", + "role": "${aws_iam_role.root_testjoinWithDefaultSeparator_Handler_IamRole_236D0F20.name}" + }, + "root_testjoin_Handler_IamRolePolicy_A86111B4": { + "//": { + "metadata": { + "path": "root/Default/Default/test:join()/Handler/IamRolePolicy", + "uniqueId": "root_testjoin_Handler_IamRolePolicy_A86111B4" + } + }, + "policy": "{\"Version\":\"2012-10-17\",\"Statement\":[{\"Effect\":\"Allow\",\"Action\":\"none:null\",\"Resource\":\"*\"}]}", + "role": "${aws_iam_role.root_testjoin_Handler_IamRole_51CF02B8.name}" + }, + "root_testlastIndexOf_Handler_IamRolePolicy_C49B9CD0": { + "//": { + "metadata": { + "path": "root/Default/Default/test:lastIndexOf()/Handler/IamRolePolicy", + "uniqueId": "root_testlastIndexOf_Handler_IamRolePolicy_C49B9CD0" + } + }, + "policy": "{\"Version\":\"2012-10-17\",\"Statement\":[{\"Effect\":\"Allow\",\"Action\":\"none:null\",\"Resource\":\"*\"}]}", + "role": "${aws_iam_role.root_testlastIndexOf_Handler_IamRole_79D10A99.name}" + }, + "root_testlength_Handler_IamRolePolicy_9DE70A2C": { + "//": { + "metadata": { + "path": "root/Default/Default/test:length/Handler/IamRolePolicy", + "uniqueId": "root_testlength_Handler_IamRolePolicy_9DE70A2C" + } + }, + "policy": "{\"Version\":\"2012-10-17\",\"Statement\":[{\"Effect\":\"Allow\",\"Action\":\"none:null\",\"Resource\":\"*\"}]}", + "role": "${aws_iam_role.root_testlength_Handler_IamRole_A8384051.name}" + }, + "root_testpushAndPop_Handler_IamRolePolicy_38557369": { + "//": { + "metadata": { + "path": "root/Default/Default/test:pushAndPop()/Handler/IamRolePolicy", + "uniqueId": "root_testpushAndPop_Handler_IamRolePolicy_38557369" + } + }, + "policy": "{\"Version\":\"2012-10-17\",\"Statement\":[{\"Effect\":\"Allow\",\"Action\":\"none:null\",\"Resource\":\"*\"}]}", + "role": "${aws_iam_role.root_testpushAndPop_Handler_IamRole_EC6118B7.name}" + } + }, + "aws_iam_role_policy_attachment": { + "root_testat_Handler_IamRolePolicyAttachment_13C52D1D": { + "//": { + "metadata": { + "path": "root/Default/Default/test:at()/Handler/IamRolePolicyAttachment", + "uniqueId": "root_testat_Handler_IamRolePolicyAttachment_13C52D1D" + } + }, + "policy_arn": "arn:aws:iam::aws:policy/service-role/AWSLambdaBasicExecutionRole", + "role": "${aws_iam_role.root_testat_Handler_IamRole_EA5BD403.name}" + }, + "root_testconcatArray_Handler_IamRolePolicyAttachment_A6817FE8": { + "//": { + "metadata": { + "path": "root/Default/Default/test:concatArray()/Handler/IamRolePolicyAttachment", + "uniqueId": "root_testconcatArray_Handler_IamRolePolicyAttachment_A6817FE8" + } + }, + "policy_arn": "arn:aws:iam::aws:policy/service-role/AWSLambdaBasicExecutionRole", + "role": "${aws_iam_role.root_testconcatArray_Handler_IamRole_1305F7EF.name}" + }, + "root_testconcatMutArray_Handler_IamRolePolicyAttachment_823829C8": { + "//": { + "metadata": { + "path": "root/Default/Default/test:concatMutArray()/Handler/IamRolePolicyAttachment", + "uniqueId": "root_testconcatMutArray_Handler_IamRolePolicyAttachment_823829C8" + } + }, + "policy_arn": "arn:aws:iam::aws:policy/service-role/AWSLambdaBasicExecutionRole", + "role": "${aws_iam_role.root_testconcatMutArray_Handler_IamRole_51074FC0.name}" + }, + "root_testcontains_Handler_IamRolePolicyAttachment_2B74BA53": { + "//": { + "metadata": { + "path": "root/Default/Default/test:contains()/Handler/IamRolePolicyAttachment", + "uniqueId": "root_testcontains_Handler_IamRolePolicyAttachment_2B74BA53" + } + }, + "policy_arn": "arn:aws:iam::aws:policy/service-role/AWSLambdaBasicExecutionRole", + "role": "${aws_iam_role.root_testcontains_Handler_IamRole_D838F461.name}" + }, + "root_testcopyMut_Handler_IamRolePolicyAttachment_A145DB50": { + "//": { + "metadata": { + "path": "root/Default/Default/test:copyMut()/Handler/IamRolePolicyAttachment", + "uniqueId": "root_testcopyMut_Handler_IamRolePolicyAttachment_A145DB50" + } + }, + "policy_arn": "arn:aws:iam::aws:policy/service-role/AWSLambdaBasicExecutionRole", + "role": "${aws_iam_role.root_testcopyMut_Handler_IamRole_0420D757.name}" + }, + "root_testcopy_Handler_IamRolePolicyAttachment_DE98366C": { + "//": { + "metadata": { + "path": "root/Default/Default/test:copy()/Handler/IamRolePolicyAttachment", + "uniqueId": "root_testcopy_Handler_IamRolePolicyAttachment_DE98366C" + } + }, + "policy_arn": "arn:aws:iam::aws:policy/service-role/AWSLambdaBasicExecutionRole", + "role": "${aws_iam_role.root_testcopy_Handler_IamRole_61CF9BB6.name}" + }, + "root_testindexOfArray_Handler_IamRolePolicyAttachment_C8C5F58B": { + "//": { + "metadata": { + "path": "root/Default/Default/test:indexOfArray()/Handler/IamRolePolicyAttachment", + "uniqueId": "root_testindexOfArray_Handler_IamRolePolicyAttachment_C8C5F58B" + } + }, + "policy_arn": "arn:aws:iam::aws:policy/service-role/AWSLambdaBasicExecutionRole", + "role": "${aws_iam_role.root_testindexOfArray_Handler_IamRole_83E668FB.name}" + }, + "root_testindexOf_Handler_IamRolePolicyAttachment_44945C33": { + "//": { + "metadata": { + "path": "root/Default/Default/test:indexOf()/Handler/IamRolePolicyAttachment", + "uniqueId": "root_testindexOf_Handler_IamRolePolicyAttachment_44945C33" + } + }, + "policy_arn": "arn:aws:iam::aws:policy/service-role/AWSLambdaBasicExecutionRole", + "role": "${aws_iam_role.root_testindexOf_Handler_IamRole_7B64B0A4.name}" + }, + "root_testjoinWithDefaultSeparator_Handler_IamRolePolicyAttachment_580EDA79": { + "//": { + "metadata": { + "path": "root/Default/Default/test:joinWithDefaultSeparator()/Handler/IamRolePolicyAttachment", + "uniqueId": "root_testjoinWithDefaultSeparator_Handler_IamRolePolicyAttachment_580EDA79" + } + }, + "policy_arn": "arn:aws:iam::aws:policy/service-role/AWSLambdaBasicExecutionRole", + "role": "${aws_iam_role.root_testjoinWithDefaultSeparator_Handler_IamRole_236D0F20.name}" + }, + "root_testjoin_Handler_IamRolePolicyAttachment_24627D71": { + "//": { + "metadata": { + "path": "root/Default/Default/test:join()/Handler/IamRolePolicyAttachment", + "uniqueId": "root_testjoin_Handler_IamRolePolicyAttachment_24627D71" + } + }, + "policy_arn": "arn:aws:iam::aws:policy/service-role/AWSLambdaBasicExecutionRole", + "role": "${aws_iam_role.root_testjoin_Handler_IamRole_51CF02B8.name}" + }, + "root_testlastIndexOf_Handler_IamRolePolicyAttachment_C8DBAEB8": { + "//": { + "metadata": { + "path": "root/Default/Default/test:lastIndexOf()/Handler/IamRolePolicyAttachment", + "uniqueId": "root_testlastIndexOf_Handler_IamRolePolicyAttachment_C8DBAEB8" + } + }, + "policy_arn": "arn:aws:iam::aws:policy/service-role/AWSLambdaBasicExecutionRole", + "role": "${aws_iam_role.root_testlastIndexOf_Handler_IamRole_79D10A99.name}" + }, + "root_testlength_Handler_IamRolePolicyAttachment_75515754": { + "//": { + "metadata": { + "path": "root/Default/Default/test:length/Handler/IamRolePolicyAttachment", + "uniqueId": "root_testlength_Handler_IamRolePolicyAttachment_75515754" + } + }, + "policy_arn": "arn:aws:iam::aws:policy/service-role/AWSLambdaBasicExecutionRole", + "role": "${aws_iam_role.root_testlength_Handler_IamRole_A8384051.name}" + }, + "root_testpushAndPop_Handler_IamRolePolicyAttachment_F2C28810": { + "//": { + "metadata": { + "path": "root/Default/Default/test:pushAndPop()/Handler/IamRolePolicyAttachment", + "uniqueId": "root_testpushAndPop_Handler_IamRolePolicyAttachment_F2C28810" + } + }, + "policy_arn": "arn:aws:iam::aws:policy/service-role/AWSLambdaBasicExecutionRole", + "role": "${aws_iam_role.root_testpushAndPop_Handler_IamRole_EC6118B7.name}" + } + }, + "aws_lambda_function": { + "root_testat_Handler_39FB3FA1": { + "//": { + "metadata": { + "path": "root/Default/Default/test:at()/Handler/Default", + "uniqueId": "root_testat_Handler_39FB3FA1" + } + }, + "environment": { + "variables": { + "WING_FUNCTION_NAME": "Handler-c858faac", + "WING_TARGET": "tf-aws" + } + }, + "function_name": "Handler-c858faac", "handler": "index.handler", "publish": true, "role": "${aws_iam_role.root_testat_Handler_IamRole_EA5BD403.arn}", @@ -216,128 +748,844 @@ module.exports = function({ }) { "security_group_ids": [], "subnet_ids": [] } - }, - "root_testlength_Handler_7245E498": { - "//": { - "metadata": { - "path": "root/Default/Default/test:length/Handler/Default", - "uniqueId": "root_testlength_Handler_7245E498" - } - }, - "environment": { - "variables": { - "WING_FUNCTION_NAME": "Handler-c8e0ccbd", - "WING_TARGET": "tf-aws" - } - }, - "function_name": "Handler-c8e0ccbd", - "handler": "index.handler", - "publish": true, - "role": "${aws_iam_role.root_testlength_Handler_IamRole_A8384051.arn}", - "runtime": "nodejs18.x", - "s3_bucket": "${aws_s3_bucket.root_Code_02F3C603.bucket}", - "s3_key": "${aws_s3_object.root_testlength_Handler_S3Object_22B052A5.key}", - "timeout": 30, - "vpc_config": { - "security_group_ids": [], - "subnet_ids": [] + }, + "root_testconcatArray_Handler_BCC85120": { + "//": { + "metadata": { + "path": "root/Default/Default/test:concatArray()/Handler/Default", + "uniqueId": "root_testconcatArray_Handler_BCC85120" + } + }, + "environment": { + "variables": { + "WING_FUNCTION_NAME": "Handler-c8ba9aa0", + "WING_TARGET": "tf-aws" + } + }, + "function_name": "Handler-c8ba9aa0", + "handler": "index.handler", + "publish": true, + "role": "${aws_iam_role.root_testconcatArray_Handler_IamRole_1305F7EF.arn}", + "runtime": "nodejs18.x", + "s3_bucket": "${aws_s3_bucket.root_Code_02F3C603.bucket}", + "s3_key": "${aws_s3_object.root_testconcatArray_Handler_S3Object_7F2389FB.key}", + "timeout": 30, + "vpc_config": { + "security_group_ids": [], + "subnet_ids": [] + } + }, + "root_testconcatMutArray_Handler_CCDA88F4": { + "//": { + "metadata": { + "path": "root/Default/Default/test:concatMutArray()/Handler/Default", + "uniqueId": "root_testconcatMutArray_Handler_CCDA88F4" + } + }, + "environment": { + "variables": { + "WING_FUNCTION_NAME": "Handler-c8e5a138", + "WING_TARGET": "tf-aws" + } + }, + "function_name": "Handler-c8e5a138", + "handler": "index.handler", + "publish": true, + "role": "${aws_iam_role.root_testconcatMutArray_Handler_IamRole_51074FC0.arn}", + "runtime": "nodejs18.x", + "s3_bucket": "${aws_s3_bucket.root_Code_02F3C603.bucket}", + "s3_key": "${aws_s3_object.root_testconcatMutArray_Handler_S3Object_500993A4.key}", + "timeout": 30, + "vpc_config": { + "security_group_ids": [], + "subnet_ids": [] + } + }, + "root_testcontains_Handler_9F29A18C": { + "//": { + "metadata": { + "path": "root/Default/Default/test:contains()/Handler/Default", + "uniqueId": "root_testcontains_Handler_9F29A18C" + } + }, + "environment": { + "variables": { + "WING_FUNCTION_NAME": "Handler-c8e953a0", + "WING_TARGET": "tf-aws" + } + }, + "function_name": "Handler-c8e953a0", + "handler": "index.handler", + "publish": true, + "role": "${aws_iam_role.root_testcontains_Handler_IamRole_D838F461.arn}", + "runtime": "nodejs18.x", + "s3_bucket": "${aws_s3_bucket.root_Code_02F3C603.bucket}", + "s3_key": "${aws_s3_object.root_testcontains_Handler_S3Object_65C920EB.key}", + "timeout": 30, + "vpc_config": { + "security_group_ids": [], + "subnet_ids": [] + } + }, + "root_testcopyMut_Handler_40DBEE6F": { + "//": { + "metadata": { + "path": "root/Default/Default/test:copyMut()/Handler/Default", + "uniqueId": "root_testcopyMut_Handler_40DBEE6F" + } + }, + "environment": { + "variables": { + "WING_FUNCTION_NAME": "Handler-c8b1cc09", + "WING_TARGET": "tf-aws" + } + }, + "function_name": "Handler-c8b1cc09", + "handler": "index.handler", + "publish": true, + "role": "${aws_iam_role.root_testcopyMut_Handler_IamRole_0420D757.arn}", + "runtime": "nodejs18.x", + "s3_bucket": "${aws_s3_bucket.root_Code_02F3C603.bucket}", + "s3_key": "${aws_s3_object.root_testcopyMut_Handler_S3Object_2868869B.key}", + "timeout": 30, + "vpc_config": { + "security_group_ids": [], + "subnet_ids": [] + } + }, + "root_testcopy_Handler_8004DED9": { + "//": { + "metadata": { + "path": "root/Default/Default/test:copy()/Handler/Default", + "uniqueId": "root_testcopy_Handler_8004DED9" + } + }, + "environment": { + "variables": { + "WING_FUNCTION_NAME": "Handler-c802a3d7", + "WING_TARGET": "tf-aws" + } + }, + "function_name": "Handler-c802a3d7", + "handler": "index.handler", + "publish": true, + "role": "${aws_iam_role.root_testcopy_Handler_IamRole_61CF9BB6.arn}", + "runtime": "nodejs18.x", + "s3_bucket": "${aws_s3_bucket.root_Code_02F3C603.bucket}", + "s3_key": "${aws_s3_object.root_testcopy_Handler_S3Object_29FB2C8F.key}", + "timeout": 30, + "vpc_config": { + "security_group_ids": [], + "subnet_ids": [] + } + }, + "root_testindexOfArray_Handler_C5842150": { + "//": { + "metadata": { + "path": "root/Default/Default/test:indexOfArray()/Handler/Default", + "uniqueId": "root_testindexOfArray_Handler_C5842150" + } + }, + "environment": { + "variables": { + "WING_FUNCTION_NAME": "Handler-c88fa7a3", + "WING_TARGET": "tf-aws" + } + }, + "function_name": "Handler-c88fa7a3", + "handler": "index.handler", + "publish": true, + "role": "${aws_iam_role.root_testindexOfArray_Handler_IamRole_83E668FB.arn}", + "runtime": "nodejs18.x", + "s3_bucket": "${aws_s3_bucket.root_Code_02F3C603.bucket}", + "s3_key": "${aws_s3_object.root_testindexOfArray_Handler_S3Object_302D960F.key}", + "timeout": 30, + "vpc_config": { + "security_group_ids": [], + "subnet_ids": [] + } + }, + "root_testindexOf_Handler_6F5475B9": { + "//": { + "metadata": { + "path": "root/Default/Default/test:indexOf()/Handler/Default", + "uniqueId": "root_testindexOf_Handler_6F5475B9" + } + }, + "environment": { + "variables": { + "WING_FUNCTION_NAME": "Handler-c80be453", + "WING_TARGET": "tf-aws" + } + }, + "function_name": "Handler-c80be453", + "handler": "index.handler", + "publish": true, + "role": "${aws_iam_role.root_testindexOf_Handler_IamRole_7B64B0A4.arn}", + "runtime": "nodejs18.x", + "s3_bucket": "${aws_s3_bucket.root_Code_02F3C603.bucket}", + "s3_key": "${aws_s3_object.root_testindexOf_Handler_S3Object_4F451E5A.key}", + "timeout": 30, + "vpc_config": { + "security_group_ids": [], + "subnet_ids": [] + } + }, + "root_testjoinWithDefaultSeparator_Handler_D6A71109": { + "//": { + "metadata": { + "path": "root/Default/Default/test:joinWithDefaultSeparator()/Handler/Default", + "uniqueId": "root_testjoinWithDefaultSeparator_Handler_D6A71109" + } + }, + "environment": { + "variables": { + "WING_FUNCTION_NAME": "Handler-c833ed71", + "WING_TARGET": "tf-aws" + } + }, + "function_name": "Handler-c833ed71", + "handler": "index.handler", + "publish": true, + "role": "${aws_iam_role.root_testjoinWithDefaultSeparator_Handler_IamRole_236D0F20.arn}", + "runtime": "nodejs18.x", + "s3_bucket": "${aws_s3_bucket.root_Code_02F3C603.bucket}", + "s3_key": "${aws_s3_object.root_testjoinWithDefaultSeparator_Handler_S3Object_42DD08C0.key}", + "timeout": 30, + "vpc_config": { + "security_group_ids": [], + "subnet_ids": [] + } + }, + "root_testjoin_Handler_CB9050B7": { + "//": { + "metadata": { + "path": "root/Default/Default/test:join()/Handler/Default", + "uniqueId": "root_testjoin_Handler_CB9050B7" + } + }, + "environment": { + "variables": { + "WING_FUNCTION_NAME": "Handler-c8a46f15", + "WING_TARGET": "tf-aws" + } + }, + "function_name": "Handler-c8a46f15", + "handler": "index.handler", + "publish": true, + "role": "${aws_iam_role.root_testjoin_Handler_IamRole_51CF02B8.arn}", + "runtime": "nodejs18.x", + "s3_bucket": "${aws_s3_bucket.root_Code_02F3C603.bucket}", + "s3_key": "${aws_s3_object.root_testjoin_Handler_S3Object_72E20B44.key}", + "timeout": 30, + "vpc_config": { + "security_group_ids": [], + "subnet_ids": [] + } + }, + "root_testlastIndexOf_Handler_6B91D55C": { + "//": { + "metadata": { + "path": "root/Default/Default/test:lastIndexOf()/Handler/Default", + "uniqueId": "root_testlastIndexOf_Handler_6B91D55C" + } + }, + "environment": { + "variables": { + "WING_FUNCTION_NAME": "Handler-c84609d0", + "WING_TARGET": "tf-aws" + } + }, + "function_name": "Handler-c84609d0", + "handler": "index.handler", + "publish": true, + "role": "${aws_iam_role.root_testlastIndexOf_Handler_IamRole_79D10A99.arn}", + "runtime": "nodejs18.x", + "s3_bucket": "${aws_s3_bucket.root_Code_02F3C603.bucket}", + "s3_key": "${aws_s3_object.root_testlastIndexOf_Handler_S3Object_2B34A1FC.key}", + "timeout": 30, + "vpc_config": { + "security_group_ids": [], + "subnet_ids": [] + } + }, + "root_testlength_Handler_7245E498": { + "//": { + "metadata": { + "path": "root/Default/Default/test:length/Handler/Default", + "uniqueId": "root_testlength_Handler_7245E498" + } + }, + "environment": { + "variables": { + "WING_FUNCTION_NAME": "Handler-c8e0ccbd", + "WING_TARGET": "tf-aws" + } + }, + "function_name": "Handler-c8e0ccbd", + "handler": "index.handler", + "publish": true, + "role": "${aws_iam_role.root_testlength_Handler_IamRole_A8384051.arn}", + "runtime": "nodejs18.x", + "s3_bucket": "${aws_s3_bucket.root_Code_02F3C603.bucket}", + "s3_key": "${aws_s3_object.root_testlength_Handler_S3Object_22B052A5.key}", + "timeout": 30, + "vpc_config": { + "security_group_ids": [], + "subnet_ids": [] + } + }, + "root_testpushAndPop_Handler_20B4DAAB": { + "//": { + "metadata": { + "path": "root/Default/Default/test:pushAndPop()/Handler/Default", + "uniqueId": "root_testpushAndPop_Handler_20B4DAAB" + } + }, + "environment": { + "variables": { + "WING_FUNCTION_NAME": "Handler-c8b6e896", + "WING_TARGET": "tf-aws" + } + }, + "function_name": "Handler-c8b6e896", + "handler": "index.handler", + "publish": true, + "role": "${aws_iam_role.root_testpushAndPop_Handler_IamRole_EC6118B7.arn}", + "runtime": "nodejs18.x", + "s3_bucket": "${aws_s3_bucket.root_Code_02F3C603.bucket}", + "s3_key": "${aws_s3_object.root_testpushAndPop_Handler_S3Object_E9F1EBBB.key}", + "timeout": 30, + "vpc_config": { + "security_group_ids": [], + "subnet_ids": [] + } + } + }, + "aws_s3_bucket": { + "root_Code_02F3C603": { + "//": { + "metadata": { + "path": "root/Default/Code", + "uniqueId": "root_Code_02F3C603" + } + }, + "bucket_prefix": "code-c84a50b1-" + }, + "root_cloudBucket_4F3C4F53": { + "//": { + "metadata": { + "path": "root/Default/Default/cloud.Bucket/Default", + "uniqueId": "root_cloudBucket_4F3C4F53" + } + }, + "bucket_prefix": "cloud-bucket-c87175e7-", + "force_destroy": false + }, + "root_myBucket_86EF9F01": { + "//": { + "metadata": { + "path": "root/Default/Default/myBucket/Default", + "uniqueId": "root_myBucket_86EF9F01" + } + }, + "bucket_prefix": "mybucket-c8573914-", + "force_destroy": false + }, + "root_mySecondBucket_DC733AF4": { + "//": { + "metadata": { + "path": "root/Default/Default/mySecondBucket/Default", + "uniqueId": "root_mySecondBucket_DC733AF4" + } + }, + "bucket_prefix": "mysecondbucket-c8d5dc33-", + "force_destroy": false + } + }, + "aws_s3_bucket_public_access_block": { + "root_cloudBucket_PublicAccessBlock_319C1C2E": { + "//": { + "metadata": { + "path": "root/Default/Default/cloud.Bucket/PublicAccessBlock", + "uniqueId": "root_cloudBucket_PublicAccessBlock_319C1C2E" + } + }, + "block_public_acls": true, + "block_public_policy": true, + "bucket": "${aws_s3_bucket.root_cloudBucket_4F3C4F53.bucket}", + "ignore_public_acls": true, + "restrict_public_buckets": true + }, + "root_myBucket_PublicAccessBlock_D0DC82F2": { + "//": { + "metadata": { + "path": "root/Default/Default/myBucket/PublicAccessBlock", + "uniqueId": "root_myBucket_PublicAccessBlock_D0DC82F2" + } + }, + "block_public_acls": true, + "block_public_policy": true, + "bucket": "${aws_s3_bucket.root_myBucket_86EF9F01.bucket}", + "ignore_public_acls": true, + "restrict_public_buckets": true + }, + "root_mySecondBucket_PublicAccessBlock_3CD2DFE6": { + "//": { + "metadata": { + "path": "root/Default/Default/mySecondBucket/PublicAccessBlock", + "uniqueId": "root_mySecondBucket_PublicAccessBlock_3CD2DFE6" + } + }, + "block_public_acls": true, + "block_public_policy": true, + "bucket": "${aws_s3_bucket.root_mySecondBucket_DC733AF4.bucket}", + "ignore_public_acls": true, + "restrict_public_buckets": true + } + }, + "aws_s3_bucket_server_side_encryption_configuration": { + "root_cloudBucket_Encryption_8ED0CD9C": { + "//": { + "metadata": { + "path": "root/Default/Default/cloud.Bucket/Encryption", + "uniqueId": "root_cloudBucket_Encryption_8ED0CD9C" + } + }, + "bucket": "${aws_s3_bucket.root_cloudBucket_4F3C4F53.bucket}", + "rule": [ + { + "apply_server_side_encryption_by_default": { + "sse_algorithm": "AES256" + } + } + ] + }, + "root_myBucket_Encryption_6D0EB5B0": { + "//": { + "metadata": { + "path": "root/Default/Default/myBucket/Encryption", + "uniqueId": "root_myBucket_Encryption_6D0EB5B0" + } + }, + "bucket": "${aws_s3_bucket.root_myBucket_86EF9F01.bucket}", + "rule": [ + { + "apply_server_side_encryption_by_default": { + "sse_algorithm": "AES256" + } + } + ] + }, + "root_mySecondBucket_Encryption_AFD9A702": { + "//": { + "metadata": { + "path": "root/Default/Default/mySecondBucket/Encryption", + "uniqueId": "root_mySecondBucket_Encryption_AFD9A702" + } + }, + "bucket": "${aws_s3_bucket.root_mySecondBucket_DC733AF4.bucket}", + "rule": [ + { + "apply_server_side_encryption_by_default": { + "sse_algorithm": "AES256" + } + } + ] + } + }, + "aws_s3_object": { + "root_testat_Handler_S3Object_C90B92D0": { + "//": { + "metadata": { + "path": "root/Default/Default/test:at()/Handler/S3Object", + "uniqueId": "root_testat_Handler_S3Object_C90B92D0" + } + }, + "bucket": "${aws_s3_bucket.root_Code_02F3C603.bucket}", + "key": "", + "source": "" + }, + "root_testconcatArray_Handler_S3Object_7F2389FB": { + "//": { + "metadata": { + "path": "root/Default/Default/test:concatArray()/Handler/S3Object", + "uniqueId": "root_testconcatArray_Handler_S3Object_7F2389FB" + } + }, + "bucket": "${aws_s3_bucket.root_Code_02F3C603.bucket}", + "key": "", + "source": "" + }, + "root_testconcatMutArray_Handler_S3Object_500993A4": { + "//": { + "metadata": { + "path": "root/Default/Default/test:concatMutArray()/Handler/S3Object", + "uniqueId": "root_testconcatMutArray_Handler_S3Object_500993A4" + } + }, + "bucket": "${aws_s3_bucket.root_Code_02F3C603.bucket}", + "key": "", + "source": "" + }, + "root_testcontains_Handler_S3Object_65C920EB": { + "//": { + "metadata": { + "path": "root/Default/Default/test:contains()/Handler/S3Object", + "uniqueId": "root_testcontains_Handler_S3Object_65C920EB" + } + }, + "bucket": "${aws_s3_bucket.root_Code_02F3C603.bucket}", + "key": "", + "source": "" + }, + "root_testcopyMut_Handler_S3Object_2868869B": { + "//": { + "metadata": { + "path": "root/Default/Default/test:copyMut()/Handler/S3Object", + "uniqueId": "root_testcopyMut_Handler_S3Object_2868869B" + } + }, + "bucket": "${aws_s3_bucket.root_Code_02F3C603.bucket}", + "key": "", + "source": "" + }, + "root_testcopy_Handler_S3Object_29FB2C8F": { + "//": { + "metadata": { + "path": "root/Default/Default/test:copy()/Handler/S3Object", + "uniqueId": "root_testcopy_Handler_S3Object_29FB2C8F" + } + }, + "bucket": "${aws_s3_bucket.root_Code_02F3C603.bucket}", + "key": "", + "source": "" + }, + "root_testindexOfArray_Handler_S3Object_302D960F": { + "//": { + "metadata": { + "path": "root/Default/Default/test:indexOfArray()/Handler/S3Object", + "uniqueId": "root_testindexOfArray_Handler_S3Object_302D960F" + } + }, + "bucket": "${aws_s3_bucket.root_Code_02F3C603.bucket}", + "key": "", + "source": "" + }, + "root_testindexOf_Handler_S3Object_4F451E5A": { + "//": { + "metadata": { + "path": "root/Default/Default/test:indexOf()/Handler/S3Object", + "uniqueId": "root_testindexOf_Handler_S3Object_4F451E5A" + } + }, + "bucket": "${aws_s3_bucket.root_Code_02F3C603.bucket}", + "key": "", + "source": "" + }, + "root_testjoinWithDefaultSeparator_Handler_S3Object_42DD08C0": { + "//": { + "metadata": { + "path": "root/Default/Default/test:joinWithDefaultSeparator()/Handler/S3Object", + "uniqueId": "root_testjoinWithDefaultSeparator_Handler_S3Object_42DD08C0" + } + }, + "bucket": "${aws_s3_bucket.root_Code_02F3C603.bucket}", + "key": "", + "source": "" + }, + "root_testjoin_Handler_S3Object_72E20B44": { + "//": { + "metadata": { + "path": "root/Default/Default/test:join()/Handler/S3Object", + "uniqueId": "root_testjoin_Handler_S3Object_72E20B44" + } + }, + "bucket": "${aws_s3_bucket.root_Code_02F3C603.bucket}", + "key": "", + "source": "" + }, + "root_testlastIndexOf_Handler_S3Object_2B34A1FC": { + "//": { + "metadata": { + "path": "root/Default/Default/test:lastIndexOf()/Handler/S3Object", + "uniqueId": "root_testlastIndexOf_Handler_S3Object_2B34A1FC" + } + }, + "bucket": "${aws_s3_bucket.root_Code_02F3C603.bucket}", + "key": "", + "source": "" + }, + "root_testlength_Handler_S3Object_22B052A5": { + "//": { + "metadata": { + "path": "root/Default/Default/test:length/Handler/S3Object", + "uniqueId": "root_testlength_Handler_S3Object_22B052A5" + } + }, + "bucket": "${aws_s3_bucket.root_Code_02F3C603.bucket}", + "key": "", + "source": "" + }, + "root_testpushAndPop_Handler_S3Object_E9F1EBBB": { + "//": { + "metadata": { + "path": "root/Default/Default/test:pushAndPop()/Handler/S3Object", + "uniqueId": "root_testpushAndPop_Handler_S3Object_E9F1EBBB" + } + }, + "bucket": "${aws_s3_bucket.root_Code_02F3C603.bucket}", + "key": "", + "source": "" + } + } + } +} +``` + +## preflight.js +```js +const $stdlib = require('@winglang/sdk'); +const $outdir = process.env.WING_SYNTH_DIR ?? "."; +const std = $stdlib.std; +const $wing_is_test = process.env.WING_IS_TEST === "true"; +const $AppBase = $stdlib.core.App.for(process.env.WING_TARGET); +const cloud = require('@winglang/sdk').cloud; +class $Root extends $stdlib.std.Resource { + constructor(scope, id) { + super(scope, id); + class $Closure1 extends $stdlib.std.Resource { + constructor(scope, id, ) { + super(scope, id); + this._addInflightOps("handle"); + this.display.hidden = true; + } + static _toInflightType(context) { + const self_client_path = "././inflight.$Closure1.js"; + return $stdlib.core.NodeJsCode.fromInline(` + require("${self_client_path}")({ + }) + `); + } + _toInflight() { + return $stdlib.core.NodeJsCode.fromInline(` + (await (async () => { + const $Closure1Client = ${$Closure1._toInflightType(this).text}; + const client = new $Closure1Client({ + }); + if (client.$inflight_init) { await client.$inflight_init(); } + return client; + })()) + `); + } + _registerBind(host, ops) { + if (ops.includes("$inflight_init")) { + } + if (ops.includes("handle")) { + } + super._registerBind(host, ops); + } + } + class $Closure2 extends $stdlib.std.Resource { + constructor(scope, id, ) { + super(scope, id); + this._addInflightOps("handle"); + this.display.hidden = true; + } + static _toInflightType(context) { + const self_client_path = "././inflight.$Closure2.js"; + return $stdlib.core.NodeJsCode.fromInline(` + require("${self_client_path}")({ + }) + `); + } + _toInflight() { + return $stdlib.core.NodeJsCode.fromInline(` + (await (async () => { + const $Closure2Client = ${$Closure2._toInflightType(this).text}; + const client = new $Closure2Client({ + }); + if (client.$inflight_init) { await client.$inflight_init(); } + return client; + })()) + `); + } + _registerBind(host, ops) { + if (ops.includes("$inflight_init")) { + } + if (ops.includes("handle")) { + } + super._registerBind(host, ops); + } + } + class $Closure3 extends $stdlib.std.Resource { + constructor(scope, id, ) { + super(scope, id); + this._addInflightOps("handle"); + this.display.hidden = true; + } + static _toInflightType(context) { + const self_client_path = "././inflight.$Closure3.js"; + return $stdlib.core.NodeJsCode.fromInline(` + require("${self_client_path}")({ + }) + `); + } + _toInflight() { + return $stdlib.core.NodeJsCode.fromInline(` + (await (async () => { + const $Closure3Client = ${$Closure3._toInflightType(this).text}; + const client = new $Closure3Client({ + }); + if (client.$inflight_init) { await client.$inflight_init(); } + return client; + })()) + `); + } + _registerBind(host, ops) { + if (ops.includes("$inflight_init")) { + } + if (ops.includes("handle")) { + } + super._registerBind(host, ops); + } + } + class $Closure4 extends $stdlib.std.Resource { + constructor(scope, id, ) { + super(scope, id); + this._addInflightOps("handle"); + this.display.hidden = true; + } + static _toInflightType(context) { + const self_client_path = "././inflight.$Closure4.js"; + return $stdlib.core.NodeJsCode.fromInline(` + require("${self_client_path}")({ + }) + `); + } + _toInflight() { + return $stdlib.core.NodeJsCode.fromInline(` + (await (async () => { + const $Closure4Client = ${$Closure4._toInflightType(this).text}; + const client = new $Closure4Client({ + }); + if (client.$inflight_init) { await client.$inflight_init(); } + return client; + })()) + `); + } + _registerBind(host, ops) { + if (ops.includes("$inflight_init")) { + } + if (ops.includes("handle")) { + } + super._registerBind(host, ops); + } + } + class $Closure5 extends $stdlib.std.Resource { + constructor(scope, id, ) { + super(scope, id); + this._addInflightOps("handle"); + this.display.hidden = true; + } + static _toInflightType(context) { + const self_client_path = "././inflight.$Closure5.js"; + return $stdlib.core.NodeJsCode.fromInline(` + require("${self_client_path}")({ + }) + `); + } + _toInflight() { + return $stdlib.core.NodeJsCode.fromInline(` + (await (async () => { + const $Closure5Client = ${$Closure5._toInflightType(this).text}; + const client = new $Closure5Client({ + }); + if (client.$inflight_init) { await client.$inflight_init(); } + return client; + })()) + `); + } + _registerBind(host, ops) { + if (ops.includes("$inflight_init")) { + } + if (ops.includes("handle")) { } - }, - "root_testpush_Handler_1F462746": { - "//": { - "metadata": { - "path": "root/Default/Default/test:push()/Handler/Default", - "uniqueId": "root_testpush_Handler_1F462746" - } - }, - "environment": { - "variables": { - "WING_FUNCTION_NAME": "Handler-c8230172", - "WING_TARGET": "tf-aws" - } - }, - "function_name": "Handler-c8230172", - "handler": "index.handler", - "publish": true, - "role": "${aws_iam_role.root_testpush_Handler_IamRole_3B5EB3DF.arn}", - "runtime": "nodejs18.x", - "s3_bucket": "${aws_s3_bucket.root_Code_02F3C603.bucket}", - "s3_key": "${aws_s3_object.root_testpush_Handler_S3Object_E277335F.key}", - "timeout": 30, - "vpc_config": { - "security_group_ids": [], - "subnet_ids": [] + super._registerBind(host, ops); + } + } + class $Closure6 extends $stdlib.std.Resource { + constructor(scope, id, ) { + super(scope, id); + this._addInflightOps("handle"); + this.display.hidden = true; + } + static _toInflightType(context) { + const self_client_path = "././inflight.$Closure6.js"; + return $stdlib.core.NodeJsCode.fromInline(` + require("${self_client_path}")({ + }) + `); + } + _toInflight() { + return $stdlib.core.NodeJsCode.fromInline(` + (await (async () => { + const $Closure6Client = ${$Closure6._toInflightType(this).text}; + const client = new $Closure6Client({ + }); + if (client.$inflight_init) { await client.$inflight_init(); } + return client; + })()) + `); + } + _registerBind(host, ops) { + if (ops.includes("$inflight_init")) { } + if (ops.includes("handle")) { + } + super._registerBind(host, ops); } - }, - "aws_s3_bucket": { - "root_Code_02F3C603": { - "//": { - "metadata": { - "path": "root/Default/Code", - "uniqueId": "root_Code_02F3C603" - } - }, - "bucket_prefix": "code-c84a50b1-" + } + class $Closure7 extends $stdlib.std.Resource { + constructor(scope, id, ) { + super(scope, id); + this._addInflightOps("handle"); + this.display.hidden = true; } - }, - "aws_s3_object": { - "root_testat_Handler_S3Object_C90B92D0": { - "//": { - "metadata": { - "path": "root/Default/Default/test:at()/Handler/S3Object", - "uniqueId": "root_testat_Handler_S3Object_C90B92D0" - } - }, - "bucket": "${aws_s3_bucket.root_Code_02F3C603.bucket}", - "key": "", - "source": "" - }, - "root_testlength_Handler_S3Object_22B052A5": { - "//": { - "metadata": { - "path": "root/Default/Default/test:length/Handler/S3Object", - "uniqueId": "root_testlength_Handler_S3Object_22B052A5" - } - }, - "bucket": "${aws_s3_bucket.root_Code_02F3C603.bucket}", - "key": "", - "source": "" - }, - "root_testpush_Handler_S3Object_E277335F": { - "//": { - "metadata": { - "path": "root/Default/Default/test:push()/Handler/S3Object", - "uniqueId": "root_testpush_Handler_S3Object_E277335F" - } - }, - "bucket": "${aws_s3_bucket.root_Code_02F3C603.bucket}", - "key": "", - "source": "" + static _toInflightType(context) { + const self_client_path = "././inflight.$Closure7.js"; + return $stdlib.core.NodeJsCode.fromInline(` + require("${self_client_path}")({ + }) + `); + } + _toInflight() { + return $stdlib.core.NodeJsCode.fromInline(` + (await (async () => { + const $Closure7Client = ${$Closure7._toInflightType(this).text}; + const client = new $Closure7Client({ + }); + if (client.$inflight_init) { await client.$inflight_init(); } + return client; + })()) + `); + } + _registerBind(host, ops) { + if (ops.includes("$inflight_init")) { + } + if (ops.includes("handle")) { + } + super._registerBind(host, ops); } } - } -} -``` - -## preflight.js -```js -const $stdlib = require('@winglang/sdk'); -const $outdir = process.env.WING_SYNTH_DIR ?? "."; -const std = $stdlib.std; -const $wing_is_test = process.env.WING_IS_TEST === "true"; -const $AppBase = $stdlib.core.App.for(process.env.WING_TARGET); -class $Root extends $stdlib.std.Resource { - constructor(scope, id) { - super(scope, id); - class $Closure1 extends $stdlib.std.Resource { + class $Closure8 extends $stdlib.std.Resource { constructor(scope, id, ) { super(scope, id); this._addInflightOps("handle"); this.display.hidden = true; } static _toInflightType(context) { - const self_client_path = "././inflight.$Closure1.js"; + const self_client_path = "././inflight.$Closure8.js"; return $stdlib.core.NodeJsCode.fromInline(` require("${self_client_path}")({ }) @@ -346,8 +1594,8 @@ class $Root extends $stdlib.std.Resource { _toInflight() { return $stdlib.core.NodeJsCode.fromInline(` (await (async () => { - const $Closure1Client = ${$Closure1._toInflightType(this).text}; - const client = new $Closure1Client({ + const $Closure8Client = ${$Closure8._toInflightType(this).text}; + const client = new $Closure8Client({ }); if (client.$inflight_init) { await client.$inflight_init(); } return client; @@ -362,14 +1610,14 @@ class $Root extends $stdlib.std.Resource { super._registerBind(host, ops); } } - class $Closure2 extends $stdlib.std.Resource { + class $Closure9 extends $stdlib.std.Resource { constructor(scope, id, ) { super(scope, id); this._addInflightOps("handle"); this.display.hidden = true; } static _toInflightType(context) { - const self_client_path = "././inflight.$Closure2.js"; + const self_client_path = "././inflight.$Closure9.js"; return $stdlib.core.NodeJsCode.fromInline(` require("${self_client_path}")({ }) @@ -378,8 +1626,8 @@ class $Root extends $stdlib.std.Resource { _toInflight() { return $stdlib.core.NodeJsCode.fromInline(` (await (async () => { - const $Closure2Client = ${$Closure2._toInflightType(this).text}; - const client = new $Closure2Client({ + const $Closure9Client = ${$Closure9._toInflightType(this).text}; + const client = new $Closure9Client({ }); if (client.$inflight_init) { await client.$inflight_init(); } return client; @@ -394,14 +1642,14 @@ class $Root extends $stdlib.std.Resource { super._registerBind(host, ops); } } - class $Closure3 extends $stdlib.std.Resource { + class $Closure10 extends $stdlib.std.Resource { constructor(scope, id, ) { super(scope, id); this._addInflightOps("handle"); this.display.hidden = true; } static _toInflightType(context) { - const self_client_path = "././inflight.$Closure3.js"; + const self_client_path = "././inflight.$Closure10.js"; return $stdlib.core.NodeJsCode.fromInline(` require("${self_client_path}")({ }) @@ -410,8 +1658,104 @@ class $Root extends $stdlib.std.Resource { _toInflight() { return $stdlib.core.NodeJsCode.fromInline(` (await (async () => { - const $Closure3Client = ${$Closure3._toInflightType(this).text}; - const client = new $Closure3Client({ + const $Closure10Client = ${$Closure10._toInflightType(this).text}; + const client = new $Closure10Client({ + }); + if (client.$inflight_init) { await client.$inflight_init(); } + return client; + })()) + `); + } + _registerBind(host, ops) { + if (ops.includes("$inflight_init")) { + } + if (ops.includes("handle")) { + } + super._registerBind(host, ops); + } + } + class $Closure11 extends $stdlib.std.Resource { + constructor(scope, id, ) { + super(scope, id); + this._addInflightOps("handle"); + this.display.hidden = true; + } + static _toInflightType(context) { + const self_client_path = "././inflight.$Closure11.js"; + return $stdlib.core.NodeJsCode.fromInline(` + require("${self_client_path}")({ + }) + `); + } + _toInflight() { + return $stdlib.core.NodeJsCode.fromInline(` + (await (async () => { + const $Closure11Client = ${$Closure11._toInflightType(this).text}; + const client = new $Closure11Client({ + }); + if (client.$inflight_init) { await client.$inflight_init(); } + return client; + })()) + `); + } + _registerBind(host, ops) { + if (ops.includes("$inflight_init")) { + } + if (ops.includes("handle")) { + } + super._registerBind(host, ops); + } + } + class $Closure12 extends $stdlib.std.Resource { + constructor(scope, id, ) { + super(scope, id); + this._addInflightOps("handle"); + this.display.hidden = true; + } + static _toInflightType(context) { + const self_client_path = "././inflight.$Closure12.js"; + return $stdlib.core.NodeJsCode.fromInline(` + require("${self_client_path}")({ + }) + `); + } + _toInflight() { + return $stdlib.core.NodeJsCode.fromInline(` + (await (async () => { + const $Closure12Client = ${$Closure12._toInflightType(this).text}; + const client = new $Closure12Client({ + }); + if (client.$inflight_init) { await client.$inflight_init(); } + return client; + })()) + `); + } + _registerBind(host, ops) { + if (ops.includes("$inflight_init")) { + } + if (ops.includes("handle")) { + } + super._registerBind(host, ops); + } + } + class $Closure13 extends $stdlib.std.Resource { + constructor(scope, id, ) { + super(scope, id); + this._addInflightOps("handle"); + this.display.hidden = true; + } + static _toInflightType(context) { + const self_client_path = "././inflight.$Closure13.js"; + return $stdlib.core.NodeJsCode.fromInline(` + require("${self_client_path}")({ + }) + `); + } + _toInflight() { + return $stdlib.core.NodeJsCode.fromInline(` + (await (async () => { + const $Closure13Client = ${$Closure13._toInflightType(this).text}; + const client = new $Closure13Client({ }); if (client.$inflight_init) { await client.$inflight_init(); } return client; @@ -426,19 +1770,100 @@ class $Root extends $stdlib.std.Resource { super._registerBind(host, ops); } } - {((cond) => {if (!cond) throw new Error(`assertion failed: '(Object.freeze([1, 2, 3]).length === 3)'`)})((Object.freeze([1, 2, 3]).length === 3))}; - {((cond) => {if (!cond) throw new Error(`assertion failed: '([1, 2, 3].length === 3)'`)})(([1, 2, 3].length === 3))}; + const bucket = this.node.root.newAbstract("@winglang/sdk.cloud.Bucket",this,"myBucket"); + const buckets = Object.freeze([bucket]); + const anotherBucket = this.node.root.newAbstract("@winglang/sdk.cloud.Bucket",this,"mySecondBucket"); + const anotherBuckets = Object.freeze([anotherBucket]); + {((cond) => {if (!cond) throw new Error("assertion failed: buckets.length == 1")})((buckets.length === 1))}; + {((cond) => {if (!cond) throw new Error("assertion failed: [1,2,3].length == 3")})((Object.freeze([1, 2, 3]).length === 3))}; + {((cond) => {if (!cond) throw new Error("assertion failed: MutArray[1,2,3].length == 3")})(([1, 2, 3].length === 3))}; this.node.root.new("@winglang/sdk.std.Test",std.Test,this,"test:length",new $Closure1(this,"$Closure1")); - {((cond) => {if (!cond) throw new Error(`assertion failed: '((Object.freeze(["hello"]).at(0)) === "hello")'`)})(((Object.freeze(["hello"]).at(0)) === "hello"))}; - {((cond) => {if (!cond) throw new Error(`assertion failed: '((["hello", "world"].at(1)) === "world")'`)})(((["hello", "world"].at(1)) === "world"))}; + {((cond) => {if (!cond) throw new Error("assertion failed: [\"hello\"].at(0) == \"hello\"")})(((Object.freeze(["hello"]).at(0)) === "hello"))}; + {((cond) => {if (!cond) throw new Error("assertion failed: MutArray[\"hello\", \"world\"].at(1) == \"world\"")})(((["hello", "world"].at(1)) === "world"))}; + {((cond) => {if (!cond) throw new Error("assertion failed: buckets.at(0).node.id == \"myBucket\"")})(((buckets.at(0)).node.id === "myBucket"))}; this.node.root.new("@winglang/sdk.std.Test",std.Test,this,"test:at()",new $Closure2(this,"$Closure2")); const a = ["hello"]; - {((cond) => {if (!cond) throw new Error(`assertion failed: '(a.length === 1)'`)})((a.length === 1))}; + {((cond) => {if (!cond) throw new Error("assertion failed: a.length == 1")})((a.length === 1))}; (a.push("world")); - {((cond) => {if (!cond) throw new Error(`assertion failed: '(a.length === 2)'`)})((a.length === 2))}; - {((cond) => {if (!cond) throw new Error(`assertion failed: '((a.at(0)) === "hello")'`)})(((a.at(0)) === "hello"))}; - {((cond) => {if (!cond) throw new Error(`assertion failed: '((a.at(1)) === "world")'`)})(((a.at(1)) === "world"))}; - this.node.root.new("@winglang/sdk.std.Test",std.Test,this,"test:push()",new $Closure3(this,"$Closure3")); + {((cond) => {if (!cond) throw new Error("assertion failed: a.length == 2")})((a.length === 2))}; + {((cond) => {if (!cond) throw new Error("assertion failed: a.at(0) == \"hello\"")})(((a.at(0)) === "hello"))}; + {((cond) => {if (!cond) throw new Error("assertion failed: a.at(1) == \"world\"")})(((a.at(1)) === "world"))}; + const item = (a.pop()); + {((cond) => {if (!cond) throw new Error("assertion failed: item == \"world\"")})((item === "world"))}; + {((cond) => {if (!cond) throw new Error("assertion failed: a.length == 1")})((a.length === 1))}; + {((cond) => {if (!cond) throw new Error("assertion failed: a.at(0) == \"hello\"")})(((a.at(0)) === "hello"))}; + this.node.root.new("@winglang/sdk.std.Test",std.Test,this,"test:pushAndPop()",new $Closure3(this,"$Closure3")); + const array = Object.freeze(["hello"]); + {((cond) => {if (!cond) throw new Error("assertion failed: array.length == 1")})((array.length === 1))}; + const mergedArray = (array.concat(Object.freeze(["wing"]))); + {((cond) => {if (!cond) throw new Error("assertion failed: mergedArray.length == 2")})((mergedArray.length === 2))}; + {((cond) => {if (!cond) throw new Error("assertion failed: mergedArray.at(0) == \"hello\"")})(((mergedArray.at(0)) === "hello"))}; + {((cond) => {if (!cond) throw new Error("assertion failed: mergedArray.at(1) == \"wing\"")})(((mergedArray.at(1)) === "wing"))}; + const b = ["hello"]; + {((cond) => {if (!cond) throw new Error("assertion failed: b.length == 1")})((b.length === 1))}; + const d = (b.concat(["wing"])); + {((cond) => {if (!cond) throw new Error("assertion failed: d.length == 2")})((d.length === 2))}; + {((cond) => {if (!cond) throw new Error("assertion failed: d.at(0) == \"hello\"")})(((d.at(0)) === "hello"))}; + {((cond) => {if (!cond) throw new Error("assertion failed: d.at(1) == \"wing\"")})(((d.at(1)) === "wing"))}; + const mergedBuckets = (buckets.concat(anotherBuckets)); + {((cond) => {if (!cond) throw new Error("assertion failed: mergedBuckets.length == 2")})((mergedBuckets.length === 2))}; + {((cond) => {if (!cond) throw new Error("assertion failed: mergedBuckets.at(0).node.id == \"myBucket\"")})(((mergedBuckets.at(0)).node.id === "myBucket"))}; + {((cond) => {if (!cond) throw new Error("assertion failed: mergedBuckets.at(1).node.id == \"mySecondBucket\"")})(((mergedBuckets.at(1)).node.id === "mySecondBucket"))}; + this.node.root.new("@winglang/sdk.std.Test",std.Test,this,"test:concatMutArray()",new $Closure4(this,"$Closure4")); + this.node.root.new("@winglang/sdk.std.Test",std.Test,this,"test:concatArray()",new $Closure5(this,"$Closure5")); + const e = ["hello", "wing"]; + {((cond) => {if (!cond) throw new Error("assertion failed: e.contains(\"wing\")")})(e.includes("wing"))}; + {((cond) => {if (!cond) throw new Error("assertion failed: !e.contains(\"NotThere\")")})((!e.includes("NotThere")))}; + {((cond) => {if (!cond) throw new Error("assertion failed: buckets.contains(buckets.at(0))")})(buckets.includes((buckets.at(0))))}; + const dummyBucket = this.node.root.newAbstract("@winglang/sdk.cloud.Bucket",this,"cloud.Bucket"); + {((cond) => {if (!cond) throw new Error("assertion failed: !buckets.contains(dummyBucket)")})((!buckets.includes(dummyBucket)))}; + const h = Object.freeze(["hello", "wing"]); + {((cond) => {if (!cond) throw new Error("assertion failed: h.contains(\"wing\")")})(h.includes("wing"))}; + {((cond) => {if (!cond) throw new Error("assertion failed: !h.contains(\"NotThere\")")})((!h.includes("NotThere")))}; + this.node.root.new("@winglang/sdk.std.Test",std.Test,this,"test:contains()",new $Closure6(this,"$Closure6")); + const g = ["hello", "wing"]; + {((cond) => {if (!cond) throw new Error("assertion failed: g.indexOf(\"wing\") == 1")})((g.indexOf("wing") === 1))}; + {((cond) => {if (!cond) throw new Error("assertion failed: g.indexOf(\"notThere\") == -1")})((g.indexOf("notThere") === (-1)))}; + {((cond) => {if (!cond) throw new Error("assertion failed: buckets.indexOf(bucket) == 0")})((buckets.indexOf(bucket) === 0))}; + {((cond) => {if (!cond) throw new Error("assertion failed: buckets.indexOf(dummyBucket) == -1")})((buckets.indexOf(dummyBucket) === (-1)))}; + this.node.root.new("@winglang/sdk.std.Test",std.Test,this,"test:indexOf()",new $Closure7(this,"$Closure7")); + const q = ["hello", "wing"]; + {((cond) => {if (!cond) throw new Error("assertion failed: q.indexOf(\"wing\") == 1")})((q.indexOf("wing") === 1))}; + {((cond) => {if (!cond) throw new Error("assertion failed: q.indexOf(\"notThere\") == -1")})((q.indexOf("notThere") === (-1)))}; + this.node.root.new("@winglang/sdk.std.Test",std.Test,this,"test:indexOfArray()",new $Closure8(this,"$Closure8")); + const m = ["hello", "wing"]; + const delimeter = ";"; + const joinedString = (m.join(delimeter)); + const expectedString = (((m.at(0)) + delimeter) + (m.at(1))); + {((cond) => {if (!cond) throw new Error("assertion failed: joinedString == expectedString")})((joinedString === expectedString))}; + const l = ["hello", "wing"]; + const separator = ","; + const joinedStringWithDefault = (m.join()); + const expectedStringWithDefault = (((m.at(0)) + separator) + (m.at(1))); + {((cond) => {if (!cond) throw new Error("assertion failed: joinedStringWithDefault == expectedStringWithDefault")})((joinedStringWithDefault === expectedStringWithDefault))}; + this.node.root.new("@winglang/sdk.std.Test",std.Test,this,"test:join()",new $Closure9(this,"$Closure9")); + this.node.root.new("@winglang/sdk.std.Test",std.Test,this,"test:joinWithDefaultSeparator()",new $Closure10(this,"$Closure10")); + const o = ["hello", "wing"]; + const p = Object.freeze([...(o)]); + {((cond) => {if (!cond) throw new Error("assertion failed: o.length == p.length")})((o.length === p.length))}; + {((cond) => {if (!cond) throw new Error("assertion failed: o.at(0) == p.at(0)")})(((o.at(0)) === (p.at(0))))}; + const copiedBuckets = [...(buckets)]; + {((cond) => {if (!cond) throw new Error("assertion failed: copiedBuckets.length == 1")})((copiedBuckets.length === 1))}; + {((cond) => {if (!cond) throw new Error("assertion failed: copiedBuckets.at(0).node.id == \"myBucket\"")})(((copiedBuckets.at(0)).node.id === "myBucket"))}; + this.node.root.new("@winglang/sdk.std.Test",std.Test,this,"test:copy()",new $Closure11(this,"$Closure11")); + const v = Object.freeze(["hello", "wing"]); + const r = [...(v)]; + {((cond) => {if (!cond) throw new Error("assertion failed: q.length == r.length")})((q.length === r.length))}; + {((cond) => {if (!cond) throw new Error("assertion failed: q.at(0) == r.at(0)")})(((q.at(0)) === (r.at(0))))}; + this.node.root.new("@winglang/sdk.std.Test",std.Test,this,"test:copyMut()",new $Closure12(this,"$Closure12")); + const lastStr = "wing"; + const s = ["hello", lastStr, lastStr]; + {((cond) => {if (!cond) throw new Error("assertion failed: s.lastIndexOf(lastStr) == 2")})((s.lastIndexOf(lastStr) === 2))}; + {((cond) => {if (!cond) throw new Error("assertion failed: s.lastIndexOf(\"something\") == -1")})((s.lastIndexOf("something") === (-1)))}; + const multipleBuckets = [bucket, bucket, anotherBucket]; + {((cond) => {if (!cond) throw new Error("assertion failed: multipleBuckets.lastIndexOf(bucket) == 1")})((multipleBuckets.lastIndexOf(bucket) === 1))}; + {((cond) => {if (!cond) throw new Error("assertion failed: multipleBuckets.lastIndexOf(dummyBucket) == -1")})((multipleBuckets.lastIndexOf(dummyBucket) === (-1)))}; + this.node.root.new("@winglang/sdk.std.Test",std.Test,this,"test:lastIndexOf()",new $Closure13(this,"$Closure13")); } } class $App extends $AppBase { diff --git a/tools/hangar/__snapshots__/test_corpus/sdk_tests/std/array.w_test_sim.md b/tools/hangar/__snapshots__/test_corpus/sdk_tests/std/array.w_test_sim.md index e53b96cfba0..063c382f029 100644 --- a/tools/hangar/__snapshots__/test_corpus/sdk_tests/std/array.w_test_sim.md +++ b/tools/hangar/__snapshots__/test_corpus/sdk_tests/std/array.w_test_sim.md @@ -2,16 +2,23 @@ ## stdout.log ```log -pass โ”€ array.wsim ยป root/env0/test:length -pass โ”€ array.wsim ยป root/env1/test:at() -pass โ”€ array.wsim ยป root/env2/test:push() +pass โ”€ array.wsim ยป root/env0/test:length +pass โ”€ array.wsim ยป root/env1/test:at() +pass โ”€ array.wsim ยป root/env10/test:copy() +pass โ”€ array.wsim ยป root/env11/test:copyMut() +pass โ”€ array.wsim ยป root/env12/test:lastIndexOf() +pass โ”€ array.wsim ยป root/env2/test:pushAndPop() +pass โ”€ array.wsim ยป root/env3/test:concatMutArray() +pass โ”€ array.wsim ยป root/env4/test:concatArray() +pass โ”€ array.wsim ยป root/env5/test:contains() +pass โ”€ array.wsim ยป root/env6/test:indexOf() +pass โ”€ array.wsim ยป root/env7/test:indexOfArray() +pass โ”€ array.wsim ยป root/env8/test:join() +pass โ”€ array.wsim ยป root/env9/test:joinWithDefaultSeparator() - - - - -Tests 1 passed (1) + +Tests 13 passed (13) +Test Files 1 passed (1) Duration - ``` diff --git a/tools/hangar/__snapshots__/test_corpus/sdk_tests/std/bool.w_compile_tf-aws.md b/tools/hangar/__snapshots__/test_corpus/sdk_tests/std/bool.w_compile_tf-aws.md index 08a28baec53..862bbd1c04a 100644 --- a/tools/hangar/__snapshots__/test_corpus/sdk_tests/std/bool.w_compile_tf-aws.md +++ b/tools/hangar/__snapshots__/test_corpus/sdk_tests/std/bool.w_compile_tf-aws.md @@ -43,7 +43,7 @@ class $Root extends $stdlib.std.Resource { constructor(scope, id) { super(scope, id); const t = (std.Boolean.fromJson((JSON.parse("true")))); - {((cond) => {if (!cond) throw new Error(`assertion failed: '(t === true)'`)})((t === true))}; + {((cond) => {if (!cond) throw new Error("assertion failed: t == true")})((t === true))}; } } class $App extends $AppBase { diff --git a/tools/hangar/__snapshots__/test_corpus/sdk_tests/std/bool.w_test_sim.md b/tools/hangar/__snapshots__/test_corpus/sdk_tests/std/bool.w_test_sim.md index 530321e4f86..6c4c3466234 100644 --- a/tools/hangar/__snapshots__/test_corpus/sdk_tests/std/bool.w_test_sim.md +++ b/tools/hangar/__snapshots__/test_corpus/sdk_tests/std/bool.w_test_sim.md @@ -4,12 +4,9 @@ ```log pass โ”€ bool.wsim (no tests) - - - - -Tests 1 passed (1) + +Tests 1 passed (1) +Test Files 1 passed (1) Duration - ``` diff --git a/tools/hangar/__snapshots__/test_corpus/sdk_tests/std/duration.w_compile_tf-aws.md b/tools/hangar/__snapshots__/test_corpus/sdk_tests/std/duration.w_compile_tf-aws.md index 0e4c3a5bf50..87944665de3 100644 --- a/tools/hangar/__snapshots__/test_corpus/sdk_tests/std/duration.w_compile_tf-aws.md +++ b/tools/hangar/__snapshots__/test_corpus/sdk_tests/std/duration.w_compile_tf-aws.md @@ -12,26 +12,26 @@ module.exports = function({ std_Duration }) { async $inflight_init() { } async handle() { - {((cond) => {if (!cond) throw new Error(`assertion failed: '((await std_Duration.fromSeconds(0.012)).seconds === (12 / 1000))'`)})(((await std_Duration.fromSeconds(0.012)).seconds === (12 / 1000)))}; - {((cond) => {if (!cond) throw new Error(`assertion failed: '((await std_Duration.fromSeconds(12)).seconds === 12)'`)})(((await std_Duration.fromSeconds(12)).seconds === 12))}; - {((cond) => {if (!cond) throw new Error(`assertion failed: '((await std_Duration.fromSeconds(720)).seconds === (12 * 60))'`)})(((await std_Duration.fromSeconds(720)).seconds === (12 * 60)))}; - {((cond) => {if (!cond) throw new Error(`assertion failed: '((await std_Duration.fromSeconds(43200)).seconds === ((12 * 60) * 60))'`)})(((await std_Duration.fromSeconds(43200)).seconds === ((12 * 60) * 60)))}; - {((cond) => {if (!cond) throw new Error(`assertion failed: '((await std_Duration.fromSeconds(1036800)).seconds === (((12 * 60) * 60) * 24))'`)})(((await std_Duration.fromSeconds(1036800)).seconds === (((12 * 60) * 60) * 24)))}; - {((cond) => {if (!cond) throw new Error(`assertion failed: '((await std_Duration.fromSeconds(31536000)).seconds === (((((12 * 60) * 60) * 24) * 365) / 12))'`)})(((await std_Duration.fromSeconds(31536000)).seconds === (((((12 * 60) * 60) * 24) * 365) / 12)))}; - {((cond) => {if (!cond) throw new Error(`assertion failed: '((await std_Duration.fromSeconds(378432000)).seconds === ((((12 * 60) * 60) * 24) * 365))'`)})(((await std_Duration.fromSeconds(378432000)).seconds === ((((12 * 60) * 60) * 24) * 365)))}; - {((cond) => {if (!cond) throw new Error(`assertion failed: '((await std_Duration.fromMilliseconds(10)).seconds === (await std_Duration.fromSeconds(0.01)).seconds)'`)})(((await std_Duration.fromMilliseconds(10)).seconds === (await std_Duration.fromSeconds(0.01)).seconds))}; - {((cond) => {if (!cond) throw new Error(`assertion failed: '((await std_Duration.fromMinutes(10)).seconds === (await std_Duration.fromSeconds(600)).seconds)'`)})(((await std_Duration.fromMinutes(10)).seconds === (await std_Duration.fromSeconds(600)).seconds))}; - {((cond) => {if (!cond) throw new Error(`assertion failed: '((await std_Duration.fromSeconds(10)).seconds === (await std_Duration.fromSeconds(10)).seconds)'`)})(((await std_Duration.fromSeconds(10)).seconds === (await std_Duration.fromSeconds(10)).seconds))}; - {((cond) => {if (!cond) throw new Error(`assertion failed: '((await std_Duration.fromHours(10)).seconds === (await std_Duration.fromSeconds(36000)).seconds)'`)})(((await std_Duration.fromHours(10)).seconds === (await std_Duration.fromSeconds(36000)).seconds))}; - {((cond) => {if (!cond) throw new Error(`assertion failed: '((await std_Duration.fromDays(10)).seconds === (await std_Duration.fromSeconds(864000)).seconds)'`)})(((await std_Duration.fromDays(10)).seconds === (await std_Duration.fromSeconds(864000)).seconds))}; - {((cond) => {if (!cond) throw new Error(`assertion failed: '((await std_Duration.fromMonths(10)).seconds === (await std_Duration.fromSeconds(26280000)).seconds)'`)})(((await std_Duration.fromMonths(10)).seconds === (await std_Duration.fromSeconds(26280000)).seconds))}; - {((cond) => {if (!cond) throw new Error(`assertion failed: '((await std_Duration.fromYears(10)).seconds === (await std_Duration.fromSeconds(315360000)).seconds)'`)})(((await std_Duration.fromYears(10)).seconds === (await std_Duration.fromSeconds(315360000)).seconds))}; - {((cond) => {if (!cond) throw new Error(`assertion failed: '((await std_Duration.fromSeconds(1)).milliseconds === 1000)'`)})(((await std_Duration.fromSeconds(1)).milliseconds === 1000))}; - {((cond) => {if (!cond) throw new Error(`assertion failed: '((await std_Duration.fromSeconds(1)).minutes === (1 / 60))'`)})(((await std_Duration.fromSeconds(1)).minutes === (1 / 60)))}; - {((cond) => {if (!cond) throw new Error(`assertion failed: '((await std_Duration.fromSeconds(1)).hours === (1 / (60 * 60)))'`)})(((await std_Duration.fromSeconds(1)).hours === (1 / (60 * 60))))}; - {((cond) => {if (!cond) throw new Error(`assertion failed: '((await std_Duration.fromSeconds(1)).days === (1 / ((60 * 60) * 24)))'`)})(((await std_Duration.fromSeconds(1)).days === (1 / ((60 * 60) * 24))))}; - {((cond) => {if (!cond) throw new Error(`assertion failed: '((await std_Duration.fromSeconds(1)).months === (1 / ((((60 * 60) * 24) * 365) / 12)))'`)})(((await std_Duration.fromSeconds(1)).months === (1 / ((((60 * 60) * 24) * 365) / 12))))}; - {((cond) => {if (!cond) throw new Error(`assertion failed: '((await std_Duration.fromSeconds(1)).years === (1 / (((60 * 60) * 24) * 365)))'`)})(((await std_Duration.fromSeconds(1)).years === (1 / (((60 * 60) * 24) * 365))))}; + {((cond) => {if (!cond) throw new Error("assertion failed: 12ms.seconds == 12 / 1000")})(((await std_Duration.fromSeconds(0.012)).seconds === (12 / 1000)))}; + {((cond) => {if (!cond) throw new Error("assertion failed: 12s.seconds == 12")})(((await std_Duration.fromSeconds(12)).seconds === 12))}; + {((cond) => {if (!cond) throw new Error("assertion failed: 12m.seconds == 12 * 60")})(((await std_Duration.fromSeconds(720)).seconds === (12 * 60)))}; + {((cond) => {if (!cond) throw new Error("assertion failed: 12h.seconds == 12 * 60 * 60")})(((await std_Duration.fromSeconds(43200)).seconds === ((12 * 60) * 60)))}; + {((cond) => {if (!cond) throw new Error("assertion failed: 12d.seconds == 12 * 60 * 60 * 24")})(((await std_Duration.fromSeconds(1036800)).seconds === (((12 * 60) * 60) * 24)))}; + {((cond) => {if (!cond) throw new Error("assertion failed: 12mo.seconds == (12 * 60 * 60 * 24 * 365) / 12")})(((await std_Duration.fromSeconds(31536000)).seconds === (((((12 * 60) * 60) * 24) * 365) / 12)))}; + {((cond) => {if (!cond) throw new Error("assertion failed: 12y.seconds == 12 * 60 * 60 * 24 * 365")})(((await std_Duration.fromSeconds(378432000)).seconds === ((((12 * 60) * 60) * 24) * 365)))}; + {((cond) => {if (!cond) throw new Error("assertion failed: duration.fromMilliseconds(10).seconds == 10ms.seconds")})(((await std_Duration.fromMilliseconds(10)).seconds === (await std_Duration.fromSeconds(0.01)).seconds))}; + {((cond) => {if (!cond) throw new Error("assertion failed: duration.fromMinutes(10).seconds == 10m.seconds")})(((await std_Duration.fromMinutes(10)).seconds === (await std_Duration.fromSeconds(600)).seconds))}; + {((cond) => {if (!cond) throw new Error("assertion failed: duration.fromSeconds(10).seconds == 10s.seconds")})(((await std_Duration.fromSeconds(10)).seconds === (await std_Duration.fromSeconds(10)).seconds))}; + {((cond) => {if (!cond) throw new Error("assertion failed: duration.fromHours(10).seconds == 10h.seconds")})(((await std_Duration.fromHours(10)).seconds === (await std_Duration.fromSeconds(36000)).seconds))}; + {((cond) => {if (!cond) throw new Error("assertion failed: duration.fromDays(10).seconds == 10d.seconds")})(((await std_Duration.fromDays(10)).seconds === (await std_Duration.fromSeconds(864000)).seconds))}; + {((cond) => {if (!cond) throw new Error("assertion failed: duration.fromMonths(10).seconds == 10mo.seconds")})(((await std_Duration.fromMonths(10)).seconds === (await std_Duration.fromSeconds(26280000)).seconds))}; + {((cond) => {if (!cond) throw new Error("assertion failed: duration.fromYears(10).seconds == 10y.seconds")})(((await std_Duration.fromYears(10)).seconds === (await std_Duration.fromSeconds(315360000)).seconds))}; + {((cond) => {if (!cond) throw new Error("assertion failed: 1s.milliseconds == 1000")})(((await std_Duration.fromSeconds(1)).milliseconds === 1000))}; + {((cond) => {if (!cond) throw new Error("assertion failed: 1s.minutes == 1 / 60")})(((await std_Duration.fromSeconds(1)).minutes === (1 / 60)))}; + {((cond) => {if (!cond) throw new Error("assertion failed: 1s.hours == 1 / (60 * 60)")})(((await std_Duration.fromSeconds(1)).hours === (1 / (60 * 60))))}; + {((cond) => {if (!cond) throw new Error("assertion failed: 1s.days == 1 / (60 * 60 * 24)")})(((await std_Duration.fromSeconds(1)).days === (1 / ((60 * 60) * 24))))}; + {((cond) => {if (!cond) throw new Error("assertion failed: 1s.months == 1 / ((60 * 60 * 24 * 365) / 12)")})(((await std_Duration.fromSeconds(1)).months === (1 / ((((60 * 60) * 24) * 365) / 12))))}; + {((cond) => {if (!cond) throw new Error("assertion failed: 1s.years == 1 / (60 * 60 * 24 * 365)")})(((await std_Duration.fromSeconds(1)).years === (1 / (((60 * 60) * 24) * 365))))}; } } return $Closure1; @@ -204,26 +204,26 @@ class $Root extends $stdlib.std.Resource { super._registerBind(host, ops); } } - {((cond) => {if (!cond) throw new Error(`assertion failed: '((std.Duration.fromSeconds(0.012)).seconds === (12 / 1000))'`)})(((std.Duration.fromSeconds(0.012)).seconds === (12 / 1000)))}; - {((cond) => {if (!cond) throw new Error(`assertion failed: '((std.Duration.fromSeconds(12)).seconds === 12)'`)})(((std.Duration.fromSeconds(12)).seconds === 12))}; - {((cond) => {if (!cond) throw new Error(`assertion failed: '((std.Duration.fromSeconds(720)).seconds === (12 * 60))'`)})(((std.Duration.fromSeconds(720)).seconds === (12 * 60)))}; - {((cond) => {if (!cond) throw new Error(`assertion failed: '((std.Duration.fromSeconds(43200)).seconds === ((12 * 60) * 60))'`)})(((std.Duration.fromSeconds(43200)).seconds === ((12 * 60) * 60)))}; - {((cond) => {if (!cond) throw new Error(`assertion failed: '((std.Duration.fromSeconds(1036800)).seconds === (((12 * 60) * 60) * 24))'`)})(((std.Duration.fromSeconds(1036800)).seconds === (((12 * 60) * 60) * 24)))}; - {((cond) => {if (!cond) throw new Error(`assertion failed: '((std.Duration.fromSeconds(31536000)).seconds === (((((12 * 60) * 60) * 24) * 365) / 12))'`)})(((std.Duration.fromSeconds(31536000)).seconds === (((((12 * 60) * 60) * 24) * 365) / 12)))}; - {((cond) => {if (!cond) throw new Error(`assertion failed: '((std.Duration.fromSeconds(378432000)).seconds === ((((12 * 60) * 60) * 24) * 365))'`)})(((std.Duration.fromSeconds(378432000)).seconds === ((((12 * 60) * 60) * 24) * 365)))}; - {((cond) => {if (!cond) throw new Error(`assertion failed: '((std.Duration.fromMilliseconds(10)).seconds === (std.Duration.fromSeconds(0.01)).seconds)'`)})(((std.Duration.fromMilliseconds(10)).seconds === (std.Duration.fromSeconds(0.01)).seconds))}; - {((cond) => {if (!cond) throw new Error(`assertion failed: '((std.Duration.fromMinutes(10)).seconds === (std.Duration.fromSeconds(600)).seconds)'`)})(((std.Duration.fromMinutes(10)).seconds === (std.Duration.fromSeconds(600)).seconds))}; - {((cond) => {if (!cond) throw new Error(`assertion failed: '((std.Duration.fromSeconds(10)).seconds === (std.Duration.fromSeconds(10)).seconds)'`)})(((std.Duration.fromSeconds(10)).seconds === (std.Duration.fromSeconds(10)).seconds))}; - {((cond) => {if (!cond) throw new Error(`assertion failed: '((std.Duration.fromHours(10)).seconds === (std.Duration.fromSeconds(36000)).seconds)'`)})(((std.Duration.fromHours(10)).seconds === (std.Duration.fromSeconds(36000)).seconds))}; - {((cond) => {if (!cond) throw new Error(`assertion failed: '((std.Duration.fromDays(10)).seconds === (std.Duration.fromSeconds(864000)).seconds)'`)})(((std.Duration.fromDays(10)).seconds === (std.Duration.fromSeconds(864000)).seconds))}; - {((cond) => {if (!cond) throw new Error(`assertion failed: '((std.Duration.fromMonths(10)).seconds === (std.Duration.fromSeconds(26280000)).seconds)'`)})(((std.Duration.fromMonths(10)).seconds === (std.Duration.fromSeconds(26280000)).seconds))}; - {((cond) => {if (!cond) throw new Error(`assertion failed: '((std.Duration.fromYears(10)).seconds === (std.Duration.fromSeconds(315360000)).seconds)'`)})(((std.Duration.fromYears(10)).seconds === (std.Duration.fromSeconds(315360000)).seconds))}; - {((cond) => {if (!cond) throw new Error(`assertion failed: '((std.Duration.fromSeconds(1)).milliseconds === 1000)'`)})(((std.Duration.fromSeconds(1)).milliseconds === 1000))}; - {((cond) => {if (!cond) throw new Error(`assertion failed: '((std.Duration.fromSeconds(1)).minutes === (1 / 60))'`)})(((std.Duration.fromSeconds(1)).minutes === (1 / 60)))}; - {((cond) => {if (!cond) throw new Error(`assertion failed: '((std.Duration.fromSeconds(1)).hours === (1 / (60 * 60)))'`)})(((std.Duration.fromSeconds(1)).hours === (1 / (60 * 60))))}; - {((cond) => {if (!cond) throw new Error(`assertion failed: '((std.Duration.fromSeconds(1)).days === (1 / ((60 * 60) * 24)))'`)})(((std.Duration.fromSeconds(1)).days === (1 / ((60 * 60) * 24))))}; - {((cond) => {if (!cond) throw new Error(`assertion failed: '((std.Duration.fromSeconds(1)).months === (1 / ((((60 * 60) * 24) * 365) / 12)))'`)})(((std.Duration.fromSeconds(1)).months === (1 / ((((60 * 60) * 24) * 365) / 12))))}; - {((cond) => {if (!cond) throw new Error(`assertion failed: '((std.Duration.fromSeconds(1)).years === (1 / (((60 * 60) * 24) * 365)))'`)})(((std.Duration.fromSeconds(1)).years === (1 / (((60 * 60) * 24) * 365))))}; + {((cond) => {if (!cond) throw new Error("assertion failed: 12ms.seconds == 12 / 1000")})(((std.Duration.fromSeconds(0.012)).seconds === (12 / 1000)))}; + {((cond) => {if (!cond) throw new Error("assertion failed: 12s.seconds == 12")})(((std.Duration.fromSeconds(12)).seconds === 12))}; + {((cond) => {if (!cond) throw new Error("assertion failed: 12m.seconds == 12 * 60")})(((std.Duration.fromSeconds(720)).seconds === (12 * 60)))}; + {((cond) => {if (!cond) throw new Error("assertion failed: 12h.seconds == 12 * 60 * 60")})(((std.Duration.fromSeconds(43200)).seconds === ((12 * 60) * 60)))}; + {((cond) => {if (!cond) throw new Error("assertion failed: 12d.seconds == 12 * 60 * 60 * 24")})(((std.Duration.fromSeconds(1036800)).seconds === (((12 * 60) * 60) * 24)))}; + {((cond) => {if (!cond) throw new Error("assertion failed: 12mo.seconds == (12 * 60 * 60 * 24 * 365) / 12")})(((std.Duration.fromSeconds(31536000)).seconds === (((((12 * 60) * 60) * 24) * 365) / 12)))}; + {((cond) => {if (!cond) throw new Error("assertion failed: 12y.seconds == 12 * 60 * 60 * 24 * 365")})(((std.Duration.fromSeconds(378432000)).seconds === ((((12 * 60) * 60) * 24) * 365)))}; + {((cond) => {if (!cond) throw new Error("assertion failed: duration.fromMilliseconds(10).seconds == 10ms.seconds")})(((std.Duration.fromMilliseconds(10)).seconds === (std.Duration.fromSeconds(0.01)).seconds))}; + {((cond) => {if (!cond) throw new Error("assertion failed: duration.fromMinutes(10).seconds == 10m.seconds")})(((std.Duration.fromMinutes(10)).seconds === (std.Duration.fromSeconds(600)).seconds))}; + {((cond) => {if (!cond) throw new Error("assertion failed: duration.fromSeconds(10).seconds == 10s.seconds")})(((std.Duration.fromSeconds(10)).seconds === (std.Duration.fromSeconds(10)).seconds))}; + {((cond) => {if (!cond) throw new Error("assertion failed: duration.fromHours(10).seconds == 10h.seconds")})(((std.Duration.fromHours(10)).seconds === (std.Duration.fromSeconds(36000)).seconds))}; + {((cond) => {if (!cond) throw new Error("assertion failed: duration.fromDays(10).seconds == 10d.seconds")})(((std.Duration.fromDays(10)).seconds === (std.Duration.fromSeconds(864000)).seconds))}; + {((cond) => {if (!cond) throw new Error("assertion failed: duration.fromMonths(10).seconds == 10mo.seconds")})(((std.Duration.fromMonths(10)).seconds === (std.Duration.fromSeconds(26280000)).seconds))}; + {((cond) => {if (!cond) throw new Error("assertion failed: duration.fromYears(10).seconds == 10y.seconds")})(((std.Duration.fromYears(10)).seconds === (std.Duration.fromSeconds(315360000)).seconds))}; + {((cond) => {if (!cond) throw new Error("assertion failed: 1s.milliseconds == 1000")})(((std.Duration.fromSeconds(1)).milliseconds === 1000))}; + {((cond) => {if (!cond) throw new Error("assertion failed: 1s.minutes == 1 / 60")})(((std.Duration.fromSeconds(1)).minutes === (1 / 60)))}; + {((cond) => {if (!cond) throw new Error("assertion failed: 1s.hours == 1 / (60 * 60)")})(((std.Duration.fromSeconds(1)).hours === (1 / (60 * 60))))}; + {((cond) => {if (!cond) throw new Error("assertion failed: 1s.days == 1 / (60 * 60 * 24)")})(((std.Duration.fromSeconds(1)).days === (1 / ((60 * 60) * 24))))}; + {((cond) => {if (!cond) throw new Error("assertion failed: 1s.months == 1 / ((60 * 60 * 24 * 365) / 12)")})(((std.Duration.fromSeconds(1)).months === (1 / ((((60 * 60) * 24) * 365) / 12))))}; + {((cond) => {if (!cond) throw new Error("assertion failed: 1s.years == 1 / (60 * 60 * 24 * 365)")})(((std.Duration.fromSeconds(1)).years === (1 / (((60 * 60) * 24) * 365))))}; this.node.root.new("@winglang/sdk.std.Test",std.Test,this,"test:duration",new $Closure1(this,"$Closure1")); } } diff --git a/tools/hangar/__snapshots__/test_corpus/sdk_tests/std/duration.w_test_sim.md b/tools/hangar/__snapshots__/test_corpus/sdk_tests/std/duration.w_test_sim.md index 4906094b4e8..c4563c7b377 100644 --- a/tools/hangar/__snapshots__/test_corpus/sdk_tests/std/duration.w_test_sim.md +++ b/tools/hangar/__snapshots__/test_corpus/sdk_tests/std/duration.w_test_sim.md @@ -4,12 +4,9 @@ ```log pass โ”€ duration.wsim ยป root/env0/test:duration - - - - -Tests 1 passed (1) + +Tests 1 passed (1) +Test Files 1 passed (1) Duration - ``` diff --git a/tools/hangar/__snapshots__/test_corpus/sdk_tests/std/json.w_compile_tf-aws.md b/tools/hangar/__snapshots__/test_corpus/sdk_tests/std/json.w_compile_tf-aws.md index 5bde71d45d7..7cb8edbf5cd 100644 --- a/tools/hangar/__snapshots__/test_corpus/sdk_tests/std/json.w_compile_tf-aws.md +++ b/tools/hangar/__snapshots__/test_corpus/sdk_tests/std/json.w_compile_tf-aws.md @@ -15,7 +15,7 @@ module.exports = function({ }) { const x = {"a":1}; ((obj, args) => { obj[args[0]] = args[1]; })(x, ["b",2]); const y = (x)["b"]; - {((cond) => {if (!cond) throw new Error(`assertion failed: '(y === 2)'`)})((y === 2))}; + {((cond) => {if (!cond) throw new Error("assertion failed: y == 2")})((y === 2))}; } } return $Closure1; @@ -39,7 +39,7 @@ module.exports = function({ }) { const a = {"c":3}; ((obj, args) => { obj[args[0]] = args[1]; })(x, [2,a]); const d = (x)[2]; - {((cond) => {if (!cond) throw new Error(`assertion failed: '((d)["c"] === 3)'`)})(((d)["c"] === 3))}; + {((cond) => {if (!cond) throw new Error("assertion failed: d.get(\"c\") == 3")})(((d)["c"] === 3))}; } } return $Closure2; @@ -313,12 +313,12 @@ class $Root extends $stdlib.std.Resource { const b = {"b":2}; ((obj, args) => { obj[args[0]] = args[1]; })(a, ["c",b]); const c = (a)["c"]; - {((cond) => {if (!cond) throw new Error(`assertion failed: '((c)["b"] === 2)'`)})(((c)["b"] === 2))}; + {((cond) => {if (!cond) throw new Error("assertion failed: c.get(\"b\") == 2")})(((c)["b"] === 2))}; this.node.root.new("@winglang/sdk.std.Test",std.Test,this,"test:set()",new $Closure1(this,"$Closure1")); const d = {"d":3}; ((obj, args) => { obj[args[0]] = args[1]; })(a, [2,d]); const e = (a)[2]; - {((cond) => {if (!cond) throw new Error(`assertion failed: '((e)["d"] === 3)'`)})(((e)["d"] === 3))}; + {((cond) => {if (!cond) throw new Error("assertion failed: e.get(\"d\") == 3")})(((e)["d"] === 3))}; this.node.root.new("@winglang/sdk.std.Test",std.Test,this,"test:setAt()",new $Closure2(this,"$Closure2")); } } diff --git a/tools/hangar/__snapshots__/test_corpus/sdk_tests/std/json.w_test_sim.md b/tools/hangar/__snapshots__/test_corpus/sdk_tests/std/json.w_test_sim.md index c63a7b60c9e..bf1c3c93e98 100644 --- a/tools/hangar/__snapshots__/test_corpus/sdk_tests/std/json.w_test_sim.md +++ b/tools/hangar/__snapshots__/test_corpus/sdk_tests/std/json.w_test_sim.md @@ -5,12 +5,9 @@ pass โ”€ json.wsim ยป root/env0/test:set() pass โ”€ json.wsim ยป root/env1/test:setAt() - - - - -Tests 1 passed (1) + +Tests 2 passed (2) +Test Files 1 passed (1) Duration - ``` diff --git a/tools/hangar/__snapshots__/test_corpus/sdk_tests/std/map.w_compile_tf-aws.md b/tools/hangar/__snapshots__/test_corpus/sdk_tests/std/map.w_compile_tf-aws.md index db2b3f14152..130d211a262 100644 --- a/tools/hangar/__snapshots__/test_corpus/sdk_tests/std/map.w_compile_tf-aws.md +++ b/tools/hangar/__snapshots__/test_corpus/sdk_tests/std/map.w_compile_tf-aws.md @@ -44,13 +44,13 @@ class $Root extends $stdlib.std.Resource { super(scope, id); const m = Object.freeze({"hello":123,"world":99}); const mkeys = Object.keys(m); - {((cond) => {if (!cond) throw new Error(`assertion failed: '(mkeys.length === 2)'`)})((mkeys.length === 2))}; - {((cond) => {if (!cond) throw new Error(`assertion failed: '((mkeys.at(0)) === "hello")'`)})(((mkeys.at(0)) === "hello"))}; - {((cond) => {if (!cond) throw new Error(`assertion failed: '((mkeys.at(1)) === "world")'`)})(((mkeys.at(1)) === "world"))}; + {((cond) => {if (!cond) throw new Error("assertion failed: mkeys.length == 2")})((mkeys.length === 2))}; + {((cond) => {if (!cond) throw new Error("assertion failed: mkeys.at(0) == \"hello\"")})(((mkeys.at(0)) === "hello"))}; + {((cond) => {if (!cond) throw new Error("assertion failed: mkeys.at(1) == \"world\"")})(((mkeys.at(1)) === "world"))}; const mvalues = Object.values(m); - {((cond) => {if (!cond) throw new Error(`assertion failed: '(mvalues.length === 2)'`)})((mvalues.length === 2))}; - {((cond) => {if (!cond) throw new Error(`assertion failed: '((mvalues.at(0)) === 123)'`)})(((mvalues.at(0)) === 123))}; - {((cond) => {if (!cond) throw new Error(`assertion failed: '((mvalues.at(1)) === 99)'`)})(((mvalues.at(1)) === 99))}; + {((cond) => {if (!cond) throw new Error("assertion failed: mvalues.length == 2")})((mvalues.length === 2))}; + {((cond) => {if (!cond) throw new Error("assertion failed: mvalues.at(0) == 123")})(((mvalues.at(0)) === 123))}; + {((cond) => {if (!cond) throw new Error("assertion failed: mvalues.at(1) == 99")})(((mvalues.at(1)) === 99))}; } } class $App extends $AppBase { diff --git a/tools/hangar/__snapshots__/test_corpus/sdk_tests/std/map.w_test_sim.md b/tools/hangar/__snapshots__/test_corpus/sdk_tests/std/map.w_test_sim.md index 4e8b0e82116..21e1d1d5f47 100644 --- a/tools/hangar/__snapshots__/test_corpus/sdk_tests/std/map.w_test_sim.md +++ b/tools/hangar/__snapshots__/test_corpus/sdk_tests/std/map.w_test_sim.md @@ -4,12 +4,9 @@ ```log pass โ”€ map.wsim (no tests) - - - - -Tests 1 passed (1) + +Tests 1 passed (1) +Test Files 1 passed (1) Duration - ``` diff --git a/tools/hangar/__snapshots__/test_corpus/sdk_tests/std/number.w_compile_tf-aws.md b/tools/hangar/__snapshots__/test_corpus/sdk_tests/std/number.w_compile_tf-aws.md index 75b443afa28..f5050161bb6 100644 --- a/tools/hangar/__snapshots__/test_corpus/sdk_tests/std/number.w_compile_tf-aws.md +++ b/tools/hangar/__snapshots__/test_corpus/sdk_tests/std/number.w_compile_tf-aws.md @@ -12,7 +12,7 @@ module.exports = function({ std_Number }) { async $inflight_init() { } async handle() { - {((cond) => {if (!cond) throw new Error(`assertion failed: '(((args) => { if (typeof args !== "number") {throw new Error("unable to parse " + typeof args + " " + args + " as a number")}; return JSON.parse(JSON.stringify(args)) })(123) === 123)'`)})((((args) => { if (typeof args !== "number") {throw new Error("unable to parse " + typeof args + " " + args + " as a number")}; return JSON.parse(JSON.stringify(args)) })(123) === 123))}; + {((cond) => {if (!cond) throw new Error("assertion failed: num.fromJson(Json 123) == 123")})((((args) => { if (typeof args !== "number") {throw new Error("unable to parse " + typeof args + " " + args + " as a number")}; return JSON.parse(JSON.stringify(args)) })(123) === 123))}; } } return $Closure1; @@ -32,7 +32,7 @@ module.exports = function({ std_Number }) { async $inflight_init() { } async handle() { - {((cond) => {if (!cond) throw new Error(`assertion failed: '(((args) => { if (isNaN(args)) {throw new Error("unable to parse \"" + args + "\" as a number")}; return parseInt(args) })("888") === 888)'`)})((((args) => { if (isNaN(args)) {throw new Error("unable to parse \"" + args + "\" as a number")}; return parseInt(args) })("888") === 888))}; + {((cond) => {if (!cond) throw new Error("assertion failed: num.fromStr(\"888\") == 888")})((((args) => { if (isNaN(args)) {throw new Error("unable to parse \"" + args + "\" as a number")}; return parseInt(args) })("888") === 888))}; } } return $Closure2; @@ -305,9 +305,9 @@ class $Root extends $stdlib.std.Resource { super._registerBind(host, ops); } } - {((cond) => {if (!cond) throw new Error(`assertion failed: '(((args) => { if (typeof args !== "number") {throw new Error("unable to parse " + typeof args + " " + args + " as a number")}; return JSON.parse(JSON.stringify(args)) })(12) === 12)'`)})((((args) => { if (typeof args !== "number") {throw new Error("unable to parse " + typeof args + " " + args + " as a number")}; return JSON.parse(JSON.stringify(args)) })(12) === 12))}; + {((cond) => {if (!cond) throw new Error("assertion failed: num.fromJson(Json 12) == 12")})((((args) => { if (typeof args !== "number") {throw new Error("unable to parse " + typeof args + " " + args + " as a number")}; return JSON.parse(JSON.stringify(args)) })(12) === 12))}; this.node.root.new("@winglang/sdk.std.Test",std.Test,this,"test:fromJson",new $Closure1(this,"$Closure1")); - {((cond) => {if (!cond) throw new Error(`assertion failed: '(((args) => { if (isNaN(args)) {throw new Error("unable to parse \"" + args + "\" as a number")}; return parseInt(args) })("42") === 42)'`)})((((args) => { if (isNaN(args)) {throw new Error("unable to parse \"" + args + "\" as a number")}; return parseInt(args) })("42") === 42))}; + {((cond) => {if (!cond) throw new Error("assertion failed: num.fromStr(\"42\") == 42")})((((args) => { if (isNaN(args)) {throw new Error("unable to parse \"" + args + "\" as a number")}; return parseInt(args) })("42") === 42))}; this.node.root.new("@winglang/sdk.std.Test",std.Test,this,"test:fromStr",new $Closure2(this,"$Closure2")); } } diff --git a/tools/hangar/__snapshots__/test_corpus/sdk_tests/std/number.w_test_sim.md b/tools/hangar/__snapshots__/test_corpus/sdk_tests/std/number.w_test_sim.md index effd7fe7cf2..c3bd8019bdc 100644 --- a/tools/hangar/__snapshots__/test_corpus/sdk_tests/std/number.w_test_sim.md +++ b/tools/hangar/__snapshots__/test_corpus/sdk_tests/std/number.w_test_sim.md @@ -5,12 +5,9 @@ pass โ”€ number.wsim ยป root/env0/test:fromJson pass โ”€ number.wsim ยป root/env1/test:fromStr - - - - -Tests 1 passed (1) + +Tests 2 passed (2) +Test Files 1 passed (1) Duration - ``` diff --git a/tools/hangar/__snapshots__/test_corpus/sdk_tests/std/range.w_test_sim.md b/tools/hangar/__snapshots__/test_corpus/sdk_tests/std/range.w_test_sim.md index 5051bfb58e8..f1f4399d82a 100644 --- a/tools/hangar/__snapshots__/test_corpus/sdk_tests/std/range.w_test_sim.md +++ b/tools/hangar/__snapshots__/test_corpus/sdk_tests/std/range.w_test_sim.md @@ -4,12 +4,9 @@ ```log pass โ”€ range.wsim (no tests) - - - - -Tests 1 passed (1) + +Tests 1 passed (1) +Test Files 1 passed (1) Duration - ``` diff --git a/tools/hangar/__snapshots__/test_corpus/sdk_tests/std/set.w_test_sim.md b/tools/hangar/__snapshots__/test_corpus/sdk_tests/std/set.w_test_sim.md index 2d6d73097a6..5ac65aafccf 100644 --- a/tools/hangar/__snapshots__/test_corpus/sdk_tests/std/set.w_test_sim.md +++ b/tools/hangar/__snapshots__/test_corpus/sdk_tests/std/set.w_test_sim.md @@ -4,12 +4,9 @@ ```log pass โ”€ set.wsim (no tests) - - - - -Tests 1 passed (1) + +Tests 1 passed (1) +Test Files 1 passed (1) Duration - ``` diff --git a/tools/hangar/__snapshots__/test_corpus/sdk_tests/std/string.w_compile_tf-aws.md b/tools/hangar/__snapshots__/test_corpus/sdk_tests/std/string.w_compile_tf-aws.md index d8a32fbd13f..c27b561f284 100644 --- a/tools/hangar/__snapshots__/test_corpus/sdk_tests/std/string.w_compile_tf-aws.md +++ b/tools/hangar/__snapshots__/test_corpus/sdk_tests/std/string.w_compile_tf-aws.md @@ -12,13 +12,13 @@ module.exports = function({ PARSE_ERROR, std_String }) { async $inflight_init() { } async handle() { - {((cond) => {if (!cond) throw new Error(`assertion failed: '(((args) => { if (typeof args !== "string") {throw new Error("unable to parse " + typeof args + " " + args + " as a string")}; return JSON.parse(JSON.stringify(args)) })("World") === "World")'`)})((((args) => { if (typeof args !== "string") {throw new Error("unable to parse " + typeof args + " " + args + " as a string")}; return JSON.parse(JSON.stringify(args)) })("World") === "World"))}; + {((cond) => {if (!cond) throw new Error("assertion failed: str.fromJson(Json \"World\") == \"World\"")})((((args) => { if (typeof args !== "string") {throw new Error("unable to parse " + typeof args + " " + args + " as a string")}; return JSON.parse(JSON.stringify(args)) })("World") === "World"))}; try { ((args) => { if (typeof args !== "string") {throw new Error("unable to parse " + typeof args + " " + args + " as a string")}; return JSON.parse(JSON.stringify(args)) })(123); } catch ($error_s) { const s = $error_s.message; - {((cond) => {if (!cond) throw new Error(`assertion failed: '(s === PARSE_ERROR)'`)})((s === PARSE_ERROR))}; + {((cond) => {if (!cond) throw new Error("assertion failed: s == PARSE_ERROR")})((s === PARSE_ERROR))}; } } } @@ -39,8 +39,8 @@ module.exports = function({ }) { async $inflight_init() { } async handle() { - {((cond) => {if (!cond) throw new Error(`assertion failed: '("hello".length === 5)'`)})(("hello".length === 5))}; - {((cond) => {if (!cond) throw new Error(`assertion failed: '("".length === 0)'`)})(("".length === 0))}; + {((cond) => {if (!cond) throw new Error("assertion failed: \"hello\".length == 5")})(("hello".length === 5))}; + {((cond) => {if (!cond) throw new Error("assertion failed: \"\".length == 0")})(("".length === 0))}; } } return $Closure2; @@ -60,7 +60,7 @@ module.exports = function({ }) { async $inflight_init() { } async handle() { - {((cond) => {if (!cond) throw new Error(`assertion failed: '((await "boom".at(0)) === "b")'`)})(((await "boom".at(0)) === "b"))}; + {((cond) => {if (!cond) throw new Error("assertion failed: \"boom\".at(0) == \"b\"")})(((await "boom".at(0)) === "b"))}; } } return $Closure3; @@ -440,23 +440,23 @@ class $Root extends $stdlib.std.Resource { } catch ($error_actual) { const actual = $error_actual.message; - {((cond) => {if (!cond) throw new Error(`assertion failed: '(actual === expected)'`)})((actual === expected))}; + {((cond) => {if (!cond) throw new Error("assertion failed: actual == expected")})((actual === expected))}; error = true; } - {((cond) => {if (!cond) throw new Error(`assertion failed: 'error'`)})(error)}; + {((cond) => {if (!cond) throw new Error("assertion failed: error")})(error)}; } ; const PARSE_ERROR = "unable to parse number 123 as a string"; - {((cond) => {if (!cond) throw new Error(`assertion failed: '(((args) => { if (typeof args !== "string") {throw new Error("unable to parse " + typeof args + " " + args + " as a string")}; return JSON.parse(JSON.stringify(args)) })("Hello") === "Hello")'`)})((((args) => { if (typeof args !== "string") {throw new Error("unable to parse " + typeof args + " " + args + " as a string")}; return JSON.parse(JSON.stringify(args)) })("Hello") === "Hello"))}; + {((cond) => {if (!cond) throw new Error("assertion failed: str.fromJson(Json \"Hello\") == \"Hello\"")})((((args) => { if (typeof args !== "string") {throw new Error("unable to parse " + typeof args + " " + args + " as a string")}; return JSON.parse(JSON.stringify(args)) })("Hello") === "Hello"))}; (assertThrows(PARSE_ERROR, () => { ((args) => { if (typeof args !== "string") {throw new Error("unable to parse " + typeof args + " " + args + " as a string")}; return JSON.parse(JSON.stringify(args)) })(123); } )); this.node.root.new("@winglang/sdk.std.Test",std.Test,this,"test:fromJson",new $Closure1(this,"$Closure1")); - {((cond) => {if (!cond) throw new Error(`assertion failed: '("hello".length === 5)'`)})(("hello".length === 5))}; - {((cond) => {if (!cond) throw new Error(`assertion failed: '("".length === 0)'`)})(("".length === 0))}; + {((cond) => {if (!cond) throw new Error("assertion failed: \"hello\".length == 5")})(("hello".length === 5))}; + {((cond) => {if (!cond) throw new Error("assertion failed: \"\".length == 0")})(("".length === 0))}; this.node.root.new("@winglang/sdk.std.Test",std.Test,this,"test:length",new $Closure2(this,"$Closure2")); - {((cond) => {if (!cond) throw new Error(`assertion failed: '(("boom".at(2)) === "o")'`)})((("boom".at(2)) === "o"))}; + {((cond) => {if (!cond) throw new Error("assertion failed: \"boom\".at(2) == \"o\"")})((("boom".at(2)) === "o"))}; this.node.root.new("@winglang/sdk.std.Test",std.Test,this,"test:at()",new $Closure3(this,"$Closure3")); } } diff --git a/tools/hangar/__snapshots__/test_corpus/sdk_tests/std/string.w_test_sim.md b/tools/hangar/__snapshots__/test_corpus/sdk_tests/std/string.w_test_sim.md index 4e600263c0c..048d9e6ebec 100644 --- a/tools/hangar/__snapshots__/test_corpus/sdk_tests/std/string.w_test_sim.md +++ b/tools/hangar/__snapshots__/test_corpus/sdk_tests/std/string.w_test_sim.md @@ -6,12 +6,9 @@ pass โ”€ string.wsim ยป root/env0/test:fromJson pass โ”€ string.wsim ยป root/env1/test:length pass โ”€ string.wsim ยป root/env2/test:at() - - - - -Tests 1 passed (1) + +Tests 3 passed (3) +Test Files 1 passed (1) Duration - ``` diff --git a/tools/hangar/__snapshots__/test_corpus/sdk_tests/table/add_row.w_compile_tf-aws.md b/tools/hangar/__snapshots__/test_corpus/sdk_tests/table/add_row.w_compile_tf-aws.md new file mode 100644 index 00000000000..ee0611a582c --- /dev/null +++ b/tools/hangar/__snapshots__/test_corpus/sdk_tests/table/add_row.w_compile_tf-aws.md @@ -0,0 +1,274 @@ +# [add_row.w](../../../../../../examples/tests/sdk_tests/table/add_row.w) | compile | tf-aws + +## inflight.$Closure1.js +```js +module.exports = function({ table, marioInfo, peachInfo, std_Json }) { + class $Closure1 { + constructor({ }) { + const $obj = (...args) => this.handle(...args); + Object.setPrototypeOf($obj, this); + return $obj; + } + async $inflight_init() { + } + async handle() { + {((cond) => {if (!cond) throw new Error("assertion failed: Json.stringify(table.get(\"mario\")) == Json.stringify(marioInfo)")})((((args) => { return JSON.stringify(args[0], null, args[1]) })([(await table.get("mario"))]) === ((args) => { return JSON.stringify(args[0], null, args[1]) })([marioInfo])))}; + {((cond) => {if (!cond) throw new Error("assertion failed: Json.stringify(table.get(\"peach\")) == Json.stringify(peachInfo)")})((((args) => { return JSON.stringify(args[0], null, args[1]) })([(await table.get("peach"))]) === ((args) => { return JSON.stringify(args[0], null, args[1]) })([peachInfo])))}; + } + } + return $Closure1; +} + +``` + +## main.tf.json +```json +{ + "//": { + "metadata": { + "backend": "local", + "stackName": "root", + "version": "0.15.2" + }, + "outputs": { + "root": { + "Default": { + "cloud.TestRunner": { + "TestFunctionArns": "WING_TEST_RUNNER_FUNCTION_ARNS" + } + } + } + } + }, + "output": { + "WING_TEST_RUNNER_FUNCTION_ARNS": { + "value": "[[\"root/Default/Default/test:addRow\",\"${aws_lambda_function.root_testaddRow_Handler_341A155A.arn}\"]]" + } + }, + "provider": { + "aws": [ + {} + ] + }, + "resource": { + "aws_dynamodb_table": { + "root_cloudTable_323D7643": { + "//": { + "metadata": { + "path": "root/Default/Default/cloud.Table/Default", + "uniqueId": "root_cloudTable_323D7643" + } + }, + "attribute": [ + { + "name": "name", + "type": "S" + } + ], + "billing_mode": "PAY_PER_REQUEST", + "hash_key": "name", + "name": "userscloud.Table-c83b78a7" + } + }, + "aws_dynamodb_table_item": { + "root_cloudTable_DynamodbTableItemmario_B5126782": { + "//": { + "metadata": { + "path": "root/Default/Default/cloud.Table/DynamodbTableItem-mario", + "uniqueId": "root_cloudTable_DynamodbTableItemmario_B5126782" + } + }, + "hash_key": "${aws_dynamodb_table.root_cloudTable_323D7643.hash_key}", + "item": "{\"name\":{\"S\":\"mario\"},\"gender\":{\"S\":\"male\"},\"role\":{\"S\":\"plumber\"}}", + "table_name": "${aws_dynamodb_table.root_cloudTable_323D7643.name}" + }, + "root_cloudTable_DynamodbTableItempeach_63A97BD4": { + "//": { + "metadata": { + "path": "root/Default/Default/cloud.Table/DynamodbTableItem-peach", + "uniqueId": "root_cloudTable_DynamodbTableItempeach_63A97BD4" + } + }, + "hash_key": "${aws_dynamodb_table.root_cloudTable_323D7643.hash_key}", + "item": "{\"name\":{\"S\":\"peach\"},\"gender\":{\"S\":\"female\"},\"role\":{\"S\":\"princess\"}}", + "table_name": "${aws_dynamodb_table.root_cloudTable_323D7643.name}" + } + }, + "aws_iam_role": { + "root_testaddRow_Handler_IamRole_938BAC5C": { + "//": { + "metadata": { + "path": "root/Default/Default/test:addRow/Handler/IamRole", + "uniqueId": "root_testaddRow_Handler_IamRole_938BAC5C" + } + }, + "assume_role_policy": "{\"Version\":\"2012-10-17\",\"Statement\":[{\"Action\":\"sts:AssumeRole\",\"Principal\":{\"Service\":\"lambda.amazonaws.com\"},\"Effect\":\"Allow\"}]}" + } + }, + "aws_iam_role_policy": { + "root_testaddRow_Handler_IamRolePolicy_4078E893": { + "//": { + "metadata": { + "path": "root/Default/Default/test:addRow/Handler/IamRolePolicy", + "uniqueId": "root_testaddRow_Handler_IamRolePolicy_4078E893" + } + }, + "policy": "{\"Version\":\"2012-10-17\",\"Statement\":[{\"Action\":[\"dynamodb:GetItem\"],\"Resource\":[\"${aws_dynamodb_table.root_cloudTable_323D7643.arn}\"],\"Effect\":\"Allow\"}]}", + "role": "${aws_iam_role.root_testaddRow_Handler_IamRole_938BAC5C.name}" + } + }, + "aws_iam_role_policy_attachment": { + "root_testaddRow_Handler_IamRolePolicyAttachment_263D7BE3": { + "//": { + "metadata": { + "path": "root/Default/Default/test:addRow/Handler/IamRolePolicyAttachment", + "uniqueId": "root_testaddRow_Handler_IamRolePolicyAttachment_263D7BE3" + } + }, + "policy_arn": "arn:aws:iam::aws:policy/service-role/AWSLambdaBasicExecutionRole", + "role": "${aws_iam_role.root_testaddRow_Handler_IamRole_938BAC5C.name}" + } + }, + "aws_lambda_function": { + "root_testaddRow_Handler_341A155A": { + "//": { + "metadata": { + "path": "root/Default/Default/test:addRow/Handler/Default", + "uniqueId": "root_testaddRow_Handler_341A155A" + } + }, + "environment": { + "variables": { + "DYNAMODB_TABLE_NAME_e8a1ff2c": "${aws_dynamodb_table.root_cloudTable_323D7643.name}", + "DYNAMODB_TABLE_NAME_e8a1ff2c_COLUMNS": "{\"gender\":0}", + "DYNAMODB_TABLE_NAME_e8a1ff2c_PRIMARY_KEY": "name", + "WING_FUNCTION_NAME": "Handler-c8f74599", + "WING_TARGET": "tf-aws" + } + }, + "function_name": "Handler-c8f74599", + "handler": "index.handler", + "publish": true, + "role": "${aws_iam_role.root_testaddRow_Handler_IamRole_938BAC5C.arn}", + "runtime": "nodejs18.x", + "s3_bucket": "${aws_s3_bucket.root_Code_02F3C603.bucket}", + "s3_key": "${aws_s3_object.root_testaddRow_Handler_S3Object_98654367.key}", + "timeout": 30, + "vpc_config": { + "security_group_ids": [], + "subnet_ids": [] + } + } + }, + "aws_s3_bucket": { + "root_Code_02F3C603": { + "//": { + "metadata": { + "path": "root/Default/Code", + "uniqueId": "root_Code_02F3C603" + } + }, + "bucket_prefix": "code-c84a50b1-" + } + }, + "aws_s3_object": { + "root_testaddRow_Handler_S3Object_98654367": { + "//": { + "metadata": { + "path": "root/Default/Default/test:addRow/Handler/S3Object", + "uniqueId": "root_testaddRow_Handler_S3Object_98654367" + } + }, + "bucket": "${aws_s3_bucket.root_Code_02F3C603.bucket}", + "key": "", + "source": "" + } + } + } +} +``` + +## preflight.js +```js +const $stdlib = require('@winglang/sdk'); +const $outdir = process.env.WING_SYNTH_DIR ?? "."; +const std = $stdlib.std; +const $wing_is_test = process.env.WING_IS_TEST === "true"; +const $AppBase = $stdlib.core.App.for(process.env.WING_TARGET); +const cloud = require('@winglang/sdk').cloud; +class $Root extends $stdlib.std.Resource { + constructor(scope, id) { + super(scope, id); + class $Closure1 extends $stdlib.std.Resource { + constructor(scope, id, ) { + super(scope, id); + this._addInflightOps("handle"); + this.display.hidden = true; + } + static _toInflightType(context) { + const self_client_path = "././inflight.$Closure1.js"; + const table_client = context._lift(table); + const marioInfo_client = context._lift(marioInfo); + const peachInfo_client = context._lift(peachInfo); + const std_JsonClient = std.Json._toInflightType(context); + return $stdlib.core.NodeJsCode.fromInline(` + require("${self_client_path}")({ + table: ${table_client}, + marioInfo: ${marioInfo_client}, + peachInfo: ${peachInfo_client}, + std_Json: ${std_JsonClient.text}, + }) + `); + } + _toInflight() { + return $stdlib.core.NodeJsCode.fromInline(` + (await (async () => { + const $Closure1Client = ${$Closure1._toInflightType(this).text}; + const client = new $Closure1Client({ + }); + if (client.$inflight_init) { await client.$inflight_init(); } + return client; + })()) + `); + } + _registerBind(host, ops) { + if (ops.includes("$inflight_init")) { + $Closure1._registerBindObject(marioInfo, host, []); + $Closure1._registerBindObject(peachInfo, host, []); + $Closure1._registerBindObject(table, host, []); + } + if (ops.includes("handle")) { + $Closure1._registerBindObject(marioInfo, host, []); + $Closure1._registerBindObject(peachInfo, host, []); + $Closure1._registerBindObject(table, host, ["get"]); + } + super._registerBind(host, ops); + } + } + const table = this.node.root.newAbstract("@winglang/sdk.cloud.Table",this,"cloud.Table",{ name: "users", primaryKey: "name", columns: Object.freeze({"gender":cloud.ColumnType.STRING}) }); + const marioInfo = Object.freeze({"gender":"male","role":"plumber"}); + const peachInfo = Object.freeze({"gender":"female","role":"princess"}); + (table.addRow("mario",marioInfo)); + (table.addRow("peach",peachInfo)); + this.node.root.new("@winglang/sdk.std.Test",std.Test,this,"test:addRow",new $Closure1(this,"$Closure1")); + } +} +class $App extends $AppBase { + constructor() { + super({ outdir: $outdir, name: "add_row", plugins: $plugins, isTestEnvironment: $wing_is_test }); + if ($wing_is_test) { + new $Root(this, "env0"); + const $test_runner = this.testRunner; + const $tests = $test_runner.findTests(); + for (let $i = 1; $i < $tests.length; $i++) { + new $Root(this, "env" + $i); + } + } else { + new $Root(this, "Default"); + } + } +} +new $App().synth(); + +``` + diff --git a/tools/hangar/__snapshots__/test_corpus/sdk_tests/table/add_row.w_test_sim.md b/tools/hangar/__snapshots__/test_corpus/sdk_tests/table/add_row.w_test_sim.md new file mode 100644 index 00000000000..3c1ecc25097 --- /dev/null +++ b/tools/hangar/__snapshots__/test_corpus/sdk_tests/table/add_row.w_test_sim.md @@ -0,0 +1,12 @@ +# [add_row.w](../../../../../../examples/tests/sdk_tests/table/add_row.w) | test | sim + +## stdout.log +```log +pass โ”€ add_row.wsim ยป root/env0/test:addRow + + +Tests 1 passed (1) +Test Files 1 passed (1) +Duration +``` + diff --git a/tools/hangar/__snapshots__/test_corpus/sdk_tests/table/list.w_compile_tf-aws.md b/tools/hangar/__snapshots__/test_corpus/sdk_tests/table/list.w_compile_tf-aws.md index 4f963fa7109..27ee5879cc7 100644 --- a/tools/hangar/__snapshots__/test_corpus/sdk_tests/table/list.w_compile_tf-aws.md +++ b/tools/hangar/__snapshots__/test_corpus/sdk_tests/table/list.w_compile_tf-aws.md @@ -20,10 +20,10 @@ module.exports = function({ table, std_String }) { } const revital = (unorderded)["revital"]; const eyal = (unorderded)["eyal"]; - {((cond) => {if (!cond) throw new Error(`assertion failed: '("eyal" === ((args) => { if (typeof args !== "string") {throw new Error("unable to parse " + typeof args + " " + args + " as a string")}; return JSON.parse(JSON.stringify(args)) })((eyal)["name"]))'`)})(("eyal" === ((args) => { if (typeof args !== "string") {throw new Error("unable to parse " + typeof args + " " + args + " as a string")}; return JSON.parse(JSON.stringify(args)) })((eyal)["name"])))}; - {((cond) => {if (!cond) throw new Error(`assertion failed: '("male" === ((args) => { if (typeof args !== "string") {throw new Error("unable to parse " + typeof args + " " + args + " as a string")}; return JSON.parse(JSON.stringify(args)) })((eyal)["gender"]))'`)})(("male" === ((args) => { if (typeof args !== "string") {throw new Error("unable to parse " + typeof args + " " + args + " as a string")}; return JSON.parse(JSON.stringify(args)) })((eyal)["gender"])))}; - {((cond) => {if (!cond) throw new Error(`assertion failed: '("revital" === ((args) => { if (typeof args !== "string") {throw new Error("unable to parse " + typeof args + " " + args + " as a string")}; return JSON.parse(JSON.stringify(args)) })((revital)["name"]))'`)})(("revital" === ((args) => { if (typeof args !== "string") {throw new Error("unable to parse " + typeof args + " " + args + " as a string")}; return JSON.parse(JSON.stringify(args)) })((revital)["name"])))}; - {((cond) => {if (!cond) throw new Error(`assertion failed: '("female" === ((args) => { if (typeof args !== "string") {throw new Error("unable to parse " + typeof args + " " + args + " as a string")}; return JSON.parse(JSON.stringify(args)) })((revital)["gender"]))'`)})(("female" === ((args) => { if (typeof args !== "string") {throw new Error("unable to parse " + typeof args + " " + args + " as a string")}; return JSON.parse(JSON.stringify(args)) })((revital)["gender"])))}; + {((cond) => {if (!cond) throw new Error("assertion failed: \"eyal\" == str.fromJson(eyal.get(\"name\"))")})(("eyal" === ((args) => { if (typeof args !== "string") {throw new Error("unable to parse " + typeof args + " " + args + " as a string")}; return JSON.parse(JSON.stringify(args)) })((eyal)["name"])))}; + {((cond) => {if (!cond) throw new Error("assertion failed: \"male\" == str.fromJson(eyal.get(\"gender\"))")})(("male" === ((args) => { if (typeof args !== "string") {throw new Error("unable to parse " + typeof args + " " + args + " as a string")}; return JSON.parse(JSON.stringify(args)) })((eyal)["gender"])))}; + {((cond) => {if (!cond) throw new Error("assertion failed: \"revital\" == str.fromJson(revital.get(\"name\"))")})(("revital" === ((args) => { if (typeof args !== "string") {throw new Error("unable to parse " + typeof args + " " + args + " as a string")}; return JSON.parse(JSON.stringify(args)) })((revital)["name"])))}; + {((cond) => {if (!cond) throw new Error("assertion failed: \"female\" == str.fromJson(revital.get(\"gender\"))")})(("female" === ((args) => { if (typeof args !== "string") {throw new Error("unable to parse " + typeof args + " " + args + " as a string")}; return JSON.parse(JSON.stringify(args)) })((revital)["gender"])))}; } } return $Closure1; diff --git a/tools/hangar/__snapshots__/test_corpus/sdk_tests/table/list.w_test_sim.md b/tools/hangar/__snapshots__/test_corpus/sdk_tests/table/list.w_test_sim.md index 7d7869429d8..51fd0a0d2d8 100644 --- a/tools/hangar/__snapshots__/test_corpus/sdk_tests/table/list.w_test_sim.md +++ b/tools/hangar/__snapshots__/test_corpus/sdk_tests/table/list.w_test_sim.md @@ -4,12 +4,9 @@ ```log pass โ”€ list.wsim ยป root/env0/test:list - - - - -Tests 1 passed (1) + +Tests 1 passed (1) +Test Files 1 passed (1) Duration - ``` diff --git a/tools/hangar/__snapshots__/test_corpus/sdk_tests/topic/on_message.w_compile_tf-aws.md b/tools/hangar/__snapshots__/test_corpus/sdk_tests/topic/on_message.w_compile_tf-aws.md index 9a7d31f7939..bbcd551f026 100644 --- a/tools/hangar/__snapshots__/test_corpus/sdk_tests/topic/on_message.w_compile_tf-aws.md +++ b/tools/hangar/__snapshots__/test_corpus/sdk_tests/topic/on_message.w_compile_tf-aws.md @@ -59,12 +59,12 @@ module.exports = function({ t, predicate, TestHelper }) { while ((i < 600)) { i = (i + 1); if ((await predicate.test())) { - {((cond) => {if (!cond) throw new Error(`assertion failed: '(await predicate.test())'`)})((await predicate.test()))}; + {((cond) => {if (!cond) throw new Error("assertion failed: predicate.test()")})((await predicate.test()))}; return; } (await TestHelper.sleep(100)); } - {((cond) => {if (!cond) throw new Error(`assertion failed: '(await predicate.test())'`)})((await predicate.test()))}; + {((cond) => {if (!cond) throw new Error("assertion failed: predicate.test()")})((await predicate.test()))}; } } return $Closure3; diff --git a/tools/hangar/__snapshots__/test_corpus/sdk_tests/topic/on_message.w_test_sim.md b/tools/hangar/__snapshots__/test_corpus/sdk_tests/topic/on_message.w_test_sim.md index 70719a4044c..71e248edffa 100644 --- a/tools/hangar/__snapshots__/test_corpus/sdk_tests/topic/on_message.w_test_sim.md +++ b/tools/hangar/__snapshots__/test_corpus/sdk_tests/topic/on_message.w_test_sim.md @@ -4,12 +4,9 @@ ```log pass โ”€ on_message.wsim ยป root/env0/test:onMessage - - - - -Tests 1 passed (1) + +Tests 1 passed (1) +Test Files 1 passed (1) Duration - ``` diff --git a/tools/hangar/__snapshots__/test_corpus/sdk_tests/util/env.w_compile_tf-aws.md b/tools/hangar/__snapshots__/test_corpus/sdk_tests/util/env.w_compile_tf-aws.md index ce1aabec6fb..27dd1301f3d 100644 --- a/tools/hangar/__snapshots__/test_corpus/sdk_tests/util/env.w_compile_tf-aws.md +++ b/tools/hangar/__snapshots__/test_corpus/sdk_tests/util/env.w_compile_tf-aws.md @@ -12,9 +12,9 @@ module.exports = function({ RANDOM, NIL, util_Util }) { async $inflight_init() { } async handle() { - {((cond) => {if (!cond) throw new Error(`assertion failed: '((await util_Util.env("WING_TARGET")).length > 0)'`)})(((await util_Util.env("WING_TARGET")).length > 0))}; + {((cond) => {if (!cond) throw new Error("assertion failed: util.env(\"WING_TARGET\").length > 0")})(((await util_Util.env("WING_TARGET")).length > 0))}; const noValue = ((await util_Util.tryEnv(RANDOM)) ?? NIL); - {((cond) => {if (!cond) throw new Error(`assertion failed: '(noValue === NIL)'`)})((noValue === NIL))}; + {((cond) => {if (!cond) throw new Error("assertion failed: noValue == NIL")})((noValue === NIL))}; } } return $Closure1; @@ -198,8 +198,8 @@ class $Root extends $stdlib.std.Resource { } const RANDOM = "RANDOM123412121212kjhkjskdjkj"; const NIL = "<>"; - {((cond) => {if (!cond) throw new Error(`assertion failed: '((util.Util.env("PATH")).length > 0)'`)})(((util.Util.env("PATH")).length > 0))}; - {((cond) => {if (!cond) throw new Error(`assertion failed: '((util.Util.env("MY_VAR")) === "my value")'`)})(((util.Util.env("MY_VAR")) === "my value"))}; + {((cond) => {if (!cond) throw new Error("assertion failed: util.env(\"PATH\").length > 0")})(((util.Util.env("PATH")).length > 0))}; + {((cond) => {if (!cond) throw new Error("assertion failed: util.env(\"MY_VAR\") == \"my value\"")})(((util.Util.env("MY_VAR")) === "my value"))}; let failed = false; try { (util.Util.env(RANDOM)); @@ -207,9 +207,9 @@ class $Root extends $stdlib.std.Resource { catch { failed = true; } - {((cond) => {if (!cond) throw new Error(`assertion failed: 'failed'`)})(failed)}; + {((cond) => {if (!cond) throw new Error("assertion failed: failed")})(failed)}; const no_value = ((util.Util.tryEnv(RANDOM)) ?? NIL); - {((cond) => {if (!cond) throw new Error(`assertion failed: '(no_value === NIL)'`)})((no_value === NIL))}; + {((cond) => {if (!cond) throw new Error("assertion failed: no_value == NIL")})((no_value === NIL))}; this.node.root.new("@winglang/sdk.std.Test",std.Test,this,"test:use util from inflight",new $Closure1(this,"$Closure1")); } } diff --git a/tools/hangar/__snapshots__/test_corpus/sdk_tests/util/env.w_test_sim.md b/tools/hangar/__snapshots__/test_corpus/sdk_tests/util/env.w_test_sim.md index 83749570030..90e19175ee9 100644 --- a/tools/hangar/__snapshots__/test_corpus/sdk_tests/util/env.w_test_sim.md +++ b/tools/hangar/__snapshots__/test_corpus/sdk_tests/util/env.w_test_sim.md @@ -4,12 +4,9 @@ ```log pass โ”€ env.wsim ยป root/env0/test:use util from inflight - - - - -Tests 1 passed (1) + +Tests 1 passed (1) +Test Files 1 passed (1) Duration - ``` diff --git a/tools/hangar/__snapshots__/test_corpus/sdk_tests/util/sleep.w_compile_tf-aws.md b/tools/hangar/__snapshots__/test_corpus/sdk_tests/util/sleep.w_compile_tf-aws.md index 846e54efee8..f864887203c 100644 --- a/tools/hangar/__snapshots__/test_corpus/sdk_tests/util/sleep.w_compile_tf-aws.md +++ b/tools/hangar/__snapshots__/test_corpus/sdk_tests/util/sleep.w_compile_tf-aws.md @@ -16,7 +16,7 @@ module.exports = function({ oneHundredMiliseconds, JSHelper, util_Util }) { (await util_Util.sleep(oneHundredMiliseconds)); const end = (await JSHelper.getTime()); const delta = (end - start); - {((cond) => {if (!cond) throw new Error(`assertion failed: '(delta >= 100)'`)})((delta >= 100))}; + {((cond) => {if (!cond) throw new Error("assertion failed: delta >= 100")})((delta >= 100))}; } } return $Closure1; diff --git a/tools/hangar/__snapshots__/test_corpus/sdk_tests/util/sleep.w_test_sim.md b/tools/hangar/__snapshots__/test_corpus/sdk_tests/util/sleep.w_test_sim.md index 1bda215bbdc..ef237f8382f 100644 --- a/tools/hangar/__snapshots__/test_corpus/sdk_tests/util/sleep.w_test_sim.md +++ b/tools/hangar/__snapshots__/test_corpus/sdk_tests/util/sleep.w_test_sim.md @@ -4,12 +4,9 @@ ```log pass โ”€ sleep.wsim ยป root/env0/test:sleep 100 mili seconds - - - - -Tests 1 passed (1) + +Tests 1 passed (1) +Test Files 1 passed (1) Duration - ``` diff --git a/tools/hangar/__snapshots__/test_corpus/sdk_tests/util/wait-until.w_compile_tf-aws.md b/tools/hangar/__snapshots__/test_corpus/sdk_tests/util/wait-until.w_compile_tf-aws.md index 9f20cc60ed7..d57620b3154 100644 --- a/tools/hangar/__snapshots__/test_corpus/sdk_tests/util/wait-until.w_compile_tf-aws.md +++ b/tools/hangar/__snapshots__/test_corpus/sdk_tests/util/wait-until.w_compile_tf-aws.md @@ -17,10 +17,10 @@ module.exports = function({ JSHelper, util_Util }) { return true; } ))) { - {((cond) => {if (!cond) throw new Error(`assertion failed: '(((await JSHelper.getTime()) - start) < 1000)'`)})((((await JSHelper.getTime()) - start) < 1000))}; + {((cond) => {if (!cond) throw new Error("assertion failed: JSHelper.getTime() - start < 1000")})((((await JSHelper.getTime()) - start) < 1000))}; } else { - {((cond) => {if (!cond) throw new Error(`assertion failed: 'false'`)})(false)}; + {((cond) => {if (!cond) throw new Error("assertion failed: false")})(false)}; } } } @@ -46,10 +46,10 @@ module.exports = function({ oneSecond, JSHelper, util_Util }) { return false; } ,{ timeout: oneSecond }))) { - {((cond) => {if (!cond) throw new Error(`assertion failed: 'false'`)})(false)}; + {((cond) => {if (!cond) throw new Error("assertion failed: false")})(false)}; } else { - {((cond) => {if (!cond) throw new Error(`assertion failed: '(((await JSHelper.getTime()) - start) > (1 * 1000))'`)})((((await JSHelper.getTime()) - start) > (1 * 1000)))}; + {((cond) => {if (!cond) throw new Error("assertion failed: JSHelper.getTime() - start > 1 * 1000")})((((await JSHelper.getTime()) - start) > (1 * 1000)))}; } } } @@ -78,10 +78,10 @@ module.exports = function({ invokeCounter, oneSecond, JSHelper, util_Util }) { ; if ((await util_Util.waitUntil(returnTrueAfter3Seconds,{ interval: oneSecond }))) { const invocations = (await invokeCounter.peek()); - {((cond) => {if (!cond) throw new Error(`assertion failed: '((invocations > 1) && (invocations < 10))'`)})(((invocations > 1) && (invocations < 10)))}; + {((cond) => {if (!cond) throw new Error("assertion failed: invocations > 1 && invocations < 10 ")})(((invocations > 1) && (invocations < 10)))}; } else { - {((cond) => {if (!cond) throw new Error(`assertion failed: 'false'`)})(false)}; + {((cond) => {if (!cond) throw new Error("assertion failed: false")})(false)}; } } } @@ -109,11 +109,11 @@ module.exports = function({ invokeCounter, oneSecond, fiveSeconds, JSHelper, uti } ; if ((await util_Util.waitUntil(returnFalse,{ interval: oneSecond, timeout: fiveSeconds }))) { - {((cond) => {if (!cond) throw new Error(`assertion failed: 'false'`)})(false)}; + {((cond) => {if (!cond) throw new Error("assertion failed: false")})(false)}; } else { const invokeCount = (await invokeCounter.peek()); - {((cond) => {if (!cond) throw new Error(`assertion failed: '((invokeCount > 3) && (invokeCount < 7))'`)})(((invokeCount > 3) && (invokeCount < 7)))}; + {((cond) => {if (!cond) throw new Error("assertion failed: invokeCount > 3 && invokeCount < 7")})(((invokeCount > 3) && (invokeCount < 7)))}; } } } @@ -140,10 +140,10 @@ module.exports = function({ invokeCounter, util_Util }) { {((msg) => {throw new Error(msg)})("ERROR")}; } )); - {((cond) => {if (!cond) throw new Error(`assertion failed: 'false'`)})(false)}; + {((cond) => {if (!cond) throw new Error("assertion failed: false")})(false)}; } catch { - {((cond) => {if (!cond) throw new Error(`assertion failed: '((await invokeCounter.peek()) === 1)'`)})(((await invokeCounter.peek()) === 1))}; + {((cond) => {if (!cond) throw new Error("assertion failed: invokeCounter.peek() == 1")})(((await invokeCounter.peek()) === 1))}; } } } diff --git a/tools/hangar/__snapshots__/test_corpus/sdk_tests/util/wait-until.w_test_sim.md b/tools/hangar/__snapshots__/test_corpus/sdk_tests/util/wait-until.w_test_sim.md index 5a4769d2123..fab60c86a86 100644 --- a/tools/hangar/__snapshots__/test_corpus/sdk_tests/util/wait-until.w_test_sim.md +++ b/tools/hangar/__snapshots__/test_corpus/sdk_tests/util/wait-until.w_test_sim.md @@ -8,12 +8,9 @@ pass โ”€ wait-until.wsim ยป root/env2/test:returns after some time waiting pass โ”€ wait-until.wsim ยป root/env3/test:setting props pass โ”€ wait-until.wsim ยป root/env4/test:throwing exception from predicate should throw immediately - - - - -Tests 1 passed (1) + +Tests 5 passed (5) +Test Files 1 passed (1) Duration - ``` diff --git a/tools/hangar/__snapshots__/test_corpus/sdk_tests/website/website.w_compile_tf-aws.md b/tools/hangar/__snapshots__/test_corpus/sdk_tests/website/website.w_compile_tf-aws.md index c11dd864ff6..cadcbd1be27 100644 --- a/tools/hangar/__snapshots__/test_corpus/sdk_tests/website/website.w_compile_tf-aws.md +++ b/tools/hangar/__snapshots__/test_corpus/sdk_tests/website/website.w_compile_tf-aws.md @@ -12,9 +12,9 @@ module.exports = function({ w, indexFile, otherFile, config, std_Json, Util }) { async $inflight_init() { } async handle() { - {((cond) => {if (!cond) throw new Error(`assertion failed: '(((args) => { return JSON.stringify(args[0], null, args[1]) })([((await Util.http(w.url)))["body"]]) === ((args) => { return JSON.stringify(args[0], null, args[1]) })([indexFile]))'`)})((((args) => { return JSON.stringify(args[0], null, args[1]) })([((await Util.http(w.url)))["body"]]) === ((args) => { return JSON.stringify(args[0], null, args[1]) })([indexFile])))}; - {((cond) => {if (!cond) throw new Error(`assertion failed: '(((args) => { return JSON.stringify(args[0], null, args[1]) })([((await Util.http((w.url + "/inner-folder/other.html"))))["body"]]) === ((args) => { return JSON.stringify(args[0], null, args[1]) })([otherFile]))'`)})((((args) => { return JSON.stringify(args[0], null, args[1]) })([((await Util.http((w.url + "/inner-folder/other.html"))))["body"]]) === ((args) => { return JSON.stringify(args[0], null, args[1]) })([otherFile])))}; - {((cond) => {if (!cond) throw new Error(`assertion failed: '(((args) => { return JSON.stringify(args[0], null, args[1]) })([((await Util.http((w.url + "/config.json"))))["body"]]) === ((args) => { return JSON.stringify(args[0], null, args[1]) })([((args) => { return JSON.stringify(args[0], null, args[1]) })([config])]))'`)})((((args) => { return JSON.stringify(args[0], null, args[1]) })([((await Util.http((w.url + "/config.json"))))["body"]]) === ((args) => { return JSON.stringify(args[0], null, args[1]) })([((args) => { return JSON.stringify(args[0], null, args[1]) })([config])])))}; + {((cond) => {if (!cond) throw new Error("assertion failed: Json.stringify(Util.http(w.url).get(\"body\")) == Json.stringify(indexFile)")})((((args) => { return JSON.stringify(args[0], null, args[1]) })([((await Util.http(w.url)))["body"]]) === ((args) => { return JSON.stringify(args[0], null, args[1]) })([indexFile])))}; + {((cond) => {if (!cond) throw new Error("assertion failed: Json.stringify(Util.http(w.url + \"/inner-folder/other.html\").get(\"body\")) == Json.stringify(otherFile)")})((((args) => { return JSON.stringify(args[0], null, args[1]) })([((await Util.http((w.url + "/inner-folder/other.html"))))["body"]]) === ((args) => { return JSON.stringify(args[0], null, args[1]) })([otherFile])))}; + {((cond) => {if (!cond) throw new Error("assertion failed: Json.stringify(Util.http(w.url + \"/config.json\").get(\"body\")) == Json.stringify(Json.stringify(config))")})((((args) => { return JSON.stringify(args[0], null, args[1]) })([((await Util.http((w.url + "/config.json"))))["body"]]) === ((args) => { return JSON.stringify(args[0], null, args[1]) })([((args) => { return JSON.stringify(args[0], null, args[1]) })([config])])))}; } } return $Closure1; @@ -431,7 +431,7 @@ class $Root extends $stdlib.std.Resource { const indexFile = (Util.readFile("./website/website/index.html")); const otherFile = (Util.readFile("./website/website/inner-folder/other.html")); (w.addJson("config.json",config)); - {((cond) => {if (!cond) throw new Error(`assertion failed: '(w.path.endsWith("sdk_tests/website/website") || w.path.endsWith("sdk_tests\\website\\website"))'`)})((w.path.endsWith("sdk_tests/website/website") || w.path.endsWith("sdk_tests\\website\\website")))}; + {((cond) => {if (!cond) throw new Error("assertion failed: w.path.endsWith(\"sdk_tests/website/website\") || w.path.endsWith(\"sdk_tests\\\\website\\\\website\")")})((w.path.endsWith("sdk_tests/website/website") || w.path.endsWith("sdk_tests\\website\\website")))}; this.node.root.new("@winglang/sdk.std.Test",std.Test,this,"test:access files on the website",new $Closure1(this,"$Closure1")); } } diff --git a/tools/hangar/__snapshots__/test_corpus/sdk_tests/website/website.w_test_sim.md b/tools/hangar/__snapshots__/test_corpus/sdk_tests/website/website.w_test_sim.md index c449a0ab3bb..f5f2d0f6011 100644 --- a/tools/hangar/__snapshots__/test_corpus/sdk_tests/website/website.w_test_sim.md +++ b/tools/hangar/__snapshots__/test_corpus/sdk_tests/website/website.w_test_sim.md @@ -4,12 +4,9 @@ ```log pass โ”€ website.wsim ยป root/env0/test:access files on the website - - - - -Tests 1 passed (1) + +Tests 1 passed (1) +Test Files 1 passed (1) Duration - ``` diff --git a/tools/hangar/__snapshots__/test_corpus/valid/anon_function.w_compile_tf-aws.md b/tools/hangar/__snapshots__/test_corpus/valid/anon_function.w_compile_tf-aws.md index 5b6ff6cb523..7b11c67bc16 100644 --- a/tools/hangar/__snapshots__/test_corpus/valid/anon_function.w_compile_tf-aws.md +++ b/tools/hangar/__snapshots__/test_corpus/valid/anon_function.w_compile_tf-aws.md @@ -43,7 +43,7 @@ class $Root extends $stdlib.std.Resource { constructor(scope, id) { super(scope, id); const myfunc = (x) => { - {console.log(`${x}`)}; + {console.log(String.raw({ raw: ["", ""] }, x))}; x = (x + 1); if ((x > 3.14)) { return; @@ -53,7 +53,7 @@ class $Root extends $stdlib.std.Resource { ; (myfunc(1)); (( (x) => { - {((cond) => {if (!cond) throw new Error(`assertion failed: '(x === 1)'`)})((x === 1))}; + {((cond) => {if (!cond) throw new Error("assertion failed: x == 1")})((x === 1))}; } )(1)); } diff --git a/tools/hangar/__snapshots__/test_corpus/valid/anon_function.w_test_sim.md b/tools/hangar/__snapshots__/test_corpus/valid/anon_function.w_test_sim.md index d95519eecc8..8d5b3b8f55e 100644 --- a/tools/hangar/__snapshots__/test_corpus/valid/anon_function.w_test_sim.md +++ b/tools/hangar/__snapshots__/test_corpus/valid/anon_function.w_test_sim.md @@ -7,12 +7,9 @@ 3 pass โ”€ anon_function.wsim (no tests) - - - - -Tests 1 passed (1) + +Tests 1 passed (1) +Test Files 1 passed (1) Duration - ``` diff --git a/tools/hangar/__snapshots__/test_corpus/valid/api.w_compile_tf-aws.md b/tools/hangar/__snapshots__/test_corpus/valid/api.w_compile_tf-aws.md index 9c33a8b59b5..055595a7cea 100644 --- a/tools/hangar/__snapshots__/test_corpus/valid/api.w_compile_tf-aws.md +++ b/tools/hangar/__snapshots__/test_corpus/valid/api.w_compile_tf-aws.md @@ -40,7 +40,7 @@ module.exports = function({ api }) { } async handle() { const url = api.url; - {((cond) => {if (!cond) throw new Error(`assertion failed: 'url.startsWith("http")'`)})(url.startsWith("http"))}; + {((cond) => {if (!cond) throw new Error("assertion failed: url.startsWith(\"http\")")})(url.startsWith("http"))}; } } return $Closure2; @@ -60,7 +60,7 @@ module.exports = function({ __parent_this_3 }) { async $inflight_init() { } async handle(req) { - const text = `${__parent_this_3.api.url}/endpoint2`; + const text = String.raw({ raw: ["", "/endpoint2"] }, __parent_this_3.api.url); return { "status": 200, "body": text,} diff --git a/tools/hangar/__snapshots__/test_corpus/valid/api.w_test_sim.md b/tools/hangar/__snapshots__/test_corpus/valid/api.w_test_sim.md index 10b6785bcaf..99f4b1317a8 100644 --- a/tools/hangar/__snapshots__/test_corpus/valid/api.w_test_sim.md +++ b/tools/hangar/__snapshots__/test_corpus/valid/api.w_test_sim.md @@ -4,12 +4,9 @@ ```log pass โ”€ api.wsim ยป root/env0/test:api url - - - - -Tests 1 passed (1) + +Tests 1 passed (1) +Test Files 1 passed (1) Duration - ``` diff --git a/tools/hangar/__snapshots__/test_corpus/valid/api_path_vars.w_compile_tf-aws.md b/tools/hangar/__snapshots__/test_corpus/valid/api_path_vars.w_compile_tf-aws.md index 7ea7960c873..50427c240fc 100644 --- a/tools/hangar/__snapshots__/test_corpus/valid/api_path_vars.w_compile_tf-aws.md +++ b/tools/hangar/__snapshots__/test_corpus/valid/api_path_vars.w_compile_tf-aws.md @@ -26,7 +26,7 @@ module.exports = function({ std_Json }) { ## inflight.$Closure2.js ```js -module.exports = function({ f, api }) { +module.exports = function({ api, http_Util, std_Json }) { class $Closure2 { constructor({ }) { const $obj = (...args) => this.handle(...args); @@ -37,9 +37,9 @@ module.exports = function({ f, api }) { } async handle() { const username = "tsuf"; - const res = (await f.get(`${api.url}/users/${username}`)); - {((cond) => {if (!cond) throw new Error(`assertion failed: '((res)["status"] === 200)'`)})(((res)["status"] === 200))}; - {((cond) => {if (!cond) throw new Error(`assertion failed: '(((res)["body"])["user"] === username)'`)})((((res)["body"])["user"] === username))}; + const res = (await http_Util.get(String.raw({ raw: ["", "/users/", ""] }, api.url, username))); + {((cond) => {if (!cond) throw new Error("assertion failed: res.status == 200")})((res.status === 200))}; + {((cond) => {if (!cond) throw new Error("assertion failed: Json.parse(res.body ?? \"\").get(\"user\") == username")})((((JSON.parse((res.body ?? ""))))["user"] === username))}; } } return $Closure2; @@ -47,23 +47,6 @@ module.exports = function({ f, api }) { ``` -## inflight.Fetch.js -```js -module.exports = function({ }) { - class Fetch { - constructor({ }) { - } - async $inflight_init() { - } - async get(url) { - return (require("/api_path_vars.js")["get"])(url) - } - } - return Fetch; -} - -``` - ## main.tf.json ```json { @@ -330,40 +313,10 @@ const std = $stdlib.std; const $wing_is_test = process.env.WING_IS_TEST === "true"; const $AppBase = $stdlib.core.App.for(process.env.WING_TARGET); const cloud = require('@winglang/sdk').cloud; +const http = require('@winglang/sdk').http; class $Root extends $stdlib.std.Resource { constructor(scope, id) { super(scope, id); - class Fetch extends $stdlib.std.Resource { - constructor(scope, id, ) { - super(scope, id); - this._addInflightOps("get"); - } - static _toInflightType(context) { - const self_client_path = "././inflight.Fetch.js"; - return $stdlib.core.NodeJsCode.fromInline(` - require("${self_client_path}")({ - }) - `); - } - _toInflight() { - return $stdlib.core.NodeJsCode.fromInline(` - (await (async () => { - const FetchClient = ${Fetch._toInflightType(this).text}; - const client = new FetchClient({ - }); - if (client.$inflight_init) { await client.$inflight_init(); } - return client; - })()) - `); - } - _registerBind(host, ops) { - if (ops.includes("$inflight_init")) { - } - if (ops.includes("get")) { - } - super._registerBind(host, ops); - } - } class $Closure1 extends $stdlib.std.Resource { constructor(scope, id, ) { super(scope, id); @@ -406,12 +359,14 @@ class $Root extends $stdlib.std.Resource { } static _toInflightType(context) { const self_client_path = "././inflight.$Closure2.js"; - const f_client = context._lift(f); const api_client = context._lift(api); + const http_UtilClient = http.Util._toInflightType(context); + const std_JsonClient = std.Json._toInflightType(context); return $stdlib.core.NodeJsCode.fromInline(` require("${self_client_path}")({ - f: ${f_client}, api: ${api_client}, + http_Util: ${http_UtilClient.text}, + std_Json: ${std_JsonClient.text}, }) `); } @@ -429,11 +384,9 @@ class $Root extends $stdlib.std.Resource { _registerBind(host, ops) { if (ops.includes("$inflight_init")) { $Closure2._registerBindObject(api, host, []); - $Closure2._registerBindObject(f, host, []); } if (ops.includes("handle")) { $Closure2._registerBindObject(api.url, host, []); - $Closure2._registerBindObject(f, host, ["get"]); } super._registerBind(host, ops); } @@ -441,7 +394,6 @@ class $Root extends $stdlib.std.Resource { const api = this.node.root.newAbstract("@winglang/sdk.cloud.Api",this,"cloud.Api"); const handler = new $Closure1(this,"$Closure1"); (api.get("/users/{name}",handler)); - const f = new Fetch(this,"Fetch"); this.node.root.new("@winglang/sdk.std.Test",std.Test,this,"test:test",new $Closure2(this,"$Closure2")); } } diff --git a/tools/hangar/__snapshots__/test_corpus/valid/api_path_vars.w_test_sim.md b/tools/hangar/__snapshots__/test_corpus/valid/api_path_vars.w_test_sim.md index dd606017565..6fa31afb5eb 100644 --- a/tools/hangar/__snapshots__/test_corpus/valid/api_path_vars.w_test_sim.md +++ b/tools/hangar/__snapshots__/test_corpus/valid/api_path_vars.w_test_sim.md @@ -4,12 +4,9 @@ ```log pass โ”€ api_path_vars.wsim ยป root/env0/test:test - - - - -Tests 1 passed (1) + +Tests 1 passed (1) +Test Files 1 passed (1) Duration - ``` diff --git a/tools/hangar/__snapshots__/test_corpus/valid/api_valid_path.w_compile_tf-aws.md b/tools/hangar/__snapshots__/test_corpus/valid/api_valid_path.w_compile_tf-aws.md index 90784ad63ce..00559ce1e38 100644 --- a/tools/hangar/__snapshots__/test_corpus/valid/api_valid_path.w_compile_tf-aws.md +++ b/tools/hangar/__snapshots__/test_corpus/valid/api_valid_path.w_compile_tf-aws.md @@ -312,7 +312,7 @@ class $Root extends $stdlib.std.Resource { const handler = new $Closure1(this,"$Closure1"); const testInvalidPath = (path) => { let error = ""; - const expected = `Invalid path ${path}. Url cannot contain \":\", params contains only alpha-numeric chars or \"_\".`; + const expected = String.raw({ raw: ["Invalid path ", ". Url cannot contain \":\", params contains only alpha-numeric chars or \"_\"."] }, path); try { (api.get(path,handler)); } @@ -320,7 +320,7 @@ class $Root extends $stdlib.std.Resource { const e = $error_e.message; error = e; } - {((cond) => {if (!cond) throw new Error(`assertion failed: '(error === expected)'`)})((error === expected))}; + {((cond) => {if (!cond) throw new Error("assertion failed: error == expected")})((error === expected))}; } ; const testValidPath = (path) => { @@ -332,7 +332,7 @@ class $Root extends $stdlib.std.Resource { const e = $error_e.message; error = e; } - {((cond) => {if (!cond) throw new Error(`assertion failed: '(error === "")'`)})((error === ""))}; + {((cond) => {if (!cond) throw new Error("assertion failed: error == \"\"")})((error === ""))}; } ; (testInvalidPath("/test/{sup:er/:annoying//path}")); diff --git a/tools/hangar/__snapshots__/test_corpus/valid/api_valid_path.w_test_sim.md b/tools/hangar/__snapshots__/test_corpus/valid/api_valid_path.w_test_sim.md index 6f592408804..87ab6051154 100644 --- a/tools/hangar/__snapshots__/test_corpus/valid/api_valid_path.w_test_sim.md +++ b/tools/hangar/__snapshots__/test_corpus/valid/api_valid_path.w_test_sim.md @@ -4,12 +4,9 @@ ```log pass โ”€ api_valid_path.wsim (no tests) - - - - -Tests 1 passed (1) + +Tests 1 passed (1) +Test Files 1 passed (1) Duration - ``` diff --git a/tools/hangar/__snapshots__/test_corpus/valid/assert.w_compile_tf-aws.md b/tools/hangar/__snapshots__/test_corpus/valid/assert.w_compile_tf-aws.md new file mode 100644 index 00000000000..aace693b537 --- /dev/null +++ b/tools/hangar/__snapshots__/test_corpus/valid/assert.w_compile_tf-aws.md @@ -0,0 +1,246 @@ +# [assert.w](../../../../../examples/tests/valid/assert.w) | compile | tf-aws + +## inflight.$Closure1.js +```js +module.exports = function({ s1, s2 }) { + class $Closure1 { + constructor({ }) { + const $obj = (...args) => this.handle(...args); + Object.setPrototypeOf($obj, this); + return $obj; + } + async $inflight_init() { + } + async handle() { + {((cond) => {if (!cond) throw new Error("assertion failed: \"\" == \"\"")})(("" === ""))}; + {((cond) => {if (!cond) throw new Error("assertion failed: \"\'\" == \"\'\"")})(("'" === "'"))}; + {((cond) => {if (!cond) throw new Error("assertion failed: \"\\\"\" == \"\\\"\"")})(("\"" === "\""))}; + {((cond) => {if (!cond) throw new Error("assertion failed: \"`\" == \"`\"")})(("`" === "`"))}; + {((cond) => {if (!cond) throw new Error("assertion failed: \"``\" == \"``\"")})(("``" === "``"))}; + {((cond) => {if (!cond) throw new Error("assertion failed: \"`s1`\" == \"`s1`\"")})(("`s1`" === "`s1`"))}; + {((cond) => {if (!cond) throw new Error("assertion failed: s1 == s1")})((s1 === s1))}; + {((cond) => {if (!cond) throw new Error("assertion failed: \"${s1}\" == \"${s1}\"")})((String.raw({ raw: ["", ""] }, s1) === String.raw({ raw: ["", ""] }, s1)))}; + {((cond) => {if (!cond) throw new Error("assertion failed: \"${s1}\" != \"${s2}\"")})((String.raw({ raw: ["", ""] }, s1) !== String.raw({ raw: ["", ""] }, s2)))}; + {((cond) => {if (!cond) throw new Error("assertion failed: \"a${s1}\" == \"a${s1}\"")})((String.raw({ raw: ["a", ""] }, s1) === String.raw({ raw: ["a", ""] }, s1)))}; + {((cond) => {if (!cond) throw new Error("assertion failed: \"a${s1}\" != \"b${s1}\"")})((String.raw({ raw: ["a", ""] }, s1) !== String.raw({ raw: ["b", ""] }, s1)))}; + {((cond) => {if (!cond) throw new Error("assertion failed: \"${s1}a\" == \"${s1}a\"")})((String.raw({ raw: ["", "a"] }, s1) === String.raw({ raw: ["", "a"] }, s1)))}; + {((cond) => {if (!cond) throw new Error("assertion failed: \"${s1}a\" != \"${s1}b\"")})((String.raw({ raw: ["", "a"] }, s1) !== String.raw({ raw: ["", "b"] }, s1)))}; + {((cond) => {if (!cond) throw new Error("assertion failed: \"`\'${s1}\" == \"`\'${s1}\"")})((String.raw({ raw: ["`'", ""] }, s1) === String.raw({ raw: ["`'", ""] }, s1)))}; + {((cond) => {if (!cond) throw new Error("assertion failed: \"a${s1}b${s2}c\" == \"a${s1}b${s2}c\"")})((String.raw({ raw: ["a", "b", "c"] }, s1, s2) === String.raw({ raw: ["a", "b", "c"] }, s1, s2)))}; + } + } + return $Closure1; +} + +``` + +## main.tf.json +```json +{ + "//": { + "metadata": { + "backend": "local", + "stackName": "root", + "version": "0.15.2" + }, + "outputs": { + "root": { + "Default": { + "cloud.TestRunner": { + "TestFunctionArns": "WING_TEST_RUNNER_FUNCTION_ARNS" + } + } + } + } + }, + "output": { + "WING_TEST_RUNNER_FUNCTION_ARNS": { + "value": "[[\"root/Default/Default/test:assert works inflight\",\"${aws_lambda_function.root_testassertworksinflight_Handler_C656B6E3.arn}\"]]" + } + }, + "provider": { + "aws": [ + {} + ] + }, + "resource": { + "aws_iam_role": { + "root_testassertworksinflight_Handler_IamRole_0E843492": { + "//": { + "metadata": { + "path": "root/Default/Default/test:assert works inflight/Handler/IamRole", + "uniqueId": "root_testassertworksinflight_Handler_IamRole_0E843492" + } + }, + "assume_role_policy": "{\"Version\":\"2012-10-17\",\"Statement\":[{\"Action\":\"sts:AssumeRole\",\"Principal\":{\"Service\":\"lambda.amazonaws.com\"},\"Effect\":\"Allow\"}]}" + } + }, + "aws_iam_role_policy": { + "root_testassertworksinflight_Handler_IamRolePolicy_9FDDFC6C": { + "//": { + "metadata": { + "path": "root/Default/Default/test:assert works inflight/Handler/IamRolePolicy", + "uniqueId": "root_testassertworksinflight_Handler_IamRolePolicy_9FDDFC6C" + } + }, + "policy": "{\"Version\":\"2012-10-17\",\"Statement\":[{\"Effect\":\"Allow\",\"Action\":\"none:null\",\"Resource\":\"*\"}]}", + "role": "${aws_iam_role.root_testassertworksinflight_Handler_IamRole_0E843492.name}" + } + }, + "aws_iam_role_policy_attachment": { + "root_testassertworksinflight_Handler_IamRolePolicyAttachment_4CDBB60D": { + "//": { + "metadata": { + "path": "root/Default/Default/test:assert works inflight/Handler/IamRolePolicyAttachment", + "uniqueId": "root_testassertworksinflight_Handler_IamRolePolicyAttachment_4CDBB60D" + } + }, + "policy_arn": "arn:aws:iam::aws:policy/service-role/AWSLambdaBasicExecutionRole", + "role": "${aws_iam_role.root_testassertworksinflight_Handler_IamRole_0E843492.name}" + } + }, + "aws_lambda_function": { + "root_testassertworksinflight_Handler_C656B6E3": { + "//": { + "metadata": { + "path": "root/Default/Default/test:assert works inflight/Handler/Default", + "uniqueId": "root_testassertworksinflight_Handler_C656B6E3" + } + }, + "environment": { + "variables": { + "WING_FUNCTION_NAME": "Handler-c8a7b0b3", + "WING_TARGET": "tf-aws" + } + }, + "function_name": "Handler-c8a7b0b3", + "handler": "index.handler", + "publish": true, + "role": "${aws_iam_role.root_testassertworksinflight_Handler_IamRole_0E843492.arn}", + "runtime": "nodejs18.x", + "s3_bucket": "${aws_s3_bucket.root_Code_02F3C603.bucket}", + "s3_key": "${aws_s3_object.root_testassertworksinflight_Handler_S3Object_29324B03.key}", + "timeout": 30, + "vpc_config": { + "security_group_ids": [], + "subnet_ids": [] + } + } + }, + "aws_s3_bucket": { + "root_Code_02F3C603": { + "//": { + "metadata": { + "path": "root/Default/Code", + "uniqueId": "root_Code_02F3C603" + } + }, + "bucket_prefix": "code-c84a50b1-" + } + }, + "aws_s3_object": { + "root_testassertworksinflight_Handler_S3Object_29324B03": { + "//": { + "metadata": { + "path": "root/Default/Default/test:assert works inflight/Handler/S3Object", + "uniqueId": "root_testassertworksinflight_Handler_S3Object_29324B03" + } + }, + "bucket": "${aws_s3_bucket.root_Code_02F3C603.bucket}", + "key": "", + "source": "" + } + } + } +} +``` + +## preflight.js +```js +const $stdlib = require('@winglang/sdk'); +const $outdir = process.env.WING_SYNTH_DIR ?? "."; +const std = $stdlib.std; +const $wing_is_test = process.env.WING_IS_TEST === "true"; +const $AppBase = $stdlib.core.App.for(process.env.WING_TARGET); +class $Root extends $stdlib.std.Resource { + constructor(scope, id) { + super(scope, id); + class $Closure1 extends $stdlib.std.Resource { + constructor(scope, id, ) { + super(scope, id); + this._addInflightOps("handle"); + this.display.hidden = true; + } + static _toInflightType(context) { + const self_client_path = "././inflight.$Closure1.js"; + const s1_client = context._lift(s1); + const s2_client = context._lift(s2); + return $stdlib.core.NodeJsCode.fromInline(` + require("${self_client_path}")({ + s1: ${s1_client}, + s2: ${s2_client}, + }) + `); + } + _toInflight() { + return $stdlib.core.NodeJsCode.fromInline(` + (await (async () => { + const $Closure1Client = ${$Closure1._toInflightType(this).text}; + const client = new $Closure1Client({ + }); + if (client.$inflight_init) { await client.$inflight_init(); } + return client; + })()) + `); + } + _registerBind(host, ops) { + if (ops.includes("$inflight_init")) { + $Closure1._registerBindObject(s1, host, []); + $Closure1._registerBindObject(s2, host, []); + } + if (ops.includes("handle")) { + $Closure1._registerBindObject(s1, host, []); + $Closure1._registerBindObject(s2, host, []); + } + super._registerBind(host, ops); + } + } + const s1 = "foo"; + const s2 = "bar"; + {((cond) => {if (!cond) throw new Error("assertion failed: \"\" == \"\"")})(("" === ""))}; + {((cond) => {if (!cond) throw new Error("assertion failed: \"\'\" == \"\'\"")})(("'" === "'"))}; + {((cond) => {if (!cond) throw new Error("assertion failed: \"\\\"\" == \"\\\"\"")})(("\"" === "\""))}; + {((cond) => {if (!cond) throw new Error("assertion failed: \"`\" == \"`\"")})(("`" === "`"))}; + {((cond) => {if (!cond) throw new Error("assertion failed: \"``\" == \"``\"")})(("``" === "``"))}; + {((cond) => {if (!cond) throw new Error("assertion failed: \"`s1`\" == \"`s1`\"")})(("`s1`" === "`s1`"))}; + {((cond) => {if (!cond) throw new Error("assertion failed: s1 == s1")})((s1 === s1))}; + {((cond) => {if (!cond) throw new Error("assertion failed: \"${s1}\" == \"${s1}\"")})((String.raw({ raw: ["", ""] }, s1) === String.raw({ raw: ["", ""] }, s1)))}; + {((cond) => {if (!cond) throw new Error("assertion failed: \"${s1}\" != \"${s2}\"")})((String.raw({ raw: ["", ""] }, s1) !== String.raw({ raw: ["", ""] }, s2)))}; + {((cond) => {if (!cond) throw new Error("assertion failed: \"a${s1}\" == \"a${s1}\"")})((String.raw({ raw: ["a", ""] }, s1) === String.raw({ raw: ["a", ""] }, s1)))}; + {((cond) => {if (!cond) throw new Error("assertion failed: \"a${s1}\" != \"b${s1}\"")})((String.raw({ raw: ["a", ""] }, s1) !== String.raw({ raw: ["b", ""] }, s1)))}; + {((cond) => {if (!cond) throw new Error("assertion failed: \"${s1}a\" == \"${s1}a\"")})((String.raw({ raw: ["", "a"] }, s1) === String.raw({ raw: ["", "a"] }, s1)))}; + {((cond) => {if (!cond) throw new Error("assertion failed: \"${s1}a\" != \"${s1}b\"")})((String.raw({ raw: ["", "a"] }, s1) !== String.raw({ raw: ["", "b"] }, s1)))}; + {((cond) => {if (!cond) throw new Error("assertion failed: \"`\'${s1}\" == \"`\'${s1}\"")})((String.raw({ raw: ["`'", ""] }, s1) === String.raw({ raw: ["`'", ""] }, s1)))}; + {((cond) => {if (!cond) throw new Error("assertion failed: \"a${s1}b${s2}c\" == \"a${s1}b${s2}c\"")})((String.raw({ raw: ["a", "b", "c"] }, s1, s2) === String.raw({ raw: ["a", "b", "c"] }, s1, s2)))}; + this.node.root.new("@winglang/sdk.std.Test",std.Test,this,"test:assert works inflight",new $Closure1(this,"$Closure1")); + } +} +class $App extends $AppBase { + constructor() { + super({ outdir: $outdir, name: "assert", plugins: $plugins, isTestEnvironment: $wing_is_test }); + if ($wing_is_test) { + new $Root(this, "env0"); + const $test_runner = this.testRunner; + const $tests = $test_runner.findTests(); + for (let $i = 1; $i < $tests.length; $i++) { + new $Root(this, "env" + $i); + } + } else { + new $Root(this, "Default"); + } + } +} +new $App().synth(); + +``` + diff --git a/tools/hangar/__snapshots__/test_corpus/valid/assert.w_test_sim.md b/tools/hangar/__snapshots__/test_corpus/valid/assert.w_test_sim.md new file mode 100644 index 00000000000..29a0ea1d94c --- /dev/null +++ b/tools/hangar/__snapshots__/test_corpus/valid/assert.w_test_sim.md @@ -0,0 +1,12 @@ +# [assert.w](../../../../../examples/tests/valid/assert.w) | test | sim + +## stdout.log +```log +pass โ”€ assert.wsim ยป root/env0/test:assert works inflight + + +Tests 1 passed (1) +Test Files 1 passed (1) +Duration +``` + diff --git a/tools/hangar/__snapshots__/test_corpus/valid/asynchronous_model_implicit_await_in_functions.w_test_sim.md b/tools/hangar/__snapshots__/test_corpus/valid/asynchronous_model_implicit_await_in_functions.w_test_sim.md index 0034ca89fb4..d06e690a23b 100644 --- a/tools/hangar/__snapshots__/test_corpus/valid/asynchronous_model_implicit_await_in_functions.w_test_sim.md +++ b/tools/hangar/__snapshots__/test_corpus/valid/asynchronous_model_implicit_await_in_functions.w_test_sim.md @@ -4,12 +4,9 @@ ```log pass โ”€ asynchronous_model_implicit_await_in_functions.wsim (no tests) - - - - -Tests 1 passed (1) + +Tests 1 passed (1) +Test Files 1 passed (1) Duration - ``` diff --git a/tools/hangar/__snapshots__/test_corpus/valid/bring_awscdk.w_compile_tf-aws.md b/tools/hangar/__snapshots__/test_corpus/valid/bring_awscdk.w_compile_tf-aws.md index 05c8f9eaf2d..f66329c0ac7 100644 --- a/tools/hangar/__snapshots__/test_corpus/valid/bring_awscdk.w_compile_tf-aws.md +++ b/tools/hangar/__snapshots__/test_corpus/valid/bring_awscdk.w_compile_tf-aws.md @@ -92,6 +92,7 @@ class $Root extends $stdlib.std.Resource { super._registerBind(host, ops); } } + this.node.root.new("aws-cdk-lib.App",awscdk.App,); } } class $App extends $AppBase { diff --git a/tools/hangar/__snapshots__/test_corpus/valid/bring_awscdk.w_test_sim.md b/tools/hangar/__snapshots__/test_corpus/valid/bring_awscdk.w_test_sim.md index 0508385a683..44e7b3eaa5d 100644 --- a/tools/hangar/__snapshots__/test_corpus/valid/bring_awscdk.w_test_sim.md +++ b/tools/hangar/__snapshots__/test_corpus/valid/bring_awscdk.w_test_sim.md @@ -4,12 +4,9 @@ ```log pass โ”€ bring_awscdk.wsim (no tests) - - - - -Tests 1 passed (1) + +Tests 1 passed (1) +Test Files 1 passed (1) Duration - ``` diff --git a/tools/hangar/__snapshots__/test_corpus/valid/bring_cdktf.w_compile_tf-aws.md b/tools/hangar/__snapshots__/test_corpus/valid/bring_cdktf.w_compile_tf-aws.md index 2d3a31c5f5c..1f6cd056742 100644 --- a/tools/hangar/__snapshots__/test_corpus/valid/bring_cdktf.w_compile_tf-aws.md +++ b/tools/hangar/__snapshots__/test_corpus/valid/bring_cdktf.w_compile_tf-aws.md @@ -1,5 +1,19 @@ # [bring_cdktf.w](../../../../../examples/tests/valid/bring_cdktf.w) | compile | tf-aws +## inflight.Foo.js +```js +module.exports = function({ }) { + class Foo { + constructor({ }) { + } + async $inflight_init() { + } + } + return Foo; +} + +``` + ## main.tf.json ```json { @@ -57,9 +71,42 @@ const std = $stdlib.std; const $wing_is_test = process.env.WING_IS_TEST === "true"; const $AppBase = $stdlib.core.App.for(process.env.WING_TARGET); const aws = require("@cdktf/provider-aws"); +const cdktf = require("cdktf"); class $Root extends $stdlib.std.Resource { constructor(scope, id) { super(scope, id); + class Foo extends $stdlib.std.Resource { + constructor(scope, id, ) { + super(scope, id); + this.node.root.new("cdktf.S3Backend",cdktf.S3Backend,this,{ + "bucket": "foo", + "key": "bar",} + ); + } + static _toInflightType(context) { + const self_client_path = "././inflight.Foo.js"; + return $stdlib.core.NodeJsCode.fromInline(` + require("${self_client_path}")({ + }) + `); + } + _toInflight() { + return $stdlib.core.NodeJsCode.fromInline(` + (await (async () => { + const FooClient = ${Foo._toInflightType(this).text}; + const client = new FooClient({ + }); + if (client.$inflight_init) { await client.$inflight_init(); } + return client; + })()) + `); + } + _registerBind(host, ops) { + if (ops.includes("$inflight_init")) { + } + super._registerBind(host, ops); + } + } this.node.root.new("@cdktf/provider-aws.s3Bucket.S3Bucket",aws.s3Bucket.S3Bucket,this,"Bucket",{ bucketPrefix: "hello", versioning: { "enabled": true, "mfaDelete": true,} diff --git a/tools/hangar/__snapshots__/test_corpus/valid/bring_cdktf.w_test_sim.md b/tools/hangar/__snapshots__/test_corpus/valid/bring_cdktf.w_test_sim.md index a27a7ab62cd..42023a0a8c1 100644 --- a/tools/hangar/__snapshots__/test_corpus/valid/bring_cdktf.w_test_sim.md +++ b/tools/hangar/__snapshots__/test_corpus/valid/bring_cdktf.w_test_sim.md @@ -4,12 +4,9 @@ ```log pass โ”€ bring_cdktf.wsim (no tests) - - - - -Tests 1 passed (1) + +Tests 1 passed (1) +Test Files 1 passed (1) Duration - ``` diff --git a/tools/hangar/__snapshots__/test_corpus/valid/bring_jsii.w_compile_tf-aws.md b/tools/hangar/__snapshots__/test_corpus/valid/bring_jsii.w_compile_tf-aws.md index c52f762eb62..7c1414e14c1 100644 --- a/tools/hangar/__snapshots__/test_corpus/valid/bring_jsii.w_compile_tf-aws.md +++ b/tools/hangar/__snapshots__/test_corpus/valid/bring_jsii.w_compile_tf-aws.md @@ -12,7 +12,7 @@ module.exports = function({ greeting }) { async $inflight_init() { } async handle() { - {((cond) => {if (!cond) throw new Error(`assertion failed: '(greeting === "Hello, wingnuts")'`)})((greeting === "Hello, wingnuts"))}; + {((cond) => {if (!cond) throw new Error("assertion failed: greeting == \"Hello, wingnuts\"")})((greeting === "Hello, wingnuts"))}; } } return $Closure1; diff --git a/tools/hangar/__snapshots__/test_corpus/valid/bring_jsii.w_test_sim.md b/tools/hangar/__snapshots__/test_corpus/valid/bring_jsii.w_test_sim.md index a42bd6f0fcf..6d701997604 100644 --- a/tools/hangar/__snapshots__/test_corpus/valid/bring_jsii.w_test_sim.md +++ b/tools/hangar/__snapshots__/test_corpus/valid/bring_jsii.w_test_sim.md @@ -4,12 +4,9 @@ ```log pass โ”€ bring_jsii.wsim ยป root/env0/test:sayHello - - - - -Tests 1 passed (1) + +Tests 1 passed (1) +Test Files 1 passed (1) Duration - ``` diff --git a/tools/hangar/__snapshots__/test_corpus/valid/bring_jsii_path.w_compile_tf-aws.md b/tools/hangar/__snapshots__/test_corpus/valid/bring_jsii_path.w_compile_tf-aws.md index 724d8c155f2..2da87633f0c 100644 --- a/tools/hangar/__snapshots__/test_corpus/valid/bring_jsii_path.w_compile_tf-aws.md +++ b/tools/hangar/__snapshots__/test_corpus/valid/bring_jsii_path.w_compile_tf-aws.md @@ -12,7 +12,7 @@ module.exports = function({ greeting }) { async $inflight_init() { } async handle() { - {((cond) => {if (!cond) throw new Error(`assertion failed: '(greeting === "Hello, wingnuts")'`)})((greeting === "Hello, wingnuts"))}; + {((cond) => {if (!cond) throw new Error("assertion failed: greeting == \"Hello, wingnuts\"")})((greeting === "Hello, wingnuts"))}; } } return $Closure1; diff --git a/tools/hangar/__snapshots__/test_corpus/valid/bring_jsii_path.w_test_sim.md b/tools/hangar/__snapshots__/test_corpus/valid/bring_jsii_path.w_test_sim.md index 052c2871920..33dae7cf7da 100644 --- a/tools/hangar/__snapshots__/test_corpus/valid/bring_jsii_path.w_test_sim.md +++ b/tools/hangar/__snapshots__/test_corpus/valid/bring_jsii_path.w_test_sim.md @@ -4,12 +4,9 @@ ```log pass โ”€ bring_jsii_path.wsim ยป root/env0/test:sayHello - - - - -Tests 1 passed (1) + +Tests 1 passed (1) +Test Files 1 passed (1) Duration - ``` diff --git a/tools/hangar/__snapshots__/test_corpus/valid/bring_projen.w_compile_tf-aws.md b/tools/hangar/__snapshots__/test_corpus/valid/bring_projen.w_compile_tf-aws.md index 3e0ac3948dc..50a7f2cbb5b 100644 --- a/tools/hangar/__snapshots__/test_corpus/valid/bring_projen.w_compile_tf-aws.md +++ b/tools/hangar/__snapshots__/test_corpus/valid/bring_projen.w_compile_tf-aws.md @@ -43,7 +43,7 @@ const projen = require("projen"); class $Root extends $stdlib.std.Resource { constructor(scope, id) { super(scope, id); - {((cond) => {if (!cond) throw new Error(`assertion failed: '(projen.LogLevel.OFF !== projen.LogLevel.VERBOSE)'`)})((projen.LogLevel.OFF !== projen.LogLevel.VERBOSE))}; + {((cond) => {if (!cond) throw new Error("assertion failed: projen.LogLevel.OFF != projen.LogLevel.VERBOSE")})((projen.LogLevel.OFF !== projen.LogLevel.VERBOSE))}; } } class $App extends $AppBase { diff --git a/tools/hangar/__snapshots__/test_corpus/valid/bring_projen.w_test_sim.md b/tools/hangar/__snapshots__/test_corpus/valid/bring_projen.w_test_sim.md index a259c0e78bb..74dec5090ea 100644 --- a/tools/hangar/__snapshots__/test_corpus/valid/bring_projen.w_test_sim.md +++ b/tools/hangar/__snapshots__/test_corpus/valid/bring_projen.w_test_sim.md @@ -4,12 +4,9 @@ ```log pass โ”€ bring_projen.wsim (no tests) - - - - -Tests 1 passed (1) + +Tests 1 passed (1) +Test Files 1 passed (1) Duration - ``` diff --git a/tools/hangar/__snapshots__/test_corpus/valid/bucket_events.w_compile_tf-aws.md b/tools/hangar/__snapshots__/test_corpus/valid/bucket_events.w_compile_tf-aws.md index fd5e65d867d..ab9ad7f67b8 100644 --- a/tools/hangar/__snapshots__/test_corpus/valid/bucket_events.w_compile_tf-aws.md +++ b/tools/hangar/__snapshots__/test_corpus/valid/bucket_events.w_compile_tf-aws.md @@ -12,7 +12,7 @@ module.exports = function({ }) { async $inflight_init() { } async handle(key) { - {console.log(`deleted ${key}`)}; + {console.log(String.raw({ raw: ["deleted ", ""] }, key))}; } } return $Closure1; @@ -32,7 +32,7 @@ module.exports = function({ }) { async $inflight_init() { } async handle(key) { - {console.log(`updated ${key}`)}; + {console.log(String.raw({ raw: ["updated ", ""] }, key))}; } } return $Closure2; @@ -52,7 +52,7 @@ module.exports = function({ }) { async $inflight_init() { } async handle(key) { - {console.log(`created ${key}`)}; + {console.log(String.raw({ raw: ["created ", ""] }, key))}; } } return $Closure3; @@ -72,7 +72,7 @@ module.exports = function({ other }) { async $inflight_init() { } async handle(key, event) { - (await other.put(`last_${event}_key`,key)); + (await other.put(String.raw({ raw: ["last_", "_key"] }, event),key)); } } return $Closure4; diff --git a/tools/hangar/__snapshots__/test_corpus/valid/bucket_events.w_test_sim.md b/tools/hangar/__snapshots__/test_corpus/valid/bucket_events.w_test_sim.md index f48e6c18de1..1ebb701310b 100644 --- a/tools/hangar/__snapshots__/test_corpus/valid/bucket_events.w_test_sim.md +++ b/tools/hangar/__snapshots__/test_corpus/valid/bucket_events.w_test_sim.md @@ -14,12 +14,9 @@ pass โ”Œ bucket_events.wsim ยป root/env0/test:putting and deleting from a bucket โ”‚ deleted c โ”” other bucket event called! - - - - -Tests 1 passed (1) + +Tests 1 passed (1) +Test Files 1 passed (1) Duration - ``` diff --git a/tools/hangar/__snapshots__/test_corpus/valid/bucket_keys.w_compile_tf-aws.md b/tools/hangar/__snapshots__/test_corpus/valid/bucket_keys.w_compile_tf-aws.md index 257a671f21e..064f923d3d7 100644 --- a/tools/hangar/__snapshots__/test_corpus/valid/bucket_keys.w_compile_tf-aws.md +++ b/tools/hangar/__snapshots__/test_corpus/valid/bucket_keys.w_compile_tf-aws.md @@ -18,11 +18,11 @@ module.exports = function({ b }) { (await b.put("foo/bar/","text")); (await b.put("foo/bar/baz","text")); const objs = (await b.list()); - {((cond) => {if (!cond) throw new Error(`assertion failed: '((await objs.at(0)) === "foo")'`)})(((await objs.at(0)) === "foo"))}; - {((cond) => {if (!cond) throw new Error(`assertion failed: '((await objs.at(1)) === "foo/")'`)})(((await objs.at(1)) === "foo/"))}; - {((cond) => {if (!cond) throw new Error(`assertion failed: '((await objs.at(2)) === "foo/bar")'`)})(((await objs.at(2)) === "foo/bar"))}; - {((cond) => {if (!cond) throw new Error(`assertion failed: '((await objs.at(3)) === "foo/bar/")'`)})(((await objs.at(3)) === "foo/bar/"))}; - {((cond) => {if (!cond) throw new Error(`assertion failed: '((await objs.at(4)) === "foo/bar/baz")'`)})(((await objs.at(4)) === "foo/bar/baz"))}; + {((cond) => {if (!cond) throw new Error("assertion failed: objs.at(0) == \"foo\"")})(((await objs.at(0)) === "foo"))}; + {((cond) => {if (!cond) throw new Error("assertion failed: objs.at(1) == \"foo/\"")})(((await objs.at(1)) === "foo/"))}; + {((cond) => {if (!cond) throw new Error("assertion failed: objs.at(2) == \"foo/bar\"")})(((await objs.at(2)) === "foo/bar"))}; + {((cond) => {if (!cond) throw new Error("assertion failed: objs.at(3) == \"foo/bar/\"")})(((await objs.at(3)) === "foo/bar/"))}; + {((cond) => {if (!cond) throw new Error("assertion failed: objs.at(4) == \"foo/bar/baz\"")})(((await objs.at(4)) === "foo/bar/baz"))}; } } return $Closure1; diff --git a/tools/hangar/__snapshots__/test_corpus/valid/bucket_keys.w_test_sim.md b/tools/hangar/__snapshots__/test_corpus/valid/bucket_keys.w_test_sim.md index f560bf28c42..1a89b2d7a82 100644 --- a/tools/hangar/__snapshots__/test_corpus/valid/bucket_keys.w_test_sim.md +++ b/tools/hangar/__snapshots__/test_corpus/valid/bucket_keys.w_test_sim.md @@ -4,12 +4,9 @@ ```log pass โ”€ bucket_keys.wsim ยป root/env0/test:test - - - - -Tests 1 passed (1) + +Tests 1 passed (1) +Test Files 1 passed (1) Duration - ``` diff --git a/tools/hangar/__snapshots__/test_corpus/valid/calling_inflight_variants.w_compile_tf-aws.md b/tools/hangar/__snapshots__/test_corpus/valid/calling_inflight_variants.w_compile_tf-aws.md index ef326dd497b..ad27d4c6e98 100644 --- a/tools/hangar/__snapshots__/test_corpus/valid/calling_inflight_variants.w_compile_tf-aws.md +++ b/tools/hangar/__snapshots__/test_corpus/valid/calling_inflight_variants.w_compile_tf-aws.md @@ -32,8 +32,8 @@ module.exports = function({ foo }) { async $inflight_init() { } async handle() { - {((cond) => {if (!cond) throw new Error(`assertion failed: '((await foo.callFn(true)) === 1)'`)})(((await foo.callFn(true)) === 1))}; - {((cond) => {if (!cond) throw new Error(`assertion failed: '((await foo.callFn(false)) === 2)'`)})(((await foo.callFn(false)) === 2))}; + {((cond) => {if (!cond) throw new Error("assertion failed: foo.callFn(true) == 1")})(((await foo.callFn(true)) === 1))}; + {((cond) => {if (!cond) throw new Error("assertion failed: foo.callFn(false) == 2")})(((await foo.callFn(false)) === 2))}; (await foo.callFn2()); } } @@ -55,7 +55,7 @@ module.exports = function({ }) { } ; const ret = (await this.inflight2()); - {((cond) => {if (!cond) throw new Error(`assertion failed: '(ret === 2)'`)})((ret === 2))}; + {((cond) => {if (!cond) throw new Error("assertion failed: ret == 2")})((ret === 2))}; } async makeFn(x) { if ((x === true)) { @@ -72,8 +72,8 @@ module.exports = function({ }) { async callFn2() { const one = (await this.inflight1()); const two = (await this.inflight2()); - {((cond) => {if (!cond) throw new Error(`assertion failed: '(one === 1)'`)})((one === 1))}; - {((cond) => {if (!cond) throw new Error(`assertion failed: '(two === 2)'`)})((two === 2))}; + {((cond) => {if (!cond) throw new Error("assertion failed: one == 1")})((one === 1))}; + {((cond) => {if (!cond) throw new Error("assertion failed: two == 2")})((two === 2))}; } } return Foo; diff --git a/tools/hangar/__snapshots__/test_corpus/valid/calling_inflight_variants.w_test_sim.md b/tools/hangar/__snapshots__/test_corpus/valid/calling_inflight_variants.w_test_sim.md index 22920999d13..bcf77c087ff 100644 --- a/tools/hangar/__snapshots__/test_corpus/valid/calling_inflight_variants.w_test_sim.md +++ b/tools/hangar/__snapshots__/test_corpus/valid/calling_inflight_variants.w_test_sim.md @@ -4,12 +4,9 @@ ```log pass โ”€ calling_inflight_variants.wsim ยป root/env0/test:calling different types of inflights - - - - -Tests 1 passed (1) + +Tests 1 passed (1) +Test Files 1 passed (1) Duration - ``` diff --git a/tools/hangar/__snapshots__/test_corpus/valid/capture_containers.w_compile_tf-aws.md b/tools/hangar/__snapshots__/test_corpus/valid/capture_containers.w_compile_tf-aws.md index c481160a4b1..1e967844498 100644 --- a/tools/hangar/__snapshots__/test_corpus/valid/capture_containers.w_compile_tf-aws.md +++ b/tools/hangar/__snapshots__/test_corpus/valid/capture_containers.w_compile_tf-aws.md @@ -12,15 +12,15 @@ module.exports = function({ arr, mySet, myMap, arrOfMap, j }) { async $inflight_init() { } async handle() { - {((cond) => {if (!cond) throw new Error(`assertion failed: '((await arr.at(0)) === "hello")'`)})(((await arr.at(0)) === "hello"))}; - {((cond) => {if (!cond) throw new Error(`assertion failed: '((await arr.at(1)) === "world")'`)})(((await arr.at(1)) === "world"))}; - {((cond) => {if (!cond) throw new Error(`assertion failed: '(arr.length === 2)'`)})((arr.length === 2))}; - {((cond) => {if (!cond) throw new Error(`assertion failed: '(await mySet.has("my"))'`)})((await mySet.has("my")))}; - {((cond) => {if (!cond) throw new Error(`assertion failed: '(mySet.size === 2)'`)})((mySet.size === 2))}; - {((cond) => {if (!cond) throw new Error(`assertion failed: '("world" in (myMap))'`)})(("world" in (myMap)))}; - {((cond) => {if (!cond) throw new Error(`assertion failed: '(Object.keys(myMap).length === 2)'`)})((Object.keys(myMap).length === 2))}; - {((cond) => {if (!cond) throw new Error(`assertion failed: '("bang" in ((await arrOfMap.at(0))))'`)})(("bang" in ((await arrOfMap.at(0)))))}; - {((cond) => {if (!cond) throw new Error(`assertion failed: '((j)["b"] === "world")'`)})(((j)["b"] === "world"))}; + {((cond) => {if (!cond) throw new Error("assertion failed: arr.at(0) == \"hello\"")})(((await arr.at(0)) === "hello"))}; + {((cond) => {if (!cond) throw new Error("assertion failed: arr.at(1) == \"world\"")})(((await arr.at(1)) === "world"))}; + {((cond) => {if (!cond) throw new Error("assertion failed: arr.length == 2")})((arr.length === 2))}; + {((cond) => {if (!cond) throw new Error("assertion failed: mySet.has(\"my\")")})((await mySet.has("my")))}; + {((cond) => {if (!cond) throw new Error("assertion failed: mySet.size == 2")})((mySet.size === 2))}; + {((cond) => {if (!cond) throw new Error("assertion failed: myMap.has(\"world\")")})(("world" in (myMap)))}; + {((cond) => {if (!cond) throw new Error("assertion failed: myMap.size() == 2")})((Object.keys(myMap).length === 2))}; + {((cond) => {if (!cond) throw new Error("assertion failed: arrOfMap.at(0).has(\"bang\")")})(("bang" in ((await arrOfMap.at(0)))))}; + {((cond) => {if (!cond) throw new Error("assertion failed: j.get(\"b\") == \"world\"")})(((j)["b"] === "world"))}; } } return $Closure1; diff --git a/tools/hangar/__snapshots__/test_corpus/valid/capture_containers.w_test_sim.md b/tools/hangar/__snapshots__/test_corpus/valid/capture_containers.w_test_sim.md index 00e289f7b2a..608fd13f858 100644 --- a/tools/hangar/__snapshots__/test_corpus/valid/capture_containers.w_test_sim.md +++ b/tools/hangar/__snapshots__/test_corpus/valid/capture_containers.w_test_sim.md @@ -4,12 +4,9 @@ ```log pass โ”€ capture_containers.wsim ยป root/env0/test:capture_containers - - - - -Tests 1 passed (1) + +Tests 1 passed (1) +Test Files 1 passed (1) Duration - ``` diff --git a/tools/hangar/__snapshots__/test_corpus/valid/capture_in_binary.w_compile_tf-aws.md b/tools/hangar/__snapshots__/test_corpus/valid/capture_in_binary.w_compile_tf-aws.md index 5f584cae386..e14edef33aa 100644 --- a/tools/hangar/__snapshots__/test_corpus/valid/capture_in_binary.w_compile_tf-aws.md +++ b/tools/hangar/__snapshots__/test_corpus/valid/capture_in_binary.w_compile_tf-aws.md @@ -13,8 +13,8 @@ module.exports = function({ b, x }) { } async handle() { (await b.put("file","foo")); - {((cond) => {if (!cond) throw new Error(`assertion failed: '((await b.get("file")) === "foo")'`)})(((await b.get("file")) === "foo"))}; - {((cond) => {if (!cond) throw new Error(`assertion failed: '(12 === x)'`)})((12 === x))}; + {((cond) => {if (!cond) throw new Error("assertion failed: b.get(\"file\") == \"foo\"")})(((await b.get("file")) === "foo"))}; + {((cond) => {if (!cond) throw new Error("assertion failed: 12 == x")})((12 === x))}; } } return $Closure1; diff --git a/tools/hangar/__snapshots__/test_corpus/valid/capture_in_binary.w_test_sim.md b/tools/hangar/__snapshots__/test_corpus/valid/capture_in_binary.w_test_sim.md index 01c7bac66a8..d80ee78d880 100644 --- a/tools/hangar/__snapshots__/test_corpus/valid/capture_in_binary.w_test_sim.md +++ b/tools/hangar/__snapshots__/test_corpus/valid/capture_in_binary.w_test_sim.md @@ -4,12 +4,9 @@ ```log pass โ”€ capture_in_binary.wsim ยป root/env0/test:binary expressions - - - - -Tests 1 passed (1) + +Tests 1 passed (1) +Test Files 1 passed (1) Duration - ``` diff --git a/tools/hangar/__snapshots__/test_corpus/valid/capture_mutables.w_compile_tf-aws.md b/tools/hangar/__snapshots__/test_corpus/valid/capture_mutables.w_compile_tf-aws.md new file mode 100644 index 00000000000..c8c6287b9ac --- /dev/null +++ b/tools/hangar/__snapshots__/test_corpus/valid/capture_mutables.w_compile_tf-aws.md @@ -0,0 +1,287 @@ +# [capture_mutables.w](../../../../../examples/tests/valid/capture_mutables.w) | compile | tf-aws + +## inflight.$Closure1.js +```js +module.exports = function({ a, s, m, aCloned }) { + class $Closure1 { + constructor({ }) { + const $obj = (...args) => this.handle(...args); + Object.setPrototypeOf($obj, this); + return $obj; + } + async $inflight_init() { + } + async handle() { + {((cond) => {if (!cond) throw new Error("assertion failed: a.length == 1")})((a.length === 1))}; + {((cond) => {if (!cond) throw new Error("assertion failed: s.size == 1")})((s.size === 1))}; + {((cond) => {if (!cond) throw new Error("assertion failed: m.size() == 1")})((Object.keys(m).length === 1))}; + {((cond) => {if (!cond) throw new Error("assertion failed: aCloned.length == 1")})((aCloned.length === 1))}; + } + } + return $Closure1; +} + +``` + +## inflight.$Closure2.js +```js +module.exports = function({ handler }) { + class $Closure2 { + constructor({ }) { + const $obj = (...args) => this.handle(...args); + Object.setPrototypeOf($obj, this); + return $obj; + } + async $inflight_init() { + } + async handle() { + (await handler()); + } + } + return $Closure2; +} + +``` + +## main.tf.json +```json +{ + "//": { + "metadata": { + "backend": "local", + "stackName": "root", + "version": "0.15.2" + }, + "outputs": { + "root": { + "Default": { + "cloud.TestRunner": { + "TestFunctionArns": "WING_TEST_RUNNER_FUNCTION_ARNS" + } + } + } + } + }, + "output": { + "WING_TEST_RUNNER_FUNCTION_ARNS": { + "value": "[[\"root/Default/Default/test:main\",\"${aws_lambda_function.root_testmain_Handler_4ADAC335.arn}\"]]" + } + }, + "provider": { + "aws": [ + {} + ] + }, + "resource": { + "aws_iam_role": { + "root_testmain_Handler_IamRole_0300CAA5": { + "//": { + "metadata": { + "path": "root/Default/Default/test:main/Handler/IamRole", + "uniqueId": "root_testmain_Handler_IamRole_0300CAA5" + } + }, + "assume_role_policy": "{\"Version\":\"2012-10-17\",\"Statement\":[{\"Action\":\"sts:AssumeRole\",\"Principal\":{\"Service\":\"lambda.amazonaws.com\"},\"Effect\":\"Allow\"}]}" + } + }, + "aws_iam_role_policy": { + "root_testmain_Handler_IamRolePolicy_184F2A46": { + "//": { + "metadata": { + "path": "root/Default/Default/test:main/Handler/IamRolePolicy", + "uniqueId": "root_testmain_Handler_IamRolePolicy_184F2A46" + } + }, + "policy": "{\"Version\":\"2012-10-17\",\"Statement\":[{\"Effect\":\"Allow\",\"Action\":\"none:null\",\"Resource\":\"*\"}]}", + "role": "${aws_iam_role.root_testmain_Handler_IamRole_0300CAA5.name}" + } + }, + "aws_iam_role_policy_attachment": { + "root_testmain_Handler_IamRolePolicyAttachment_F254CEF9": { + "//": { + "metadata": { + "path": "root/Default/Default/test:main/Handler/IamRolePolicyAttachment", + "uniqueId": "root_testmain_Handler_IamRolePolicyAttachment_F254CEF9" + } + }, + "policy_arn": "arn:aws:iam::aws:policy/service-role/AWSLambdaBasicExecutionRole", + "role": "${aws_iam_role.root_testmain_Handler_IamRole_0300CAA5.name}" + } + }, + "aws_lambda_function": { + "root_testmain_Handler_4ADAC335": { + "//": { + "metadata": { + "path": "root/Default/Default/test:main/Handler/Default", + "uniqueId": "root_testmain_Handler_4ADAC335" + } + }, + "environment": { + "variables": { + "WING_FUNCTION_NAME": "Handler-c8d10438", + "WING_TARGET": "tf-aws" + } + }, + "function_name": "Handler-c8d10438", + "handler": "index.handler", + "publish": true, + "role": "${aws_iam_role.root_testmain_Handler_IamRole_0300CAA5.arn}", + "runtime": "nodejs18.x", + "s3_bucket": "${aws_s3_bucket.root_Code_02F3C603.bucket}", + "s3_key": "${aws_s3_object.root_testmain_Handler_S3Object_2601AAE9.key}", + "timeout": 30, + "vpc_config": { + "security_group_ids": [], + "subnet_ids": [] + } + } + }, + "aws_s3_bucket": { + "root_Code_02F3C603": { + "//": { + "metadata": { + "path": "root/Default/Code", + "uniqueId": "root_Code_02F3C603" + } + }, + "bucket_prefix": "code-c84a50b1-" + } + }, + "aws_s3_object": { + "root_testmain_Handler_S3Object_2601AAE9": { + "//": { + "metadata": { + "path": "root/Default/Default/test:main/Handler/S3Object", + "uniqueId": "root_testmain_Handler_S3Object_2601AAE9" + } + }, + "bucket": "${aws_s3_bucket.root_Code_02F3C603.bucket}", + "key": "", + "source": "" + } + } + } +} +``` + +## preflight.js +```js +const $stdlib = require('@winglang/sdk'); +const $outdir = process.env.WING_SYNTH_DIR ?? "."; +const std = $stdlib.std; +const $wing_is_test = process.env.WING_IS_TEST === "true"; +const $AppBase = $stdlib.core.App.for(process.env.WING_TARGET); +class $Root extends $stdlib.std.Resource { + constructor(scope, id) { + super(scope, id); + class $Closure1 extends $stdlib.std.Resource { + constructor(scope, id, ) { + super(scope, id); + this._addInflightOps("handle"); + this.display.hidden = true; + } + static _toInflightType(context) { + const self_client_path = "././inflight.$Closure1.js"; + const a_client = context._lift(a); + const s_client = context._lift(s); + const m_client = context._lift(m); + const aCloned_client = context._lift(aCloned); + return $stdlib.core.NodeJsCode.fromInline(` + require("${self_client_path}")({ + a: ${a_client}, + s: ${s_client}, + m: ${m_client}, + aCloned: ${aCloned_client}, + }) + `); + } + _toInflight() { + return $stdlib.core.NodeJsCode.fromInline(` + (await (async () => { + const $Closure1Client = ${$Closure1._toInflightType(this).text}; + const client = new $Closure1Client({ + }); + if (client.$inflight_init) { await client.$inflight_init(); } + return client; + })()) + `); + } + _registerBind(host, ops) { + if (ops.includes("$inflight_init")) { + $Closure1._registerBindObject(a, host, []); + $Closure1._registerBindObject(aCloned, host, []); + $Closure1._registerBindObject(m, host, []); + $Closure1._registerBindObject(s, host, []); + } + if (ops.includes("handle")) { + $Closure1._registerBindObject(a, host, ["length"]); + $Closure1._registerBindObject(aCloned, host, ["length"]); + $Closure1._registerBindObject(m, host, ["size"]); + $Closure1._registerBindObject(s, host, ["size"]); + } + super._registerBind(host, ops); + } + } + class $Closure2 extends $stdlib.std.Resource { + constructor(scope, id, ) { + super(scope, id); + this._addInflightOps("handle"); + this.display.hidden = true; + } + static _toInflightType(context) { + const self_client_path = "././inflight.$Closure2.js"; + const handler_client = context._lift(handler); + return $stdlib.core.NodeJsCode.fromInline(` + require("${self_client_path}")({ + handler: ${handler_client}, + }) + `); + } + _toInflight() { + return $stdlib.core.NodeJsCode.fromInline(` + (await (async () => { + const $Closure2Client = ${$Closure2._toInflightType(this).text}; + const client = new $Closure2Client({ + }); + if (client.$inflight_init) { await client.$inflight_init(); } + return client; + })()) + `); + } + _registerBind(host, ops) { + if (ops.includes("$inflight_init")) { + $Closure2._registerBindObject(handler, host, []); + } + if (ops.includes("handle")) { + $Closure2._registerBindObject(handler, host, ["handle"]); + } + super._registerBind(host, ops); + } + } + const a = ["hello"]; + const s = new Set([12]); + const m = {"hello":true}; + const aCloned = [...(Object.freeze(["hello"]))]; + const handler = new $Closure1(this,"$Closure1"); + this.node.root.new("@winglang/sdk.std.Test",std.Test,this,"test:main",new $Closure2(this,"$Closure2")); + } +} +class $App extends $AppBase { + constructor() { + super({ outdir: $outdir, name: "capture_mutables", plugins: $plugins, isTestEnvironment: $wing_is_test }); + if ($wing_is_test) { + new $Root(this, "env0"); + const $test_runner = this.testRunner; + const $tests = $test_runner.findTests(); + for (let $i = 1; $i < $tests.length; $i++) { + new $Root(this, "env" + $i); + } + } else { + new $Root(this, "Default"); + } + } +} +new $App().synth(); + +``` + diff --git a/tools/hangar/__snapshots__/test_corpus/valid/capture_mutables.w_test_sim.md b/tools/hangar/__snapshots__/test_corpus/valid/capture_mutables.w_test_sim.md new file mode 100644 index 00000000000..a19e3b7bc6c --- /dev/null +++ b/tools/hangar/__snapshots__/test_corpus/valid/capture_mutables.w_test_sim.md @@ -0,0 +1,12 @@ +# [capture_mutables.w](../../../../../examples/tests/valid/capture_mutables.w) | test | sim + +## stdout.log +```log +pass โ”€ capture_mutables.wsim ยป root/env0/test:main + + +Tests 1 passed (1) +Test Files 1 passed (1) +Duration +``` + diff --git a/tools/hangar/__snapshots__/test_corpus/valid/capture_primitives.w_compile_tf-aws.md b/tools/hangar/__snapshots__/test_corpus/valid/capture_primitives.w_compile_tf-aws.md index 77f1be2598f..9e9cfd715e1 100644 --- a/tools/hangar/__snapshots__/test_corpus/valid/capture_primitives.w_compile_tf-aws.md +++ b/tools/hangar/__snapshots__/test_corpus/valid/capture_primitives.w_compile_tf-aws.md @@ -14,8 +14,8 @@ module.exports = function({ myStr, myNum, mySecondBool, myBool, myDur }) { async handle(s) { {console.log(myStr)}; const n = myNum; - {console.log(`${n}`)}; - {((cond) => {if (!cond) throw new Error(`assertion failed: '(mySecondBool === false)'`)})((mySecondBool === false))}; + {console.log(String.raw({ raw: ["", ""] }, n))}; + {((cond) => {if (!cond) throw new Error("assertion failed: mySecondBool == false")})((mySecondBool === false))}; if (myBool) { {console.log("bool=true")}; } @@ -25,8 +25,8 @@ module.exports = function({ myStr, myNum, mySecondBool, myBool, myDur }) { const min = myDur.minutes; const sec = myDur.seconds; const hr = myDur.hours; - const split = (await `min=${min} sec=${sec} hr=${hr}`.split(" ")); - {((cond) => {if (!cond) throw new Error(`assertion failed: '(split.length === 3)'`)})((split.length === 3))}; + const split = (await String.raw({ raw: ["min=", " sec=", " hr=", ""] }, min, sec, hr).split(" ")); + {((cond) => {if (!cond) throw new Error("assertion failed: split.length == 3")})((split.length === 3))}; } } return $Closure1; diff --git a/tools/hangar/__snapshots__/test_corpus/valid/capture_primitives.w_test_sim.md b/tools/hangar/__snapshots__/test_corpus/valid/capture_primitives.w_test_sim.md index 352d0c1cab1..c7ee840f54d 100644 --- a/tools/hangar/__snapshots__/test_corpus/valid/capture_primitives.w_test_sim.md +++ b/tools/hangar/__snapshots__/test_corpus/valid/capture_primitives.w_test_sim.md @@ -4,12 +4,9 @@ ```log pass โ”€ capture_primitives.wsim (no tests) - - - - -Tests 1 passed (1) + +Tests 1 passed (1) +Test Files 1 passed (1) Duration - ``` diff --git a/tools/hangar/__snapshots__/test_corpus/valid/capture_reassigable_class_field.w_compile_tf-aws.md b/tools/hangar/__snapshots__/test_corpus/valid/capture_reassigable_class_field.w_compile_tf-aws.md new file mode 100644 index 00000000000..1f7d2b570d1 --- /dev/null +++ b/tools/hangar/__snapshots__/test_corpus/valid/capture_reassigable_class_field.w_compile_tf-aws.md @@ -0,0 +1,477 @@ +# [capture_reassigable_class_field.w](../../../../../examples/tests/valid/capture_reassigable_class_field.w) | compile | tf-aws + +## inflight.$Closure1.js +```js +module.exports = function({ }) { + class $Closure1 { + constructor({ }) { + const $obj = (...args) => this.handle(...args); + Object.setPrototypeOf($obj, this); + return $obj; + } + async $inflight_init() { + } + async handle(k) { + } + } + return $Closure1; +} + +``` + +## inflight.$Closure2.js +```js +module.exports = function({ counter }) { + class $Closure2 { + constructor({ }) { + const $obj = (...args) => this.handle(...args); + Object.setPrototypeOf($obj, this); + return $obj; + } + async $inflight_init() { + } + async handle(key) { + (await counter.inc(1,key)); + } + } + return $Closure2; +} + +``` + +## inflight.$Closure3.js +```js +module.exports = function({ kv, counter, util_Util }) { + class $Closure3 { + constructor({ }) { + const $obj = (...args) => this.handle(...args); + Object.setPrototypeOf($obj, this); + return $obj; + } + async $inflight_init() { + } + async handle() { + (await kv.set("k",Object.freeze({"value":"v"}))); + (await kv.set("k2",Object.freeze({"value":"v"}))); + (await kv.get("k")); + (await kv.get("k")); + (await kv.get("k2")); + {((cond) => {if (!cond) throw new Error("assertion failed: util.waitUntil((): bool => {\n return counter.peek(\"k\") == 2;\n })")})((await util_Util.waitUntil(async () => { + return ((await counter.peek("k")) === 2); + } + )))}; + {((cond) => {if (!cond) throw new Error("assertion failed: util.waitUntil((): bool => {\n return counter.peek(\"k2\") == 1;\n })")})((await util_Util.waitUntil(async () => { + return ((await counter.peek("k2")) === 1); + } + )))}; + } + } + return $Closure3; +} + +``` + +## inflight.KeyValueStore.js +```js +module.exports = function({ }) { + class KeyValueStore { + constructor({ bucket, onUpdateCallback }) { + this.bucket = bucket; + this.onUpdateCallback = onUpdateCallback; + } + async $inflight_init() { + } + async get(key) { + (await this.onUpdateCallback(key)); + return (await this.bucket.getJson(key)); + } + async set(key, value) { + (await this.bucket.putJson(key,value)); + } + } + return KeyValueStore; +} + +``` + +## main.tf.json +```json +{ + "//": { + "metadata": { + "backend": "local", + "stackName": "root", + "version": "0.15.2" + }, + "outputs": { + "root": { + "Default": { + "cloud.TestRunner": { + "TestFunctionArns": "WING_TEST_RUNNER_FUNCTION_ARNS" + } + } + } + } + }, + "output": { + "WING_TEST_RUNNER_FUNCTION_ARNS": { + "value": "[[\"root/Default/Default/test:main\",\"${aws_lambda_function.root_testmain_Handler_4ADAC335.arn}\"]]" + } + }, + "provider": { + "aws": [ + {} + ] + }, + "resource": { + "aws_dynamodb_table": { + "root_sasa_B91F09DA": { + "//": { + "metadata": { + "path": "root/Default/Default/sasa/Default", + "uniqueId": "root_sasa_B91F09DA" + } + }, + "attribute": [ + { + "name": "id", + "type": "S" + } + ], + "billing_mode": "PAY_PER_REQUEST", + "hash_key": "id", + "name": "wing-counter-sasa-c8fc4cc8" + } + }, + "aws_iam_role": { + "root_testmain_Handler_IamRole_0300CAA5": { + "//": { + "metadata": { + "path": "root/Default/Default/test:main/Handler/IamRole", + "uniqueId": "root_testmain_Handler_IamRole_0300CAA5" + } + }, + "assume_role_policy": "{\"Version\":\"2012-10-17\",\"Statement\":[{\"Action\":\"sts:AssumeRole\",\"Principal\":{\"Service\":\"lambda.amazonaws.com\"},\"Effect\":\"Allow\"}]}" + } + }, + "aws_iam_role_policy": { + "root_testmain_Handler_IamRolePolicy_184F2A46": { + "//": { + "metadata": { + "path": "root/Default/Default/test:main/Handler/IamRolePolicy", + "uniqueId": "root_testmain_Handler_IamRolePolicy_184F2A46" + } + }, + "policy": "{\"Version\":\"2012-10-17\",\"Statement\":[{\"Action\":[\"s3:PutObject*\",\"s3:Abort*\"],\"Resource\":[\"${aws_s3_bucket.root_KeyValueStore_cloudBucket_B6A49C6A.arn}\",\"${aws_s3_bucket.root_KeyValueStore_cloudBucket_B6A49C6A.arn}/*\"],\"Effect\":\"Allow\"},{\"Action\":[\"s3:GetObject*\",\"s3:GetBucket*\",\"s3:List*\"],\"Resource\":[\"${aws_s3_bucket.root_KeyValueStore_cloudBucket_B6A49C6A.arn}\",\"${aws_s3_bucket.root_KeyValueStore_cloudBucket_B6A49C6A.arn}/*\"],\"Effect\":\"Allow\"},{\"Action\":[\"dynamodb:UpdateItem\"],\"Resource\":[\"${aws_dynamodb_table.root_sasa_B91F09DA.arn}\"],\"Effect\":\"Allow\"},{\"Action\":[\"dynamodb:GetItem\"],\"Resource\":[\"${aws_dynamodb_table.root_sasa_B91F09DA.arn}\"],\"Effect\":\"Allow\"}]}", + "role": "${aws_iam_role.root_testmain_Handler_IamRole_0300CAA5.name}" + } + }, + "aws_iam_role_policy_attachment": { + "root_testmain_Handler_IamRolePolicyAttachment_F254CEF9": { + "//": { + "metadata": { + "path": "root/Default/Default/test:main/Handler/IamRolePolicyAttachment", + "uniqueId": "root_testmain_Handler_IamRolePolicyAttachment_F254CEF9" + } + }, + "policy_arn": "arn:aws:iam::aws:policy/service-role/AWSLambdaBasicExecutionRole", + "role": "${aws_iam_role.root_testmain_Handler_IamRole_0300CAA5.name}" + } + }, + "aws_lambda_function": { + "root_testmain_Handler_4ADAC335": { + "//": { + "metadata": { + "path": "root/Default/Default/test:main/Handler/Default", + "uniqueId": "root_testmain_Handler_4ADAC335" + } + }, + "environment": { + "variables": { + "BUCKET_NAME_ce72b88b": "${aws_s3_bucket.root_KeyValueStore_cloudBucket_B6A49C6A.bucket}", + "BUCKET_NAME_ce72b88b_IS_PUBLIC": "false", + "DYNAMODB_TABLE_NAME_5a275103": "${aws_dynamodb_table.root_sasa_B91F09DA.name}", + "WING_FUNCTION_NAME": "Handler-c8d10438", + "WING_TARGET": "tf-aws" + } + }, + "function_name": "Handler-c8d10438", + "handler": "index.handler", + "publish": true, + "role": "${aws_iam_role.root_testmain_Handler_IamRole_0300CAA5.arn}", + "runtime": "nodejs18.x", + "s3_bucket": "${aws_s3_bucket.root_Code_02F3C603.bucket}", + "s3_key": "${aws_s3_object.root_testmain_Handler_S3Object_2601AAE9.key}", + "timeout": 30, + "vpc_config": { + "security_group_ids": [], + "subnet_ids": [] + } + } + }, + "aws_s3_bucket": { + "root_Code_02F3C603": { + "//": { + "metadata": { + "path": "root/Default/Code", + "uniqueId": "root_Code_02F3C603" + } + }, + "bucket_prefix": "code-c84a50b1-" + }, + "root_KeyValueStore_cloudBucket_B6A49C6A": { + "//": { + "metadata": { + "path": "root/Default/Default/KeyValueStore/cloud.Bucket/Default", + "uniqueId": "root_KeyValueStore_cloudBucket_B6A49C6A" + } + }, + "bucket_prefix": "cloud-bucket-c8a9ef69-", + "force_destroy": false + } + }, + "aws_s3_bucket_public_access_block": { + "root_KeyValueStore_cloudBucket_PublicAccessBlock_742F6520": { + "//": { + "metadata": { + "path": "root/Default/Default/KeyValueStore/cloud.Bucket/PublicAccessBlock", + "uniqueId": "root_KeyValueStore_cloudBucket_PublicAccessBlock_742F6520" + } + }, + "block_public_acls": true, + "block_public_policy": true, + "bucket": "${aws_s3_bucket.root_KeyValueStore_cloudBucket_B6A49C6A.bucket}", + "ignore_public_acls": true, + "restrict_public_buckets": true + } + }, + "aws_s3_bucket_server_side_encryption_configuration": { + "root_KeyValueStore_cloudBucket_Encryption_FDD09906": { + "//": { + "metadata": { + "path": "root/Default/Default/KeyValueStore/cloud.Bucket/Encryption", + "uniqueId": "root_KeyValueStore_cloudBucket_Encryption_FDD09906" + } + }, + "bucket": "${aws_s3_bucket.root_KeyValueStore_cloudBucket_B6A49C6A.bucket}", + "rule": [ + { + "apply_server_side_encryption_by_default": { + "sse_algorithm": "AES256" + } + } + ] + } + }, + "aws_s3_object": { + "root_testmain_Handler_S3Object_2601AAE9": { + "//": { + "metadata": { + "path": "root/Default/Default/test:main/Handler/S3Object", + "uniqueId": "root_testmain_Handler_S3Object_2601AAE9" + } + }, + "bucket": "${aws_s3_bucket.root_Code_02F3C603.bucket}", + "key": "", + "source": "" + } + } + } +} +``` + +## preflight.js +```js +const $stdlib = require('@winglang/sdk'); +const $outdir = process.env.WING_SYNTH_DIR ?? "."; +const std = $stdlib.std; +const $wing_is_test = process.env.WING_IS_TEST === "true"; +const $AppBase = $stdlib.core.App.for(process.env.WING_TARGET); +const cloud = require('@winglang/sdk').cloud; +const util = require('@winglang/sdk').util; +class $Root extends $stdlib.std.Resource { + constructor(scope, id) { + super(scope, id); + class KeyValueStore extends $stdlib.std.Resource { + constructor(scope, id, ) { + super(scope, id); + this._addInflightOps("get", "set"); + this.bucket = this.node.root.newAbstract("@winglang/sdk.cloud.Bucket",this,"cloud.Bucket"); + const __parent_this_1 = this; + class $Closure1 extends $stdlib.std.Resource { + constructor(scope, id, ) { + super(scope, id); + this._addInflightOps("handle"); + this.display.hidden = true; + } + static _toInflightType(context) { + const self_client_path = "././inflight.$Closure1.js"; + return $stdlib.core.NodeJsCode.fromInline(` + require("${self_client_path}")({ + }) + `); + } + _toInflight() { + return $stdlib.core.NodeJsCode.fromInline(` + (await (async () => { + const $Closure1Client = ${$Closure1._toInflightType(this).text}; + const client = new $Closure1Client({ + }); + if (client.$inflight_init) { await client.$inflight_init(); } + return client; + })()) + `); + } + _registerBind(host, ops) { + if (ops.includes("$inflight_init")) { + } + if (ops.includes("handle")) { + } + super._registerBind(host, ops); + } + } + this.onUpdateCallback = new $Closure1(this,"$Closure1"); + } + onUpdate(fn) { + this.onUpdateCallback = fn; + } + static _toInflightType(context) { + const self_client_path = "././inflight.KeyValueStore.js"; + return $stdlib.core.NodeJsCode.fromInline(` + require("${self_client_path}")({ + }) + `); + } + _toInflight() { + const bucket_client = this._lift(this.bucket); + const onUpdateCallback_client = this._lift(this.onUpdateCallback); + return $stdlib.core.NodeJsCode.fromInline(` + (await (async () => { + const KeyValueStoreClient = ${KeyValueStore._toInflightType(this).text}; + const client = new KeyValueStoreClient({ + bucket: ${bucket_client}, + onUpdateCallback: ${onUpdateCallback_client}, + }); + if (client.$inflight_init) { await client.$inflight_init(); } + return client; + })()) + `); + } + _registerBind(host, ops) { + if (ops.includes("$inflight_init")) { + KeyValueStore._registerBindObject(this.bucket, host, []); + KeyValueStore._registerBindObject(this.onUpdateCallback, host, []); + } + if (ops.includes("get")) { + KeyValueStore._registerBindObject(this.bucket, host, ["getJson"]); + KeyValueStore._registerBindObject(this.onUpdateCallback, host, ["handle"]); + } + if (ops.includes("set")) { + KeyValueStore._registerBindObject(this.bucket, host, ["putJson"]); + } + super._registerBind(host, ops); + } + } + class $Closure2 extends $stdlib.std.Resource { + constructor(scope, id, ) { + super(scope, id); + this._addInflightOps("handle"); + this.display.hidden = true; + } + static _toInflightType(context) { + const self_client_path = "././inflight.$Closure2.js"; + const counter_client = context._lift(counter); + return $stdlib.core.NodeJsCode.fromInline(` + require("${self_client_path}")({ + counter: ${counter_client}, + }) + `); + } + _toInflight() { + return $stdlib.core.NodeJsCode.fromInline(` + (await (async () => { + const $Closure2Client = ${$Closure2._toInflightType(this).text}; + const client = new $Closure2Client({ + }); + if (client.$inflight_init) { await client.$inflight_init(); } + return client; + })()) + `); + } + _registerBind(host, ops) { + if (ops.includes("$inflight_init")) { + $Closure2._registerBindObject(counter, host, []); + } + if (ops.includes("handle")) { + $Closure2._registerBindObject(counter, host, ["inc"]); + } + super._registerBind(host, ops); + } + } + class $Closure3 extends $stdlib.std.Resource { + constructor(scope, id, ) { + super(scope, id); + this._addInflightOps("handle"); + this.display.hidden = true; + } + static _toInflightType(context) { + const self_client_path = "././inflight.$Closure3.js"; + const kv_client = context._lift(kv); + const counter_client = context._lift(counter); + const util_UtilClient = util.Util._toInflightType(context); + return $stdlib.core.NodeJsCode.fromInline(` + require("${self_client_path}")({ + kv: ${kv_client}, + counter: ${counter_client}, + util_Util: ${util_UtilClient.text}, + }) + `); + } + _toInflight() { + return $stdlib.core.NodeJsCode.fromInline(` + (await (async () => { + const $Closure3Client = ${$Closure3._toInflightType(this).text}; + const client = new $Closure3Client({ + }); + if (client.$inflight_init) { await client.$inflight_init(); } + return client; + })()) + `); + } + _registerBind(host, ops) { + if (ops.includes("$inflight_init")) { + $Closure3._registerBindObject(counter, host, []); + $Closure3._registerBindObject(kv, host, []); + } + if (ops.includes("handle")) { + $Closure3._registerBindObject(counter, host, ["peek"]); + $Closure3._registerBindObject(kv, host, ["get", "set"]); + } + super._registerBind(host, ops); + } + } + const kv = new KeyValueStore(this,"KeyValueStore"); + const counter = this.node.root.newAbstract("@winglang/sdk.cloud.Counter",this,"sasa"); + (kv.onUpdate(new $Closure2(this,"$Closure2"))); + this.node.root.new("@winglang/sdk.std.Test",std.Test,this,"test:main",new $Closure3(this,"$Closure3")); + } +} +class $App extends $AppBase { + constructor() { + super({ outdir: $outdir, name: "capture_reassigable_class_field", plugins: $plugins, isTestEnvironment: $wing_is_test }); + if ($wing_is_test) { + new $Root(this, "env0"); + const $test_runner = this.testRunner; + const $tests = $test_runner.findTests(); + for (let $i = 1; $i < $tests.length; $i++) { + new $Root(this, "env" + $i); + } + } else { + new $Root(this, "Default"); + } + } +} +new $App().synth(); + +``` + diff --git a/tools/hangar/__snapshots__/test_corpus/valid/capture_reassigable_class_field.w_test_sim.md b/tools/hangar/__snapshots__/test_corpus/valid/capture_reassigable_class_field.w_test_sim.md new file mode 100644 index 00000000000..cbb5d86f0dd --- /dev/null +++ b/tools/hangar/__snapshots__/test_corpus/valid/capture_reassigable_class_field.w_test_sim.md @@ -0,0 +1,12 @@ +# [capture_reassigable_class_field.w](../../../../../examples/tests/valid/capture_reassigable_class_field.w) | test | sim + +## stdout.log +```log +pass โ”€ capture_reassigable_class_field.wsim ยป root/env0/test:main + + +Tests 1 passed (1) +Test Files 1 passed (1) +Duration +``` + diff --git a/tools/hangar/__snapshots__/test_corpus/valid/capture_reassignable.w_compile_tf-aws.md b/tools/hangar/__snapshots__/test_corpus/valid/capture_reassignable.w_compile_tf-aws.md new file mode 100644 index 00000000000..4cc16593dbb --- /dev/null +++ b/tools/hangar/__snapshots__/test_corpus/valid/capture_reassignable.w_compile_tf-aws.md @@ -0,0 +1,270 @@ +# [capture_reassignable.w](../../../../../examples/tests/valid/capture_reassignable.w) | compile | tf-aws + +## inflight.$Closure1.js +```js +module.exports = function({ x }) { + class $Closure1 { + constructor({ }) { + const $obj = (...args) => this.handle(...args); + Object.setPrototypeOf($obj, this); + return $obj; + } + async $inflight_init() { + } + async handle() { + {((cond) => {if (!cond) throw new Error("assertion failed: x == 5")})((x === 5))}; + } + } + return $Closure1; +} + +``` + +## inflight.$Closure2.js +```js +module.exports = function({ handler }) { + class $Closure2 { + constructor({ }) { + const $obj = (...args) => this.handle(...args); + Object.setPrototypeOf($obj, this); + return $obj; + } + async $inflight_init() { + } + async handle() { + (await handler()); + } + } + return $Closure2; +} + +``` + +## main.tf.json +```json +{ + "//": { + "metadata": { + "backend": "local", + "stackName": "root", + "version": "0.15.2" + }, + "outputs": { + "root": { + "Default": { + "cloud.TestRunner": { + "TestFunctionArns": "WING_TEST_RUNNER_FUNCTION_ARNS" + } + } + } + } + }, + "output": { + "WING_TEST_RUNNER_FUNCTION_ARNS": { + "value": "[[\"root/Default/Default/test:main\",\"${aws_lambda_function.root_testmain_Handler_4ADAC335.arn}\"]]" + } + }, + "provider": { + "aws": [ + {} + ] + }, + "resource": { + "aws_iam_role": { + "root_testmain_Handler_IamRole_0300CAA5": { + "//": { + "metadata": { + "path": "root/Default/Default/test:main/Handler/IamRole", + "uniqueId": "root_testmain_Handler_IamRole_0300CAA5" + } + }, + "assume_role_policy": "{\"Version\":\"2012-10-17\",\"Statement\":[{\"Action\":\"sts:AssumeRole\",\"Principal\":{\"Service\":\"lambda.amazonaws.com\"},\"Effect\":\"Allow\"}]}" + } + }, + "aws_iam_role_policy": { + "root_testmain_Handler_IamRolePolicy_184F2A46": { + "//": { + "metadata": { + "path": "root/Default/Default/test:main/Handler/IamRolePolicy", + "uniqueId": "root_testmain_Handler_IamRolePolicy_184F2A46" + } + }, + "policy": "{\"Version\":\"2012-10-17\",\"Statement\":[{\"Effect\":\"Allow\",\"Action\":\"none:null\",\"Resource\":\"*\"}]}", + "role": "${aws_iam_role.root_testmain_Handler_IamRole_0300CAA5.name}" + } + }, + "aws_iam_role_policy_attachment": { + "root_testmain_Handler_IamRolePolicyAttachment_F254CEF9": { + "//": { + "metadata": { + "path": "root/Default/Default/test:main/Handler/IamRolePolicyAttachment", + "uniqueId": "root_testmain_Handler_IamRolePolicyAttachment_F254CEF9" + } + }, + "policy_arn": "arn:aws:iam::aws:policy/service-role/AWSLambdaBasicExecutionRole", + "role": "${aws_iam_role.root_testmain_Handler_IamRole_0300CAA5.name}" + } + }, + "aws_lambda_function": { + "root_testmain_Handler_4ADAC335": { + "//": { + "metadata": { + "path": "root/Default/Default/test:main/Handler/Default", + "uniqueId": "root_testmain_Handler_4ADAC335" + } + }, + "environment": { + "variables": { + "WING_FUNCTION_NAME": "Handler-c8d10438", + "WING_TARGET": "tf-aws" + } + }, + "function_name": "Handler-c8d10438", + "handler": "index.handler", + "publish": true, + "role": "${aws_iam_role.root_testmain_Handler_IamRole_0300CAA5.arn}", + "runtime": "nodejs18.x", + "s3_bucket": "${aws_s3_bucket.root_Code_02F3C603.bucket}", + "s3_key": "${aws_s3_object.root_testmain_Handler_S3Object_2601AAE9.key}", + "timeout": 30, + "vpc_config": { + "security_group_ids": [], + "subnet_ids": [] + } + } + }, + "aws_s3_bucket": { + "root_Code_02F3C603": { + "//": { + "metadata": { + "path": "root/Default/Code", + "uniqueId": "root_Code_02F3C603" + } + }, + "bucket_prefix": "code-c84a50b1-" + } + }, + "aws_s3_object": { + "root_testmain_Handler_S3Object_2601AAE9": { + "//": { + "metadata": { + "path": "root/Default/Default/test:main/Handler/S3Object", + "uniqueId": "root_testmain_Handler_S3Object_2601AAE9" + } + }, + "bucket": "${aws_s3_bucket.root_Code_02F3C603.bucket}", + "key": "", + "source": "" + } + } + } +} +``` + +## preflight.js +```js +const $stdlib = require('@winglang/sdk'); +const $outdir = process.env.WING_SYNTH_DIR ?? "."; +const std = $stdlib.std; +const $wing_is_test = process.env.WING_IS_TEST === "true"; +const $AppBase = $stdlib.core.App.for(process.env.WING_TARGET); +const cloud = require('@winglang/sdk').cloud; +class $Root extends $stdlib.std.Resource { + constructor(scope, id) { + super(scope, id); + class $Closure1 extends $stdlib.std.Resource { + constructor(scope, id, ) { + super(scope, id); + this._addInflightOps("handle"); + this.display.hidden = true; + } + static _toInflightType(context) { + const self_client_path = "././inflight.$Closure1.js"; + const x_client = context._lift(x); + return $stdlib.core.NodeJsCode.fromInline(` + require("${self_client_path}")({ + x: ${x_client}, + }) + `); + } + _toInflight() { + return $stdlib.core.NodeJsCode.fromInline(` + (await (async () => { + const $Closure1Client = ${$Closure1._toInflightType(this).text}; + const client = new $Closure1Client({ + }); + if (client.$inflight_init) { await client.$inflight_init(); } + return client; + })()) + `); + } + _registerBind(host, ops) { + if (ops.includes("$inflight_init")) { + $Closure1._registerBindObject(x, host, []); + } + if (ops.includes("handle")) { + $Closure1._registerBindObject(x, host, []); + } + super._registerBind(host, ops); + } + } + class $Closure2 extends $stdlib.std.Resource { + constructor(scope, id, ) { + super(scope, id); + this._addInflightOps("handle"); + this.display.hidden = true; + } + static _toInflightType(context) { + const self_client_path = "././inflight.$Closure2.js"; + const handler_client = context._lift(handler); + return $stdlib.core.NodeJsCode.fromInline(` + require("${self_client_path}")({ + handler: ${handler_client}, + }) + `); + } + _toInflight() { + return $stdlib.core.NodeJsCode.fromInline(` + (await (async () => { + const $Closure2Client = ${$Closure2._toInflightType(this).text}; + const client = new $Closure2Client({ + }); + if (client.$inflight_init) { await client.$inflight_init(); } + return client; + })()) + `); + } + _registerBind(host, ops) { + if (ops.includes("$inflight_init")) { + $Closure2._registerBindObject(handler, host, []); + } + if (ops.includes("handle")) { + $Closure2._registerBindObject(handler, host, ["handle"]); + } + super._registerBind(host, ops); + } + } + let x = 5; + const handler = new $Closure1(this,"$Closure1"); + this.node.root.new("@winglang/sdk.std.Test",std.Test,this,"test:main",new $Closure2(this,"$Closure2")); + } +} +class $App extends $AppBase { + constructor() { + super({ outdir: $outdir, name: "capture_reassignable", plugins: $plugins, isTestEnvironment: $wing_is_test }); + if ($wing_is_test) { + new $Root(this, "env0"); + const $test_runner = this.testRunner; + const $tests = $test_runner.findTests(); + for (let $i = 1; $i < $tests.length; $i++) { + new $Root(this, "env" + $i); + } + } else { + new $Root(this, "Default"); + } + } +} +new $App().synth(); + +``` + diff --git a/tools/hangar/__snapshots__/test_corpus/valid/capture_reassignable.w_test_sim.md b/tools/hangar/__snapshots__/test_corpus/valid/capture_reassignable.w_test_sim.md new file mode 100644 index 00000000000..a4bc3e73c2f --- /dev/null +++ b/tools/hangar/__snapshots__/test_corpus/valid/capture_reassignable.w_test_sim.md @@ -0,0 +1,12 @@ +# [capture_reassignable.w](../../../../../examples/tests/valid/capture_reassignable.w) | test | sim + +## stdout.log +```log +pass โ”€ capture_reassignable.wsim ยป root/env0/test:main + + +Tests 1 passed (1) +Test Files 1 passed (1) +Duration +``` + diff --git a/tools/hangar/__snapshots__/test_corpus/valid/capture_resource_and_data.w_compile_tf-aws.md b/tools/hangar/__snapshots__/test_corpus/valid/capture_resource_and_data.w_compile_tf-aws.md index cf2216a0bf6..7e5164511f4 100644 --- a/tools/hangar/__snapshots__/test_corpus/valid/capture_resource_and_data.w_compile_tf-aws.md +++ b/tools/hangar/__snapshots__/test_corpus/valid/capture_resource_and_data.w_compile_tf-aws.md @@ -12,9 +12,9 @@ module.exports = function({ data, res, queue }) { async $inflight_init() { } async handle() { - {((cond) => {if (!cond) throw new Error(`assertion failed: '(data.size === 3)'`)})((data.size === 3))}; + {((cond) => {if (!cond) throw new Error("assertion failed: data.size == 3")})((data.size === 3))}; (await res.put("file.txt","world")); - {((cond) => {if (!cond) throw new Error(`assertion failed: '((await res.get("file.txt")) === "world")'`)})(((await res.get("file.txt")) === "world"))}; + {((cond) => {if (!cond) throw new Error("assertion failed: res.get(\"file.txt\") == \"world\"")})(((await res.get("file.txt")) === "world"))}; (await queue.push("spirulina")); } } diff --git a/tools/hangar/__snapshots__/test_corpus/valid/capture_resource_and_data.w_test_sim.md b/tools/hangar/__snapshots__/test_corpus/valid/capture_resource_and_data.w_test_sim.md index fdb4a5c37f0..842ee956b19 100644 --- a/tools/hangar/__snapshots__/test_corpus/valid/capture_resource_and_data.w_test_sim.md +++ b/tools/hangar/__snapshots__/test_corpus/valid/capture_resource_and_data.w_test_sim.md @@ -4,12 +4,9 @@ ```log pass โ”€ capture_resource_and_data.wsim ยป root/env0/test:resource and data - - - - -Tests 1 passed (1) + +Tests 1 passed (1) +Test Files 1 passed (1) Duration - ``` diff --git a/tools/hangar/__snapshots__/test_corpus/valid/capture_resource_with_no_inflight.w_compile_tf-aws.md b/tools/hangar/__snapshots__/test_corpus/valid/capture_resource_with_no_inflight.w_compile_tf-aws.md index 7073ab4ca05..888ca6de894 100644 --- a/tools/hangar/__snapshots__/test_corpus/valid/capture_resource_with_no_inflight.w_compile_tf-aws.md +++ b/tools/hangar/__snapshots__/test_corpus/valid/capture_resource_with_no_inflight.w_compile_tf-aws.md @@ -12,7 +12,7 @@ module.exports = function({ a }) { async $inflight_init() { } async handle() { - {((cond) => {if (!cond) throw new Error(`assertion failed: '("hey" === a.field)'`)})(("hey" === a.field))}; + {((cond) => {if (!cond) throw new Error("assertion failed: \"hey\" == a.field")})(("hey" === a.field))}; } } return $Closure1; diff --git a/tools/hangar/__snapshots__/test_corpus/valid/capture_resource_with_no_inflight.w_test_sim.md b/tools/hangar/__snapshots__/test_corpus/valid/capture_resource_with_no_inflight.w_test_sim.md index 77378901eed..68f9e86c622 100644 --- a/tools/hangar/__snapshots__/test_corpus/valid/capture_resource_with_no_inflight.w_test_sim.md +++ b/tools/hangar/__snapshots__/test_corpus/valid/capture_resource_with_no_inflight.w_test_sim.md @@ -4,12 +4,9 @@ ```log pass โ”€ capture_resource_with_no_inflight.wsim ยป root/env0/test:test - - - - -Tests 1 passed (1) + +Tests 1 passed (1) +Test Files 1 passed (1) Duration - ``` diff --git a/tools/hangar/__snapshots__/test_corpus/valid/capture_tokens.w_compile_tf-aws.md b/tools/hangar/__snapshots__/test_corpus/valid/capture_tokens.w_compile_tf-aws.md index 3a1e9855049..7aa0778b16b 100644 --- a/tools/hangar/__snapshots__/test_corpus/valid/capture_tokens.w_compile_tf-aws.md +++ b/tools/hangar/__snapshots__/test_corpus/valid/capture_tokens.w_compile_tf-aws.md @@ -32,8 +32,8 @@ module.exports = function({ url, api, MyResource }) { async $inflight_init() { } async handle() { - {((cond) => {if (!cond) throw new Error(`assertion failed: '(await MyResource.isValidUrl(url))'`)})((await MyResource.isValidUrl(url)))}; - {((cond) => {if (!cond) throw new Error(`assertion failed: '(await MyResource.isValidUrl(api.url))'`)})((await MyResource.isValidUrl(api.url)))}; + {((cond) => {if (!cond) throw new Error("assertion failed: MyResource.isValidUrl(url)")})((await MyResource.isValidUrl(url)))}; + {((cond) => {if (!cond) throw new Error("assertion failed: MyResource.isValidUrl(api.url)")})((await MyResource.isValidUrl(api.url)))}; } } return $Closure2; @@ -55,8 +55,8 @@ module.exports = function({ }) { return (require("/url_utils.js")["isValidUrl"])(url) } async foo() { - {((cond) => {if (!cond) throw new Error(`assertion failed: '(await MyResource.isValidUrl(this.url))'`)})((await MyResource.isValidUrl(this.url)))}; - {((cond) => {if (!cond) throw new Error(`assertion failed: '(await MyResource.isValidUrl(this.api.url))'`)})((await MyResource.isValidUrl(this.api.url)))}; + {((cond) => {if (!cond) throw new Error("assertion failed: MyResource.isValidUrl(this.url)")})((await MyResource.isValidUrl(this.url)))}; + {((cond) => {if (!cond) throw new Error("assertion failed: MyResource.isValidUrl(this.api.url)")})((await MyResource.isValidUrl(this.api.url)))}; } } return MyResource; diff --git a/tools/hangar/__snapshots__/test_corpus/valid/capture_tokens.w_test_sim.md b/tools/hangar/__snapshots__/test_corpus/valid/capture_tokens.w_test_sim.md index a73247ab3c5..65e7b9179fb 100644 --- a/tools/hangar/__snapshots__/test_corpus/valid/capture_tokens.w_test_sim.md +++ b/tools/hangar/__snapshots__/test_corpus/valid/capture_tokens.w_test_sim.md @@ -5,12 +5,9 @@ pass โ”€ capture_tokens.wsim ยป root/env0/test:inflight class pass โ”€ capture_tokens.wsim ยป root/env1/test:inflight globals - - - - -Tests 1 passed (1) + +Tests 2 passed (2) +Test Files 1 passed (1) Duration - ``` diff --git a/tools/hangar/__snapshots__/test_corpus/valid/captures.w_test_sim.md b/tools/hangar/__snapshots__/test_corpus/valid/captures.w_test_sim.md index 6c4e27d6fc4..43ccb8111da 100644 --- a/tools/hangar/__snapshots__/test_corpus/valid/captures.w_test_sim.md +++ b/tools/hangar/__snapshots__/test_corpus/valid/captures.w_test_sim.md @@ -4,12 +4,9 @@ ```log pass โ”€ captures.wsim (no tests) - - - - -Tests 1 passed (1) + +Tests 1 passed (1) +Test Files 1 passed (1) Duration - ``` diff --git a/tools/hangar/__snapshots__/test_corpus/valid/class.w_compile_tf-aws.md b/tools/hangar/__snapshots__/test_corpus/valid/class.w_compile_tf-aws.md index 2e442249f03..e9a6443e57e 100644 --- a/tools/hangar/__snapshots__/test_corpus/valid/class.w_compile_tf-aws.md +++ b/tools/hangar/__snapshots__/test_corpus/valid/class.w_compile_tf-aws.md @@ -12,10 +12,10 @@ module.exports = function({ c5 }) { async $inflight_init() { } async handle() { - {((cond) => {if (!cond) throw new Error(`assertion failed: '(c5.x === 123)'`)})((c5.x === 123))}; - {((cond) => {if (!cond) throw new Error(`assertion failed: '(c5.y === 321)'`)})((c5.y === 321))}; + {((cond) => {if (!cond) throw new Error("assertion failed: c5.x == 123")})((c5.x === 123))}; + {((cond) => {if (!cond) throw new Error("assertion failed: c5.y == 321")})((c5.y === 321))}; (await c5.set(111)); - {((cond) => {if (!cond) throw new Error(`assertion failed: '(c5.y === 111)'`)})((c5.y === 111))}; + {((cond) => {if (!cond) throw new Error("assertion failed: c5.y == 111")})((c5.y === 111))}; } } return $Closure1; @@ -35,9 +35,9 @@ module.exports = function({ student }) { async $inflight_init() { } async handle() { - {((cond) => {if (!cond) throw new Error(`assertion failed: '(student.name === "Tom")'`)})((student.name === "Tom"))}; - {((cond) => {if (!cond) throw new Error(`assertion failed: '(student.major === "MySpace")'`)})((student.major === "MySpace"))}; - {((cond) => {if (!cond) throw new Error(`assertion failed: '(student.hrlyWage === 38)'`)})((student.hrlyWage === 38))}; + {((cond) => {if (!cond) throw new Error("assertion failed: student.name == \"Tom\"")})((student.name === "Tom"))}; + {((cond) => {if (!cond) throw new Error("assertion failed: student.major == \"MySpace\"")})((student.major === "MySpace"))}; + {((cond) => {if (!cond) throw new Error("assertion failed: student.hrlyWage == 38")})((student.hrlyWage === 38))}; } } return $Closure2; @@ -57,7 +57,7 @@ module.exports = function({ ta }) { async $inflight_init() { } async handle() { - {((cond) => {if (!cond) throw new Error(`assertion failed: '(ta.hrlyWage === 10)'`)})((ta.hrlyWage === 10))}; + {((cond) => {if (!cond) throw new Error("assertion failed: ta.hrlyWage == 10")})((ta.hrlyWage === 10))}; } } return $Closure3; @@ -78,7 +78,7 @@ module.exports = function({ B }) { } async handle() { const b = new B("ba"); - {((cond) => {if (!cond) throw new Error(`assertion failed: '(b.sound === "ba")'`)})((b.sound === "ba"))}; + {((cond) => {if (!cond) throw new Error("assertion failed: b.sound == \"ba\"")})((b.sound === "ba"))}; } } return $Closure4; @@ -1095,11 +1095,11 @@ class $Root extends $stdlib.std.Resource { } new C1(this,"C1"); const c2 = new C2(this,"C2"); - {((cond) => {if (!cond) throw new Error(`assertion failed: '(c2.x === 1)'`)})((c2.x === 1))}; + {((cond) => {if (!cond) throw new Error("assertion failed: c2.x == 1")})((c2.x === 1))}; const c3 = new C3(this,"C3",1,2); - {((cond) => {if (!cond) throw new Error(`assertion failed: '(c3.x === 1)'`)})((c3.x === 1))}; - {((cond) => {if (!cond) throw new Error(`assertion failed: '(c3.y === 2)'`)})((c3.y === 2))}; - {((cond) => {if (!cond) throw new Error(`assertion failed: '((C4.m()) === 1)'`)})(((C4.m()) === 1))}; + {((cond) => {if (!cond) throw new Error("assertion failed: c3.x == 1")})((c3.x === 1))}; + {((cond) => {if (!cond) throw new Error("assertion failed: c3.y == 2")})((c3.y === 2))}; + {((cond) => {if (!cond) throw new Error("assertion failed: C4.m() == 1")})(((C4.m()) === 1))}; const c5 = new C5(this,"C5"); this.node.root.new("@winglang/sdk.std.Test",std.Test,this,"test:access inflight field",new $Closure1(this,"$Closure1")); const student = new PaidStudent(this,"PaidStudent","Tom","MySpace",38); diff --git a/tools/hangar/__snapshots__/test_corpus/valid/class.w_test_sim.md b/tools/hangar/__snapshots__/test_corpus/valid/class.w_test_sim.md index e22d58eba1e..69a62627c6a 100644 --- a/tools/hangar/__snapshots__/test_corpus/valid/class.w_test_sim.md +++ b/tools/hangar/__snapshots__/test_corpus/valid/class.w_test_sim.md @@ -7,12 +7,9 @@ pass โ”€ class.wsim ยป root/env1/test:check derived class instance variables pass โ”€ class.wsim ยป root/env2/test:devived class init body happens after super pass โ”€ class.wsim ยป root/env3/test:inflight super constructor - - - - -Tests 1 passed (1) + +Tests 4 passed (4) +Test Files 1 passed (1) Duration - ``` diff --git a/tools/hangar/__snapshots__/test_corpus/valid/construct-base.w_compile_tf-aws.md b/tools/hangar/__snapshots__/test_corpus/valid/construct-base.w_compile_tf-aws.md index 0c6d0d49744..34bf1615612 100644 --- a/tools/hangar/__snapshots__/test_corpus/valid/construct-base.w_compile_tf-aws.md +++ b/tools/hangar/__snapshots__/test_corpus/valid/construct-base.w_compile_tf-aws.md @@ -74,7 +74,7 @@ class $Root extends $stdlib.std.Resource { class WingResource extends $stdlib.std.Resource { constructor(scope, id, ) { super(scope, id); - {console.log(`my id is ${this.node.id}`)}; + {console.log(String.raw({ raw: ["my id is ", ""] }, this.node.id))}; } static _toInflightType(context) { const self_client_path = "././inflight.WingResource.js"; @@ -111,10 +111,10 @@ class $Root extends $stdlib.std.Resource { const q = this.node.root.new("@cdktf/provider-aws.sqsQueue.SqsQueue",aws.sqsQueue.SqsQueue,this,"aws.sqsQueue.SqsQueue"); const wr = new WingResource(this,"WingResource"); const another_resource = wr; - {console.log(`path of sqs.queue: ${(getPath(q))}`)}; - {console.log(`path of wing resource: ${(getPath(wr))}`)}; + {console.log(String.raw({ raw: ["path of sqs.queue: ", ""] }, (getPath(q))))}; + {console.log(String.raw({ raw: ["path of wing resource: ", ""] }, (getPath(wr))))}; const title = ((getDisplayName(wr)) ?? "no display name"); - {console.log(`display name of wing resource: ${title}`)}; + {console.log(String.raw({ raw: ["display name of wing resource: ", ""] }, title))}; } } class $App extends $AppBase { diff --git a/tools/hangar/__snapshots__/test_corpus/valid/construct-base.w_test_sim.md b/tools/hangar/__snapshots__/test_corpus/valid/construct-base.w_test_sim.md index 782ece463ae..a46c3022090 100644 --- a/tools/hangar/__snapshots__/test_corpus/valid/construct-base.w_test_sim.md +++ b/tools/hangar/__snapshots__/test_corpus/valid/construct-base.w_test_sim.md @@ -8,12 +8,9 @@ path of wing resource: root/env0/WingResource display name of wing resource: no display name pass โ”€ construct-base.wsim (no tests) - - - - -Tests 1 passed (1) + +Tests 1 passed (1) +Test Files 1 passed (1) Duration - ``` diff --git a/tools/hangar/__snapshots__/test_corpus/valid/container_types.w_compile_tf-aws.md b/tools/hangar/__snapshots__/test_corpus/valid/container_types.w_compile_tf-aws.md index 6eabcba47d0..00878deee0b 100644 --- a/tools/hangar/__snapshots__/test_corpus/valid/container_types.w_compile_tf-aws.md +++ b/tools/hangar/__snapshots__/test_corpus/valid/container_types.w_compile_tf-aws.md @@ -172,102 +172,102 @@ class $Root extends $stdlib.std.Resource { const bucket2 = this.node.root.newAbstract("@winglang/sdk.cloud.Bucket",this,"bucket2"); const bucket3 = this.node.root.newAbstract("@winglang/sdk.cloud.Bucket",this,"bucket3"); const emptyArray = Object.freeze([]); - {((cond) => {if (!cond) throw new Error(`assertion failed: '(emptyArray.length === 0)'`)})((emptyArray.length === 0))}; + {((cond) => {if (!cond) throw new Error("assertion failed: emptyArray.length == 0")})((emptyArray.length === 0))}; const emptyArray2 = []; - {((cond) => {if (!cond) throw new Error(`assertion failed: '(emptyArray2.length === 0)'`)})((emptyArray2.length === 0))}; + {((cond) => {if (!cond) throw new Error("assertion failed: emptyArray2.length == 0")})((emptyArray2.length === 0))}; const arr1 = Object.freeze([1, 2, 3]); - {((cond) => {if (!cond) throw new Error(`assertion failed: '(arr1.length === 3)'`)})((arr1.length === 3))}; - {((cond) => {if (!cond) throw new Error(`assertion failed: '((arr1.at(1)) === 2)'`)})(((arr1.at(1)) === 2))}; + {((cond) => {if (!cond) throw new Error("assertion failed: arr1.length == 3")})((arr1.length === 3))}; + {((cond) => {if (!cond) throw new Error("assertion failed: arr1.at(1) == 2")})(((arr1.at(1)) === 2))}; const arr2 = Object.freeze(["1", "2", "3"]); - {((cond) => {if (!cond) throw new Error(`assertion failed: '(arr2.length === 3)'`)})((arr2.length === 3))}; - {((cond) => {if (!cond) throw new Error(`assertion failed: '((arr2.at(1)) === "2")'`)})(((arr2.at(1)) === "2"))}; + {((cond) => {if (!cond) throw new Error("assertion failed: arr2.length == 3")})((arr2.length === 3))}; + {((cond) => {if (!cond) throw new Error("assertion failed: arr2.at(1) == \"2\"")})(((arr2.at(1)) === "2"))}; const arr3 = Object.freeze([1, 2, 3]); - {((cond) => {if (!cond) throw new Error(`assertion failed: '(arr3.length === 3)'`)})((arr3.length === 3))}; - {((cond) => {if (!cond) throw new Error(`assertion failed: '((arr3.at(1)) === 2)'`)})(((arr3.at(1)) === 2))}; + {((cond) => {if (!cond) throw new Error("assertion failed: arr3.length == 3")})((arr3.length === 3))}; + {((cond) => {if (!cond) throw new Error("assertion failed: arr3.at(1) == 2")})(((arr3.at(1)) === 2))}; const arr4 = Object.freeze([1, 2, 3]); - {((cond) => {if (!cond) throw new Error(`assertion failed: '(arr4.length === 3)'`)})((arr4.length === 3))}; - {((cond) => {if (!cond) throw new Error(`assertion failed: '((arr4.at(1)) === 2)'`)})(((arr4.at(1)) === 2))}; + {((cond) => {if (!cond) throw new Error("assertion failed: arr4.length == 3")})((arr4.length === 3))}; + {((cond) => {if (!cond) throw new Error("assertion failed: arr4.at(1) == 2")})(((arr4.at(1)) === 2))}; const arr5 = Object.freeze([bucket1, bucket2, bucket3]); - {((cond) => {if (!cond) throw new Error(`assertion failed: '(arr5.length === 3)'`)})((arr5.length === 3))}; - {((cond) => {if (!cond) throw new Error(`assertion failed: '((arr5.at(1)) === bucket2)'`)})(((arr5.at(1)) === bucket2))}; + {((cond) => {if (!cond) throw new Error("assertion failed: arr5.length == 3")})((arr5.length === 3))}; + {((cond) => {if (!cond) throw new Error("assertion failed: arr5.at(1) == bucket2")})(((arr5.at(1)) === bucket2))}; const arr6 = Object.freeze([bucket1, bucket2, bucket3]); - {((cond) => {if (!cond) throw new Error(`assertion failed: '(arr6.length === 3)'`)})((arr6.length === 3))}; - {((cond) => {if (!cond) throw new Error(`assertion failed: '((arr6.at(1)) === bucket2)'`)})(((arr6.at(1)) === bucket2))}; + {((cond) => {if (!cond) throw new Error("assertion failed: arr6.length == 3")})((arr6.length === 3))}; + {((cond) => {if (!cond) throw new Error("assertion failed: arr6.at(1) == bucket2")})(((arr6.at(1)) === bucket2))}; const arr7 = arr4; - {((cond) => {if (!cond) throw new Error(`assertion failed: '(arr7.length === 3)'`)})((arr7.length === 3))}; - {((cond) => {if (!cond) throw new Error(`assertion failed: '((arr7.at(1)) === 2)'`)})(((arr7.at(1)) === 2))}; + {((cond) => {if (!cond) throw new Error("assertion failed: arr7.length == 3")})((arr7.length === 3))}; + {((cond) => {if (!cond) throw new Error("assertion failed: arr7.at(1) == 2")})(((arr7.at(1)) === 2))}; const emptyMap = Object.freeze({}); - {((cond) => {if (!cond) throw new Error(`assertion failed: '(Object.keys(emptyMap).length === 0)'`)})((Object.keys(emptyMap).length === 0))}; + {((cond) => {if (!cond) throw new Error("assertion failed: emptyMap.size() == 0")})((Object.keys(emptyMap).length === 0))}; const emptyMap2 = {}; - {((cond) => {if (!cond) throw new Error(`assertion failed: '(Object.keys(emptyMap2).length === 0)'`)})((Object.keys(emptyMap2).length === 0))}; + {((cond) => {if (!cond) throw new Error("assertion failed: emptyMap2.size() == 0")})((Object.keys(emptyMap2).length === 0))}; const m1 = Object.freeze({"a":1,"b":2,"c":3}); - {((cond) => {if (!cond) throw new Error(`assertion failed: '(Object.keys(m1).length === 3)'`)})((Object.keys(m1).length === 3))}; - {((cond) => {if (!cond) throw new Error(`assertion failed: '((m1)["b"] === 2)'`)})(((m1)["b"] === 2))}; + {((cond) => {if (!cond) throw new Error("assertion failed: m1.size() == 3")})((Object.keys(m1).length === 3))}; + {((cond) => {if (!cond) throw new Error("assertion failed: m1.get(\"b\") == 2")})(((m1)["b"] === 2))}; const m2 = Object.freeze({"a":1,"b":2,"c":3}); - {((cond) => {if (!cond) throw new Error(`assertion failed: '(Object.keys(m2).length === 3)'`)})((Object.keys(m2).length === 3))}; - {((cond) => {if (!cond) throw new Error(`assertion failed: '((m2)["b"] === 2)'`)})(((m2)["b"] === 2))}; + {((cond) => {if (!cond) throw new Error("assertion failed: m2.size() == 3")})((Object.keys(m2).length === 3))}; + {((cond) => {if (!cond) throw new Error("assertion failed: m2.get(\"b\") == 2")})(((m2)["b"] === 2))}; const m3 = Object.freeze({"a":1,"b":2,"c":3}); - {((cond) => {if (!cond) throw new Error(`assertion failed: '(Object.keys(m3).length === 3)'`)})((Object.keys(m3).length === 3))}; - {((cond) => {if (!cond) throw new Error(`assertion failed: '((m3)["b"] === 2)'`)})(((m3)["b"] === 2))}; + {((cond) => {if (!cond) throw new Error("assertion failed: m3.size() == 3")})((Object.keys(m3).length === 3))}; + {((cond) => {if (!cond) throw new Error("assertion failed: m3.get(\"b\") == 2")})(((m3)["b"] === 2))}; const m4 = Object.freeze({"a":1,"b":2,"c":3}); - {((cond) => {if (!cond) throw new Error(`assertion failed: '(Object.keys(m4).length === 3)'`)})((Object.keys(m4).length === 3))}; - {((cond) => {if (!cond) throw new Error(`assertion failed: '((m4)["b"] === 2)'`)})(((m4)["b"] === 2))}; + {((cond) => {if (!cond) throw new Error("assertion failed: m4.size() == 3")})((Object.keys(m4).length === 3))}; + {((cond) => {if (!cond) throw new Error("assertion failed: m4.get(\"b\") == 2")})(((m4)["b"] === 2))}; const m5 = Object.freeze({"a":bucket1,"b":bucket2,"c":bucket3}); - {((cond) => {if (!cond) throw new Error(`assertion failed: '(Object.keys(m5).length === 3)'`)})((Object.keys(m5).length === 3))}; - {((cond) => {if (!cond) throw new Error(`assertion failed: '((m5)["b"] === bucket2)'`)})(((m5)["b"] === bucket2))}; + {((cond) => {if (!cond) throw new Error("assertion failed: m5.size() == 3")})((Object.keys(m5).length === 3))}; + {((cond) => {if (!cond) throw new Error("assertion failed: m5.get(\"b\") == bucket2")})(((m5)["b"] === bucket2))}; const m6 = Object.freeze({"a":bucket1,"b":bucket2,"c":bucket3}); - {((cond) => {if (!cond) throw new Error(`assertion failed: '(Object.keys(m6).length === 3)'`)})((Object.keys(m6).length === 3))}; - {((cond) => {if (!cond) throw new Error(`assertion failed: '((m6)["b"] === bucket2)'`)})(((m6)["b"] === bucket2))}; + {((cond) => {if (!cond) throw new Error("assertion failed: m6.size() == 3")})((Object.keys(m6).length === 3))}; + {((cond) => {if (!cond) throw new Error("assertion failed: m6.get(\"b\") == bucket2")})(((m6)["b"] === bucket2))}; const m7 = m1; - {((cond) => {if (!cond) throw new Error(`assertion failed: '(Object.keys(m7).length === 3)'`)})((Object.keys(m7).length === 3))}; - {((cond) => {if (!cond) throw new Error(`assertion failed: '((m7)["b"] === 2)'`)})(((m7)["b"] === 2))}; - {((cond) => {if (!cond) throw new Error(`assertion failed: '("b" in (m7))'`)})(("b" in (m7)))}; - {((cond) => {if (!cond) throw new Error(`assertion failed: '(("boom" in (m4)) === false)'`)})((("boom" in (m4)) === false))}; + {((cond) => {if (!cond) throw new Error("assertion failed: m7.size() == 3")})((Object.keys(m7).length === 3))}; + {((cond) => {if (!cond) throw new Error("assertion failed: m7.get(\"b\") == 2")})(((m7)["b"] === 2))}; + {((cond) => {if (!cond) throw new Error("assertion failed: m7.has(\"b\")")})(("b" in (m7)))}; + {((cond) => {if (!cond) throw new Error("assertion failed: m4.has(\"boom\") == false")})((("boom" in (m4)) === false))}; const m8 = Object.freeze({"a":"a1","b":"b1","c":"c1"}); - {((cond) => {if (!cond) throw new Error(`assertion failed: '((Object.keys(m8).at(0)) === "a")'`)})(((Object.keys(m8).at(0)) === "a"))}; - {((cond) => {if (!cond) throw new Error(`assertion failed: '((Object.keys(m8).at(1)) === "b")'`)})(((Object.keys(m8).at(1)) === "b"))}; - {((cond) => {if (!cond) throw new Error(`assertion failed: '((Object.keys(m8).at(2)) === "c")'`)})(((Object.keys(m8).at(2)) === "c"))}; - {((cond) => {if (!cond) throw new Error(`assertion failed: '((Object.values(m8).at(0)) === "a1")'`)})(((Object.values(m8).at(0)) === "a1"))}; - {((cond) => {if (!cond) throw new Error(`assertion failed: '((Object.values(m8).at(1)) === "b1")'`)})(((Object.values(m8).at(1)) === "b1"))}; - {((cond) => {if (!cond) throw new Error(`assertion failed: '((Object.values(m8).at(2)) === "c1")'`)})(((Object.values(m8).at(2)) === "c1"))}; + {((cond) => {if (!cond) throw new Error("assertion failed: m8.keys().at(0) == \"a\"")})(((Object.keys(m8).at(0)) === "a"))}; + {((cond) => {if (!cond) throw new Error("assertion failed: m8.keys().at(1) == \"b\"")})(((Object.keys(m8).at(1)) === "b"))}; + {((cond) => {if (!cond) throw new Error("assertion failed: m8.keys().at(2) == \"c\"")})(((Object.keys(m8).at(2)) === "c"))}; + {((cond) => {if (!cond) throw new Error("assertion failed: m8.values().at(0) == \"a1\"")})(((Object.values(m8).at(0)) === "a1"))}; + {((cond) => {if (!cond) throw new Error("assertion failed: m8.values().at(1) == \"b1\"")})(((Object.values(m8).at(1)) === "b1"))}; + {((cond) => {if (!cond) throw new Error("assertion failed: m8.values().at(2) == \"c1\"")})(((Object.values(m8).at(2)) === "c1"))}; for (const val of Object.keys(m8)) { - {((cond) => {if (!cond) throw new Error(`assertion failed: '(!val.endsWith("1"))'`)})((!val.endsWith("1")))}; + {((cond) => {if (!cond) throw new Error("assertion failed: !val.endsWith(\"1\")")})((!val.endsWith("1")))}; } for (const val of Object.values(m8)) { - {((cond) => {if (!cond) throw new Error(`assertion failed: 'val.endsWith("1")'`)})(val.endsWith("1"))}; + {((cond) => {if (!cond) throw new Error("assertion failed: val.endsWith(\"1\")")})(val.endsWith("1"))}; } const m9 = {"a":"a1","b":"b1","c":"c1"}; - {((cond) => {if (!cond) throw new Error(`assertion failed: '((Object.keys(m9).at(0)) === "a")'`)})(((Object.keys(m9).at(0)) === "a"))}; - {((cond) => {if (!cond) throw new Error(`assertion failed: '((Object.keys(m9).at(1)) === "b")'`)})(((Object.keys(m9).at(1)) === "b"))}; - {((cond) => {if (!cond) throw new Error(`assertion failed: '((Object.keys(m9).at(2)) === "c")'`)})(((Object.keys(m9).at(2)) === "c"))}; - {((cond) => {if (!cond) throw new Error(`assertion failed: '((Object.values(m9).at(0)) === "a1")'`)})(((Object.values(m9).at(0)) === "a1"))}; - {((cond) => {if (!cond) throw new Error(`assertion failed: '((Object.values(m9).at(1)) === "b1")'`)})(((Object.values(m9).at(1)) === "b1"))}; - {((cond) => {if (!cond) throw new Error(`assertion failed: '((Object.values(m9).at(2)) === "c1")'`)})(((Object.values(m9).at(2)) === "c1"))}; + {((cond) => {if (!cond) throw new Error("assertion failed: m9.keys().at(0) == \"a\"")})(((Object.keys(m9).at(0)) === "a"))}; + {((cond) => {if (!cond) throw new Error("assertion failed: m9.keys().at(1) == \"b\"")})(((Object.keys(m9).at(1)) === "b"))}; + {((cond) => {if (!cond) throw new Error("assertion failed: m9.keys().at(2) == \"c\"")})(((Object.keys(m9).at(2)) === "c"))}; + {((cond) => {if (!cond) throw new Error("assertion failed: m9.values().at(0) == \"a1\"")})(((Object.values(m9).at(0)) === "a1"))}; + {((cond) => {if (!cond) throw new Error("assertion failed: m9.values().at(1) == \"b1\"")})(((Object.values(m9).at(1)) === "b1"))}; + {((cond) => {if (!cond) throw new Error("assertion failed: m9.values().at(2) == \"c1\"")})(((Object.values(m9).at(2)) === "c1"))}; for (const val of Object.keys(m9)) { - {((cond) => {if (!cond) throw new Error(`assertion failed: '(!val.endsWith("1"))'`)})((!val.endsWith("1")))}; + {((cond) => {if (!cond) throw new Error("assertion failed: !val.endsWith(\"1\")")})((!val.endsWith("1")))}; } for (const val of Object.values(m9)) { - {((cond) => {if (!cond) throw new Error(`assertion failed: 'val.endsWith("1")'`)})(val.endsWith("1"))}; + {((cond) => {if (!cond) throw new Error("assertion failed: val.endsWith(\"1\")")})(val.endsWith("1"))}; } const emptySet = Object.freeze(new Set([])); - {((cond) => {if (!cond) throw new Error(`assertion failed: '(emptySet.size === 0)'`)})((emptySet.size === 0))}; + {((cond) => {if (!cond) throw new Error("assertion failed: emptySet.size == 0")})((emptySet.size === 0))}; const emptySet2 = new Set([]); - {((cond) => {if (!cond) throw new Error(`assertion failed: '(emptySet2.size === 0)'`)})((emptySet2.size === 0))}; + {((cond) => {if (!cond) throw new Error("assertion failed: emptySet2.size == 0")})((emptySet2.size === 0))}; const s2 = Object.freeze(new Set([1, 2, 3])); - {((cond) => {if (!cond) throw new Error(`assertion failed: '(s2.size === 3)'`)})((s2.size === 3))}; - {((cond) => {if (!cond) throw new Error(`assertion failed: '(s2.has(1))'`)})((s2.has(1)))}; + {((cond) => {if (!cond) throw new Error("assertion failed: s2.size == 3")})((s2.size === 3))}; + {((cond) => {if (!cond) throw new Error("assertion failed: s2.has(1)")})((s2.has(1)))}; const s3 = Object.freeze(new Set([1, 2, 3])); - {((cond) => {if (!cond) throw new Error(`assertion failed: '(s3.size === 3)'`)})((s3.size === 3))}; - {((cond) => {if (!cond) throw new Error(`assertion failed: '(s3.has(1))'`)})((s3.has(1)))}; + {((cond) => {if (!cond) throw new Error("assertion failed: s3.size == 3")})((s3.size === 3))}; + {((cond) => {if (!cond) throw new Error("assertion failed: s3.has(1)")})((s3.has(1)))}; const s4 = Object.freeze(new Set([1, 2, 3])); - {((cond) => {if (!cond) throw new Error(`assertion failed: '(s4.size === 3)'`)})((s4.size === 3))}; - {((cond) => {if (!cond) throw new Error(`assertion failed: '(s4.has(1))'`)})((s4.has(1)))}; + {((cond) => {if (!cond) throw new Error("assertion failed: s4.size == 3")})((s4.size === 3))}; + {((cond) => {if (!cond) throw new Error("assertion failed: s4.has(1)")})((s4.has(1)))}; const s6 = Object.freeze(new Set([bucket1, bucket2, bucket3])); - {((cond) => {if (!cond) throw new Error(`assertion failed: '(s6.size === 3)'`)})((s6.size === 3))}; - {((cond) => {if (!cond) throw new Error(`assertion failed: '(s6.has(bucket2))'`)})((s6.has(bucket2)))}; + {((cond) => {if (!cond) throw new Error("assertion failed: s6.size == 3")})((s6.size === 3))}; + {((cond) => {if (!cond) throw new Error("assertion failed: s6.has(bucket2)")})((s6.has(bucket2)))}; const s7 = s2; - {((cond) => {if (!cond) throw new Error(`assertion failed: '(s7.size === 3)'`)})((s7.size === 3))}; - {((cond) => {if (!cond) throw new Error(`assertion failed: '(s7.has(1))'`)})((s7.has(1)))}; + {((cond) => {if (!cond) throw new Error("assertion failed: s7.size == 3")})((s7.size === 3))}; + {((cond) => {if (!cond) throw new Error("assertion failed: s7.has(1)")})((s7.has(1)))}; } } class $App extends $AppBase { diff --git a/tools/hangar/__snapshots__/test_corpus/valid/container_types.w_test_sim.md b/tools/hangar/__snapshots__/test_corpus/valid/container_types.w_test_sim.md index 8e491d8d2d0..307bed04d70 100644 --- a/tools/hangar/__snapshots__/test_corpus/valid/container_types.w_test_sim.md +++ b/tools/hangar/__snapshots__/test_corpus/valid/container_types.w_test_sim.md @@ -4,12 +4,9 @@ ```log pass โ”€ container_types.wsim (no tests) - - - - -Tests 1 passed (1) + +Tests 1 passed (1) +Test Files 1 passed (1) Duration - ``` diff --git a/tools/hangar/__snapshots__/test_corpus/valid/debug_env.w_test_sim.md b/tools/hangar/__snapshots__/test_corpus/valid/debug_env.w_test_sim.md index 087f85b712e..43946a08247 100644 --- a/tools/hangar/__snapshots__/test_corpus/valid/debug_env.w_test_sim.md +++ b/tools/hangar/__snapshots__/test_corpus/valid/debug_env.w_test_sim.md @@ -7,12 +7,9 @@ level 0: { this => A } level 1: { A => A [type], assert => (condition: bool): void, cloud => cloud [namespace], log => (message: str): void, panic => (message: str): void, std => std [namespace], throw => (message: str): void } pass โ”€ debug_env.wsim (no tests) - - - - -Tests 1 passed (1) + +Tests 1 passed (1) +Test Files 1 passed (1) Duration - ``` diff --git a/tools/hangar/__snapshots__/test_corpus/valid/doubler.w_compile_tf-aws.md b/tools/hangar/__snapshots__/test_corpus/valid/doubler.w_compile_tf-aws.md index d7d46f3a99b..9fbf33d3264 100644 --- a/tools/hangar/__snapshots__/test_corpus/valid/doubler.w_compile_tf-aws.md +++ b/tools/hangar/__snapshots__/test_corpus/valid/doubler.w_compile_tf-aws.md @@ -12,7 +12,7 @@ module.exports = function({ }) { async $inflight_init() { } async handle(m) { - return `Hello ${m}!`; + return String.raw({ raw: ["Hello ", "!"] }, m); } } return $Closure1; @@ -76,7 +76,7 @@ module.exports = function({ f }) { } async handle() { const result = (await f.invoke("2")); - {((cond) => {if (!cond) throw new Error(`assertion failed: '(result === "8")'`)})((result === "8"))}; + {((cond) => {if (!cond) throw new Error("assertion failed: result == \"8\"")})((result === "8"))}; } } return $Closure4; diff --git a/tools/hangar/__snapshots__/test_corpus/valid/doubler.w_test_sim.md b/tools/hangar/__snapshots__/test_corpus/valid/doubler.w_test_sim.md index 41ec6b7c3e9..86cd7a0bb99 100644 --- a/tools/hangar/__snapshots__/test_corpus/valid/doubler.w_test_sim.md +++ b/tools/hangar/__snapshots__/test_corpus/valid/doubler.w_test_sim.md @@ -4,12 +4,9 @@ ```log pass โ”€ doubler.wsim ยป root/env0/test:f(2) == 8 - - - - -Tests 1 passed (1) + +Tests 1 passed (1) +Test Files 1 passed (1) Duration - ``` diff --git a/tools/hangar/__snapshots__/test_corpus/valid/enums.w_test_sim.md b/tools/hangar/__snapshots__/test_corpus/valid/enums.w_test_sim.md index 2edf5223ae9..de8b9baefae 100644 --- a/tools/hangar/__snapshots__/test_corpus/valid/enums.w_test_sim.md +++ b/tools/hangar/__snapshots__/test_corpus/valid/enums.w_test_sim.md @@ -4,12 +4,9 @@ ```log pass โ”€ enums.wsim (no tests) - - - - -Tests 1 passed (1) + +Tests 1 passed (1) +Test Files 1 passed (1) Duration - ``` diff --git a/tools/hangar/__snapshots__/test_corpus/valid/expressions_binary_operators.w_compile_tf-aws.md b/tools/hangar/__snapshots__/test_corpus/valid/expressions_binary_operators.w_compile_tf-aws.md index 86cc3e0db9c..1ff9033fd11 100644 --- a/tools/hangar/__snapshots__/test_corpus/valid/expressions_binary_operators.w_compile_tf-aws.md +++ b/tools/hangar/__snapshots__/test_corpus/valid/expressions_binary_operators.w_compile_tf-aws.md @@ -50,15 +50,15 @@ class $Root extends $stdlib.std.Resource { const yf = ((-20.22) * xf); const zf = ((xf + yf) - (-0.01)); const fxzy = (5 ** (2 ** 3)); - {((cond) => {if (!cond) throw new Error(`assertion failed: '(fxzy === 390625)'`)})((fxzy === 390625))}; + {((cond) => {if (!cond) throw new Error("assertion failed: fxzy == 390625")})((fxzy === 390625))}; const xyzf = Math.trunc(501 / (99 + 1)); - {((cond) => {if (!cond) throw new Error(`assertion failed: '(xyzf === 5)'`)})((xyzf === 5))}; + {((cond) => {if (!cond) throw new Error("assertion failed: xyzf == 5")})((xyzf === 5))}; const xyznf = Math.trunc((-501) / (99 + 1)); - {((cond) => {if (!cond) throw new Error(`assertion failed: '(xyznf === (-5))'`)})((xyznf === (-5)))}; + {((cond) => {if (!cond) throw new Error("assertion failed: xyznf == -5")})((xyznf === (-5)))}; const xyznfj = Math.trunc(501.9 / ((-99.1) - 0.91)); - {((cond) => {if (!cond) throw new Error(`assertion failed: '(xyznfj === (-5))'`)})((xyznfj === (-5)))}; + {((cond) => {if (!cond) throw new Error("assertion failed: xyznfj == -5")})((xyznfj === (-5)))}; const xynfj = Math.trunc((-501.9) / ((-99.1) - 0.91)); - {((cond) => {if (!cond) throw new Error(`assertion failed: '(xynfj === 5)'`)})((xynfj === 5))}; + {((cond) => {if (!cond) throw new Error("assertion failed: xynfj == 5")})((xynfj === 5))}; } } class $App extends $AppBase { diff --git a/tools/hangar/__snapshots__/test_corpus/valid/expressions_binary_operators.w_test_sim.md b/tools/hangar/__snapshots__/test_corpus/valid/expressions_binary_operators.w_test_sim.md index cebf1a9751c..b8d9f4f4ef0 100644 --- a/tools/hangar/__snapshots__/test_corpus/valid/expressions_binary_operators.w_test_sim.md +++ b/tools/hangar/__snapshots__/test_corpus/valid/expressions_binary_operators.w_test_sim.md @@ -4,12 +4,9 @@ ```log pass โ”€ expressions_binary_operators.wsim (no tests) - - - - -Tests 1 passed (1) + +Tests 1 passed (1) +Test Files 1 passed (1) Duration - ``` diff --git a/tools/hangar/__snapshots__/test_corpus/valid/expressions_string_interpolation.w_compile_tf-aws.md b/tools/hangar/__snapshots__/test_corpus/valid/expressions_string_interpolation.w_compile_tf-aws.md index 021a763e06c..982e5f5e8c6 100644 --- a/tools/hangar/__snapshots__/test_corpus/valid/expressions_string_interpolation.w_compile_tf-aws.md +++ b/tools/hangar/__snapshots__/test_corpus/valid/expressions_string_interpolation.w_compile_tf-aws.md @@ -45,10 +45,10 @@ class $Root extends $stdlib.std.Resource { const regularString = "str\n\""; const emptyString = ""; const number = 1; - const coolString = `cool \"\${${regularString}}\" test`; - const reallyCoolString = `${number}${emptyString}\n${coolString}\n\${empty_string}${"string-in-string"}!`; - const beginingWithCoolStrings = `${regularString} ${number} <- cool`; - const endingWithCoolStrings = `cool -> ${regularString} ${number}`; + const coolString = String.raw({ raw: ["cool \"\${", "}\" test"] }, regularString); + const reallyCoolString = String.raw({ raw: ["", "", "\n", "\n\${empty_string}", "!"] }, number, emptyString, coolString, "string-in-string"); + const beginingWithCoolStrings = String.raw({ raw: ["", " ", " <- cool"] }, regularString, number); + const endingWithCoolStrings = String.raw({ raw: ["cool -> ", " ", ""] }, regularString, number); } } class $App extends $AppBase { diff --git a/tools/hangar/__snapshots__/test_corpus/valid/expressions_string_interpolation.w_test_sim.md b/tools/hangar/__snapshots__/test_corpus/valid/expressions_string_interpolation.w_test_sim.md index e4cb88a3093..c8d2968d5c6 100644 --- a/tools/hangar/__snapshots__/test_corpus/valid/expressions_string_interpolation.w_test_sim.md +++ b/tools/hangar/__snapshots__/test_corpus/valid/expressions_string_interpolation.w_test_sim.md @@ -4,12 +4,9 @@ ```log pass โ”€ expressions_string_interpolation.wsim (no tests) - - - - -Tests 1 passed (1) + +Tests 1 passed (1) +Test Files 1 passed (1) Duration - ``` diff --git a/tools/hangar/__snapshots__/test_corpus/valid/extern_implementation.w_compile_tf-aws.md b/tools/hangar/__snapshots__/test_corpus/valid/extern_implementation.w_compile_tf-aws.md index 8d3985a690b..902265fd63f 100644 --- a/tools/hangar/__snapshots__/test_corpus/valid/extern_implementation.w_compile_tf-aws.md +++ b/tools/hangar/__snapshots__/test_corpus/valid/extern_implementation.w_compile_tf-aws.md @@ -61,10 +61,10 @@ module.exports = function({ }) { return (require("/external_js.js")["print"])(msg) } async call() { - {((cond) => {if (!cond) throw new Error(`assertion failed: '(await Foo.regexInflight("[a-z]+-\\d+","abc-123"))'`)})((await Foo.regexInflight("[a-z]+-\\d+","abc-123")))}; + {((cond) => {if (!cond) throw new Error("assertion failed: Foo.regexInflight(\"[a-z]+-\\\\d+\", \"abc-123\")")})((await Foo.regexInflight("[a-z]+-\\d+","abc-123")))}; const uuid = (await Foo.getUuid()); - {((cond) => {if (!cond) throw new Error(`assertion failed: '(uuid.length === 36)'`)})((uuid.length === 36))}; - {((cond) => {if (!cond) throw new Error(`assertion failed: '((await Foo.getData()) === "Cool data!")'`)})(((await Foo.getData()) === "Cool data!"))}; + {((cond) => {if (!cond) throw new Error("assertion failed: uuid.length == 36")})((uuid.length === 36))}; + {((cond) => {if (!cond) throw new Error("assertion failed: Foo.getData() == \"Cool data!\"")})(((await Foo.getData()) === "Cool data!"))}; } } return Foo; @@ -391,8 +391,8 @@ class $Root extends $stdlib.std.Resource { super._registerBind(host, ops); } } - {((cond) => {if (!cond) throw new Error(`assertion failed: '((Foo.getGreeting("Wingding")) === "Hello, Wingding!")'`)})(((Foo.getGreeting("Wingding")) === "Hello, Wingding!"))}; - {((cond) => {if (!cond) throw new Error(`assertion failed: '((Foo.v4()).length === 36)'`)})(((Foo.v4()).length === 36))}; + {((cond) => {if (!cond) throw new Error("assertion failed: Foo.getGreeting(\"Wingding\") == \"Hello, Wingding!\"")})(((Foo.getGreeting("Wingding")) === "Hello, Wingding!"))}; + {((cond) => {if (!cond) throw new Error("assertion failed: Foo.v4().length == 36")})(((Foo.v4()).length === 36))}; const f = new Foo(this,"Foo"); this.node.root.new("@winglang/sdk.std.Test",std.Test,this,"test:call",new $Closure1(this,"$Closure1")); this.node.root.new("@winglang/sdk.std.Test",std.Test,this,"test:console",new $Closure2(this,"$Closure2")); diff --git a/tools/hangar/__snapshots__/test_corpus/valid/extern_implementation.w_test_sim.md b/tools/hangar/__snapshots__/test_corpus/valid/extern_implementation.w_test_sim.md index 82239ea0633..e084f80cd25 100644 --- a/tools/hangar/__snapshots__/test_corpus/valid/extern_implementation.w_test_sim.md +++ b/tools/hangar/__snapshots__/test_corpus/valid/extern_implementation.w_test_sim.md @@ -6,12 +6,9 @@ pass โ”€ extern_implementation.wsim ยป root/env0/test:call pass โ”Œ extern_implementation.wsim ยป root/env1/test:console โ”” printing hey there - - - - -Tests 1 passed (1) + +Tests 2 passed (2) +Test Files 1 passed (1) Duration - ``` diff --git a/tools/hangar/__snapshots__/test_corpus/valid/file_counter.w_compile_tf-aws.md b/tools/hangar/__snapshots__/test_corpus/valid/file_counter.w_compile_tf-aws.md index e178c0aecef..c0e0adbe835 100644 --- a/tools/hangar/__snapshots__/test_corpus/valid/file_counter.w_compile_tf-aws.md +++ b/tools/hangar/__snapshots__/test_corpus/valid/file_counter.w_compile_tf-aws.md @@ -13,7 +13,7 @@ module.exports = function({ counter, bucket }) { } async handle(body) { const next = (await counter.inc()); - const key = `myfile-${"hi"}.txt`; + const key = String.raw({ raw: ["myfile-", ".txt"] }, "hi"); (await bucket.put(key,body)); } } diff --git a/tools/hangar/__snapshots__/test_corpus/valid/file_counter.w_test_sim.md b/tools/hangar/__snapshots__/test_corpus/valid/file_counter.w_test_sim.md index 51c50555dad..fb0426a1c39 100644 --- a/tools/hangar/__snapshots__/test_corpus/valid/file_counter.w_test_sim.md +++ b/tools/hangar/__snapshots__/test_corpus/valid/file_counter.w_test_sim.md @@ -4,12 +4,9 @@ ```log pass โ”€ file_counter.wsim (no tests) - - - - -Tests 1 passed (1) + +Tests 1 passed (1) +Test Files 1 passed (1) Duration - ``` diff --git a/tools/hangar/__snapshots__/test_corpus/valid/for_loop.w_compile_tf-aws.md b/tools/hangar/__snapshots__/test_corpus/valid/for_loop.w_compile_tf-aws.md index 04b7e0145a7..90e2b00bc95 100644 --- a/tools/hangar/__snapshots__/test_corpus/valid/for_loop.w_compile_tf-aws.md +++ b/tools/hangar/__snapshots__/test_corpus/valid/for_loop.w_compile_tf-aws.md @@ -13,9 +13,9 @@ module.exports = function({ }) { } async handle(event) { for (const x of ((s,e,i) => { function* iterator(start,end,inclusive) { let i = start; let limit = inclusive ? ((end < start) ? end - 1 : end + 1) : end; while (i < limit) yield i++; while (i > limit) yield i--; }; return iterator(s,e,i); })(0,10,false)) { - {((cond) => {if (!cond) throw new Error(`assertion failed: '(x <= 0)'`)})((x <= 0))}; - {((cond) => {if (!cond) throw new Error(`assertion failed: '(x > 10)'`)})((x > 10))}; - {console.log(`${x}`)}; + {((cond) => {if (!cond) throw new Error("assertion failed: x <= 0")})((x <= 0))}; + {((cond) => {if (!cond) throw new Error("assertion failed: x > 10")})((x > 10))}; + {console.log(String.raw({ raw: ["", ""] }, x))}; } } } @@ -242,8 +242,8 @@ class $Root extends $stdlib.std.Resource { const uniqueNumbers = Object.freeze(new Set([1, 2, 3])); for (const word of words) { for (const number of uniqueNumbers) { - {((cond) => {if (!cond) throw new Error(`assertion failed: '(number > 0)'`)})((number > 0))}; - {console.log(`${word}: ${number}`)}; + {((cond) => {if (!cond) throw new Error("assertion failed: number > 0")})((number > 0))}; + {console.log(String.raw({ raw: ["", ": ", ""] }, word, number))}; } } let i = 0; @@ -252,130 +252,130 @@ class $Root extends $stdlib.std.Resource { let preBreakHits = 0; let postBreakHits = 0; for (const number of uniqueNumbers) { - {((cond) => {if (!cond) throw new Error(`assertion failed: '(number > 0)'`)})((number > 0))}; - {console.log(`${word}: ${number}`)}; + {((cond) => {if (!cond) throw new Error("assertion failed: number > 0")})((number > 0))}; + {console.log(String.raw({ raw: ["", ": ", ""] }, word, number))}; preBreakHits = (preBreakHits + 1); if ((number === 2)) { break; } postBreakHits = (postBreakHits + 1); } - {((cond) => {if (!cond) throw new Error(`assertion failed: '(preBreakHits === 2)'`)})((preBreakHits === 2))}; - {((cond) => {if (!cond) throw new Error(`assertion failed: '(postBreakHits === 1)'`)})((postBreakHits === 1))}; + {((cond) => {if (!cond) throw new Error("assertion failed: preBreakHits == 2")})((preBreakHits === 2))}; + {((cond) => {if (!cond) throw new Error("assertion failed: postBreakHits == 1")})((postBreakHits === 1))}; } - {((cond) => {if (!cond) throw new Error(`assertion failed: '(i === 3)'`)})((i === 3))}; + {((cond) => {if (!cond) throw new Error("assertion failed: i == 3")})((i === 3))}; let j = 0; for (const word of words) { j = (j + 1); let preContinueHits = 0; let postContinueHits = 0; for (const number of uniqueNumbers) { - {((cond) => {if (!cond) throw new Error(`assertion failed: '(number > 0)'`)})((number > 0))}; - {console.log(`${word}: ${number}`)}; + {((cond) => {if (!cond) throw new Error("assertion failed: number > 0")})((number > 0))}; + {console.log(String.raw({ raw: ["", ": ", ""] }, word, number))}; preContinueHits = (preContinueHits + 1); if ((number > 0)) { continue; } postContinueHits = (postContinueHits + 1); } - {((cond) => {if (!cond) throw new Error(`assertion failed: '(preContinueHits === 3)'`)})((preContinueHits === 3))}; - {((cond) => {if (!cond) throw new Error(`assertion failed: '(postContinueHits === 0)'`)})((postContinueHits === 0))}; + {((cond) => {if (!cond) throw new Error("assertion failed: preContinueHits == 3")})((preContinueHits === 3))}; + {((cond) => {if (!cond) throw new Error("assertion failed: postContinueHits == 0")})((postContinueHits === 0))}; } - {((cond) => {if (!cond) throw new Error(`assertion failed: '(j === 3)'`)})((j === 3))}; + {((cond) => {if (!cond) throw new Error("assertion failed: j == 3")})((j === 3))}; {console.log("---\nfor x in 0..0 { ... }")}; for (const x of $stdlib.std.Range.of(0, 0, false)) { - {((cond) => {if (!cond) throw new Error(`assertion failed: 'false'`)})(false)}; + {((cond) => {if (!cond) throw new Error("assertion failed: false")})(false)}; } {console.log("there's no value to iterate")}; {console.log("---\nfor x in 0..=0 { ... }")}; for (const x of $stdlib.std.Range.of(0, 0, true)) { - {((cond) => {if (!cond) throw new Error(`assertion failed: '(x === 0)'`)})((x === 0))}; - {console.log(`${x}`)}; + {((cond) => {if (!cond) throw new Error("assertion failed: x == 0")})((x === 0))}; + {console.log(String.raw({ raw: ["", ""] }, x))}; } {console.log("---\nfor x in 0..2 { ... }")}; for (const x of $stdlib.std.Range.of(0, 2, false)) { - {((cond) => {if (!cond) throw new Error(`assertion failed: '(x >= 0)'`)})((x >= 0))}; - {((cond) => {if (!cond) throw new Error(`assertion failed: '(x < 2)'`)})((x < 2))}; - {console.log(`${x}`)}; + {((cond) => {if (!cond) throw new Error("assertion failed: x >= 0")})((x >= 0))}; + {((cond) => {if (!cond) throw new Error("assertion failed: x < 2")})((x < 2))}; + {console.log(String.raw({ raw: ["", ""] }, x))}; } {console.log("---\nfor x in 0..=2 { ... }")}; for (const x of $stdlib.std.Range.of(0, 2, true)) { - {((cond) => {if (!cond) throw new Error(`assertion failed: '(x >= 0)'`)})((x >= 0))}; - {((cond) => {if (!cond) throw new Error(`assertion failed: '(x <= 2)'`)})((x <= 2))}; - {console.log(`${x}`)}; + {((cond) => {if (!cond) throw new Error("assertion failed: x >= 0")})((x >= 0))}; + {((cond) => {if (!cond) throw new Error("assertion failed: x <= 2")})((x <= 2))}; + {console.log(String.raw({ raw: ["", ""] }, x))}; } {console.log("---\nfor x in 2..0 { ... }")}; for (const x of $stdlib.std.Range.of(2, 0, false)) { - {((cond) => {if (!cond) throw new Error(`assertion failed: '(x <= 2)'`)})((x <= 2))}; - {((cond) => {if (!cond) throw new Error(`assertion failed: '(x > 0)'`)})((x > 0))}; - {console.log(`${x}`)}; + {((cond) => {if (!cond) throw new Error("assertion failed: x <= 2")})((x <= 2))}; + {((cond) => {if (!cond) throw new Error("assertion failed: x > 0")})((x > 0))}; + {console.log(String.raw({ raw: ["", ""] }, x))}; } {console.log("---\nfor x in 2..=0 { ... }")}; for (const x of $stdlib.std.Range.of(2, 0, true)) { - {((cond) => {if (!cond) throw new Error(`assertion failed: '(x <= 2)'`)})((x <= 2))}; - {((cond) => {if (!cond) throw new Error(`assertion failed: '(x >= 0)'`)})((x >= 0))}; - {console.log(`${x}`)}; + {((cond) => {if (!cond) throw new Error("assertion failed: x <= 2")})((x <= 2))}; + {((cond) => {if (!cond) throw new Error("assertion failed: x >= 0")})((x >= 0))}; + {console.log(String.raw({ raw: ["", ""] }, x))}; } {console.log("---\nfor x in 0..-2 { ... }")}; for (const x of $stdlib.std.Range.of(0, (-2), false)) { - {((cond) => {if (!cond) throw new Error(`assertion failed: '(x <= 0)'`)})((x <= 0))}; - {((cond) => {if (!cond) throw new Error(`assertion failed: '(x > (-2))'`)})((x > (-2)))}; - {console.log(`${x}`)}; + {((cond) => {if (!cond) throw new Error("assertion failed: x <= 0")})((x <= 0))}; + {((cond) => {if (!cond) throw new Error("assertion failed: x > -2")})((x > (-2)))}; + {console.log(String.raw({ raw: ["", ""] }, x))}; } {console.log("---\nfor x in 0..=-2 { ... }")}; for (const x of $stdlib.std.Range.of(0, (-2), true)) { - {((cond) => {if (!cond) throw new Error(`assertion failed: '(x <= 0)'`)})((x <= 0))}; - {((cond) => {if (!cond) throw new Error(`assertion failed: '(x > (-3))'`)})((x > (-3)))}; - {console.log(`${x}`)}; + {((cond) => {if (!cond) throw new Error("assertion failed: x <= 0")})((x <= 0))}; + {((cond) => {if (!cond) throw new Error("assertion failed: x > -3")})((x > (-3)))}; + {console.log(String.raw({ raw: ["", ""] }, x))}; } {console.log("---\nfor x in -2..0 { ... }")}; for (const x of $stdlib.std.Range.of((-2), 0, false)) { - {((cond) => {if (!cond) throw new Error(`assertion failed: '(x >= (-2))'`)})((x >= (-2)))}; - {((cond) => {if (!cond) throw new Error(`assertion failed: '(x < 0)'`)})((x < 0))}; - {console.log(`${x}`)}; + {((cond) => {if (!cond) throw new Error("assertion failed: x >= -2")})((x >= (-2)))}; + {((cond) => {if (!cond) throw new Error("assertion failed: x < 0")})((x < 0))}; + {console.log(String.raw({ raw: ["", ""] }, x))}; } {console.log("---\nfor x in -2..=0 { ... }")}; for (const x of $stdlib.std.Range.of((-2), 0, true)) { - {((cond) => {if (!cond) throw new Error(`assertion failed: '(x >= (-2))'`)})((x >= (-2)))}; - {((cond) => {if (!cond) throw new Error(`assertion failed: '(x <= 0)'`)})((x <= 0))}; - {console.log(`${x}`)}; + {((cond) => {if (!cond) throw new Error("assertion failed: x >= -2")})((x >= (-2)))}; + {((cond) => {if (!cond) throw new Error("assertion failed: x <= 0")})((x <= 0))}; + {console.log(String.raw({ raw: ["", ""] }, x))}; } const z = 2; {console.log("---\nfor x in 0..z { ... } <=> x = 2")}; for (const x of $stdlib.std.Range.of(0, z, false)) { - {((cond) => {if (!cond) throw new Error(`assertion failed: '(x >= 0)'`)})((x >= 0))}; - {((cond) => {if (!cond) throw new Error(`assertion failed: '(x < 2)'`)})((x < 2))}; - {console.log(`${x}`)}; + {((cond) => {if (!cond) throw new Error("assertion failed: x >= 0")})((x >= 0))}; + {((cond) => {if (!cond) throw new Error("assertion failed: x < 2")})((x < 2))}; + {console.log(String.raw({ raw: ["", ""] }, x))}; } {console.log("---\nfor x in 0..=z { ... } <=> x = 2")}; for (const x of $stdlib.std.Range.of(0, z, true)) { - {((cond) => {if (!cond) throw new Error(`assertion failed: '(x >= 0)'`)})((x >= 0))}; - {((cond) => {if (!cond) throw new Error(`assertion failed: '(x <= 2)'`)})((x <= 2))}; - {console.log(`${x}`)}; + {((cond) => {if (!cond) throw new Error("assertion failed: x >= 0")})((x >= 0))}; + {((cond) => {if (!cond) throw new Error("assertion failed: x <= 2")})((x <= 2))}; + {console.log(String.raw({ raw: ["", ""] }, x))}; } {console.log("---\nfor x in z..0 { ... } <=> x = 2")}; for (const x of $stdlib.std.Range.of(z, 0, false)) { - {((cond) => {if (!cond) throw new Error(`assertion failed: '(x <= 2)'`)})((x <= 2))}; - {((cond) => {if (!cond) throw new Error(`assertion failed: '(x > 0)'`)})((x > 0))}; - {console.log(`${x}`)}; + {((cond) => {if (!cond) throw new Error("assertion failed: x <= 2")})((x <= 2))}; + {((cond) => {if (!cond) throw new Error("assertion failed: x > 0")})((x > 0))}; + {console.log(String.raw({ raw: ["", ""] }, x))}; } {console.log("---\nfor x in 0..(z*2) { ... } <=> x = 2")}; for (const x of $stdlib.std.Range.of(0, (z * 2), false)) { - {((cond) => {if (!cond) throw new Error(`assertion failed: '(x >= 0)'`)})((x >= 0))}; - {((cond) => {if (!cond) throw new Error(`assertion failed: '(x < 4)'`)})((x < 4))}; - {console.log(`${x}`)}; + {((cond) => {if (!cond) throw new Error("assertion failed: x >= 0")})((x >= 0))}; + {((cond) => {if (!cond) throw new Error("assertion failed: x < 4")})((x < 4))}; + {console.log(String.raw({ raw: ["", ""] }, x))}; } {console.log("---\nfor x in 0..=(z*2) { ... } <=> x = 2")}; for (const x of $stdlib.std.Range.of(0, (z * 2), true)) { - {((cond) => {if (!cond) throw new Error(`assertion failed: '(x >= 0)'`)})((x >= 0))}; - {((cond) => {if (!cond) throw new Error(`assertion failed: '(x <= 4)'`)})((x <= 4))}; - {console.log(`${x}`)}; + {((cond) => {if (!cond) throw new Error("assertion failed: x >= 0")})((x >= 0))}; + {((cond) => {if (!cond) throw new Error("assertion failed: x <= 4")})((x <= 4))}; + {console.log(String.raw({ raw: ["", ""] }, x))}; } {console.log("---\nfor x in (z*2)..0 { ... } <=> x = 2")}; for (const x of $stdlib.std.Range.of((z * 2), 0, false)) { - {((cond) => {if (!cond) throw new Error(`assertion failed: '(x <= 4)'`)})((x <= 4))}; - {((cond) => {if (!cond) throw new Error(`assertion failed: '(x > 0)'`)})((x > 0))}; - {console.log(`${x}`)}; + {((cond) => {if (!cond) throw new Error("assertion failed: x <= 4")})((x <= 4))}; + {((cond) => {if (!cond) throw new Error("assertion failed: x > 0")})((x > 0))}; + {console.log(String.raw({ raw: ["", ""] }, x))}; } this.node.root.newAbstract("@winglang/sdk.cloud.Function",this,"cloud.Function",new $Closure1(this,"$Closure1")); } diff --git a/tools/hangar/__snapshots__/test_corpus/valid/for_loop.w_test_sim.md b/tools/hangar/__snapshots__/test_corpus/valid/for_loop.w_test_sim.md index a548437b76a..b355b004aea 100644 --- a/tools/hangar/__snapshots__/test_corpus/valid/for_loop.w_test_sim.md +++ b/tools/hangar/__snapshots__/test_corpus/valid/for_loop.w_test_sim.md @@ -102,12 +102,9 @@ for x in (z*2)..0 { ... } <=> x = 2 1 pass โ”€ for_loop.wsim (no tests) - - - - -Tests 1 passed (1) + +Tests 1 passed (1) +Test Files 1 passed (1) Duration - ``` diff --git a/tools/hangar/__snapshots__/test_corpus/valid/forward_decl.w_compile_tf-aws.md b/tools/hangar/__snapshots__/test_corpus/valid/forward_decl.w_compile_tf-aws.md index 88a5230a271..f64b7a0654e 100644 --- a/tools/hangar/__snapshots__/test_corpus/valid/forward_decl.w_compile_tf-aws.md +++ b/tools/hangar/__snapshots__/test_corpus/valid/forward_decl.w_compile_tf-aws.md @@ -64,7 +64,7 @@ class $Root extends $stdlib.std.Resource { } method2() { (this.method1()); - {console.log(`${this.f}`)}; + {console.log(String.raw({ raw: ["", ""] }, this.f))}; (this.method2()); } method1() { @@ -98,7 +98,7 @@ class $Root extends $stdlib.std.Resource { } const x = "hi"; if (true) { - {console.log(`${x}`)}; + {console.log(String.raw({ raw: ["", ""] }, x))}; const y = new R(this,"R"); } } diff --git a/tools/hangar/__snapshots__/test_corpus/valid/forward_decl.w_test_sim.md b/tools/hangar/__snapshots__/test_corpus/valid/forward_decl.w_test_sim.md index 0035830a1c3..35d667c0173 100644 --- a/tools/hangar/__snapshots__/test_corpus/valid/forward_decl.w_test_sim.md +++ b/tools/hangar/__snapshots__/test_corpus/valid/forward_decl.w_test_sim.md @@ -5,12 +5,9 @@ hi pass โ”€ forward_decl.wsim (no tests) - - - - -Tests 1 passed (1) + +Tests 1 passed (1) +Test Files 1 passed (1) Duration - ``` diff --git a/tools/hangar/__snapshots__/test_corpus/valid/function_returns_function.w_compile_tf-aws.md b/tools/hangar/__snapshots__/test_corpus/valid/function_returns_function.w_compile_tf-aws.md index 671fc5a764c..e07be19e19d 100644 --- a/tools/hangar/__snapshots__/test_corpus/valid/function_returns_function.w_compile_tf-aws.md +++ b/tools/hangar/__snapshots__/test_corpus/valid/function_returns_function.w_compile_tf-aws.md @@ -21,8 +21,8 @@ module.exports = function({ }) { ; const wingInflightFn = (await iFn("wing")); const dingInflightFn = (await iFn("ding")); - {((cond) => {if (!cond) throw new Error(`assertion failed: '(await wingInflightFn())'`)})((await wingInflightFn()))}; - {((cond) => {if (!cond) throw new Error(`assertion failed: '(!(await dingInflightFn()))'`)})((!(await dingInflightFn())))}; + {((cond) => {if (!cond) throw new Error("assertion failed: wingInflightFn()")})((await wingInflightFn()))}; + {((cond) => {if (!cond) throw new Error("assertion failed: !dingInflightFn()")})((!(await dingInflightFn())))}; } } return $Closure1; @@ -203,8 +203,8 @@ class $Root extends $stdlib.std.Resource { ; const wingFn = (fn("wing")); const dingFn = (fn("ding")); - {((cond) => {if (!cond) throw new Error(`assertion failed: '(wingFn())'`)})((wingFn()))}; - {((cond) => {if (!cond) throw new Error(`assertion failed: '(!(dingFn()))'`)})((!(dingFn())))}; + {((cond) => {if (!cond) throw new Error("assertion failed: wingFn()")})((wingFn()))}; + {((cond) => {if (!cond) throw new Error("assertion failed: !dingFn()")})((!(dingFn())))}; this.node.root.new("@winglang/sdk.std.Test",std.Test,this,"test:inflight functions can return other inflight functions",new $Closure1(this,"$Closure1")); } } diff --git a/tools/hangar/__snapshots__/test_corpus/valid/function_returns_function.w_test_sim.md b/tools/hangar/__snapshots__/test_corpus/valid/function_returns_function.w_test_sim.md index 055323f5bc6..53f8f532abf 100644 --- a/tools/hangar/__snapshots__/test_corpus/valid/function_returns_function.w_test_sim.md +++ b/tools/hangar/__snapshots__/test_corpus/valid/function_returns_function.w_test_sim.md @@ -4,12 +4,9 @@ ```log pass โ”€ function_returns_function.wsim ยป root/env0/test:inflight functions can return other inflight functions - - - - -Tests 1 passed (1) + +Tests 1 passed (1) +Test Files 1 passed (1) Duration - ``` diff --git a/tools/hangar/__snapshots__/test_corpus/valid/function_type.w_test_sim.md b/tools/hangar/__snapshots__/test_corpus/valid/function_type.w_test_sim.md index 583d9aa9152..5eae35c572b 100644 --- a/tools/hangar/__snapshots__/test_corpus/valid/function_type.w_test_sim.md +++ b/tools/hangar/__snapshots__/test_corpus/valid/function_type.w_test_sim.md @@ -4,12 +4,9 @@ ```log pass โ”€ function_type.wsim (no tests) - - - - -Tests 1 passed (1) + +Tests 1 passed (1) +Test Files 1 passed (1) Duration - ``` diff --git a/tools/hangar/__snapshots__/test_corpus/valid/hello.w_compile_tf-aws.md b/tools/hangar/__snapshots__/test_corpus/valid/hello.w_compile_tf-aws.md index 659bd6954a0..edb6c819ba4 100644 --- a/tools/hangar/__snapshots__/test_corpus/valid/hello.w_compile_tf-aws.md +++ b/tools/hangar/__snapshots__/test_corpus/valid/hello.w_compile_tf-aws.md @@ -12,7 +12,7 @@ module.exports = function({ bucket }) { async $inflight_init() { } async handle(message) { - (await bucket.put("wing.txt",`Hello, ${message}`)); + (await bucket.put("wing.txt",String.raw({ raw: ["Hello, ", ""] }, message))); } } return $Closure1; diff --git a/tools/hangar/__snapshots__/test_corpus/valid/hello.w_test_sim.md b/tools/hangar/__snapshots__/test_corpus/valid/hello.w_test_sim.md index 1094ac2e473..69b065aa791 100644 --- a/tools/hangar/__snapshots__/test_corpus/valid/hello.w_test_sim.md +++ b/tools/hangar/__snapshots__/test_corpus/valid/hello.w_test_sim.md @@ -4,12 +4,9 @@ ```log pass โ”€ hello.wsim (no tests) - - - - -Tests 1 passed (1) + +Tests 1 passed (1) +Test Files 1 passed (1) Duration - ``` diff --git a/tools/hangar/__snapshots__/test_corpus/valid/identical_inflights.w_test_sim.md b/tools/hangar/__snapshots__/test_corpus/valid/identical_inflights.w_test_sim.md index 5322b2c52b6..c85e05fe7f0 100644 --- a/tools/hangar/__snapshots__/test_corpus/valid/identical_inflights.w_test_sim.md +++ b/tools/hangar/__snapshots__/test_corpus/valid/identical_inflights.w_test_sim.md @@ -4,12 +4,9 @@ ```log pass โ”€ identical_inflights.wsim (no tests) - - - - -Tests 1 passed (1) + +Tests 1 passed (1) +Test Files 1 passed (1) Duration - ``` diff --git a/tools/hangar/__snapshots__/test_corpus/valid/impl_interface.w_test_sim.md b/tools/hangar/__snapshots__/test_corpus/valid/impl_interface.w_test_sim.md index cc8ffb0f78f..0a4b3e19865 100644 --- a/tools/hangar/__snapshots__/test_corpus/valid/impl_interface.w_test_sim.md +++ b/tools/hangar/__snapshots__/test_corpus/valid/impl_interface.w_test_sim.md @@ -4,12 +4,9 @@ ```log pass โ”€ impl_interface.wsim (no tests) - - - - -Tests 1 passed (1) + +Tests 1 passed (1) +Test Files 1 passed (1) Duration - ``` diff --git a/tools/hangar/__snapshots__/test_corpus/valid/implicit_std.w_compile_tf-aws.md b/tools/hangar/__snapshots__/test_corpus/valid/implicit_std.w_compile_tf-aws.md index bac60655682..82f435d6503 100644 --- a/tools/hangar/__snapshots__/test_corpus/valid/implicit_std.w_compile_tf-aws.md +++ b/tools/hangar/__snapshots__/test_corpus/valid/implicit_std.w_compile_tf-aws.md @@ -44,8 +44,8 @@ class $Root extends $stdlib.std.Resource { super(scope, id); const d = (std.Duration.fromMinutes(5)); const n = ((args) => { if (isNaN(args)) {throw new Error("unable to parse \"" + args + "\" as a number")}; return parseInt(args) })("12"); - {((cond) => {if (!cond) throw new Error(`assertion failed: '(d.seconds === (5 * 60))'`)})((d.seconds === (5 * 60)))}; - {((cond) => {if (!cond) throw new Error(`assertion failed: '(n === 12)'`)})((n === 12))}; + {((cond) => {if (!cond) throw new Error("assertion failed: d.seconds == 5 * 60")})((d.seconds === (5 * 60)))}; + {((cond) => {if (!cond) throw new Error("assertion failed: n == 12")})((n === 12))}; } } class $App extends $AppBase { diff --git a/tools/hangar/__snapshots__/test_corpus/valid/implicit_std.w_test_sim.md b/tools/hangar/__snapshots__/test_corpus/valid/implicit_std.w_test_sim.md index daa14df63b0..9d48eada49d 100644 --- a/tools/hangar/__snapshots__/test_corpus/valid/implicit_std.w_test_sim.md +++ b/tools/hangar/__snapshots__/test_corpus/valid/implicit_std.w_test_sim.md @@ -4,12 +4,9 @@ ```log pass โ”€ implicit_std.wsim (no tests) - - - - -Tests 1 passed (1) + +Tests 1 passed (1) +Test Files 1 passed (1) Duration - ``` diff --git a/tools/hangar/__snapshots__/test_corpus/valid/inflight-subscribers.w_test_sim.md b/tools/hangar/__snapshots__/test_corpus/valid/inflight-subscribers.w_test_sim.md index 914c302a120..ed41c844e68 100644 --- a/tools/hangar/__snapshots__/test_corpus/valid/inflight-subscribers.w_test_sim.md +++ b/tools/hangar/__snapshots__/test_corpus/valid/inflight-subscribers.w_test_sim.md @@ -4,12 +4,9 @@ ```log pass โ”€ inflight-subscribers.wsim (no tests) - - - - -Tests 1 passed (1) + +Tests 1 passed (1) +Test Files 1 passed (1) Duration - ``` diff --git a/tools/hangar/__snapshots__/test_corpus/valid/inflight_capture_static.w_compile_tf-aws.md b/tools/hangar/__snapshots__/test_corpus/valid/inflight_capture_static.w_compile_tf-aws.md index 325f65b4f55..da1e78af66b 100644 --- a/tools/hangar/__snapshots__/test_corpus/valid/inflight_capture_static.w_compile_tf-aws.md +++ b/tools/hangar/__snapshots__/test_corpus/valid/inflight_capture_static.w_compile_tf-aws.md @@ -12,7 +12,7 @@ module.exports = function({ Preflight }) { async $inflight_init() { } async handle() { - {((cond) => {if (!cond) throw new Error(`assertion failed: '((await Preflight.staticMethod(123)) === "foo-123")'`)})(((await Preflight.staticMethod(123)) === "foo-123"))}; + {((cond) => {if (!cond) throw new Error("assertion failed: Preflight.staticMethod(123) == \"foo-123\"")})(((await Preflight.staticMethod(123)) === "foo-123"))}; } } return $Closure1; @@ -32,7 +32,7 @@ module.exports = function({ OuterInflight }) { async $inflight_init() { } async handle() { - {((cond) => {if (!cond) throw new Error(`assertion failed: '((await OuterInflight.staticMethod("hello")) === 5)'`)})(((await OuterInflight.staticMethod("hello")) === 5))}; + {((cond) => {if (!cond) throw new Error("assertion failed: OuterInflight.staticMethod(\"hello\") == 5")})(((await OuterInflight.staticMethod("hello")) === 5))}; } } return $Closure2; @@ -53,7 +53,7 @@ module.exports = function({ }) { } async handle() { const InnerInflight = require("./inflight.InnerInflight.js")({}); - {((cond) => {if (!cond) throw new Error(`assertion failed: '((await InnerInflight.staticMethod()) === "hello")'`)})(((await InnerInflight.staticMethod()) === "hello"))}; + {((cond) => {if (!cond) throw new Error("assertion failed: InnerInflight.staticMethod() == \"hello\"")})(((await InnerInflight.staticMethod()) === "hello"))}; } } return $Closure3; @@ -77,10 +77,10 @@ module.exports = function({ util_Util }) { const $IF_LET_VALUE = (await util_Util.tryEnv("WING_TARGET")); if ($IF_LET_VALUE != undefined) { const target = $IF_LET_VALUE; - {console.log(`WING_TARGET=${target}`)}; + {console.log(String.raw({ raw: ["WING_TARGET=", ""] }, target))}; } else { - {((cond) => {if (!cond) throw new Error(`assertion failed: 'false'`)})(false)}; + {((cond) => {if (!cond) throw new Error("assertion failed: false /* target not defined*/")})(false)}; } } } @@ -129,7 +129,7 @@ module.exports = function({ }) { async $inflight_init() { } static async staticMethod(a) { - return `foo-${a}`; + return String.raw({ raw: ["foo-", ""] }, a); } } return Preflight; diff --git a/tools/hangar/__snapshots__/test_corpus/valid/inflight_capture_static.w_test_sim.md b/tools/hangar/__snapshots__/test_corpus/valid/inflight_capture_static.w_test_sim.md index aec6772f664..59874262154 100644 --- a/tools/hangar/__snapshots__/test_corpus/valid/inflight_capture_static.w_test_sim.md +++ b/tools/hangar/__snapshots__/test_corpus/valid/inflight_capture_static.w_test_sim.md @@ -8,12 +8,9 @@ pass โ”€ inflight_capture_static.wsim ยป root/env2/test:call static method of an pass โ”Œ inflight_capture_static.wsim ยป root/env3/test:call static method of a namespaced type โ”” WING_TARGET=sim - - - - -Tests 1 passed (1) + +Tests 4 passed (4) +Test Files 1 passed (1) Duration - ``` diff --git a/tools/hangar/__snapshots__/test_corpus/valid/inflight_class_as_struct_members.w_compile_tf-aws.md b/tools/hangar/__snapshots__/test_corpus/valid/inflight_class_as_struct_members.w_compile_tf-aws.md index 743be69be70..d689c942cd4 100644 --- a/tools/hangar/__snapshots__/test_corpus/valid/inflight_class_as_struct_members.w_compile_tf-aws.md +++ b/tools/hangar/__snapshots__/test_corpus/valid/inflight_class_as_struct_members.w_compile_tf-aws.md @@ -35,7 +35,7 @@ module.exports = function({ getBar }) { } async handle() { const bar = (await getBar()); - {((cond) => {if (!cond) throw new Error(`assertion failed: '((await bar.foo.get()) === 42)'`)})(((await bar.foo.get()) === 42))}; + {((cond) => {if (!cond) throw new Error("assertion failed: bar.foo.get() == 42")})(((await bar.foo.get()) === 42))}; } } return $Closure2; diff --git a/tools/hangar/__snapshots__/test_corpus/valid/inflight_class_as_struct_members.w_test_sim.md b/tools/hangar/__snapshots__/test_corpus/valid/inflight_class_as_struct_members.w_test_sim.md index eb8288b525a..be86651d6d7 100644 --- a/tools/hangar/__snapshots__/test_corpus/valid/inflight_class_as_struct_members.w_test_sim.md +++ b/tools/hangar/__snapshots__/test_corpus/valid/inflight_class_as_struct_members.w_test_sim.md @@ -4,12 +4,9 @@ ```log pass โ”€ inflight_class_as_struct_members.wsim ยป root/env0/test:test - - - - -Tests 1 passed (1) + +Tests 1 passed (1) +Test Files 1 passed (1) Duration - ``` diff --git a/tools/hangar/__snapshots__/test_corpus/valid/inflight_class_capture_const.w_compile_tf-aws.md b/tools/hangar/__snapshots__/test_corpus/valid/inflight_class_capture_const.w_compile_tf-aws.md index 0694bfea0d4..be393d915a2 100644 --- a/tools/hangar/__snapshots__/test_corpus/valid/inflight_class_capture_const.w_compile_tf-aws.md +++ b/tools/hangar/__snapshots__/test_corpus/valid/inflight_class_capture_const.w_compile_tf-aws.md @@ -13,7 +13,7 @@ module.exports = function({ myConst, Foo }) { } async handle() { const x = new Foo(); - {((cond) => {if (!cond) throw new Error(`assertion failed: '((await x.getValue()) === myConst)'`)})(((await x.getValue()) === myConst))}; + {((cond) => {if (!cond) throw new Error("assertion failed: x.getValue() == myConst")})(((await x.getValue()) === myConst))}; } } return $Closure1; diff --git a/tools/hangar/__snapshots__/test_corpus/valid/inflight_class_capture_const.w_test_sim.md b/tools/hangar/__snapshots__/test_corpus/valid/inflight_class_capture_const.w_test_sim.md index f34f52f3789..5d4c8406f20 100644 --- a/tools/hangar/__snapshots__/test_corpus/valid/inflight_class_capture_const.w_test_sim.md +++ b/tools/hangar/__snapshots__/test_corpus/valid/inflight_class_capture_const.w_test_sim.md @@ -4,12 +4,9 @@ ```log pass โ”€ inflight_class_capture_const.wsim ยป root/env0/test:inflight class captures const - - - - -Tests 1 passed (1) + +Tests 1 passed (1) +Test Files 1 passed (1) Duration - ``` diff --git a/tools/hangar/__snapshots__/test_corpus/valid/inflight_class_capture_preflight_object.w_test_sim.md b/tools/hangar/__snapshots__/test_corpus/valid/inflight_class_capture_preflight_object.w_test_sim.md index 207c8ede4b2..dc7a252436f 100644 --- a/tools/hangar/__snapshots__/test_corpus/valid/inflight_class_capture_preflight_object.w_test_sim.md +++ b/tools/hangar/__snapshots__/test_corpus/valid/inflight_class_capture_preflight_object.w_test_sim.md @@ -4,12 +4,9 @@ ```log pass โ”€ inflight_class_capture_preflight_object.wsim (no tests) - - - - -Tests 1 passed (1) + +Tests 1 passed (1) +Test Files 1 passed (1) Duration - ``` diff --git a/tools/hangar/__snapshots__/test_corpus/valid/inflight_class_definitions.w_compile_tf-aws.md b/tools/hangar/__snapshots__/test_corpus/valid/inflight_class_definitions.w_compile_tf-aws.md index d51ba5c1b23..698f1266ed3 100644 --- a/tools/hangar/__snapshots__/test_corpus/valid/inflight_class_definitions.w_compile_tf-aws.md +++ b/tools/hangar/__snapshots__/test_corpus/valid/inflight_class_definitions.w_compile_tf-aws.md @@ -14,7 +14,7 @@ module.exports = function({ }) { async handle() { const C = require("./inflight.C.js")({}); const c = new C(); - {((cond) => {if (!cond) throw new Error(`assertion failed: '((await c.foo()) === "c1")'`)})(((await c.foo()) === "c1"))}; + {((cond) => {if (!cond) throw new Error("assertion failed: c.foo() == \"c1\"")})(((await c.foo()) === "c1"))}; } } return $Closure1; @@ -54,12 +54,12 @@ module.exports = function({ a, fn, d, innerD, B }) { async $inflight_init() { } async handle() { - {((cond) => {if (!cond) throw new Error(`assertion failed: '((await a.goo()) === "a2")'`)})(((await a.goo()) === "a2"))}; + {((cond) => {if (!cond) throw new Error("assertion failed: a.goo() == \"a2\"")})(((await a.goo()) === "a2"))}; const b = new B(); - {((cond) => {if (!cond) throw new Error(`assertion failed: '((await b.foo()) === "b1")'`)})(((await b.foo()) === "b1"))}; + {((cond) => {if (!cond) throw new Error("assertion failed: b.foo() == \"b1\"")})(((await b.foo()) === "b1"))}; (await fn()); - {((cond) => {if (!cond) throw new Error(`assertion failed: '((await d.callInner()) === "f1")'`)})(((await d.callInner()) === "f1"))}; - {((cond) => {if (!cond) throw new Error(`assertion failed: '((await innerD()) === "f1")'`)})(((await innerD()) === "f1"))}; + {((cond) => {if (!cond) throw new Error("assertion failed: d.callInner() == \"f1\"")})(((await d.callInner()) === "f1"))}; + {((cond) => {if (!cond) throw new Error("assertion failed: innerD() == \"f1\"")})(((await innerD()) === "f1"))}; } } return $Closure3; @@ -425,7 +425,7 @@ class $Root extends $stdlib.std.Resource { } } const pb = new E(this,"E"); - {((cond) => {if (!cond) throw new Error(`assertion failed: '((pb.foo()) === "e1")'`)})(((pb.foo()) === "e1"))}; + {((cond) => {if (!cond) throw new Error("assertion failed: pb.foo() == \"e1\"")})(((pb.foo()) === "e1"))}; class F extends $stdlib.std.Resource { constructor(scope, id, ) { super(scope, id); @@ -578,7 +578,7 @@ class $Root extends $stdlib.std.Resource { } } const a = new A(this,"A"); - {((cond) => {if (!cond) throw new Error(`assertion failed: '((a.foo()) === "a1")'`)})(((a.foo()) === "a1"))}; + {((cond) => {if (!cond) throw new Error("assertion failed: a.foo() == \"a1\"")})(((a.foo()) === "a1"))}; const fn = new $Closure1(this,"$Closure1"); const d = new D(this,"D"); const innerD = (d.getInner()); diff --git a/tools/hangar/__snapshots__/test_corpus/valid/inflight_class_definitions.w_test_sim.md b/tools/hangar/__snapshots__/test_corpus/valid/inflight_class_definitions.w_test_sim.md index 7bd3f8e2fa2..a3bc16a944f 100644 --- a/tools/hangar/__snapshots__/test_corpus/valid/inflight_class_definitions.w_test_sim.md +++ b/tools/hangar/__snapshots__/test_corpus/valid/inflight_class_definitions.w_test_sim.md @@ -4,12 +4,9 @@ ```log pass โ”€ inflight_class_definitions.wsim ยป root/env0/test:test - - - - -Tests 1 passed (1) + +Tests 1 passed (1) +Test Files 1 passed (1) Duration - ``` diff --git a/tools/hangar/__snapshots__/test_corpus/valid/inflight_class_inner_capture_mutable.w_compile_tf-aws.md b/tools/hangar/__snapshots__/test_corpus/valid/inflight_class_inner_capture_mutable.w_compile_tf-aws.md index df03758e895..2a8a86195a1 100644 --- a/tools/hangar/__snapshots__/test_corpus/valid/inflight_class_inner_capture_mutable.w_compile_tf-aws.md +++ b/tools/hangar/__snapshots__/test_corpus/valid/inflight_class_inner_capture_mutable.w_compile_tf-aws.md @@ -15,9 +15,9 @@ module.exports = function({ }) { const y = [1]; let i = 10; const Inner = require("./inflight.Inner.js")({y, i}); - {((cond) => {if (!cond) throw new Error(`assertion failed: '((await new Inner().dang()) === 11)'`)})(((await new Inner().dang()) === 11))}; - {((cond) => {if (!cond) throw new Error(`assertion failed: '((await y.at(1)) === 2)'`)})(((await y.at(1)) === 2))}; - {((cond) => {if (!cond) throw new Error(`assertion failed: '(i === 10)'`)})((i === 10))}; + {((cond) => {if (!cond) throw new Error("assertion failed: new Inner().dang() == 11")})(((await new Inner().dang()) === 11))}; + {((cond) => {if (!cond) throw new Error("assertion failed: y.at(1) == 2")})(((await y.at(1)) === 2))}; + {((cond) => {if (!cond) throw new Error("assertion failed: i == 10")})((i === 10))}; } } return $Closure1; diff --git a/tools/hangar/__snapshots__/test_corpus/valid/inflight_class_inner_capture_mutable.w_test_sim.md b/tools/hangar/__snapshots__/test_corpus/valid/inflight_class_inner_capture_mutable.w_test_sim.md index 564c67f2af8..4eb79b13110 100644 --- a/tools/hangar/__snapshots__/test_corpus/valid/inflight_class_inner_capture_mutable.w_test_sim.md +++ b/tools/hangar/__snapshots__/test_corpus/valid/inflight_class_inner_capture_mutable.w_test_sim.md @@ -4,12 +4,9 @@ ```log pass โ”€ inflight_class_inner_capture_mutable.wsim ยป root/env0/test:inner inflight class capture immutable - - - - -Tests 1 passed (1) + +Tests 1 passed (1) +Test Files 1 passed (1) Duration - ``` diff --git a/tools/hangar/__snapshots__/test_corpus/valid/inflight_class_inside_inflight_closure.w_compile_tf-aws.md b/tools/hangar/__snapshots__/test_corpus/valid/inflight_class_inside_inflight_closure.w_compile_tf-aws.md index 30fb426adc1..54f653fef04 100644 --- a/tools/hangar/__snapshots__/test_corpus/valid/inflight_class_inside_inflight_closure.w_compile_tf-aws.md +++ b/tools/hangar/__snapshots__/test_corpus/valid/inflight_class_inside_inflight_closure.w_compile_tf-aws.md @@ -59,7 +59,7 @@ module.exports = function({ }) { const Foo = require("./inflight.Foo.js")({x}); const foo = new Foo(); const y = (await foo.getX()); - {((cond) => {if (!cond) throw new Error(`assertion failed: '(y === 12)'`)})((y === 12))}; + {((cond) => {if (!cond) throw new Error("assertion failed: y == 12")})((y === 12))}; } } return $Closure3; @@ -90,7 +90,7 @@ module.exports = function({ }) { this.field = "value"; } async method() { - {((cond) => {if (!cond) throw new Error(`assertion failed: '(this.field === "value")'`)})((this.field === "value"))}; + {((cond) => {if (!cond) throw new Error("assertion failed: this.field == \"value\"")})((this.field === "value"))}; } } return InflightClass; diff --git a/tools/hangar/__snapshots__/test_corpus/valid/inflight_class_inside_inflight_closure.w_test_sim.md b/tools/hangar/__snapshots__/test_corpus/valid/inflight_class_inside_inflight_closure.w_test_sim.md index 93808c88c1e..cc6962d40a5 100644 --- a/tools/hangar/__snapshots__/test_corpus/valid/inflight_class_inside_inflight_closure.w_test_sim.md +++ b/tools/hangar/__snapshots__/test_corpus/valid/inflight_class_inside_inflight_closure.w_test_sim.md @@ -5,12 +5,9 @@ pass โ”€ inflight_class_inside_inflight_closure.wsim ยป root/env0/test:it works pass โ”€ inflight_class_inside_inflight_closure.wsim ยป root/env1/test:inflight class inside closure captures from closure - - - - -Tests 1 passed (1) + +Tests 2 passed (2) +Test Files 1 passed (1) Duration - ``` diff --git a/tools/hangar/__snapshots__/test_corpus/valid/inflight_class_modifiers.w_test_sim.md b/tools/hangar/__snapshots__/test_corpus/valid/inflight_class_modifiers.w_test_sim.md index 4c658ba67e1..af1e4d0509e 100644 --- a/tools/hangar/__snapshots__/test_corpus/valid/inflight_class_modifiers.w_test_sim.md +++ b/tools/hangar/__snapshots__/test_corpus/valid/inflight_class_modifiers.w_test_sim.md @@ -4,12 +4,9 @@ ```log pass โ”€ inflight_class_modifiers.wsim (no tests) - - - - -Tests 1 passed (1) + +Tests 1 passed (1) +Test Files 1 passed (1) Duration - ``` diff --git a/tools/hangar/__snapshots__/test_corpus/valid/inflight_class_outside_inflight_closure.w_compile_tf-aws.md b/tools/hangar/__snapshots__/test_corpus/valid/inflight_class_outside_inflight_closure.w_compile_tf-aws.md index 44f24ebae53..698975a86a0 100644 --- a/tools/hangar/__snapshots__/test_corpus/valid/inflight_class_outside_inflight_closure.w_compile_tf-aws.md +++ b/tools/hangar/__snapshots__/test_corpus/valid/inflight_class_outside_inflight_closure.w_compile_tf-aws.md @@ -13,7 +13,7 @@ module.exports = function({ BinaryOperation }) { } async handle() { const op = new BinaryOperation(10,20); - {((cond) => {if (!cond) throw new Error(`assertion failed: '((await op.add()) === 30)'`)})(((await op.add()) === 30))}; + {((cond) => {if (!cond) throw new Error("assertion failed: op.add() == 30")})(((await op.add()) === 30))}; } } return $Closure1; diff --git a/tools/hangar/__snapshots__/test_corpus/valid/inflight_class_outside_inflight_closure.w_test_sim.md b/tools/hangar/__snapshots__/test_corpus/valid/inflight_class_outside_inflight_closure.w_test_sim.md index 9495bc294ee..5f0afc19cbc 100644 --- a/tools/hangar/__snapshots__/test_corpus/valid/inflight_class_outside_inflight_closure.w_test_sim.md +++ b/tools/hangar/__snapshots__/test_corpus/valid/inflight_class_outside_inflight_closure.w_test_sim.md @@ -4,12 +4,9 @@ ```log pass โ”€ inflight_class_outside_inflight_closure.wsim ยป root/env0/test:inflight class outside inflight closure - - - - -Tests 1 passed (1) + +Tests 1 passed (1) +Test Files 1 passed (1) Duration - ``` diff --git a/tools/hangar/__snapshots__/test_corpus/valid/inflight_class_structural_interace_handler.w_compile_tf-aws.md b/tools/hangar/__snapshots__/test_corpus/valid/inflight_class_structural_interace_handler.w_compile_tf-aws.md index 4698868681b..16bfb58377b 100644 --- a/tools/hangar/__snapshots__/test_corpus/valid/inflight_class_structural_interace_handler.w_compile_tf-aws.md +++ b/tools/hangar/__snapshots__/test_corpus/valid/inflight_class_structural_interace_handler.w_compile_tf-aws.md @@ -14,9 +14,9 @@ module.exports = function({ NotGoo }) { async handle() { const YesGoo = require("./inflight.YesGoo.js")({}); const y = new YesGoo(); - {((cond) => {if (!cond) throw new Error(`assertion failed: '((await y.handle()) === 456)'`)})(((await y.handle()) === 456))}; + {((cond) => {if (!cond) throw new Error("assertion failed: y.handle() == 456")})(((await y.handle()) === 456))}; const x = new NotGoo(); - {((cond) => {if (!cond) throw new Error(`assertion failed: '((await x.handle()) === 123)'`)})(((await x.handle()) === 123))}; + {((cond) => {if (!cond) throw new Error("assertion failed: x.handle() == 123")})(((await x.handle()) === 123))}; } } return $Closure1; diff --git a/tools/hangar/__snapshots__/test_corpus/valid/inflight_class_structural_interace_handler.w_test_sim.md b/tools/hangar/__snapshots__/test_corpus/valid/inflight_class_structural_interace_handler.w_test_sim.md index 7ecd68d196e..bdc5ae07e6d 100644 --- a/tools/hangar/__snapshots__/test_corpus/valid/inflight_class_structural_interace_handler.w_test_sim.md +++ b/tools/hangar/__snapshots__/test_corpus/valid/inflight_class_structural_interace_handler.w_test_sim.md @@ -4,12 +4,9 @@ ```log pass โ”€ inflight_class_structural_interace_handler.wsim ยป root/env0/test:structure interface types for 'handle' - - - - -Tests 1 passed (1) + +Tests 1 passed (1) +Test Files 1 passed (1) Duration - ``` diff --git a/tools/hangar/__snapshots__/test_corpus/valid/inflight_class_without_init.w_test_sim.md b/tools/hangar/__snapshots__/test_corpus/valid/inflight_class_without_init.w_test_sim.md index 0ce2763442c..8b3b344e9d1 100644 --- a/tools/hangar/__snapshots__/test_corpus/valid/inflight_class_without_init.w_test_sim.md +++ b/tools/hangar/__snapshots__/test_corpus/valid/inflight_class_without_init.w_test_sim.md @@ -4,12 +4,9 @@ ```log pass โ”€ inflight_class_without_init.wsim ยป root/env0/test:inflight class without init - - - - -Tests 1 passed (1) + +Tests 1 passed (1) +Test Files 1 passed (1) Duration - ``` diff --git a/tools/hangar/__snapshots__/test_corpus/valid/inflight_concat.w_test_sim.md b/tools/hangar/__snapshots__/test_corpus/valid/inflight_concat.w_test_sim.md index 21cfe1ac42b..e600dcee70f 100644 --- a/tools/hangar/__snapshots__/test_corpus/valid/inflight_concat.w_test_sim.md +++ b/tools/hangar/__snapshots__/test_corpus/valid/inflight_concat.w_test_sim.md @@ -4,12 +4,9 @@ ```log pass โ”€ inflight_concat.wsim (no tests) - - - - -Tests 1 passed (1) + +Tests 1 passed (1) +Test Files 1 passed (1) Duration - ``` diff --git a/tools/hangar/__snapshots__/test_corpus/valid/inflights_calling_inflights.w_compile_tf-aws.md b/tools/hangar/__snapshots__/test_corpus/valid/inflights_calling_inflights.w_compile_tf-aws.md index c4ced9b0bf3..b1ad855393a 100644 --- a/tools/hangar/__snapshots__/test_corpus/valid/inflights_calling_inflights.w_compile_tf-aws.md +++ b/tools/hangar/__snapshots__/test_corpus/valid/inflights_calling_inflights.w_compile_tf-aws.md @@ -53,7 +53,7 @@ module.exports = function({ func1, globalBucket }) { } async handle() { (await func1.invoke("hi1")); - {((cond) => {if (!cond) throw new Error(`assertion failed: '((await globalBucket.get("file1")) === "hi1")'`)})(((await globalBucket.get("file1")) === "hi1"))}; + {((cond) => {if (!cond) throw new Error("assertion failed: globalBucket.get(\"file1\") == \"hi1\"")})(((await globalBucket.get("file1")) === "hi1"))}; } } return $Closure3; @@ -95,7 +95,7 @@ module.exports = function({ x }) { } async handle() { const val = (await x.foo()); - {((cond) => {if (!cond) throw new Error(`assertion failed: '(val === "hello")'`)})((val === "hello"))}; + {((cond) => {if (!cond) throw new Error("assertion failed: val == \"hello\"")})((val === "hello"))}; } } return $Closure5; diff --git a/tools/hangar/__snapshots__/test_corpus/valid/inflights_calling_inflights.w_test_sim.md b/tools/hangar/__snapshots__/test_corpus/valid/inflights_calling_inflights.w_test_sim.md index dc1914a2552..32b31a9680c 100644 --- a/tools/hangar/__snapshots__/test_corpus/valid/inflights_calling_inflights.w_test_sim.md +++ b/tools/hangar/__snapshots__/test_corpus/valid/inflights_calling_inflights.w_test_sim.md @@ -5,12 +5,9 @@ pass โ”€ inflights_calling_inflights.wsim ยป root/env0/test:inflights can call other inflights pass โ”€ inflights_calling_inflights.wsim ยป root/env1/test:variable can be an inflight closure - - - - -Tests 1 passed (1) + +Tests 2 passed (2) +Test Files 1 passed (1) Duration - ``` diff --git a/tools/hangar/__snapshots__/test_corpus/valid/interface.w_test_sim.md b/tools/hangar/__snapshots__/test_corpus/valid/interface.w_test_sim.md index 8f0f7672fc7..2fec34b3c41 100644 --- a/tools/hangar/__snapshots__/test_corpus/valid/interface.w_test_sim.md +++ b/tools/hangar/__snapshots__/test_corpus/valid/interface.w_test_sim.md @@ -4,12 +4,9 @@ ```log pass โ”€ interface.wsim (no tests) - - - - -Tests 1 passed (1) + +Tests 1 passed (1) +Test Files 1 passed (1) Duration - ``` diff --git a/tools/hangar/__snapshots__/test_corpus/valid/json.w_compile_tf-aws.md b/tools/hangar/__snapshots__/test_corpus/valid/json.w_compile_tf-aws.md index 7169dce44a3..193b8b42bb4 100644 --- a/tools/hangar/__snapshots__/test_corpus/valid/json.w_compile_tf-aws.md +++ b/tools/hangar/__snapshots__/test_corpus/valid/json.w_compile_tf-aws.md @@ -96,7 +96,7 @@ class $Root extends $stdlib.std.Resource { const jsonMutObj = {"hello":123,"world":[1, "cat", 3],"boom boom":{"hello":1233}}; const message = "Coolness"; ((obj, args) => { obj[args[0]] = args[1]; })(jsonMutObj, ["hello",message]); - {((cond) => {if (!cond) throw new Error(`assertion failed: '((jsonMutObj)["hello"] === message)'`)})(((jsonMutObj)["hello"] === message))}; + {((cond) => {if (!cond) throw new Error("assertion failed: jsonMutObj.get(\"hello\") == message")})(((jsonMutObj)["hello"] === message))}; const someNumber = 999; const jj = someNumber; const jj1 = Object.freeze({"foo":someNumber}); @@ -106,24 +106,24 @@ class $Root extends $stdlib.std.Resource { } ; const jj3 = (getStr()); - {((cond) => {if (!cond) throw new Error(`assertion failed: '(jj3 === "hello")'`)})((jj3 === "hello"))}; + {((cond) => {if (!cond) throw new Error("assertion failed: jj3 == Json \"hello\"")})((jj3 === "hello"))}; const f = new Foo(this,"Foo"); const jj4 = f.SumStr; - {((cond) => {if (!cond) throw new Error(`assertion failed: '(jj4 === "wow!")'`)})((jj4 === "wow!"))}; + {((cond) => {if (!cond) throw new Error("assertion failed: jj4 == Json \"wow!\"")})((jj4 === "wow!"))}; const someJson = {"x":someNumber}; - {((cond) => {if (!cond) throw new Error(`assertion failed: '((someJson)["x"] === someNumber)'`)})(((someJson)["x"] === someNumber))}; + {((cond) => {if (!cond) throw new Error("assertion failed: someJson.get(\"x\") == someNumber")})(((someJson)["x"] === someNumber))}; ((obj, args) => { obj[args[0]] = args[1]; })(someJson, ["x",111]); - {((cond) => {if (!cond) throw new Error(`assertion failed: '((someJson)["x"] === 111)'`)})(((someJson)["x"] === 111))}; + {((cond) => {if (!cond) throw new Error("assertion failed: someJson.get(\"x\") == 111")})(((someJson)["x"] === 111))}; const x = Object.freeze({"cool":"beans"}); const nestedJson = {"a":"hello","b":{"c":"world","d":{"foo":"foo","bar":123}}}; ((obj, args) => { obj[args[0]] = args[1]; })(((nestedJson)["b"])["d"], ["foo","tastic"]); - {((cond) => {if (!cond) throw new Error(`assertion failed: '((((nestedJson)["b"])["d"])["foo"] === "tastic")'`)})(((((nestedJson)["b"])["d"])["foo"] === "tastic"))}; - {((cond) => {if (!cond) throw new Error(`assertion failed: '((((nestedJson)["b"])["d"])["bar"] === 123)'`)})(((((nestedJson)["b"])["d"])["bar"] === 123))}; + {((cond) => {if (!cond) throw new Error("assertion failed: nestedJson.get(\"b\").get(\"d\").get(\"foo\") == \"tastic\"")})(((((nestedJson)["b"])["d"])["foo"] === "tastic"))}; + {((cond) => {if (!cond) throw new Error("assertion failed: nestedJson.get(\"b\").get(\"d\").get(\"bar\") == 123")})(((((nestedJson)["b"])["d"])["bar"] === 123))}; const b = "buckle"; const arr = [1, 2, b, "my", "shoe", 3, 4, ["shut", "the", "door"]]; - {((cond) => {if (!cond) throw new Error(`assertion failed: '((arr)[0] === 1)'`)})(((arr)[0] === 1))}; - {((cond) => {if (!cond) throw new Error(`assertion failed: '((arr)[2] === b)'`)})(((arr)[2] === b))}; - {((cond) => {if (!cond) throw new Error(`assertion failed: '(((arr)[7])[0] === "shut")'`)})((((arr)[7])[0] === "shut"))}; + {((cond) => {if (!cond) throw new Error("assertion failed: arr.getAt(0) == 1")})(((arr)[0] === 1))}; + {((cond) => {if (!cond) throw new Error("assertion failed: arr.getAt(2) == b")})(((arr)[2] === b))}; + {((cond) => {if (!cond) throw new Error("assertion failed: arr.getAt(7).getAt(0) == \"shut\"")})((((arr)[7])[0] === "shut"))}; Object.freeze({"a":[1, 2, "world"],"b":[1, 2, "world"]}); const emptyJson = Object.freeze({}); const emptyJsonArr = []; @@ -136,9 +136,73 @@ class $Root extends $stdlib.std.Resource { const theTowerOfJson = {"a":{},"b":{"c":{},"d":[[[{}]]]},"e":{"f":{"g":{},"h":[{}, []]}}}; ((obj, args) => { obj[args[0]] = args[1]; })(((((theTowerOfJson)["e"])["f"])["h"])[0], ["a",1]); const thatSuperNestedValue = (((((theTowerOfJson)["e"])["f"])["h"])[0])["a"]; - {((cond) => {if (!cond) throw new Error(`assertion failed: '(((args) => { if (typeof args !== "number") {throw new Error("unable to parse " + typeof args + " " + args + " as a number")}; return JSON.parse(JSON.stringify(args)) })(thatSuperNestedValue) === 1)'`)})((((args) => { if (typeof args !== "number") {throw new Error("unable to parse " + typeof args + " " + args + " as a number")}; return JSON.parse(JSON.stringify(args)) })(thatSuperNestedValue) === 1))}; + {((cond) => {if (!cond) throw new Error("assertion failed: num.fromJson(thatSuperNestedValue) == 1")})((((args) => { if (typeof args !== "number") {throw new Error("unable to parse " + typeof args + " " + args + " as a number")}; return JSON.parse(JSON.stringify(args)) })(thatSuperNestedValue) === 1))}; const unestedJsonArr = [1, 2, 3]; - {((cond) => {if (!cond) throw new Error(`assertion failed: '((unestedJsonArr)[0] === 1)'`)})(((unestedJsonArr)[0] === 1))}; + {((cond) => {if (!cond) throw new Error("assertion failed: unestedJsonArr.getAt(0) == 1")})(((unestedJsonArr)[0] === 1))}; + const jsonElements = Object.freeze({"strings":{"single":"Hello","array":["Hello", "World", "!"]},"numbers":{"one":1,"two":2,"three":3},"bools":{"t":true,"f":false}}); + { + const $IF_LET_VALUE = ((arg) => { return (typeof arg === "string") ? JSON.parse(JSON.stringify(arg)) : undefined })(((jsonElements)?.["strings"])?.["single"]); + if ($IF_LET_VALUE != undefined) { + const val = $IF_LET_VALUE; + {((cond) => {if (!cond) throw new Error("assertion failed: val == \"Hello\"")})((val === "Hello"))}; + } + else { + {((cond) => {if (!cond) throw new Error("assertion failed: false")})(false)}; + } + } + { + const $IF_LET_VALUE = ((jsonElements)?.["strings"])?.["array"]; + if ($IF_LET_VALUE != undefined) { + const vals = $IF_LET_VALUE; + { + const $IF_LET_VALUE = (vals)?.[0]; + if ($IF_LET_VALUE != undefined) { + const hello = $IF_LET_VALUE; + {((cond) => {if (!cond) throw new Error("assertion failed: hello == \"Hello\"")})((hello === "Hello"))}; + } + else { + {((cond) => {if (!cond) throw new Error("assertion failed: false")})(false)}; + } + } + } + else { + {((cond) => {if (!cond) throw new Error("assertion failed: false")})(false)}; + } + } + { + const $IF_LET_VALUE = ((arg) => { return (typeof arg === "number") ? JSON.parse(JSON.stringify(arg)) : undefined })(((jsonElements)?.["numbers"])?.["two"]); + if ($IF_LET_VALUE != undefined) { + const two = $IF_LET_VALUE; + {((cond) => {if (!cond) throw new Error("assertion failed: two + 2 == 4")})(((two + 2) === 4))}; + } + else { + {((cond) => {if (!cond) throw new Error("assertion failed: false")})(false)}; + } + } + { + const $IF_LET_VALUE = ((arg) => { return (typeof arg === "boolean") ? JSON.parse(JSON.stringify(arg)) : undefined })(((jsonElements)?.["bools"])?.["t"]); + if ($IF_LET_VALUE != undefined) { + const truth = $IF_LET_VALUE; + {((cond) => {if (!cond) throw new Error("assertion failed: truth")})(truth)}; + } + else { + {((cond) => {if (!cond) throw new Error("assertion failed: false")})(false)}; + } + } + { + const $IF_LET_VALUE = ((((jsonElements)?.["strings"])?.["non"])?.["existant"])?.["element"]; + if ($IF_LET_VALUE != undefined) { + const val = $IF_LET_VALUE; + {((cond) => {if (!cond) throw new Error("assertion failed: false")})(false)}; + } + } + { + const $IF_LET_VALUE = (((jsonElements)?.["cant"])?.[1000])?.[42]; + if ($IF_LET_VALUE != undefined) { + const val = $IF_LET_VALUE; + {((cond) => {if (!cond) throw new Error("assertion failed: false")})(false)}; + } + } } } class $App extends $AppBase { diff --git a/tools/hangar/__snapshots__/test_corpus/valid/json.w_test_sim.md b/tools/hangar/__snapshots__/test_corpus/valid/json.w_test_sim.md index 5a22e45f311..7cfbd921cae 100644 --- a/tools/hangar/__snapshots__/test_corpus/valid/json.w_test_sim.md +++ b/tools/hangar/__snapshots__/test_corpus/valid/json.w_test_sim.md @@ -4,12 +4,9 @@ ```log pass โ”€ json.wsim (no tests) - - - - -Tests 1 passed (1) + +Tests 1 passed (1) +Test Files 1 passed (1) Duration - ``` diff --git a/tools/hangar/__snapshots__/test_corpus/valid/json_bucket.w_compile_tf-aws.md b/tools/hangar/__snapshots__/test_corpus/valid/json_bucket.w_compile_tf-aws.md index 51268064971..87ba7f04d67 100644 --- a/tools/hangar/__snapshots__/test_corpus/valid/json_bucket.w_compile_tf-aws.md +++ b/tools/hangar/__snapshots__/test_corpus/valid/json_bucket.w_compile_tf-aws.md @@ -13,7 +13,7 @@ module.exports = function({ b, fileName }) { } async handle(msg) { const x = (await b.getJson(fileName)); - {((cond) => {if (!cond) throw new Error(`assertion failed: '(((((x)["persons"])[0])["fears"])[1] === "failure")'`)})((((((x)["persons"])[0])["fears"])[1] === "failure"))}; + {((cond) => {if (!cond) throw new Error("assertion failed: x.get(\"persons\").getAt(0).get(\"fears\").getAt(1) == \"failure\"")})((((((x)["persons"])[0])["fears"])[1] === "failure"))}; } } return $Closure1; diff --git a/tools/hangar/__snapshots__/test_corpus/valid/json_bucket.w_test_sim.md b/tools/hangar/__snapshots__/test_corpus/valid/json_bucket.w_test_sim.md index ffc9392ee3d..a9b15ec5966 100644 --- a/tools/hangar/__snapshots__/test_corpus/valid/json_bucket.w_test_sim.md +++ b/tools/hangar/__snapshots__/test_corpus/valid/json_bucket.w_test_sim.md @@ -4,12 +4,9 @@ ```log pass โ”€ json_bucket.wsim ยป root/env0/test:put - - - - -Tests 1 passed (1) + +Tests 1 passed (1) +Test Files 1 passed (1) Duration - ``` diff --git a/tools/hangar/__snapshots__/test_corpus/valid/json_static.w_compile_tf-aws.md b/tools/hangar/__snapshots__/test_corpus/valid/json_static.w_compile_tf-aws.md index 93ddcf5ec98..b497644463f 100644 --- a/tools/hangar/__snapshots__/test_corpus/valid/json_static.w_compile_tf-aws.md +++ b/tools/hangar/__snapshots__/test_corpus/valid/json_static.w_compile_tf-aws.md @@ -13,7 +13,7 @@ module.exports = function({ jj, std_Json }) { } async handle() { const ss = ((args) => { return JSON.stringify(args[0], null, args[1]) })([jj]); - {((cond) => {if (!cond) throw new Error(`assertion failed: '(ss === "{\"a\":123,\"b\":{\"c\":456,\"d\":789}}")'`)})((ss === "{\"a\":123,\"b\":{\"c\":456,\"d\":789}}"))}; + {((cond) => {if (!cond) throw new Error("assertion failed: ss == \"{\\\"a\\\":123,\\\"b\\\":{\\\"c\\\":456,\\\"d\\\":789}}\"")})((ss === "{\"a\":123,\"b\":{\"c\":456,\"d\":789}}"))}; } } return $Closure1; @@ -34,8 +34,8 @@ module.exports = function({ std_Json }) { } async handle() { const hasCheck = Object.freeze({"a":"hello","b":"wing"}); - {((cond) => {if (!cond) throw new Error(`assertion failed: '(((args) => { return args[0].hasOwnProperty(args[1]); })([hasCheck,"a"]) === true)'`)})((((args) => { return args[0].hasOwnProperty(args[1]); })([hasCheck,"a"]) === true))}; - {((cond) => {if (!cond) throw new Error(`assertion failed: '(((args) => { return args[0].hasOwnProperty(args[1]); })([hasCheck,"c"]) === false)'`)})((((args) => { return args[0].hasOwnProperty(args[1]); })([hasCheck,"c"]) === false))}; + {((cond) => {if (!cond) throw new Error("assertion failed: Json.has(hasCheck, \"a\") == true")})((((args) => { return args[0].hasOwnProperty(args[1]); })([hasCheck,"a"]) === true))}; + {((cond) => {if (!cond) throw new Error("assertion failed: Json.has(hasCheck, \"c\") == false")})((((args) => { return args[0].hasOwnProperty(args[1]); })([hasCheck,"c"]) === false))}; } } return $Closure2; @@ -315,34 +315,34 @@ class $Root extends $stdlib.std.Resource { } const x = Object.freeze({"a":123,"b":{"c":456,"d":789}}); const k = (Object.keys(x)); - {((cond) => {if (!cond) throw new Error(`assertion failed: '(k.length === 2)'`)})((k.length === 2))}; + {((cond) => {if (!cond) throw new Error("assertion failed: k.length == 2")})((k.length === 2))}; const v = (Object.values(x)); - {((cond) => {if (!cond) throw new Error(`assertion failed: '((v.at(0)) === 123)'`)})(((v.at(0)) === 123))}; + {((cond) => {if (!cond) throw new Error("assertion failed: v.at(0) == 123")})(((v.at(0)) === 123))}; const m = (JSON.parse(JSON.stringify(x))); ((obj, args) => { obj[args[0]] = args[1]; })(m, ["a",321]); - {((cond) => {if (!cond) throw new Error(`assertion failed: '((m)["a"] === 321)'`)})(((m)["a"] === 321))}; + {((cond) => {if (!cond) throw new Error("assertion failed: m.get(\"a\") == 321")})(((m)["a"] === 321))}; const n = Object.freeze(JSON.parse(JSON.stringify(m))); - {((cond) => {if (!cond) throw new Error(`assertion failed: '(m !== n)'`)})((m !== n))}; + {((cond) => {if (!cond) throw new Error("assertion failed: m != n")})((m !== n))}; let k2 = (Object.keys(m)); - {((cond) => {if (!cond) throw new Error(`assertion failed: '(k2.length === 2)'`)})((k2.length === 2))}; + {((cond) => {if (!cond) throw new Error("assertion failed: k2.length == 2")})((k2.length === 2))}; ((args) => { delete (args[0])[args[1]]; })([m,"b"]); k2 = (Object.keys(m)); - {((cond) => {if (!cond) throw new Error(`assertion failed: '(k2.length === 1)'`)})((k2.length === 1))}; + {((cond) => {if (!cond) throw new Error("assertion failed: k2.length == 1")})((k2.length === 1))}; const s = "{\"a\": 123, \"b\": {\"c\": 456, \"d\": 789}}"; const j = (JSON.parse(s)); - {((cond) => {if (!cond) throw new Error(`assertion failed: '((Object.keys(j)).length === 2)'`)})(((Object.keys(j)).length === 2))}; + {((cond) => {if (!cond) throw new Error("assertion failed: Json.keys(j).length == 2")})(((Object.keys(j)).length === 2))}; const invalidJson = "invalid"; const tryParsed = (((args) => { try { return JSON.parse(args); } catch (err) { return undefined; } })(invalidJson) ?? Object.freeze({"key":"value"})); - {((cond) => {if (!cond) throw new Error(`assertion failed: '((tryParsed)["key"] === "value")'`)})(((tryParsed)["key"] === "value"))}; + {((cond) => {if (!cond) throw new Error("assertion failed: tryParsed.get(\"key\") == \"value\"")})(((tryParsed)["key"] === "value"))}; const jj = Object.freeze({"a":123,"b":{"c":456,"d":789}}); const ss = ((args) => { return JSON.stringify(args[0], null, args[1]) })([jj]); - {((cond) => {if (!cond) throw new Error(`assertion failed: '(ss === "{\"a\":123,\"b\":{\"c\":456,\"d\":789}}")'`)})((ss === "{\"a\":123,\"b\":{\"c\":456,\"d\":789}}"))}; + {((cond) => {if (!cond) throw new Error("assertion failed: ss == \"{\\\"a\\\":123,\\\"b\\\":{\\\"c\\\":456,\\\"d\\\":789}}\"")})((ss === "{\"a\":123,\"b\":{\"c\":456,\"d\":789}}"))}; const ss2 = ((args) => { return JSON.stringify(args[0], null, args[1]) })([jj,2]); - {((cond) => {if (!cond) throw new Error(`assertion failed: '(ss2 === "{\n \"a\": 123,\n \"b\": {\n \"c\": 456,\n \"d\": 789\n }\n}")'`)})((ss2 === "{\n \"a\": 123,\n \"b\": {\n \"c\": 456,\n \"d\": 789\n }\n}"))}; + {((cond) => {if (!cond) throw new Error("assertion failed: ss2 == \"{\\n \\\"a\\\": 123,\\n \\\"b\\\": {\\n \\\"c\\\": 456,\\n \\\"d\\\": 789\\n }\\n}\"")})((ss2 === "{\n \"a\": 123,\n \"b\": {\n \"c\": 456,\n \"d\": 789\n }\n}"))}; const jsonOfMany = Object.freeze({"a":123,"b":"hello","c":true}); - {((cond) => {if (!cond) throw new Error(`assertion failed: '(((args) => { if (typeof args !== "string") {throw new Error("unable to parse " + typeof args + " " + args + " as a string")}; return JSON.parse(JSON.stringify(args)) })((jsonOfMany)["b"]) === "hello")'`)})((((args) => { if (typeof args !== "string") {throw new Error("unable to parse " + typeof args + " " + args + " as a string")}; return JSON.parse(JSON.stringify(args)) })((jsonOfMany)["b"]) === "hello"))}; - {((cond) => {if (!cond) throw new Error(`assertion failed: '(((args) => { if (typeof args !== "number") {throw new Error("unable to parse " + typeof args + " " + args + " as a number")}; return JSON.parse(JSON.stringify(args)) })((jsonOfMany)["a"]) === 123)'`)})((((args) => { if (typeof args !== "number") {throw new Error("unable to parse " + typeof args + " " + args + " as a number")}; return JSON.parse(JSON.stringify(args)) })((jsonOfMany)["a"]) === 123))}; - {((cond) => {if (!cond) throw new Error(`assertion failed: '(std.Boolean.fromJson((jsonOfMany)["c"]))'`)})((std.Boolean.fromJson((jsonOfMany)["c"])))}; + {((cond) => {if (!cond) throw new Error("assertion failed: str.fromJson(jsonOfMany.get(\"b\")) == \"hello\"")})((((args) => { if (typeof args !== "string") {throw new Error("unable to parse " + typeof args + " " + args + " as a string")}; return JSON.parse(JSON.stringify(args)) })((jsonOfMany)["b"]) === "hello"))}; + {((cond) => {if (!cond) throw new Error("assertion failed: num.fromJson(jsonOfMany.get(\"a\")) == 123")})((((args) => { if (typeof args !== "number") {throw new Error("unable to parse " + typeof args + " " + args + " as a number")}; return JSON.parse(JSON.stringify(args)) })((jsonOfMany)["a"]) === 123))}; + {((cond) => {if (!cond) throw new Error("assertion failed: bool.fromJson(jsonOfMany.get(\"c\"))")})((std.Boolean.fromJson((jsonOfMany)["c"])))}; this.node.root.new("@winglang/sdk.std.Test",std.Test,this,"test:Access Json static inflight",new $Closure1(this,"$Closure1")); this.node.root.new("@winglang/sdk.std.Test",std.Test,this,"test:has key or not",new $Closure2(this,"$Closure2")); } diff --git a/tools/hangar/__snapshots__/test_corpus/valid/json_static.w_test_sim.md b/tools/hangar/__snapshots__/test_corpus/valid/json_static.w_test_sim.md index 86a5ff42955..4ef8b033e47 100644 --- a/tools/hangar/__snapshots__/test_corpus/valid/json_static.w_test_sim.md +++ b/tools/hangar/__snapshots__/test_corpus/valid/json_static.w_test_sim.md @@ -5,12 +5,9 @@ pass โ”€ json_static.wsim ยป root/env0/test:Access Json static inflight pass โ”€ json_static.wsim ยป root/env1/test:has key or not - - - - -Tests 1 passed (1) + +Tests 2 passed (2) +Test Files 1 passed (1) Duration - ``` diff --git a/tools/hangar/__snapshots__/test_corpus/valid/json_string_interpolation.w_compile_tf-aws.md b/tools/hangar/__snapshots__/test_corpus/valid/json_string_interpolation.w_compile_tf-aws.md new file mode 100644 index 00000000000..4a134c7f47c --- /dev/null +++ b/tools/hangar/__snapshots__/test_corpus/valid/json_string_interpolation.w_compile_tf-aws.md @@ -0,0 +1,70 @@ +# [json_string_interpolation.w](../../../../../examples/tests/valid/json_string_interpolation.w) | compile | tf-aws + +## main.tf.json +```json +{ + "//": { + "metadata": { + "backend": "local", + "stackName": "root", + "version": "0.15.2" + }, + "outputs": { + "root": { + "Default": { + "cloud.TestRunner": { + "TestFunctionArns": "WING_TEST_RUNNER_FUNCTION_ARNS" + } + } + } + } + }, + "output": { + "WING_TEST_RUNNER_FUNCTION_ARNS": { + "value": "[]" + } + }, + "provider": { + "aws": [ + {} + ] + } +} +``` + +## preflight.js +```js +const $stdlib = require('@winglang/sdk'); +const $outdir = process.env.WING_SYNTH_DIR ?? "."; +const std = $stdlib.std; +const $wing_is_test = process.env.WING_IS_TEST === "true"; +const $AppBase = $stdlib.core.App.for(process.env.WING_TARGET); +class $Root extends $stdlib.std.Resource { + constructor(scope, id) { + super(scope, id); + const obj = Object.freeze({"strValue":"test","numValue":1}); + const notStringifyStrValue = String.raw({ raw: ["string: ", ""] }, ((e) => typeof e === 'string' ? e : JSON.stringify(e, null, 2))((obj)["strValue"])); + {((cond) => {if (!cond) throw new Error("assertion failed: notStringifyStrValue == \"string: test\"")})((notStringifyStrValue === "string: test"))}; + const stringifyNumValue = String.raw({ raw: ["number: ", ""] }, ((e) => typeof e === 'string' ? e : JSON.stringify(e, null, 2))((obj)["numValue"])); + {((cond) => {if (!cond) throw new Error("assertion failed: stringifyNumValue == \"number: 1\"")})((stringifyNumValue === "number: 1"))}; + } +} +class $App extends $AppBase { + constructor() { + super({ outdir: $outdir, name: "json_string_interpolation", plugins: $plugins, isTestEnvironment: $wing_is_test }); + if ($wing_is_test) { + new $Root(this, "env0"); + const $test_runner = this.testRunner; + const $tests = $test_runner.findTests(); + for (let $i = 1; $i < $tests.length; $i++) { + new $Root(this, "env" + $i); + } + } else { + new $Root(this, "Default"); + } + } +} +new $App().synth(); + +``` + diff --git a/tools/hangar/__snapshots__/test_corpus/valid/json_string_interpolation.w_test_sim.md b/tools/hangar/__snapshots__/test_corpus/valid/json_string_interpolation.w_test_sim.md new file mode 100644 index 00000000000..8a4e62fb653 --- /dev/null +++ b/tools/hangar/__snapshots__/test_corpus/valid/json_string_interpolation.w_test_sim.md @@ -0,0 +1,12 @@ +# [json_string_interpolation.w](../../../../../examples/tests/valid/json_string_interpolation.w) | test | sim + +## stdout.log +```log +pass โ”€ json_string_interpolation.wsim (no tests) + + +Tests 1 passed (1) +Test Files 1 passed (1) +Duration +``` + diff --git a/tools/hangar/__snapshots__/test_corpus/valid/mut_container_types.w_compile_tf-aws.md b/tools/hangar/__snapshots__/test_corpus/valid/mut_container_types.w_compile_tf-aws.md index bfa999faeb0..99e65aeea1a 100644 --- a/tools/hangar/__snapshots__/test_corpus/valid/mut_container_types.w_compile_tf-aws.md +++ b/tools/hangar/__snapshots__/test_corpus/valid/mut_container_types.w_compile_tf-aws.md @@ -178,35 +178,35 @@ class $Root extends $stdlib.std.Resource { (arr1.push("a")); (arr2.push(4)); (arr3.push(bucket3)); - {((cond) => {if (!cond) throw new Error(`assertion failed: '((arr2.pop()) === 4)'`)})(((arr2.pop()) === 4))}; - {((cond) => {if (!cond) throw new Error(`assertion failed: '(arr1.length === 4)'`)})((arr1.length === 4))}; - {((cond) => {if (!cond) throw new Error(`assertion failed: '((arr4.at(0)) === "a")'`)})(((arr4.at(0)) === "a"))}; + {((cond) => {if (!cond) throw new Error("assertion failed: arr2.pop() == 4")})(((arr2.pop()) === 4))}; + {((cond) => {if (!cond) throw new Error("assertion failed: arr1.length == 4")})((arr1.length === 4))}; + {((cond) => {if (!cond) throw new Error("assertion failed: arr4.at(0) == \"a\"")})(((arr4.at(0)) === "a"))}; const s1 = new Set([1, 2, 3, 3]); const s2 = new Set(["hello", "world", "hello"]); const s3 = new Set([bucket1, bucket2, bucket2]); (s1.add(5)); (s2.add("bye")); (s3.add(bucket3)); - {((cond) => {if (!cond) throw new Error(`assertion failed: '(s2.has("bye"))'`)})((s2.has("bye")))}; - {((cond) => {if (!cond) throw new Error(`assertion failed: '(s2.has("hello"))'`)})((s2.has("hello")))}; - {((cond) => {if (!cond) throw new Error(`assertion failed: '(s3.has(bucket2))'`)})((s3.has(bucket2)))}; + {((cond) => {if (!cond) throw new Error("assertion failed: s2.has(\"bye\")")})((s2.has("bye")))}; + {((cond) => {if (!cond) throw new Error("assertion failed: s2.has(\"hello\")")})((s2.has("hello")))}; + {((cond) => {if (!cond) throw new Error("assertion failed: s3.has(bucket2)")})((s3.has(bucket2)))}; const m1 = {"hello":"world"}; const m2 = {"hello":123}; const m3 = {"b1":bucket1,"b2":bucket2}; const m4 = m1; const m5 = {"goodbye":"world"}; const m6 = {"a":m1,"b":m5}; - {((cond) => {if (!cond) throw new Error(`assertion failed: '("hello" in (m1))'`)})(("hello" in (m1)))}; - {((cond) => {if (!cond) throw new Error(`assertion failed: '(Object.keys(m2).length === 1)'`)})((Object.keys(m2).length === 1))}; - {((cond) => {if (!cond) throw new Error(`assertion failed: '((m3)["b1"] === bucket1)'`)})(((m3)["b1"] === bucket1))}; - {((cond) => {if (!cond) throw new Error(`assertion failed: '(Object.keys(m4).length === 1)'`)})((Object.keys(m4).length === 1))}; - {((cond) => {if (!cond) throw new Error(`assertion failed: '(((m6)["a"])["hello"] === "world")'`)})((((m6)["a"])["hello"] === "world"))}; + {((cond) => {if (!cond) throw new Error("assertion failed: m1.has(\"hello\")")})(("hello" in (m1)))}; + {((cond) => {if (!cond) throw new Error("assertion failed: m2.size() == 1")})((Object.keys(m2).length === 1))}; + {((cond) => {if (!cond) throw new Error("assertion failed: m3.get(\"b1\") == bucket1")})(((m3)["b1"] === bucket1))}; + {((cond) => {if (!cond) throw new Error("assertion failed: m4.size() == 1")})((Object.keys(m4).length === 1))}; + {((cond) => {if (!cond) throw new Error("assertion failed: m6.get(\"a\").get(\"hello\") == \"world\"")})((((m6)["a"])["hello"] === "world"))}; ((obj, args) => { obj[args[0]] = args[1]; })(m1, ["hello","goodbye"]); ((obj, args) => { obj[args[0]] = args[1]; })(m6, ["a",{"foo":"bar"}]); ((map) => { for(const k in map){delete map[k]}; })(m2); - {((cond) => {if (!cond) throw new Error(`assertion failed: '(Object.keys(m2).length === 0)'`)})((Object.keys(m2).length === 0))}; - {((cond) => {if (!cond) throw new Error(`assertion failed: '((m1)["hello"] === "goodbye")'`)})(((m1)["hello"] === "goodbye"))}; - {((cond) => {if (!cond) throw new Error(`assertion failed: '(((m6)["a"])["foo"] === "bar")'`)})((((m6)["a"])["foo"] === "bar"))}; + {((cond) => {if (!cond) throw new Error("assertion failed: m2.size() == 0")})((Object.keys(m2).length === 0))}; + {((cond) => {if (!cond) throw new Error("assertion failed: m1.get(\"hello\") == \"goodbye\"")})(((m1)["hello"] === "goodbye"))}; + {((cond) => {if (!cond) throw new Error("assertion failed: m6.get(\"a\").get(\"foo\") == \"bar\"")})((((m6)["a"])["foo"] === "bar"))}; } } class $App extends $AppBase { diff --git a/tools/hangar/__snapshots__/test_corpus/valid/mut_container_types.w_test_sim.md b/tools/hangar/__snapshots__/test_corpus/valid/mut_container_types.w_test_sim.md index 036bfc5f6c1..ad8c694100f 100644 --- a/tools/hangar/__snapshots__/test_corpus/valid/mut_container_types.w_test_sim.md +++ b/tools/hangar/__snapshots__/test_corpus/valid/mut_container_types.w_test_sim.md @@ -4,12 +4,9 @@ ```log pass โ”€ mut_container_types.wsim (no tests) - - - - -Tests 1 passed (1) + +Tests 1 passed (1) +Test Files 1 passed (1) Duration - ``` diff --git a/tools/hangar/__snapshots__/test_corpus/valid/nil.w_compile_tf-aws.md b/tools/hangar/__snapshots__/test_corpus/valid/nil.w_compile_tf-aws.md index 94e1e0b177f..f1690b2f88c 100644 --- a/tools/hangar/__snapshots__/test_corpus/valid/nil.w_compile_tf-aws.md +++ b/tools/hangar/__snapshots__/test_corpus/valid/nil.w_compile_tf-aws.md @@ -12,8 +12,8 @@ module.exports = function({ foo }) { async $inflight_init() { } async handle() { - {((cond) => {if (!cond) throw new Error(`assertion failed: '((((await foo.returnNil(true))) != null) === true)'`)})(((((await foo.returnNil(true))) != null) === true))}; - {((cond) => {if (!cond) throw new Error(`assertion failed: '((((await foo.returnNil(false))) != null) === false)'`)})(((((await foo.returnNil(false))) != null) === false))}; + {((cond) => {if (!cond) throw new Error("assertion failed: foo.returnNil(true)? == true")})(((((await foo.returnNil(true))) != null) === true))}; + {((cond) => {if (!cond) throw new Error("assertion failed: foo.returnNil(false)? == false")})(((((await foo.returnNil(false))) != null) === false))}; } } return $Closure1; @@ -33,13 +33,13 @@ module.exports = function({ foo }) { async $inflight_init() { } async handle() { - {((cond) => {if (!cond) throw new Error(`assertion failed: '((((await foo.getOptionalValue())) != null) === false)'`)})(((((await foo.getOptionalValue())) != null) === false))}; + {((cond) => {if (!cond) throw new Error("assertion failed: foo.getOptionalValue()? == false")})(((((await foo.getOptionalValue())) != null) === false))}; (await foo.setOptionalValue("hello")); - {((cond) => {if (!cond) throw new Error(`assertion failed: '((((await foo.getOptionalValue())) != null) === true)'`)})(((((await foo.getOptionalValue())) != null) === true))}; - {((cond) => {if (!cond) throw new Error(`assertion failed: '((await foo.getOptionalValue()) !== undefined)'`)})(((await foo.getOptionalValue()) !== undefined))}; + {((cond) => {if (!cond) throw new Error("assertion failed: foo.getOptionalValue()? == true")})(((((await foo.getOptionalValue())) != null) === true))}; + {((cond) => {if (!cond) throw new Error("assertion failed: foo.getOptionalValue() != nil")})(((await foo.getOptionalValue()) !== undefined))}; (await foo.setOptionalValue(undefined)); - {((cond) => {if (!cond) throw new Error(`assertion failed: '((((await foo.getOptionalValue())) != null) === false)'`)})(((((await foo.getOptionalValue())) != null) === false))}; - {((cond) => {if (!cond) throw new Error(`assertion failed: '((await foo.getOptionalValue()) === undefined)'`)})(((await foo.getOptionalValue()) === undefined))}; + {((cond) => {if (!cond) throw new Error("assertion failed: foo.getOptionalValue()? == false")})(((((await foo.getOptionalValue())) != null) === false))}; + {((cond) => {if (!cond) throw new Error("assertion failed: foo.getOptionalValue() == nil")})(((await foo.getOptionalValue()) === undefined))}; } } return $Closure2; diff --git a/tools/hangar/__snapshots__/test_corpus/valid/nil.w_test_sim.md b/tools/hangar/__snapshots__/test_corpus/valid/nil.w_test_sim.md index 7eaa7bfd666..52be06c55a3 100644 --- a/tools/hangar/__snapshots__/test_corpus/valid/nil.w_test_sim.md +++ b/tools/hangar/__snapshots__/test_corpus/valid/nil.w_test_sim.md @@ -5,12 +5,9 @@ pass โ”€ nil.wsim ยป root/env0/test:nil return pass โ”€ nil.wsim ยป root/env1/test:optional instance variable - - - - -Tests 1 passed (1) + +Tests 2 passed (2) +Test Files 1 passed (1) Duration - ``` diff --git a/tools/hangar/__snapshots__/test_corpus/valid/optionals.w_compile_tf-aws.md b/tools/hangar/__snapshots__/test_corpus/valid/optionals.w_compile_tf-aws.md index 88c3130f39d..6bd83f41cb8 100644 --- a/tools/hangar/__snapshots__/test_corpus/valid/optionals.w_compile_tf-aws.md +++ b/tools/hangar/__snapshots__/test_corpus/valid/optionals.w_compile_tf-aws.md @@ -12,7 +12,7 @@ module.exports = function({ payloadWithoutOptions, payloadWithBucket }) { async $inflight_init() { } async handle() { - {((cond) => {if (!cond) throw new Error(`assertion failed: '(((payloadWithoutOptions.b) != null) === false)'`)})((((payloadWithoutOptions.b) != null) === false))}; + {((cond) => {if (!cond) throw new Error("assertion failed: payloadWithoutOptions.b? == false")})((((payloadWithoutOptions.b) != null) === false))}; if (((payloadWithBucket.c) != null)) { (await payloadWithBucket.c.put("x.txt","something")); } @@ -441,14 +441,14 @@ class $Root extends $stdlib.std.Resource { } } const x = 4; - {((cond) => {if (!cond) throw new Error(`assertion failed: '(((x) != null) === true)'`)})((((x) != null) === true))}; - {((cond) => {if (!cond) throw new Error(`assertion failed: '((!((x) != null)) === false)'`)})(((!((x) != null)) === false))}; - {((cond) => {if (!cond) throw new Error(`assertion failed: '((x ?? 5) === 4)'`)})(((x ?? 5) === 4))}; + {((cond) => {if (!cond) throw new Error("assertion failed: x? == true")})((((x) != null) === true))}; + {((cond) => {if (!cond) throw new Error("assertion failed: !x? == false")})(((!((x) != null)) === false))}; + {((cond) => {if (!cond) throw new Error("assertion failed: x ?? 5 == 4")})(((x ?? 5) === 4))}; const y = (x ?? 5); - {((cond) => {if (!cond) throw new Error(`assertion failed: '(y === 4)'`)})((y === 4))}; + {((cond) => {if (!cond) throw new Error("assertion failed: y == 4")})((y === 4))}; const optionalSup = new Super(this,"Super"); const s = (optionalSup ?? new Sub(this,"Sub")); - {((cond) => {if (!cond) throw new Error(`assertion failed: '(s.name === "Super")'`)})((s.name === "Super"))}; + {((cond) => {if (!cond) throw new Error("assertion failed: s.name == \"Super\"")})((s.name === "Super"))}; let name = { "first": "John", "last": "Doe",} @@ -457,7 +457,7 @@ class $Root extends $stdlib.std.Resource { const $IF_LET_VALUE = name; if ($IF_LET_VALUE != undefined) { const n = $IF_LET_VALUE; - {((cond) => {if (!cond) throw new Error(`assertion failed: '(n.first === "John")'`)})((n.first === "John"))}; + {((cond) => {if (!cond) throw new Error("assertion failed: n.first == \"John\"")})((n.first === "John"))}; } } name = undefined; @@ -465,10 +465,10 @@ class $Root extends $stdlib.std.Resource { const $IF_LET_VALUE = name; if ($IF_LET_VALUE != undefined) { const n = $IF_LET_VALUE; - {((cond) => {if (!cond) throw new Error(`assertion failed: 'false'`)})(false)}; + {((cond) => {if (!cond) throw new Error("assertion failed: false")})(false)}; } else { - {((cond) => {if (!cond) throw new Error(`assertion failed: 'true'`)})(true)}; + {((cond) => {if (!cond) throw new Error("assertion failed: true")})(true)}; } } const tryParseName = (fullName) => { @@ -486,15 +486,15 @@ class $Root extends $stdlib.std.Resource { const $IF_LET_VALUE = (tryParseName("Good Name")); if ($IF_LET_VALUE != undefined) { const parsedName = $IF_LET_VALUE; - {((cond) => {if (!cond) throw new Error(`assertion failed: '(parsedName.first === "Good")'`)})((parsedName.first === "Good"))}; + {((cond) => {if (!cond) throw new Error("assertion failed: parsedName.first == \"Good\"")})((parsedName.first === "Good"))}; { const $IF_LET_VALUE = parsedName.last; if ($IF_LET_VALUE != undefined) { const lastName = $IF_LET_VALUE; - {((cond) => {if (!cond) throw new Error(`assertion failed: '(lastName === "Name")'`)})((lastName === "Name"))}; + {((cond) => {if (!cond) throw new Error("assertion failed: lastName == \"Name\"")})((lastName === "Name"))}; } else { - {((cond) => {if (!cond) throw new Error(`assertion failed: 'false'`)})(false)}; + {((cond) => {if (!cond) throw new Error("assertion failed: false")})(false)}; } } } @@ -503,12 +503,12 @@ class $Root extends $stdlib.std.Resource { const $IF_LET_VALUE = (tryParseName("BadName")); if ($IF_LET_VALUE != undefined) { const parsedName = $IF_LET_VALUE; - {((cond) => {if (!cond) throw new Error(`assertion failed: '(parsedName.first === "BadName")'`)})((parsedName.first === "BadName"))}; + {((cond) => {if (!cond) throw new Error("assertion failed: parsedName.first == \"BadName\"")})((parsedName.first === "BadName"))}; { const $IF_LET_VALUE = parsedName.last; if ($IF_LET_VALUE != undefined) { const lastName = $IF_LET_VALUE; - {((cond) => {if (!cond) throw new Error(`assertion failed: 'false'`)})(false)}; + {((cond) => {if (!cond) throw new Error("assertion failed: false")})(false)}; } } } @@ -518,10 +518,10 @@ class $Root extends $stdlib.std.Resource { const $IF_LET_VALUE = falsy; if ($IF_LET_VALUE != undefined) { const f = $IF_LET_VALUE; - {((cond) => {if (!cond) throw new Error(`assertion failed: '(f === false)'`)})((f === false))}; + {((cond) => {if (!cond) throw new Error("assertion failed: f == false")})((f === false))}; } else { - {((cond) => {if (!cond) throw new Error(`assertion failed: 'false'`)})(false)}; + {((cond) => {if (!cond) throw new Error("assertion failed: false")})(false)}; } } const shadow = "root"; @@ -529,16 +529,16 @@ class $Root extends $stdlib.std.Resource { const $IF_LET_VALUE = shadow; if ($IF_LET_VALUE != undefined) { const shadow = $IF_LET_VALUE; - {((cond) => {if (!cond) throw new Error(`assertion failed: '(shadow === "root")'`)})((shadow === "root"))}; + {((cond) => {if (!cond) throw new Error("assertion failed: shadow == \"root\"")})((shadow === "root"))}; const shadow1 = "nested"; { const $IF_LET_VALUE = shadow1; if ($IF_LET_VALUE != undefined) { const shadow1 = $IF_LET_VALUE; - {((cond) => {if (!cond) throw new Error(`assertion failed: '(shadow1 === "nested")'`)})((shadow1 === "nested"))}; + {((cond) => {if (!cond) throw new Error("assertion failed: shadow1 == \"nested\"")})((shadow1 === "nested"))}; } else { - {((cond) => {if (!cond) throw new Error(`assertion failed: 'false'`)})(false)}; + {((cond) => {if (!cond) throw new Error("assertion failed: false")})(false)}; } } } @@ -556,18 +556,18 @@ class $Root extends $stdlib.std.Resource { } } ; - {((cond) => {if (!cond) throw new Error(`assertion failed: '((fun("hello")) === "hello")'`)})(((fun("hello")) === "hello"))}; - {((cond) => {if (!cond) throw new Error(`assertion failed: '((fun(undefined)) === "default")'`)})(((fun(undefined)) === "default"))}; + {((cond) => {if (!cond) throw new Error("assertion failed: fun(\"hello\") == \"hello\"")})(((fun("hello")) === "hello"))}; + {((cond) => {if (!cond) throw new Error("assertion failed: fun(nil) == \"default\"")})(((fun(undefined)) === "default"))}; const tree = new Node(this,"eight",8,new Node(this,"three",3,new Node(this,"one",1,undefined,undefined),new Node(this,"six",6,undefined,undefined)),new Node(this,"ten",10,undefined,new Node(this,"fourteen",14,new Node(this,"thirteen",13,undefined,undefined),undefined))); const thirteen = tree.right.right.left.value; const notThere = tree.right.right.right; - {((cond) => {if (!cond) throw new Error(`assertion failed: '(thirteen === 13)'`)})((thirteen === 13))}; - {((cond) => {if (!cond) throw new Error(`assertion failed: '(notThere === undefined)'`)})((notThere === undefined))}; + {((cond) => {if (!cond) throw new Error("assertion failed: thirteen == 13")})((thirteen === 13))}; + {((cond) => {if (!cond) throw new Error("assertion failed: notThere == nil")})((notThere === undefined))}; { const $IF_LET_VALUE = tree.left.left; if ($IF_LET_VALUE != undefined) { const o = $IF_LET_VALUE; - {((cond) => {if (!cond) throw new Error(`assertion failed: '(o.value === 1)'`)})((o.value === 1))}; + {((cond) => {if (!cond) throw new Error("assertion failed: o.value == 1")})((o.value === 1))}; } } const payloadWithoutOptions = { diff --git a/tools/hangar/__snapshots__/test_corpus/valid/optionals.w_test_sim.md b/tools/hangar/__snapshots__/test_corpus/valid/optionals.w_test_sim.md index c8befe9036e..67b48e49dd3 100644 --- a/tools/hangar/__snapshots__/test_corpus/valid/optionals.w_test_sim.md +++ b/tools/hangar/__snapshots__/test_corpus/valid/optionals.w_test_sim.md @@ -4,12 +4,9 @@ ```log pass โ”€ optionals.wsim ยป root/env0/test:t - - - - -Tests 1 passed (1) + +Tests 1 passed (1) +Test Files 1 passed (1) Duration - ``` diff --git a/tools/hangar/__snapshots__/test_corpus/valid/primitive_methods.w_compile_tf-aws.md b/tools/hangar/__snapshots__/test_corpus/valid/primitive_methods.w_compile_tf-aws.md index 158b78a4c65..52831faed87 100644 --- a/tools/hangar/__snapshots__/test_corpus/valid/primitive_methods.w_compile_tf-aws.md +++ b/tools/hangar/__snapshots__/test_corpus/valid/primitive_methods.w_compile_tf-aws.md @@ -47,12 +47,12 @@ class $Root extends $stdlib.std.Resource { const f = (d) => { } ; - const stringy = `${dur.minutes}:${dur.seconds}`; + const stringy = String.raw({ raw: ["", ":", ""] }, dur.minutes, dur.seconds); {console.log(stringy)}; if ((stringy.includes("60") && (((stringy.split(":")).at(0)) === "60"))) { - {console.log(`${stringy.length}!`)}; + {console.log(String.raw({ raw: ["", "!"] }, stringy.length))}; } - {((cond) => {if (!cond) throw new Error(`assertion failed: '(((args) => { if (isNaN(args)) {throw new Error("unable to parse \"" + args + "\" as a number")}; return parseInt(args) })("123") === 123)'`)})((((args) => { if (isNaN(args)) {throw new Error("unable to parse \"" + args + "\" as a number")}; return parseInt(args) })("123") === 123))}; + {((cond) => {if (!cond) throw new Error("assertion failed: num.fromStr(\"123\") == 123")})((((args) => { if (isNaN(args)) {throw new Error("unable to parse \"" + args + "\" as a number")}; return parseInt(args) })("123") === 123))}; } } class $App extends $AppBase { diff --git a/tools/hangar/__snapshots__/test_corpus/valid/primitive_methods.w_test_sim.md b/tools/hangar/__snapshots__/test_corpus/valid/primitive_methods.w_test_sim.md index 8f208242c8c..ee78b721d90 100644 --- a/tools/hangar/__snapshots__/test_corpus/valid/primitive_methods.w_test_sim.md +++ b/tools/hangar/__snapshots__/test_corpus/valid/primitive_methods.w_test_sim.md @@ -5,12 +5,9 @@ 1:60 pass โ”€ primitive_methods.wsim (no tests) - - - - -Tests 1 passed (1) + +Tests 1 passed (1) +Test Files 1 passed (1) Duration - ``` diff --git a/tools/hangar/__snapshots__/test_corpus/valid/print.w_test_sim.md b/tools/hangar/__snapshots__/test_corpus/valid/print.w_test_sim.md index 47bd0f01485..4d305c46a5f 100644 --- a/tools/hangar/__snapshots__/test_corpus/valid/print.w_test_sim.md +++ b/tools/hangar/__snapshots__/test_corpus/valid/print.w_test_sim.md @@ -11,12 +11,9 @@ pass โ”Œ print.wsim ยป root/env1/test:log2 โ”‚ inflight log 2.1 โ”” inflight log 2.2 - - - - -Tests 1 passed (1) + +Tests 2 passed (2) +Test Files 1 passed (1) Duration - ``` diff --git a/tools/hangar/__snapshots__/test_corpus/valid/reassignment.w_compile_tf-aws.md b/tools/hangar/__snapshots__/test_corpus/valid/reassignment.w_compile_tf-aws.md index a3a2dea6c4d..843ae77e038 100644 --- a/tools/hangar/__snapshots__/test_corpus/valid/reassignment.w_compile_tf-aws.md +++ b/tools/hangar/__snapshots__/test_corpus/valid/reassignment.w_compile_tf-aws.md @@ -4,7 +4,8 @@ ```js module.exports = function({ }) { class R { - constructor({ f1 }) { + constructor({ f, f1 }) { + this.f = f; this.f1 = f1; } async $inflight_init() { @@ -76,11 +77,13 @@ class $Root extends $stdlib.std.Resource { `); } _toInflight() { + const f_client = this._lift(this.f); const f1_client = this._lift(this.f1); return $stdlib.core.NodeJsCode.fromInline(` (await (async () => { const RClient = ${R._toInflightType(this).text}; const client = new RClient({ + f: ${f_client}, f1: ${f1_client}, }); if (client.$inflight_init) { await client.$inflight_init(); } @@ -90,26 +93,27 @@ class $Root extends $stdlib.std.Resource { } _registerBind(host, ops) { if (ops.includes("$inflight_init")) { + R._registerBindObject(this.f, host, []); R._registerBindObject(this.f1, host, []); } super._registerBind(host, ops); } } let x = 5; - {((cond) => {if (!cond) throw new Error(`assertion failed: '(x === 5)'`)})((x === 5))}; + {((cond) => {if (!cond) throw new Error("assertion failed: x == 5")})((x === 5))}; x = (x + 1); - {((cond) => {if (!cond) throw new Error(`assertion failed: '(x === 6)'`)})((x === 6))}; + {((cond) => {if (!cond) throw new Error("assertion failed: x == 6")})((x === 6))}; const r = new R(this,"R"); (r.inc()); - {((cond) => {if (!cond) throw new Error(`assertion failed: '(r.f === 2)'`)})((r.f === 2))}; + {((cond) => {if (!cond) throw new Error("assertion failed: r.f == 2")})((r.f === 2))}; const f = (arg) => { arg = 0; return arg; } ; const y = 1; - {((cond) => {if (!cond) throw new Error(`assertion failed: '((f(y)) === 0)'`)})(((f(y)) === 0))}; - {((cond) => {if (!cond) throw new Error(`assertion failed: '(y === 1)'`)})((y === 1))}; + {((cond) => {if (!cond) throw new Error("assertion failed: f(y) == 0")})(((f(y)) === 0))}; + {((cond) => {if (!cond) throw new Error("assertion failed: y == 1")})((y === 1))}; } } class $App extends $AppBase { diff --git a/tools/hangar/__snapshots__/test_corpus/valid/reassignment.w_test_sim.md b/tools/hangar/__snapshots__/test_corpus/valid/reassignment.w_test_sim.md index b7d18b9db46..716e7975fe8 100644 --- a/tools/hangar/__snapshots__/test_corpus/valid/reassignment.w_test_sim.md +++ b/tools/hangar/__snapshots__/test_corpus/valid/reassignment.w_test_sim.md @@ -4,12 +4,9 @@ ```log pass โ”€ reassignment.wsim (no tests) - - - - -Tests 1 passed (1) + +Tests 1 passed (1) +Test Files 1 passed (1) Duration - ``` diff --git a/tools/hangar/__snapshots__/test_corpus/valid/redis.w_compile_tf-aws.md b/tools/hangar/__snapshots__/test_corpus/valid/redis.w_compile_tf-aws.md index f11917abe95..a78a976cb9d 100644 --- a/tools/hangar/__snapshots__/test_corpus/valid/redis.w_compile_tf-aws.md +++ b/tools/hangar/__snapshots__/test_corpus/valid/redis.w_compile_tf-aws.md @@ -15,10 +15,10 @@ module.exports = function({ r, r2 }) { const connection = (await r.rawClient()); (await connection.set("wing","does redis")); const value = (await connection.get("wing")); - {((cond) => {if (!cond) throw new Error(`assertion failed: '(value === "does redis")'`)})((value === "does redis"))}; + {((cond) => {if (!cond) throw new Error("assertion failed: value == \"does redis\"")})((value === "does redis"))}; (await r2.set("wing","does redis again")); const value2 = (await r2.get("wing")); - {((cond) => {if (!cond) throw new Error(`assertion failed: '(value2 === "does redis again")'`)})((value2 === "does redis again"))}; + {((cond) => {if (!cond) throw new Error("assertion failed: value2 == \"does redis again\"")})((value2 === "does redis again"))}; } } return $Closure1; diff --git a/tools/hangar/__snapshots__/test_corpus/valid/redis.w_test_sim.md b/tools/hangar/__snapshots__/test_corpus/valid/redis.w_test_sim.md index 15a1b95851f..fae9f3c9e52 100644 --- a/tools/hangar/__snapshots__/test_corpus/valid/redis.w_test_sim.md +++ b/tools/hangar/__snapshots__/test_corpus/valid/redis.w_test_sim.md @@ -4,12 +4,9 @@ ```log pass โ”€ redis.wsim ยป root/env0/test:test - - - - -Tests 1 passed (1) + +Tests 1 passed (1) +Test Files 1 passed (1) Duration - ``` diff --git a/tools/hangar/__snapshots__/test_corpus/valid/resource.w_compile_tf-aws.md b/tools/hangar/__snapshots__/test_corpus/valid/resource.w_compile_tf-aws.md index e8e5c77422e..d0453c9805c 100644 --- a/tools/hangar/__snapshots__/test_corpus/valid/resource.w_compile_tf-aws.md +++ b/tools/hangar/__snapshots__/test_corpus/valid/resource.w_compile_tf-aws.md @@ -13,9 +13,9 @@ module.exports = function({ res, bucket }) { } async handle() { const s = (await res.myMethod()); - {((cond) => {if (!cond) throw new Error(`assertion failed: '(s === "counter is: 101")'`)})((s === "counter is: 101"))}; - {((cond) => {if (!cond) throw new Error(`assertion failed: '((await bucket.list()).length === 1)'`)})(((await bucket.list()).length === 1))}; - {((cond) => {if (!cond) throw new Error(`assertion failed: '(res.foo.inflightField === 123)'`)})((res.foo.inflightField === 123))}; + {((cond) => {if (!cond) throw new Error("assertion failed: s == \"counter is: 101\"")})((s === "counter is: 101"))}; + {((cond) => {if (!cond) throw new Error("assertion failed: bucket.list().length == 1")})(((await bucket.list()).length === 1))}; + {((cond) => {if (!cond) throw new Error("assertion failed: res.foo.inflightField == 123")})((res.foo.inflightField === 123))}; (await res.testTypeAccess()); } } @@ -123,14 +123,14 @@ module.exports = function({ Foo, MyEnum }) { async myMethod() { (await this.foo.fooInc()); const s = (await Foo.fooStatic()); - (await this.b.put("foo",`counter is: ${(await this.foo.fooGet())}`)); + (await this.b.put("foo",String.raw({ raw: ["counter is: ", ""] }, (await this.foo.fooGet())))); return (await this.b.get("foo")); } async testTypeAccess() { if (true) { - {((cond) => {if (!cond) throw new Error(`assertion failed: '((await Bar.barStatic()) === "bar static")'`)})(((await Bar.barStatic()) === "bar static"))}; - {((cond) => {if (!cond) throw new Error(`assertion failed: '((await Foo.fooStatic()) === "foo static")'`)})(((await Foo.fooStatic()) === "foo static"))}; - {((cond) => {if (!cond) throw new Error(`assertion failed: '(this.e === MyEnum.B)'`)})((this.e === MyEnum.B))}; + {((cond) => {if (!cond) throw new Error("assertion failed: Bar.barStatic() == \"bar static\"")})(((await Bar.barStatic()) === "bar static"))}; + {((cond) => {if (!cond) throw new Error("assertion failed: Foo.fooStatic() == \"foo static\"")})(((await Foo.fooStatic()) === "foo static"))}; + {((cond) => {if (!cond) throw new Error("assertion failed: this.e == MyEnum.B")})((this.e === MyEnum.B))}; } } } @@ -1303,13 +1303,13 @@ class $Root extends $stdlib.std.Resource { constructor(scope, id, ) { super(scope, id); const d1 = new Dummy(this,"Dummy"); - {((cond) => {if (!cond) throw new Error(`assertion failed: 'd1.node.path.endsWith("/ScopeAndIdTestClass/Dummy")'`)})(d1.node.path.endsWith("/ScopeAndIdTestClass/Dummy"))}; + {((cond) => {if (!cond) throw new Error("assertion failed: d1.node.path.endsWith(\"/ScopeAndIdTestClass/Dummy\")")})(d1.node.path.endsWith("/ScopeAndIdTestClass/Dummy"))}; const d2 = new Dummy(d1,"Dummy"); - {((cond) => {if (!cond) throw new Error(`assertion failed: 'd2.node.path.endsWith("/ScopeAndIdTestClass/Dummy/Dummy")'`)})(d2.node.path.endsWith("/ScopeAndIdTestClass/Dummy/Dummy"))}; + {((cond) => {if (!cond) throw new Error("assertion failed: d2.node.path.endsWith(\"/ScopeAndIdTestClass/Dummy/Dummy\")")})(d2.node.path.endsWith("/ScopeAndIdTestClass/Dummy/Dummy"))}; for (const i of $stdlib.std.Range.of(0, 3, false)) { - const x = new Dummy(this,`tc${i}`); - const expected_path = `/ScopeAndIdTestClass/tc${i}`; - {((cond) => {if (!cond) throw new Error(`assertion failed: 'x.node.path.endsWith(expected_path)'`)})(x.node.path.endsWith(expected_path))}; + const x = new Dummy(this,String.raw({ raw: ["tc", ""] }, i)); + const expected_path = String.raw({ raw: ["/ScopeAndIdTestClass/tc", ""] }, i); + {((cond) => {if (!cond) throw new Error("assertion failed: x.node.path.endsWith(expected_path)")})(x.node.path.endsWith(expected_path))}; } } static _toInflightType(context) { diff --git a/tools/hangar/__snapshots__/test_corpus/valid/resource.w_test_sim.md b/tools/hangar/__snapshots__/test_corpus/valid/resource.w_test_sim.md index 8df465e5712..34b66842c8c 100644 --- a/tools/hangar/__snapshots__/test_corpus/valid/resource.w_test_sim.md +++ b/tools/hangar/__snapshots__/test_corpus/valid/resource.w_test_sim.md @@ -5,12 +5,9 @@ pass โ”€ resource.wsim ยป root/env0/test:test pass โ”€ resource.wsim ยป root/env1/test:dependency cycles - - - - -Tests 1 passed (1) + +Tests 2 passed (2) +Test Files 1 passed (1) Duration - ``` diff --git a/tools/hangar/__snapshots__/test_corpus/valid/resource_as_inflight_literal.w_compile_tf-aws.md b/tools/hangar/__snapshots__/test_corpus/valid/resource_as_inflight_literal.w_compile_tf-aws.md index 70dd88a6282..a03dcf6dd1b 100644 --- a/tools/hangar/__snapshots__/test_corpus/valid/resource_as_inflight_literal.w_compile_tf-aws.md +++ b/tools/hangar/__snapshots__/test_corpus/valid/resource_as_inflight_literal.w_compile_tf-aws.md @@ -12,7 +12,7 @@ module.exports = function({ fn }) { async $inflight_init() { } async handle() { - {((cond) => {if (!cond) throw new Error(`assertion failed: '((await fn.invoke("test")) === "hello world!")'`)})(((await fn.invoke("test")) === "hello world!"))}; + {((cond) => {if (!cond) throw new Error("assertion failed: fn.invoke(\"test\") == \"hello world!\"")})(((await fn.invoke("test")) === "hello world!"))}; } } return $Closure1; diff --git a/tools/hangar/__snapshots__/test_corpus/valid/resource_as_inflight_literal.w_test_sim.md b/tools/hangar/__snapshots__/test_corpus/valid/resource_as_inflight_literal.w_test_sim.md index 2a190740c5c..5208d1ff41c 100644 --- a/tools/hangar/__snapshots__/test_corpus/valid/resource_as_inflight_literal.w_test_sim.md +++ b/tools/hangar/__snapshots__/test_corpus/valid/resource_as_inflight_literal.w_test_sim.md @@ -4,12 +4,9 @@ ```log pass โ”€ resource_as_inflight_literal.wsim ยป root/env0/test:test - - - - -Tests 1 passed (1) + +Tests 1 passed (1) +Test Files 1 passed (1) Duration - ``` diff --git a/tools/hangar/__snapshots__/test_corpus/valid/resource_captures.w_compile_tf-aws.md b/tools/hangar/__snapshots__/test_corpus/valid/resource_captures.w_compile_tf-aws.md index d8f6fdb1581..358bc5d65c5 100644 --- a/tools/hangar/__snapshots__/test_corpus/valid/resource_captures.w_compile_tf-aws.md +++ b/tools/hangar/__snapshots__/test_corpus/valid/resource_captures.w_compile_tf-aws.md @@ -91,54 +91,54 @@ module.exports = function({ }) { } async testNoCapture() { const arr = Object.freeze([1, 2, 3]); - {((cond) => {if (!cond) throw new Error(`assertion failed: '(arr.length === 3)'`)})((arr.length === 3))}; - {console.log(`array.len=${arr.length}`)}; + {((cond) => {if (!cond) throw new Error("assertion failed: arr.length == 3")})((arr.length === 3))}; + {console.log(String.raw({ raw: ["array.len=", ""] }, arr.length))}; } async testCaptureCollectionsOfData() { - {((cond) => {if (!cond) throw new Error(`assertion failed: '(this.arrayOfStr.length === 2)'`)})((this.arrayOfStr.length === 2))}; - {((cond) => {if (!cond) throw new Error(`assertion failed: '((await this.arrayOfStr.at(0)) === "s1")'`)})(((await this.arrayOfStr.at(0)) === "s1"))}; - {((cond) => {if (!cond) throw new Error(`assertion failed: '((await this.arrayOfStr.at(1)) === "s2")'`)})(((await this.arrayOfStr.at(1)) === "s2"))}; - {((cond) => {if (!cond) throw new Error(`assertion failed: '((this.mapOfNum)["k1"] === 11)'`)})(((this.mapOfNum)["k1"] === 11))}; - {((cond) => {if (!cond) throw new Error(`assertion failed: '((this.mapOfNum)["k2"] === 22)'`)})(((this.mapOfNum)["k2"] === 22))}; - {((cond) => {if (!cond) throw new Error(`assertion failed: '(await this.setOfStr.has("s1"))'`)})((await this.setOfStr.has("s1")))}; - {((cond) => {if (!cond) throw new Error(`assertion failed: '(await this.setOfStr.has("s2"))'`)})((await this.setOfStr.has("s2")))}; - {((cond) => {if (!cond) throw new Error(`assertion failed: '(!(await this.setOfStr.has("s3")))'`)})((!(await this.setOfStr.has("s3"))))}; + {((cond) => {if (!cond) throw new Error("assertion failed: this.arrayOfStr.length == 2")})((this.arrayOfStr.length === 2))}; + {((cond) => {if (!cond) throw new Error("assertion failed: this.arrayOfStr.at(0) == \"s1\"")})(((await this.arrayOfStr.at(0)) === "s1"))}; + {((cond) => {if (!cond) throw new Error("assertion failed: this.arrayOfStr.at(1) == \"s2\"")})(((await this.arrayOfStr.at(1)) === "s2"))}; + {((cond) => {if (!cond) throw new Error("assertion failed: this.mapOfNum.get(\"k1\") == 11")})(((this.mapOfNum)["k1"] === 11))}; + {((cond) => {if (!cond) throw new Error("assertion failed: this.mapOfNum.get(\"k2\") == 22")})(((this.mapOfNum)["k2"] === 22))}; + {((cond) => {if (!cond) throw new Error("assertion failed: this.setOfStr.has(\"s1\")")})((await this.setOfStr.has("s1")))}; + {((cond) => {if (!cond) throw new Error("assertion failed: this.setOfStr.has(\"s2\")")})((await this.setOfStr.has("s2")))}; + {((cond) => {if (!cond) throw new Error("assertion failed: !this.setOfStr.has(\"s3\")")})((!(await this.setOfStr.has("s3"))))}; } async testCapturePrimitives() { - {((cond) => {if (!cond) throw new Error(`assertion failed: '(this.myStr === "myString")'`)})((this.myStr === "myString"))}; - {((cond) => {if (!cond) throw new Error(`assertion failed: '(this.myNum === 42)'`)})((this.myNum === 42))}; - {((cond) => {if (!cond) throw new Error(`assertion failed: '(this.myBool === true)'`)})((this.myBool === true))}; + {((cond) => {if (!cond) throw new Error("assertion failed: this.myStr == \"myString\"")})((this.myStr === "myString"))}; + {((cond) => {if (!cond) throw new Error("assertion failed: this.myNum == 42")})((this.myNum === 42))}; + {((cond) => {if (!cond) throw new Error("assertion failed: this.myBool == true")})((this.myBool === true))}; } async testCaptureOptional() { - {((cond) => {if (!cond) throw new Error(`assertion failed: '((this.myOptStr ?? "") === "myOptString")'`)})(((this.myOptStr ?? "") === "myOptString"))}; + {((cond) => {if (!cond) throw new Error("assertion failed: this.myOptStr ?? \"\" == \"myOptString\"")})(((this.myOptStr ?? "") === "myOptString"))}; } async testCaptureResource() { (await this.myResource.put("f1.txt","f1")); - {((cond) => {if (!cond) throw new Error(`assertion failed: '((await this.myResource.get("f1.txt")) === "f1")'`)})(((await this.myResource.get("f1.txt")) === "f1"))}; - {((cond) => {if (!cond) throw new Error(`assertion failed: '((await this.myResource.list()).length === 1)'`)})(((await this.myResource.list()).length === 1))}; + {((cond) => {if (!cond) throw new Error("assertion failed: this.myResource.get(\"f1.txt\") == \"f1\"")})(((await this.myResource.get("f1.txt")) === "f1"))}; + {((cond) => {if (!cond) throw new Error("assertion failed: this.myResource.list().length == 1")})(((await this.myResource.list()).length === 1))}; } async testNestedInflightField() { - {((cond) => {if (!cond) throw new Error(`assertion failed: '(this.another.myField === "hello!")'`)})((this.another.myField === "hello!"))}; - {console.log(`field=${this.another.myField}`)}; + {((cond) => {if (!cond) throw new Error("assertion failed: this.another.myField == \"hello!\"")})((this.another.myField === "hello!"))}; + {console.log(String.raw({ raw: ["field=", ""] }, this.another.myField))}; } async testNestedResource() { - {((cond) => {if (!cond) throw new Error(`assertion failed: '((await this.another.first.myResource.list()).length === 0)'`)})(((await this.another.first.myResource.list()).length === 0))}; + {((cond) => {if (!cond) throw new Error("assertion failed: this.another.first.myResource.list().length == 0")})(((await this.another.first.myResource.list()).length === 0))}; (await this.another.first.myResource.put("hello",this.myStr)); - {console.log(`this.another.first.myResource:${(await this.another.first.myResource.get("hello"))}`)}; + {console.log(String.raw({ raw: ["this.another.first.myResource:", ""] }, (await this.another.first.myResource.get("hello"))))}; } async testExpressionRecursive() { (await this.myQueue.push(this.myStr)); } async testExternal() { - {((cond) => {if (!cond) throw new Error(`assertion failed: '((await this.extBucket.list()).length === 0)'`)})(((await this.extBucket.list()).length === 0))}; - {((cond) => {if (!cond) throw new Error(`assertion failed: '(this.extNum === 12)'`)})((this.extNum === 12))}; + {((cond) => {if (!cond) throw new Error("assertion failed: this.extBucket.list().length == 0")})(((await this.extBucket.list()).length === 0))}; + {((cond) => {if (!cond) throw new Error("assertion failed: this.extNum == 12")})((this.extNum === 12))}; } async testUserDefinedResource() { - {((cond) => {if (!cond) throw new Error(`assertion failed: '((await this.another.meaningOfLife()) === 42)'`)})(((await this.another.meaningOfLife()) === 42))}; - {((cond) => {if (!cond) throw new Error(`assertion failed: '((await this.another.anotherFunc()) === "42")'`)})(((await this.another.anotherFunc()) === "42"))}; + {((cond) => {if (!cond) throw new Error("assertion failed: this.another.meaningOfLife() == 42")})(((await this.another.meaningOfLife()) === 42))}; + {((cond) => {if (!cond) throw new Error("assertion failed: this.another.anotherFunc() == \"42\"")})(((await this.another.anotherFunc()) === "42"))}; } async testInflightField() { - {((cond) => {if (!cond) throw new Error(`assertion failed: '(this.inflightField === 123)'`)})((this.inflightField === 123))}; + {((cond) => {if (!cond) throw new Error("assertion failed: this.inflightField == 123")})((this.inflightField === 123))}; } } return MyResource; diff --git a/tools/hangar/__snapshots__/test_corpus/valid/resource_captures.w_test_sim.md b/tools/hangar/__snapshots__/test_corpus/valid/resource_captures.w_test_sim.md index d4747547974..651652f9d26 100644 --- a/tools/hangar/__snapshots__/test_corpus/valid/resource_captures.w_test_sim.md +++ b/tools/hangar/__snapshots__/test_corpus/valid/resource_captures.w_test_sim.md @@ -7,12 +7,9 @@ pass โ”Œ resource_captures.wsim ยป root/env0/test:test โ”‚ field=hello! โ”” this.another.first.myResource:myString - - - - -Tests 1 passed (1) + +Tests 1 passed (1) +Test Files 1 passed (1) Duration - ``` diff --git a/tools/hangar/__snapshots__/test_corpus/valid/resource_captures_globals.w_compile_tf-aws.md b/tools/hangar/__snapshots__/test_corpus/valid/resource_captures_globals.w_compile_tf-aws.md index 9c787722191..5559e50b3e9 100644 --- a/tools/hangar/__snapshots__/test_corpus/valid/resource_captures_globals.w_compile_tf-aws.md +++ b/tools/hangar/__snapshots__/test_corpus/valid/resource_captures_globals.w_compile_tf-aws.md @@ -32,7 +32,7 @@ module.exports = function({ Another }) { async $inflight_init() { } async handle() { - {((cond) => {if (!cond) throw new Error(`assertion failed: '((await Another.myStaticMethod()) === 0)'`)})(((await Another.myStaticMethod()) === 0))}; + {((cond) => {if (!cond) throw new Error("assertion failed: Another.myStaticMethod() == 0")})(((await Another.myStaticMethod()) === 0))}; } } return $Closure2; @@ -49,7 +49,7 @@ module.exports = function({ globalCounter }) { this.myField = myField; } async $inflight_init() { - {((cond) => {if (!cond) throw new Error(`assertion failed: '((await globalCounter.peek()) === 0)'`)})(((await globalCounter.peek()) === 0))}; + {((cond) => {if (!cond) throw new Error("assertion failed: globalCounter.peek() == 0")})(((await globalCounter.peek()) === 0))}; } async myMethod() { (await globalCounter.inc()); @@ -92,16 +92,16 @@ module.exports = function({ globalBucket, globalStr, globalBool, globalNum, glob async myPut() { (await this.localTopic.publish("hello")); (await globalBucket.put("key","value")); - {((cond) => {if (!cond) throw new Error(`assertion failed: '(globalStr === "hello")'`)})((globalStr === "hello"))}; - {((cond) => {if (!cond) throw new Error(`assertion failed: '(globalBool === true)'`)})((globalBool === true))}; - {((cond) => {if (!cond) throw new Error(`assertion failed: '(globalNum === 42)'`)})((globalNum === 42))}; - {((cond) => {if (!cond) throw new Error(`assertion failed: '((await globalArrayOfStr.at(0)) === "hello")'`)})(((await globalArrayOfStr.at(0)) === "hello"))}; - {((cond) => {if (!cond) throw new Error(`assertion failed: '((globalMapOfNum)["a"] === (-5))'`)})(((globalMapOfNum)["a"] === (-5)))}; - {((cond) => {if (!cond) throw new Error(`assertion failed: '(await globalSetOfStr.has("a"))'`)})((await globalSetOfStr.has("a")))}; - {((cond) => {if (!cond) throw new Error(`assertion failed: '(globalAnother.myField === "hello!")'`)})((globalAnother.myField === "hello!"))}; + {((cond) => {if (!cond) throw new Error("assertion failed: globalStr == \"hello\"")})((globalStr === "hello"))}; + {((cond) => {if (!cond) throw new Error("assertion failed: globalBool == true")})((globalBool === true))}; + {((cond) => {if (!cond) throw new Error("assertion failed: globalNum == 42")})((globalNum === 42))}; + {((cond) => {if (!cond) throw new Error("assertion failed: globalArrayOfStr.at(0) == \"hello\"")})(((await globalArrayOfStr.at(0)) === "hello"))}; + {((cond) => {if (!cond) throw new Error("assertion failed: globalMapOfNum.get(\"a\") == -5")})(((globalMapOfNum)["a"] === (-5)))}; + {((cond) => {if (!cond) throw new Error("assertion failed: globalSetOfStr.has(\"a\")")})((await globalSetOfStr.has("a")))}; + {((cond) => {if (!cond) throw new Error("assertion failed: globalAnother.myField == \"hello!\"")})((globalAnother.myField === "hello!"))}; (await globalAnother.first.myResource.put("key","value")); - {((cond) => {if (!cond) throw new Error(`assertion failed: '((await globalAnother.myMethod()) > 0)'`)})(((await globalAnother.myMethod()) > 0))}; - {((cond) => {if (!cond) throw new Error(`assertion failed: '((await Another.myStaticMethod()) > 0)'`)})(((await Another.myStaticMethod()) > 0))}; + {((cond) => {if (!cond) throw new Error("assertion failed: globalAnother.myMethod() > 0")})(((await globalAnother.myMethod()) > 0))}; + {((cond) => {if (!cond) throw new Error("assertion failed: Another.myStaticMethod() > 0")})(((await Another.myStaticMethod()) > 0))}; } } return MyResource; diff --git a/tools/hangar/__snapshots__/test_corpus/valid/resource_captures_globals.w_test_sim.md b/tools/hangar/__snapshots__/test_corpus/valid/resource_captures_globals.w_test_sim.md index 4051bb8c161..36ddada28fe 100644 --- a/tools/hangar/__snapshots__/test_corpus/valid/resource_captures_globals.w_test_sim.md +++ b/tools/hangar/__snapshots__/test_corpus/valid/resource_captures_globals.w_test_sim.md @@ -5,12 +5,9 @@ pass โ”€ resource_captures_globals.wsim ยป root/env0/test:test pass โ”€ resource_captures_globals.wsim ยป root/env1/test:access cloud resource through static methods only - - - - -Tests 1 passed (1) + +Tests 2 passed (2) +Test Files 1 passed (1) Duration - ``` diff --git a/tools/hangar/__snapshots__/test_corpus/valid/service.w_test_sim.md b/tools/hangar/__snapshots__/test_corpus/valid/service.w_test_sim.md index bff95dd1854..d7fa923eac9 100644 --- a/tools/hangar/__snapshots__/test_corpus/valid/service.w_test_sim.md +++ b/tools/hangar/__snapshots__/test_corpus/valid/service.w_test_sim.md @@ -4,12 +4,9 @@ ```log pass โ”€ service.wsim (no tests) - - - - -Tests 1 passed (1) + +Tests 1 passed (1) +Test Files 1 passed (1) Duration - ``` diff --git a/tools/hangar/__snapshots__/test_corpus/valid/shadowing.w_compile_tf-aws.md b/tools/hangar/__snapshots__/test_corpus/valid/shadowing.w_compile_tf-aws.md index 6a30ba72f32..37537319a85 100644 --- a/tools/hangar/__snapshots__/test_corpus/valid/shadowing.w_compile_tf-aws.md +++ b/tools/hangar/__snapshots__/test_corpus/valid/shadowing.w_compile_tf-aws.md @@ -41,10 +41,10 @@ module.exports = function({ fn }) { } async handle() { const result = (await fn()); - {((cond) => {if (!cond) throw new Error(`assertion failed: '(result.length === 3)'`)})((result.length === 3))}; - {((cond) => {if (!cond) throw new Error(`assertion failed: '((await result.at(0)) === "hola!")'`)})(((await result.at(0)) === "hola!"))}; - {((cond) => {if (!cond) throw new Error(`assertion failed: '((await result.at(1)) === "world")'`)})(((await result.at(1)) === "world"))}; - {((cond) => {if (!cond) throw new Error(`assertion failed: '((await result.at(2)) === "bang")'`)})(((await result.at(2)) === "bang"))}; + {((cond) => {if (!cond) throw new Error("assertion failed: result.length == 3")})((result.length === 3))}; + {((cond) => {if (!cond) throw new Error("assertion failed: result.at(0) == \"hola!\"")})(((await result.at(0)) === "hola!"))}; + {((cond) => {if (!cond) throw new Error("assertion failed: result.at(1) == \"world\"")})(((await result.at(1)) === "world"))}; + {((cond) => {if (!cond) throw new Error("assertion failed: result.at(2) == \"bang\"")})(((await result.at(2)) === "bang"))}; } } return $Closure2; diff --git a/tools/hangar/__snapshots__/test_corpus/valid/shadowing.w_test_sim.md b/tools/hangar/__snapshots__/test_corpus/valid/shadowing.w_test_sim.md index c650511c632..c557353a15b 100644 --- a/tools/hangar/__snapshots__/test_corpus/valid/shadowing.w_test_sim.md +++ b/tools/hangar/__snapshots__/test_corpus/valid/shadowing.w_test_sim.md @@ -4,12 +4,9 @@ ```log pass โ”€ shadowing.wsim ยป root/env0/test:capture shadow interaction - - - - -Tests 1 passed (1) + +Tests 1 passed (1) +Test Files 1 passed (1) Duration - ``` diff --git a/tools/hangar/__snapshots__/test_corpus/valid/statements_if.w_compile_tf-aws.md b/tools/hangar/__snapshots__/test_corpus/valid/statements_if.w_compile_tf-aws.md index 17bdc14d1a1..373e57d54c8 100644 --- a/tools/hangar/__snapshots__/test_corpus/valid/statements_if.w_compile_tf-aws.md +++ b/tools/hangar/__snapshots__/test_corpus/valid/statements_if.w_compile_tf-aws.md @@ -16,20 +16,20 @@ module.exports = function({ }) { const x = 2; if ((true && ((x + 2) === 4))) { if ((true && ((x + 3) === 4))) { - {((cond) => {if (!cond) throw new Error(`assertion failed: 'false'`)})(false)}; + {((cond) => {if (!cond) throw new Error("assertion failed: false")})(false)}; } else if ((true && ((x + 3) === 6))) { - {((cond) => {if (!cond) throw new Error(`assertion failed: 'false'`)})(false)}; + {((cond) => {if (!cond) throw new Error("assertion failed: false")})(false)}; } else if ((false || ((x + 3) === 5))) { - {((cond) => {if (!cond) throw new Error(`assertion failed: 'true'`)})(true)}; + {((cond) => {if (!cond) throw new Error("assertion failed: true")})(true)}; } else { - {((cond) => {if (!cond) throw new Error(`assertion failed: 'false'`)})(false)}; + {((cond) => {if (!cond) throw new Error("assertion failed: false")})(false)}; } } else { - {((cond) => {if (!cond) throw new Error(`assertion failed: 'false'`)})(false)}; + {((cond) => {if (!cond) throw new Error("assertion failed: false")})(false)}; } } } @@ -208,23 +208,23 @@ class $Root extends $stdlib.std.Resource { const f = false; if ((true && ((x + 2) === 4))) { if ((true && ((x + 3) === 4))) { - {((cond) => {if (!cond) throw new Error(`assertion failed: 'false'`)})(false)}; + {((cond) => {if (!cond) throw new Error("assertion failed: false")})(false)}; } else if ((true && ((x + 3) === 6))) { - {((cond) => {if (!cond) throw new Error(`assertion failed: 'false'`)})(false)}; + {((cond) => {if (!cond) throw new Error("assertion failed: false")})(false)}; } else if ((false || ((x + 3) === 5))) { - {((cond) => {if (!cond) throw new Error(`assertion failed: 'true'`)})(true)}; + {((cond) => {if (!cond) throw new Error("assertion failed: true")})(true)}; } else if ((!f)) { - {((cond) => {if (!cond) throw new Error(`assertion failed: '(!(!(!f)))'`)})((!(!(!f))))}; + {((cond) => {if (!cond) throw new Error("assertion failed: !!!f")})((!(!(!f))))}; } else { - {((cond) => {if (!cond) throw new Error(`assertion failed: 'false'`)})(false)}; + {((cond) => {if (!cond) throw new Error("assertion failed: false")})(false)}; } } else { - {((cond) => {if (!cond) throw new Error(`assertion failed: 'false'`)})(false)}; + {((cond) => {if (!cond) throw new Error("assertion failed: false")})(false)}; } } this.node.root.new("@winglang/sdk.std.Test",std.Test,this,"test:test",new $Closure1(this,"$Closure1")); diff --git a/tools/hangar/__snapshots__/test_corpus/valid/statements_if.w_test_sim.md b/tools/hangar/__snapshots__/test_corpus/valid/statements_if.w_test_sim.md index b308ee6aa2a..c1560839fc6 100644 --- a/tools/hangar/__snapshots__/test_corpus/valid/statements_if.w_test_sim.md +++ b/tools/hangar/__snapshots__/test_corpus/valid/statements_if.w_test_sim.md @@ -4,12 +4,9 @@ ```log pass โ”€ statements_if.wsim ยป root/env0/test:test - - - - -Tests 1 passed (1) + +Tests 1 passed (1) +Test Files 1 passed (1) Duration - ``` diff --git a/tools/hangar/__snapshots__/test_corpus/valid/statements_variable_declarations.w_test_sim.md b/tools/hangar/__snapshots__/test_corpus/valid/statements_variable_declarations.w_test_sim.md index da49eb97c1e..33c0f466576 100644 --- a/tools/hangar/__snapshots__/test_corpus/valid/statements_variable_declarations.w_test_sim.md +++ b/tools/hangar/__snapshots__/test_corpus/valid/statements_variable_declarations.w_test_sim.md @@ -4,12 +4,9 @@ ```log pass โ”€ statements_variable_declarations.wsim (no tests) - - - - -Tests 1 passed (1) + +Tests 1 passed (1) +Test Files 1 passed (1) Duration - ``` diff --git a/tools/hangar/__snapshots__/test_corpus/valid/static_members.w_compile_tf-aws.md b/tools/hangar/__snapshots__/test_corpus/valid/static_members.w_compile_tf-aws.md index 84151f8725a..86805db4a85 100644 --- a/tools/hangar/__snapshots__/test_corpus/valid/static_members.w_compile_tf-aws.md +++ b/tools/hangar/__snapshots__/test_corpus/valid/static_members.w_compile_tf-aws.md @@ -14,8 +14,8 @@ module.exports = function({ }) { async handle() { const InflightClass = require("./inflight.InflightClass.js")({}); const inflightClass = new InflightClass(); - {((cond) => {if (!cond) throw new Error(`assertion failed: '((await inflightClass.inflightMethod()) === "Inflight method")'`)})(((await inflightClass.inflightMethod()) === "Inflight method"))}; - {((cond) => {if (!cond) throw new Error(`assertion failed: '((await InflightClass.staticInflightMethod()) === "Static inflight method")'`)})(((await InflightClass.staticInflightMethod()) === "Static inflight method"))}; + {((cond) => {if (!cond) throw new Error("assertion failed: inflightClass.inflightMethod() == \"Inflight method\"")})(((await inflightClass.inflightMethod()) === "Inflight method"))}; + {((cond) => {if (!cond) throw new Error("assertion failed: InflightClass.staticInflightMethod() == \"Static inflight method\"")})(((await InflightClass.staticInflightMethod()) === "Static inflight method"))}; } } return $Closure1; @@ -265,8 +265,8 @@ class $Root extends $stdlib.std.Resource { } } const foo = new Foo(this,"Foo"); - {((cond) => {if (!cond) throw new Error(`assertion failed: '(foo.instanceField === 100)'`)})((foo.instanceField === 100))}; - {((cond) => {if (!cond) throw new Error(`assertion failed: '((Foo.m()) === 99)'`)})(((Foo.m()) === 99))}; + {((cond) => {if (!cond) throw new Error("assertion failed: foo.instanceField == 100")})((foo.instanceField === 100))}; + {((cond) => {if (!cond) throw new Error("assertion failed: Foo.m() == 99")})(((Foo.m()) === 99))}; this.node.root.new("@winglang/sdk.std.Test",std.Test,this,"test:test",new $Closure1(this,"$Closure1")); } } diff --git a/tools/hangar/__snapshots__/test_corpus/valid/static_members.w_test_sim.md b/tools/hangar/__snapshots__/test_corpus/valid/static_members.w_test_sim.md index 196dfad7ba8..e3d57009036 100644 --- a/tools/hangar/__snapshots__/test_corpus/valid/static_members.w_test_sim.md +++ b/tools/hangar/__snapshots__/test_corpus/valid/static_members.w_test_sim.md @@ -4,12 +4,9 @@ ```log pass โ”€ static_members.wsim ยป root/env0/test:test - - - - -Tests 1 passed (1) + +Tests 1 passed (1) +Test Files 1 passed (1) Duration - ``` diff --git a/tools/hangar/__snapshots__/test_corpus/valid/std_containers.w_compile_tf-aws.md b/tools/hangar/__snapshots__/test_corpus/valid/std_containers.w_compile_tf-aws.md index 937680878e9..4d7534ff4a4 100644 --- a/tools/hangar/__snapshots__/test_corpus/valid/std_containers.w_compile_tf-aws.md +++ b/tools/hangar/__snapshots__/test_corpus/valid/std_containers.w_compile_tf-aws.md @@ -47,41 +47,41 @@ class $Root extends $stdlib.std.Resource { (mutArray.push("three")); const immutArray = Object.freeze([...(mutArray)]); const s = (sArray.at(1)); - {((cond) => {if (!cond) throw new Error(`assertion failed: '(s === "two")'`)})((s === "two"))}; - {((cond) => {if (!cond) throw new Error(`assertion failed: '((sArray.at(1)) === "two")'`)})(((sArray.at(1)) === "two"))}; - {((cond) => {if (!cond) throw new Error(`assertion failed: '(sArray.length === 2)'`)})((sArray.length === 2))}; - {((cond) => {if (!cond) throw new Error(`assertion failed: '(immutArray.length === 3)'`)})((immutArray.length === 3))}; + {((cond) => {if (!cond) throw new Error("assertion failed: s == \"two\"")})((s === "two"))}; + {((cond) => {if (!cond) throw new Error("assertion failed: sArray.at(1) == \"two\"")})(((sArray.at(1)) === "two"))}; + {((cond) => {if (!cond) throw new Error("assertion failed: sArray.length == 2")})((sArray.length === 2))}; + {((cond) => {if (!cond) throw new Error("assertion failed: immutArray.length == 3")})((immutArray.length === 3))}; const sArray2 = Object.freeze(["if", "you", "build", "it"]); const sArray3 = Object.freeze(["he", "will", "come", "for", "you"]); const mergedArray = (sArray2.concat(sArray3)); - {((cond) => {if (!cond) throw new Error(`assertion failed: '(mergedArray.length === 9)'`)})((mergedArray.length === 9))}; - {((cond) => {if (!cond) throw new Error(`assertion failed: '((mergedArray.at(5)) === "will")'`)})(((mergedArray.at(5)) === "will"))}; - {((cond) => {if (!cond) throw new Error(`assertion failed: 'mergedArray.includes("build")'`)})(mergedArray.includes("build"))}; - {((cond) => {if (!cond) throw new Error(`assertion failed: '(!mergedArray.includes("bring"))'`)})((!mergedArray.includes("bring")))}; - {((cond) => {if (!cond) throw new Error(`assertion failed: '(mergedArray.indexOf("you") === 1)'`)})((mergedArray.indexOf("you") === 1))}; - {((cond) => {if (!cond) throw new Error(`assertion failed: '((mergedArray.join(" ")) === "if you build it he will come for you")'`)})(((mergedArray.join(" ")) === "if you build it he will come for you"))}; - {((cond) => {if (!cond) throw new Error(`assertion failed: '((mergedArray.join()) === "if,you,build,it,he,will,come,for,you")'`)})(((mergedArray.join()) === "if,you,build,it,he,will,come,for,you"))}; - {((cond) => {if (!cond) throw new Error(`assertion failed: '(mergedArray.lastIndexOf("you") === 8)'`)})((mergedArray.lastIndexOf("you") === 8))}; + {((cond) => {if (!cond) throw new Error("assertion failed: mergedArray.length == 9")})((mergedArray.length === 9))}; + {((cond) => {if (!cond) throw new Error("assertion failed: mergedArray.at(5) == \"will\"")})(((mergedArray.at(5)) === "will"))}; + {((cond) => {if (!cond) throw new Error("assertion failed: mergedArray.contains(\"build\")")})(mergedArray.includes("build"))}; + {((cond) => {if (!cond) throw new Error("assertion failed: !mergedArray.contains(\"bring\")")})((!mergedArray.includes("bring")))}; + {((cond) => {if (!cond) throw new Error("assertion failed: mergedArray.indexOf(\"you\") == 1")})((mergedArray.indexOf("you") === 1))}; + {((cond) => {if (!cond) throw new Error("assertion failed: mergedArray.join(\" \") == \"if you build it he will come for you\"")})(((mergedArray.join(" ")) === "if you build it he will come for you"))}; + {((cond) => {if (!cond) throw new Error("assertion failed: mergedArray.join() == \"if,you,build,it,he,will,come,for,you\"")})(((mergedArray.join()) === "if,you,build,it,he,will,come,for,you"))}; + {((cond) => {if (!cond) throw new Error("assertion failed: mergedArray.lastIndexOf(\"you\") == 8")})((mergedArray.lastIndexOf("you") === 8))}; const mutArray2 = ["how", "does", "that", "look"]; const mergedMutArray = (mutArray.concat(mutArray2)); - {((cond) => {if (!cond) throw new Error(`assertion failed: '(mergedMutArray.length === 7)'`)})((mergedMutArray.length === 7))}; - {((cond) => {if (!cond) throw new Error(`assertion failed: '((mergedMutArray.at(5)) === "that")'`)})(((mergedMutArray.at(5)) === "that"))}; + {((cond) => {if (!cond) throw new Error("assertion failed: mergedMutArray.length == 7")})((mergedMutArray.length === 7))}; + {((cond) => {if (!cond) throw new Error("assertion failed: mergedMutArray.at(5) == \"that\"")})(((mergedMutArray.at(5)) === "that"))}; const sSet = Object.freeze(new Set(["one", "two"])); const mutSet = new Set(sSet); (mutSet.add("three")); const immutSet = Object.freeze(new Set(mutSet)); - {((cond) => {if (!cond) throw new Error(`assertion failed: '(sSet.has("one"))'`)})((sSet.has("one")))}; - {((cond) => {if (!cond) throw new Error(`assertion failed: '(sSet.size === 2)'`)})((sSet.size === 2))}; - {((cond) => {if (!cond) throw new Error(`assertion failed: '(immutSet.size === 3)'`)})((immutSet.size === 3))}; + {((cond) => {if (!cond) throw new Error("assertion failed: sSet.has(\"one\")")})((sSet.has("one")))}; + {((cond) => {if (!cond) throw new Error("assertion failed: sSet.size == 2")})((sSet.size === 2))}; + {((cond) => {if (!cond) throw new Error("assertion failed: immutSet.size == 3")})((immutSet.size === 3))}; const sMap = Object.freeze({"one":1,"two":2}); const nestedMap = Object.freeze({"a":Object.freeze({"b":Object.freeze({"c":"hello"})})}); const mutMap = {...(sMap)}; ((obj, args) => { obj[args[0]] = args[1]; })(mutMap, ["five",5]); const immutMap = Object.freeze({...(mutMap)}); - {((cond) => {if (!cond) throw new Error(`assertion failed: '((sMap)["one"] === 1)'`)})(((sMap)["one"] === 1))}; - {((cond) => {if (!cond) throw new Error(`assertion failed: '(Object.keys(sMap).length === 2)'`)})((Object.keys(sMap).length === 2))}; - {((cond) => {if (!cond) throw new Error(`assertion failed: '(Object.keys(immutMap).length === 3)'`)})((Object.keys(immutMap).length === 3))}; - {((cond) => {if (!cond) throw new Error(`assertion failed: '((((nestedMap)["a"])["b"])["c"] === "hello")'`)})(((((nestedMap)["a"])["b"])["c"] === "hello"))}; + {((cond) => {if (!cond) throw new Error("assertion failed: sMap.get(\"one\") == 1")})(((sMap)["one"] === 1))}; + {((cond) => {if (!cond) throw new Error("assertion failed: sMap.size() == 2")})((Object.keys(sMap).length === 2))}; + {((cond) => {if (!cond) throw new Error("assertion failed: immutMap.size() == 3")})((Object.keys(immutMap).length === 3))}; + {((cond) => {if (!cond) throw new Error("assertion failed: nestedMap.get(\"a\").get(\"b\").get(\"c\") == \"hello\"")})(((((nestedMap)["a"])["b"])["c"] === "hello"))}; } } class $App extends $AppBase { diff --git a/tools/hangar/__snapshots__/test_corpus/valid/std_containers.w_test_sim.md b/tools/hangar/__snapshots__/test_corpus/valid/std_containers.w_test_sim.md index de86a49aea8..595bfdb907c 100644 --- a/tools/hangar/__snapshots__/test_corpus/valid/std_containers.w_test_sim.md +++ b/tools/hangar/__snapshots__/test_corpus/valid/std_containers.w_test_sim.md @@ -4,12 +4,9 @@ ```log pass โ”€ std_containers.wsim (no tests) - - - - -Tests 1 passed (1) + +Tests 1 passed (1) +Test Files 1 passed (1) Duration - ``` diff --git a/tools/hangar/__snapshots__/test_corpus/valid/std_string.w_compile_tf-aws.md b/tools/hangar/__snapshots__/test_corpus/valid/std_string.w_compile_tf-aws.md index 1a75d8597e2..056e53bdae1 100644 --- a/tools/hangar/__snapshots__/test_corpus/valid/std_string.w_compile_tf-aws.md +++ b/tools/hangar/__snapshots__/test_corpus/valid/std_string.w_compile_tf-aws.md @@ -12,7 +12,7 @@ module.exports = function({ s1, s2 }) { async $inflight_init() { } async handle() { - {console.log(`index of \"s\" in s1 is ${s1.indexOf("s")}`)}; + {console.log(String.raw({ raw: ["index of \"s\" in s1 is ", ""] }, s1.indexOf("s")))}; {console.log((await (await s1.split(" ")).at(1)))}; {console.log((await s1.concat(s2)))}; } @@ -195,21 +195,21 @@ class $Root extends $stdlib.std.Resource { } const s1 = "some string"; const s2 = "s are immutable"; - {((cond) => {if (!cond) throw new Error(`assertion failed: '(s1.length === 11)'`)})((s1.length === 11))}; - {((cond) => {if (!cond) throw new Error(`assertion failed: '((s1.at(7)) === "r")'`)})(((s1.at(7)) === "r"))}; - {((cond) => {if (!cond) throw new Error(`assertion failed: '((s1.concat(s2)) === "some strings are immutable")'`)})(((s1.concat(s2)) === "some strings are immutable"))}; - {((cond) => {if (!cond) throw new Error(`assertion failed: 's1.includes("some")'`)})(s1.includes("some"))}; - {((cond) => {if (!cond) throw new Error(`assertion failed: '(!"some".includes(s1))'`)})((!"some".includes(s1)))}; - {((cond) => {if (!cond) throw new Error(`assertion failed: 's1.endsWith("string")'`)})(s1.endsWith("string"))}; - {((cond) => {if (!cond) throw new Error(`assertion failed: '(s1.indexOf("s") === 0)'`)})((s1.indexOf("s") === 0))}; - {((cond) => {if (!cond) throw new Error(`assertion failed: '("Some String".toLocaleLowerCase() === "some string")'`)})(("Some String".toLocaleLowerCase() === "some string"))}; - {((cond) => {if (!cond) throw new Error(`assertion failed: '(((s1.split(" ")).at(0)) === "some")'`)})((((s1.split(" ")).at(0)) === "some"))}; - {((cond) => {if (!cond) throw new Error(`assertion failed: 's1.startsWith("some")'`)})(s1.startsWith("some"))}; - {((cond) => {if (!cond) throw new Error(`assertion failed: '((s1.substring(5)) === "string")'`)})(((s1.substring(5)) === "string"))}; - {((cond) => {if (!cond) throw new Error(`assertion failed: '((s1.substring(5,7)) === "st")'`)})(((s1.substring(5,7)) === "st"))}; - {((cond) => {if (!cond) throw new Error(`assertion failed: '((" some string ".trim()) === "some string")'`)})(((" some string ".trim()) === "some string"))}; - {((cond) => {if (!cond) throw new Error(`assertion failed: '("Some String".toLocaleUpperCase() === "SOME STRING")'`)})(("Some String".toLocaleUpperCase() === "SOME STRING"))}; - {((cond) => {if (!cond) throw new Error(`assertion failed: '(("hello" + " world") === "hello world")'`)})((("hello" + " world") === "hello world"))}; + {((cond) => {if (!cond) throw new Error("assertion failed: s1.length == 11")})((s1.length === 11))}; + {((cond) => {if (!cond) throw new Error("assertion failed: s1.at(7) == \"r\"")})(((s1.at(7)) === "r"))}; + {((cond) => {if (!cond) throw new Error("assertion failed: s1.concat(s2) == \"some strings are immutable\"")})(((s1.concat(s2)) === "some strings are immutable"))}; + {((cond) => {if (!cond) throw new Error("assertion failed: s1.contains(\"some\")")})(s1.includes("some"))}; + {((cond) => {if (!cond) throw new Error("assertion failed: !\"some\".contains(s1)")})((!"some".includes(s1)))}; + {((cond) => {if (!cond) throw new Error("assertion failed: s1.endsWith(\"string\")")})(s1.endsWith("string"))}; + {((cond) => {if (!cond) throw new Error("assertion failed: s1.indexOf(\"s\") == 0")})((s1.indexOf("s") === 0))}; + {((cond) => {if (!cond) throw new Error("assertion failed: \"Some String\".lowercase() == \"some string\"")})(("Some String".toLocaleLowerCase() === "some string"))}; + {((cond) => {if (!cond) throw new Error("assertion failed: s1.split(\" \").at(0) == \"some\"")})((((s1.split(" ")).at(0)) === "some"))}; + {((cond) => {if (!cond) throw new Error("assertion failed: s1.startsWith(\"some\")")})(s1.startsWith("some"))}; + {((cond) => {if (!cond) throw new Error("assertion failed: s1.substring(5) == \"string\"")})(((s1.substring(5)) === "string"))}; + {((cond) => {if (!cond) throw new Error("assertion failed: s1.substring(5, 7) == \"st\"")})(((s1.substring(5,7)) === "st"))}; + {((cond) => {if (!cond) throw new Error("assertion failed: \" some string \".trim() == \"some string\"")})(((" some string ".trim()) === "some string"))}; + {((cond) => {if (!cond) throw new Error("assertion failed: \"Some String\".uppercase() == \"SOME STRING\"")})(("Some String".toLocaleUpperCase() === "SOME STRING"))}; + {((cond) => {if (!cond) throw new Error("assertion failed: \"hello\" + \" world\" == \"hello world\"")})((("hello" + " world") === "hello world"))}; this.node.root.new("@winglang/sdk.std.Test",std.Test,this,"test:string",new $Closure1(this,"$Closure1")); } } diff --git a/tools/hangar/__snapshots__/test_corpus/valid/std_string.w_test_sim.md b/tools/hangar/__snapshots__/test_corpus/valid/std_string.w_test_sim.md index eecd923d5c1..d9b758464e7 100644 --- a/tools/hangar/__snapshots__/test_corpus/valid/std_string.w_test_sim.md +++ b/tools/hangar/__snapshots__/test_corpus/valid/std_string.w_test_sim.md @@ -7,12 +7,9 @@ pass โ”Œ std_string.wsim ยป root/env0/test:string โ”‚ string โ”” some strings are immutable - - - - -Tests 1 passed (1) + +Tests 1 passed (1) +Test Files 1 passed (1) Duration - ``` diff --git a/tools/hangar/__snapshots__/test_corpus/valid/structs.w_compile_tf-aws.md b/tools/hangar/__snapshots__/test_corpus/valid/structs.w_compile_tf-aws.md index 4c1f50de414..e914b721aae 100644 --- a/tools/hangar/__snapshots__/test_corpus/valid/structs.w_compile_tf-aws.md +++ b/tools/hangar/__snapshots__/test_corpus/valid/structs.w_compile_tf-aws.md @@ -107,9 +107,9 @@ class $Root extends $stdlib.std.Resource { "field0": "foo",} ,} ; - {((cond) => {if (!cond) throw new Error(`assertion failed: '(x.field0 === "Sup")'`)})((x.field0 === "Sup"))}; - {((cond) => {if (!cond) throw new Error(`assertion failed: '(y.field1 === 1)'`)})((y.field1 === 1))}; - {((cond) => {if (!cond) throw new Error(`assertion failed: '(y.field3.field0 === "foo")'`)})((y.field3.field0 === "foo"))}; + {((cond) => {if (!cond) throw new Error("assertion failed: x.field0 == \"Sup\"")})((x.field0 === "Sup"))}; + {((cond) => {if (!cond) throw new Error("assertion failed: y.field1 == 1")})((y.field1 === 1))}; + {((cond) => {if (!cond) throw new Error("assertion failed: y.field3.field0 == \"foo\"")})((y.field3.field0 === "foo"))}; const s = { "a": "Boom baby",} ; diff --git a/tools/hangar/__snapshots__/test_corpus/valid/structs.w_test_sim.md b/tools/hangar/__snapshots__/test_corpus/valid/structs.w_test_sim.md index 3e4beff47e8..fdab33abea0 100644 --- a/tools/hangar/__snapshots__/test_corpus/valid/structs.w_test_sim.md +++ b/tools/hangar/__snapshots__/test_corpus/valid/structs.w_test_sim.md @@ -4,12 +4,9 @@ ```log pass โ”€ structs.wsim (no tests) - - - - -Tests 1 passed (1) + +Tests 1 passed (1) +Test Files 1 passed (1) Duration - ``` diff --git a/tools/hangar/__snapshots__/test_corpus/valid/symbol_shadow.w_compile_tf-aws.md b/tools/hangar/__snapshots__/test_corpus/valid/symbol_shadow.w_compile_tf-aws.md index 241a09962a3..8c1a4128e23 100644 --- a/tools/hangar/__snapshots__/test_corpus/valid/symbol_shadow.w_compile_tf-aws.md +++ b/tools/hangar/__snapshots__/test_corpus/valid/symbol_shadow.w_compile_tf-aws.md @@ -12,7 +12,7 @@ module.exports = function({ s }) { async $inflight_init() { } async handle() { - {((cond) => {if (!cond) throw new Error(`assertion failed: '(s === "inner")'`)})((s === "inner"))}; + {((cond) => {if (!cond) throw new Error("assertion failed: s == \"inner\"")})((s === "inner"))}; } } return $Closure1; @@ -32,7 +32,7 @@ module.exports = function({ s }) { async $inflight_init() { } async handle() { - {((cond) => {if (!cond) throw new Error(`assertion failed: '(s === "inResource")'`)})((s === "inResource"))}; + {((cond) => {if (!cond) throw new Error("assertion failed: s == \"inResource\"")})((s === "inResource"))}; } } return $Closure2; @@ -52,7 +52,7 @@ module.exports = function({ s }) { async $inflight_init() { } async handle() { - {((cond) => {if (!cond) throw new Error(`assertion failed: '(s === "top")'`)})((s === "top"))}; + {((cond) => {if (!cond) throw new Error("assertion failed: s == \"top\"")})((s === "top"))}; } } return $Closure3; @@ -73,7 +73,7 @@ module.exports = function({ }) { } async handle() { const s = "insideInflight"; - {((cond) => {if (!cond) throw new Error(`assertion failed: '(s === "insideInflight")'`)})((s === "insideInflight"))}; + {((cond) => {if (!cond) throw new Error("assertion failed: s == \"insideInflight\"")})((s === "insideInflight"))}; } } return $Closure4; @@ -429,7 +429,7 @@ class $Root extends $stdlib.std.Resource { constructor(scope, id, ) { super(scope, id); const s = "inResource"; - {((cond) => {if (!cond) throw new Error(`assertion failed: '(s === "inResource")'`)})((s === "inResource"))}; + {((cond) => {if (!cond) throw new Error("assertion failed: s == \"inResource\"")})((s === "inResource"))}; const __parent_this_2 = this; class $Closure2 extends $stdlib.std.Resource { constructor(scope, id, ) { @@ -564,7 +564,7 @@ class $Root extends $stdlib.std.Resource { const s = "top"; if (true) { const s = "inner"; - {((cond) => {if (!cond) throw new Error(`assertion failed: '(s === "inner")'`)})((s === "inner"))}; + {((cond) => {if (!cond) throw new Error("assertion failed: s == \"inner\"")})((s === "inner"))}; class $Closure1 extends $stdlib.std.Resource { constructor(scope, id, ) { super(scope, id); @@ -603,7 +603,7 @@ class $Root extends $stdlib.std.Resource { } this.node.root.new("@winglang/sdk.std.Test",std.Test,this,"test:inflight nested should not capture the shadowed var",new $Closure1(this,"$Closure1")); } - {((cond) => {if (!cond) throw new Error(`assertion failed: '(s === "top")'`)})((s === "top"))}; + {((cond) => {if (!cond) throw new Error("assertion failed: s == \"top\"")})((s === "top"))}; new A(this,"A"); this.node.root.new("@winglang/sdk.std.Test",std.Test,this,"test:inflight on top should capture top",new $Closure3(this,"$Closure3")); this.node.root.new("@winglang/sdk.std.Test",std.Test,this,"test:insideInflight should capture the right scope",new $Closure4(this,"$Closure4")); diff --git a/tools/hangar/__snapshots__/test_corpus/valid/symbol_shadow.w_test_sim.md b/tools/hangar/__snapshots__/test_corpus/valid/symbol_shadow.w_test_sim.md index 6e003d089f7..3baee90d4e6 100644 --- a/tools/hangar/__snapshots__/test_corpus/valid/symbol_shadow.w_test_sim.md +++ b/tools/hangar/__snapshots__/test_corpus/valid/symbol_shadow.w_test_sim.md @@ -7,12 +7,9 @@ pass โ”€ symbol_shadow.wsim ยป root/env1/A/test:inflight in resource should capt pass โ”€ symbol_shadow.wsim ยป root/env2/test:inflight on top should capture top pass โ”€ symbol_shadow.wsim ยป root/env3/test:insideInflight should capture the right scope - - - - -Tests 1 passed (1) + +Tests 4 passed (4) +Test Files 1 passed (1) Duration - ``` diff --git a/tools/hangar/__snapshots__/test_corpus/valid/table.w_test_sim.md b/tools/hangar/__snapshots__/test_corpus/valid/table.w_test_sim.md index 669a9f26ebc..eb424f595ea 100644 --- a/tools/hangar/__snapshots__/test_corpus/valid/table.w_test_sim.md +++ b/tools/hangar/__snapshots__/test_corpus/valid/table.w_test_sim.md @@ -4,12 +4,9 @@ ```log pass โ”€ table.wsim (no tests) - - - - -Tests 1 passed (1) + +Tests 1 passed (1) +Test Files 1 passed (1) Duration - ``` diff --git a/tools/hangar/__snapshots__/test_corpus/valid/test_bucket.w_compile_tf-aws.md b/tools/hangar/__snapshots__/test_corpus/valid/test_bucket.w_compile_tf-aws.md index a08b2444bf7..b0ea6cc1cdb 100644 --- a/tools/hangar/__snapshots__/test_corpus/valid/test_bucket.w_compile_tf-aws.md +++ b/tools/hangar/__snapshots__/test_corpus/valid/test_bucket.w_compile_tf-aws.md @@ -12,9 +12,9 @@ module.exports = function({ b }) { async $inflight_init() { } async handle() { - {((cond) => {if (!cond) throw new Error(`assertion failed: '((await b.list()).length === 0)'`)})(((await b.list()).length === 0))}; + {((cond) => {if (!cond) throw new Error("assertion failed: b.list().length == 0")})(((await b.list()).length === 0))}; (await b.put("hello.txt","world")); - {((cond) => {if (!cond) throw new Error(`assertion failed: '((await b.list()).length === 1)'`)})(((await b.list()).length === 1))}; + {((cond) => {if (!cond) throw new Error("assertion failed: b.list().length == 1")})(((await b.list()).length === 1))}; } } return $Closure1; @@ -35,7 +35,7 @@ module.exports = function({ b }) { } async handle() { (await b.put("hello.txt","world")); - {((cond) => {if (!cond) throw new Error(`assertion failed: '((await b.get("hello.txt")) === "world")'`)})(((await b.get("hello.txt")) === "world"))}; + {((cond) => {if (!cond) throw new Error("assertion failed: b.get(\"hello.txt\") == \"world\"")})(((await b.get("hello.txt")) === "world"))}; } } return $Closure2; diff --git a/tools/hangar/__snapshots__/test_corpus/valid/test_bucket.w_test_sim.md b/tools/hangar/__snapshots__/test_corpus/valid/test_bucket.w_test_sim.md index e820cbce8bc..1f2cd68a75b 100644 --- a/tools/hangar/__snapshots__/test_corpus/valid/test_bucket.w_test_sim.md +++ b/tools/hangar/__snapshots__/test_corpus/valid/test_bucket.w_test_sim.md @@ -5,12 +5,9 @@ pass โ”€ test_bucket.wsim ยป root/env0/test:put pass โ”€ test_bucket.wsim ยป root/env1/test:get - - - - -Tests 1 passed (1) + +Tests 2 passed (2) +Test Files 1 passed (1) Duration - ``` diff --git a/tools/hangar/__snapshots__/test_corpus/valid/test_without_bring.w_compile_tf-aws.md b/tools/hangar/__snapshots__/test_corpus/valid/test_without_bring.w_compile_tf-aws.md index edf3c5964d5..3c356627ea5 100644 --- a/tools/hangar/__snapshots__/test_corpus/valid/test_without_bring.w_compile_tf-aws.md +++ b/tools/hangar/__snapshots__/test_corpus/valid/test_without_bring.w_compile_tf-aws.md @@ -12,7 +12,7 @@ module.exports = function({ }) { async $inflight_init() { } async handle() { - {((cond) => {if (!cond) throw new Error(`assertion failed: 'true'`)})(true)}; + {((cond) => {if (!cond) throw new Error("assertion failed: true")})(true)}; } } return $Closure1; diff --git a/tools/hangar/__snapshots__/test_corpus/valid/test_without_bring.w_test_sim.md b/tools/hangar/__snapshots__/test_corpus/valid/test_without_bring.w_test_sim.md index 3c6b3bdd8b8..5050eaa35d4 100644 --- a/tools/hangar/__snapshots__/test_corpus/valid/test_without_bring.w_test_sim.md +++ b/tools/hangar/__snapshots__/test_corpus/valid/test_without_bring.w_test_sim.md @@ -4,12 +4,9 @@ ```log pass โ”€ test_without_bring.wsim ยป root/env0/test:hello test - - - - -Tests 1 passed (1) + +Tests 1 passed (1) +Test Files 1 passed (1) Duration - ``` diff --git a/tools/hangar/__snapshots__/test_corpus/valid/try_catch.w_compile_tf-aws.md b/tools/hangar/__snapshots__/test_corpus/valid/try_catch.w_compile_tf-aws.md index 110fb47c6f6..bbeb38e132d 100644 --- a/tools/hangar/__snapshots__/test_corpus/valid/try_catch.w_compile_tf-aws.md +++ b/tools/hangar/__snapshots__/test_corpus/valid/try_catch.w_compile_tf-aws.md @@ -49,14 +49,14 @@ class $Root extends $stdlib.std.Resource { } catch ($error_e) { const e = $error_e.message; - {((cond) => {if (!cond) throw new Error(`assertion failed: '(e === "hello")'`)})((e === "hello"))}; + {((cond) => {if (!cond) throw new Error("assertion failed: e == \"hello\"")})((e === "hello"))}; x = "caught"; } finally { - {((cond) => {if (!cond) throw new Error(`assertion failed: '(x === "caught")'`)})((x === "caught"))}; + {((cond) => {if (!cond) throw new Error("assertion failed: x == \"caught\"")})((x === "caught"))}; x = "finally"; } - {((cond) => {if (!cond) throw new Error(`assertion failed: '(x === "finally")'`)})((x === "finally"))}; + {((cond) => {if (!cond) throw new Error("assertion failed: x == \"finally\"")})((x === "finally"))}; try { x = "I got here"; } @@ -65,10 +65,10 @@ class $Root extends $stdlib.std.Resource { x = "caught"; } finally { - {((cond) => {if (!cond) throw new Error(`assertion failed: '(x === "I got here")'`)})((x === "I got here"))}; + {((cond) => {if (!cond) throw new Error("assertion failed: x == \"I got here\"")})((x === "I got here"))}; x = "finally"; } - {((cond) => {if (!cond) throw new Error(`assertion failed: '(x === "finally")'`)})((x === "finally"))}; + {((cond) => {if (!cond) throw new Error("assertion failed: x == \"finally\"")})((x === "finally"))}; try { try { {((msg) => {throw new Error(msg)})("hello")}; @@ -76,7 +76,7 @@ class $Root extends $stdlib.std.Resource { finally { x = "finally with no catch"; } - {((cond) => {if (!cond) throw new Error(`assertion failed: '(x === "finally with no catch")'`)})((x === "finally with no catch"))}; + {((cond) => {if (!cond) throw new Error("assertion failed: x == \"finally with no catch\"")})((x === "finally with no catch"))}; } catch { } @@ -85,15 +85,8 @@ class $Root extends $stdlib.std.Resource { finally { x = "finally with no catch and no exception"; } - {((cond) => {if (!cond) throw new Error(`assertion failed: '(x === "finally with no catch and no exception")'`)})((x === "finally with no catch and no exception"))}; - {((cond) => {if (!cond) throw new Error(`assertion failed: '((( () => { - try { - } - finally { - return 1; - } - } - )()) === 1)'`)})(((( () => { + {((cond) => {if (!cond) throw new Error("assertion failed: x == \"finally with no catch and no exception\"")})((x === "finally with no catch and no exception"))}; + {((cond) => {if (!cond) throw new Error("assertion failed: (():num => { try {} finally {return 1;}})() == 1")})(((( () => { try { } finally { @@ -101,15 +94,7 @@ class $Root extends $stdlib.std.Resource { } } )()) === 1))}; - {((cond) => {if (!cond) throw new Error(`assertion failed: '((( () => { - try { - {((msg) => {throw new Error(msg)})("")}; - } - catch { - return 2; - } - } - )()) === 2)'`)})(((( () => { + {((cond) => {if (!cond) throw new Error("assertion failed: (():num => { try {throw(\"\");} catch {return 2;}})() == 2")})(((( () => { try { {((msg) => {throw new Error(msg)})("")}; } @@ -118,14 +103,7 @@ class $Root extends $stdlib.std.Resource { } } )()) === 2))}; - {((cond) => {if (!cond) throw new Error(`assertion failed: '((( () => { - try { - return 3; - } - finally { - } - } - )()) === 3)'`)})(((( () => { + {((cond) => {if (!cond) throw new Error("assertion failed: (():num => { try {return 3;} finally {}})() == 3")})(((( () => { try { return 3; } diff --git a/tools/hangar/__snapshots__/test_corpus/valid/try_catch.w_test_sim.md b/tools/hangar/__snapshots__/test_corpus/valid/try_catch.w_test_sim.md index 14502780ebb..f9e7d49355b 100644 --- a/tools/hangar/__snapshots__/test_corpus/valid/try_catch.w_test_sim.md +++ b/tools/hangar/__snapshots__/test_corpus/valid/try_catch.w_test_sim.md @@ -4,12 +4,9 @@ ```log pass โ”€ try_catch.wsim (no tests) - - - - -Tests 1 passed (1) + +Tests 1 passed (1) +Test Files 1 passed (1) Duration - ``` diff --git a/tools/hangar/__snapshots__/test_corpus/valid/website_with_api.w_test_sim.md b/tools/hangar/__snapshots__/test_corpus/valid/website_with_api.w_test_sim.md index ec942b7fe9c..d722e2edca8 100644 --- a/tools/hangar/__snapshots__/test_corpus/valid/website_with_api.w_test_sim.md +++ b/tools/hangar/__snapshots__/test_corpus/valid/website_with_api.w_test_sim.md @@ -4,12 +4,9 @@ ```log pass โ”€ website_with_api.wsim (no tests) - - - - -Tests 1 passed (1) + +Tests 1 passed (1) +Test Files 1 passed (1) Duration - ``` diff --git a/tools/hangar/__snapshots__/test_corpus/valid/while.w_compile_tf-aws.md b/tools/hangar/__snapshots__/test_corpus/valid/while.w_compile_tf-aws.md index 7bb62ac4401..60233f46c68 100644 --- a/tools/hangar/__snapshots__/test_corpus/valid/while.w_compile_tf-aws.md +++ b/tools/hangar/__snapshots__/test_corpus/valid/while.w_compile_tf-aws.md @@ -56,7 +56,7 @@ class $Root extends $stdlib.std.Resource { break; } } - {((cond) => {if (!cond) throw new Error(`assertion failed: '(z === 3)'`)})((z === 3))}; + {((cond) => {if (!cond) throw new Error("assertion failed: z == 3")})((z === 3))}; while (true) { break; } @@ -69,8 +69,8 @@ class $Root extends $stdlib.std.Resource { } v = (v + 1); } - {((cond) => {if (!cond) throw new Error(`assertion failed: '(i === 10)'`)})((i === 10))}; - {((cond) => {if (!cond) throw new Error(`assertion failed: '(v === 5)'`)})((v === 5))}; + {((cond) => {if (!cond) throw new Error("assertion failed: i == 10")})((i === 10))}; + {((cond) => {if (!cond) throw new Error("assertion failed: v == 5")})((v === 5))}; } } class $App extends $AppBase { diff --git a/tools/hangar/__snapshots__/test_corpus/valid/while.w_test_sim.md b/tools/hangar/__snapshots__/test_corpus/valid/while.w_test_sim.md index 531cefc50c9..9b2c2986ced 100644 --- a/tools/hangar/__snapshots__/test_corpus/valid/while.w_test_sim.md +++ b/tools/hangar/__snapshots__/test_corpus/valid/while.w_test_sim.md @@ -4,12 +4,9 @@ ```log pass โ”€ while.wsim (no tests) - - - - -Tests 1 passed (1) + +Tests 1 passed (1) +Test Files 1 passed (1) Duration - ``` diff --git a/tools/hangar/__snapshots__/test_corpus/valid/while_loop_await.w_compile_tf-aws.md b/tools/hangar/__snapshots__/test_corpus/valid/while_loop_await.w_compile_tf-aws.md index 770024ff115..bf5849074c8 100644 --- a/tools/hangar/__snapshots__/test_corpus/valid/while_loop_await.w_compile_tf-aws.md +++ b/tools/hangar/__snapshots__/test_corpus/valid/while_loop_await.w_compile_tf-aws.md @@ -18,7 +18,7 @@ module.exports = function({ }) { } ; while (((await iterator(i)) < 3)) { - {console.log(`${i}`)}; + {console.log(String.raw({ raw: ["", ""] }, i))}; } } } diff --git a/tools/hangar/__snapshots__/test_corpus/valid/while_loop_await.w_test_sim.md b/tools/hangar/__snapshots__/test_corpus/valid/while_loop_await.w_test_sim.md index a2df3aaa632..156c98485fc 100644 --- a/tools/hangar/__snapshots__/test_corpus/valid/while_loop_await.w_test_sim.md +++ b/tools/hangar/__snapshots__/test_corpus/valid/while_loop_await.w_test_sim.md @@ -4,12 +4,9 @@ ```log pass โ”€ while_loop_await.wsim (no tests) - - - - -Tests 1 passed (1) + +Tests 1 passed (1) +Test Files 1 passed (1) Duration - ``` diff --git a/tools/hangar/package-lock.json b/tools/hangar/package-lock.json index c0a0c0f951c..58fe6366321 100644 --- a/tools/hangar/package-lock.json +++ b/tools/hangar/package-lock.json @@ -9,7 +9,7 @@ "version": "0.0.0", "license": "Apache-2.0", "devDependencies": { - "@cdktf/provider-aws": "^12.0.13", + "cdktf": "^0.17.0", "execa": "^7.1.1", "npm": "^9.6.4", "tsx": "^3.12.6", @@ -17,19 +17,6 @@ "yaml": "^2.2.1" } }, - "node_modules/@cdktf/provider-aws": { - "version": "12.0.13", - "resolved": "https://registry.npmjs.org/@cdktf/provider-aws/-/provider-aws-12.0.13.tgz", - "integrity": "sha512-uGayQpfVsxPYbsTrxM1p/9mtb6MbrrFqWHgHqLyhoOUzHqunwTtoGrcJJtkPZJwqHUdkZwK3OWwEYy7RtD2dow==", - "dev": true, - "engines": { - "node": ">= 14.17.0" - }, - "peerDependencies": { - "cdktf": "^0.15.0", - "constructs": "^10.0.0" - } - }, "node_modules/@esbuild-kit/cjs-loader": { "version": "2.4.2", "resolved": "https://registry.npmjs.org/@esbuild-kit/cjs-loader/-/cjs-loader-2.4.2.tgz", @@ -566,16 +553,15 @@ } }, "node_modules/cdktf": { - "version": "0.15.5", - "resolved": "https://registry.npmjs.org/cdktf/-/cdktf-0.15.5.tgz", - "integrity": "sha512-fcamLs7SKz+kTbQFf+fOXDGvmwT5bH4bHwp+jkVKjGTRsu6C8z5oFVAjKYm+aP1tC7sSWG967+ihSx6+uPNAGw==", + "version": "0.17.0", + "resolved": "https://registry.npmjs.org/cdktf/-/cdktf-0.17.0.tgz", + "integrity": "sha512-4R57uBLBqeb8NgfKZdn/az8UE3yXxGHyzH6Xjsz1Oo9kNvSkPibX7YqNLUpuCgdYNVgU2fdaNoHj9h4LXc6iCw==", "bundleDependencies": [ "archiver", "json-stable-stringify", "semver" ], "dev": true, - "peer": true, "dependencies": { "archiver": "5.3.1", "json-stable-stringify": "^1.0.2", @@ -590,7 +576,6 @@ "dev": true, "inBundle": true, "license": "MIT", - "peer": true, "dependencies": { "archiver-utils": "^2.1.0", "async": "^3.2.3", @@ -609,7 +594,6 @@ "dev": true, "inBundle": true, "license": "MIT", - "peer": true, "dependencies": { "glob": "^7.1.4", "graceful-fs": "^4.2.0", @@ -631,7 +615,6 @@ "dev": true, "inBundle": true, "license": "MIT", - "peer": true, "dependencies": { "core-util-is": "~1.0.0", "inherits": "~2.0.3", @@ -647,7 +630,6 @@ "dev": true, "inBundle": true, "license": "MIT", - "peer": true, "dependencies": { "safe-buffer": "~5.1.0" } @@ -656,15 +638,13 @@ "version": "3.2.4", "dev": true, "inBundle": true, - "license": "MIT", - "peer": true + "license": "MIT" }, "node_modules/cdktf/node_modules/balanced-match": { "version": "1.0.2", "dev": true, "inBundle": true, - "license": "MIT", - "peer": true + "license": "MIT" }, "node_modules/cdktf/node_modules/base64-js": { "version": "1.5.1", @@ -684,15 +664,13 @@ } ], "inBundle": true, - "license": "MIT", - "peer": true + "license": "MIT" }, "node_modules/cdktf/node_modules/bl": { "version": "4.1.0", "dev": true, "inBundle": true, "license": "MIT", - "peer": true, "dependencies": { "buffer": "^5.5.0", "inherits": "^2.0.4", @@ -704,7 +682,6 @@ "dev": true, "inBundle": true, "license": "MIT", - "peer": true, "dependencies": { "balanced-match": "^1.0.0" } @@ -728,7 +705,6 @@ ], "inBundle": true, "license": "MIT", - "peer": true, "dependencies": { "base64-js": "^1.3.1", "ieee754": "^1.1.13" @@ -739,7 +715,6 @@ "dev": true, "inBundle": true, "license": "MIT", - "peer": true, "engines": { "node": "*" } @@ -749,7 +724,6 @@ "dev": true, "inBundle": true, "license": "MIT", - "peer": true, "dependencies": { "buffer-crc32": "^0.2.13", "crc32-stream": "^4.0.2", @@ -764,22 +738,19 @@ "version": "0.0.1", "dev": true, "inBundle": true, - "license": "MIT", - "peer": true + "license": "MIT" }, "node_modules/cdktf/node_modules/core-util-is": { "version": "1.0.3", "dev": true, "inBundle": true, - "license": "MIT", - "peer": true + "license": "MIT" }, "node_modules/cdktf/node_modules/crc-32": { "version": "1.2.2", "dev": true, "inBundle": true, "license": "Apache-2.0", - "peer": true, "bin": { "crc32": "bin/crc32.njs" }, @@ -792,7 +763,6 @@ "dev": true, "inBundle": true, "license": "MIT", - "peer": true, "dependencies": { "crc-32": "^1.2.0", "readable-stream": "^3.4.0" @@ -806,7 +776,6 @@ "dev": true, "inBundle": true, "license": "MIT", - "peer": true, "dependencies": { "once": "^1.4.0" } @@ -815,22 +784,19 @@ "version": "1.0.0", "dev": true, "inBundle": true, - "license": "MIT", - "peer": true + "license": "MIT" }, "node_modules/cdktf/node_modules/fs.realpath": { "version": "1.0.0", "dev": true, "inBundle": true, - "license": "ISC", - "peer": true + "license": "ISC" }, "node_modules/cdktf/node_modules/glob": { "version": "7.2.3", "dev": true, "inBundle": true, "license": "ISC", - "peer": true, "dependencies": { "fs.realpath": "^1.0.0", "inflight": "^1.0.4", @@ -851,7 +817,6 @@ "dev": true, "inBundle": true, "license": "MIT", - "peer": true, "dependencies": { "balanced-match": "^1.0.0", "concat-map": "0.0.1" @@ -862,7 +827,6 @@ "dev": true, "inBundle": true, "license": "ISC", - "peer": true, "dependencies": { "brace-expansion": "^1.1.7" }, @@ -874,8 +838,7 @@ "version": "4.2.10", "dev": true, "inBundle": true, - "license": "ISC", - "peer": true + "license": "ISC" }, "node_modules/cdktf/node_modules/ieee754": { "version": "1.2.1", @@ -895,15 +858,13 @@ } ], "inBundle": true, - "license": "BSD-3-Clause", - "peer": true + "license": "BSD-3-Clause" }, "node_modules/cdktf/node_modules/inflight": { "version": "1.0.6", "dev": true, "inBundle": true, "license": "ISC", - "peer": true, "dependencies": { "once": "^1.3.0", "wrappy": "1" @@ -913,22 +874,19 @@ "version": "2.0.4", "dev": true, "inBundle": true, - "license": "ISC", - "peer": true + "license": "ISC" }, "node_modules/cdktf/node_modules/isarray": { "version": "1.0.0", "dev": true, "inBundle": true, - "license": "MIT", - "peer": true + "license": "MIT" }, "node_modules/cdktf/node_modules/json-stable-stringify": { "version": "1.0.2", "dev": true, "inBundle": true, "license": "MIT", - "peer": true, "dependencies": { "jsonify": "^0.0.1" }, @@ -941,7 +899,6 @@ "dev": true, "inBundle": true, "license": "Public Domain", - "peer": true, "funding": { "url": "https://github.com/sponsors/ljharb" } @@ -951,7 +908,6 @@ "dev": true, "inBundle": true, "license": "MIT", - "peer": true, "dependencies": { "readable-stream": "^2.0.5" }, @@ -964,7 +920,6 @@ "dev": true, "inBundle": true, "license": "MIT", - "peer": true, "dependencies": { "core-util-is": "~1.0.0", "inherits": "~2.0.3", @@ -980,7 +935,6 @@ "dev": true, "inBundle": true, "license": "MIT", - "peer": true, "dependencies": { "safe-buffer": "~5.1.0" } @@ -989,43 +943,37 @@ "version": "4.2.0", "dev": true, "inBundle": true, - "license": "MIT", - "peer": true + "license": "MIT" }, "node_modules/cdktf/node_modules/lodash.difference": { "version": "4.5.0", "dev": true, "inBundle": true, - "license": "MIT", - "peer": true + "license": "MIT" }, "node_modules/cdktf/node_modules/lodash.flatten": { "version": "4.4.0", "dev": true, "inBundle": true, - "license": "MIT", - "peer": true + "license": "MIT" }, "node_modules/cdktf/node_modules/lodash.isplainobject": { "version": "4.0.6", "dev": true, "inBundle": true, - "license": "MIT", - "peer": true + "license": "MIT" }, "node_modules/cdktf/node_modules/lodash.union": { "version": "4.6.0", "dev": true, "inBundle": true, - "license": "MIT", - "peer": true + "license": "MIT" }, "node_modules/cdktf/node_modules/lru-cache": { "version": "6.0.0", "dev": true, "inBundle": true, "license": "ISC", - "peer": true, "dependencies": { "yallist": "^4.0.0" }, @@ -1038,7 +986,6 @@ "dev": true, "inBundle": true, "license": "ISC", - "peer": true, "dependencies": { "brace-expansion": "^2.0.1" }, @@ -1051,7 +998,6 @@ "dev": true, "inBundle": true, "license": "MIT", - "peer": true, "engines": { "node": ">=0.10.0" } @@ -1061,7 +1007,6 @@ "dev": true, "inBundle": true, "license": "ISC", - "peer": true, "dependencies": { "wrappy": "1" } @@ -1071,7 +1016,6 @@ "dev": true, "inBundle": true, "license": "MIT", - "peer": true, "engines": { "node": ">=0.10.0" } @@ -1080,15 +1024,13 @@ "version": "2.0.1", "dev": true, "inBundle": true, - "license": "MIT", - "peer": true + "license": "MIT" }, "node_modules/cdktf/node_modules/readable-stream": { "version": "3.6.0", "dev": true, "inBundle": true, "license": "MIT", - "peer": true, "dependencies": { "inherits": "^2.0.3", "string_decoder": "^1.1.1", @@ -1103,7 +1045,6 @@ "dev": true, "inBundle": true, "license": "Apache-2.0", - "peer": true, "dependencies": { "minimatch": "^5.1.0" } @@ -1112,15 +1053,13 @@ "version": "5.1.2", "dev": true, "inBundle": true, - "license": "MIT", - "peer": true + "license": "MIT" }, "node_modules/cdktf/node_modules/semver": { "version": "7.3.8", "dev": true, "inBundle": true, "license": "ISC", - "peer": true, "dependencies": { "lru-cache": "^6.0.0" }, @@ -1136,7 +1075,6 @@ "dev": true, "inBundle": true, "license": "MIT", - "peer": true, "dependencies": { "safe-buffer": "~5.2.0" } @@ -1159,15 +1097,13 @@ } ], "inBundle": true, - "license": "MIT", - "peer": true + "license": "MIT" }, "node_modules/cdktf/node_modules/tar-stream": { "version": "2.2.0", "dev": true, "inBundle": true, "license": "MIT", - "peer": true, "dependencies": { "bl": "^4.0.3", "end-of-stream": "^1.4.1", @@ -1183,29 +1119,25 @@ "version": "1.0.2", "dev": true, "inBundle": true, - "license": "MIT", - "peer": true + "license": "MIT" }, "node_modules/cdktf/node_modules/wrappy": { "version": "1.0.2", "dev": true, "inBundle": true, - "license": "ISC", - "peer": true + "license": "ISC" }, "node_modules/cdktf/node_modules/yallist": { "version": "4.0.0", "dev": true, "inBundle": true, - "license": "ISC", - "peer": true + "license": "ISC" }, "node_modules/cdktf/node_modules/zip-stream": { "version": "4.1.0", "dev": true, "inBundle": true, "license": "MIT", - "peer": true, "dependencies": { "archiver-utils": "^2.1.0", "compress-commons": "^4.1.0", @@ -1262,9 +1194,9 @@ } }, "node_modules/constructs": { - "version": "10.2.55", - "resolved": "https://registry.npmjs.org/constructs/-/constructs-10.2.55.tgz", - "integrity": "sha512-TjH8BRN9qpmjZqq0ixH1NqgPHam0tQJcMQ6puffM0Sj0dRPXaJAzOtbHpn24rhjE+90vIQ8jBAUO8v8Sdp1uAQ==", + "version": "10.2.60", + "resolved": "https://registry.npmjs.org/constructs/-/constructs-10.2.60.tgz", + "integrity": "sha512-rO9EHXhUZpA1Gz5wk5ewCVaol6anSilDzS7uv4Fmgx+tKTcxchAl10z8ObjZMjcQYNw+5FBVIzSagSKJanbHdQ==", "dev": true, "peer": true, "engines": { @@ -5447,13 +5379,6 @@ } }, "dependencies": { - "@cdktf/provider-aws": { - "version": "12.0.13", - "resolved": "https://registry.npmjs.org/@cdktf/provider-aws/-/provider-aws-12.0.13.tgz", - "integrity": "sha512-uGayQpfVsxPYbsTrxM1p/9mtb6MbrrFqWHgHqLyhoOUzHqunwTtoGrcJJtkPZJwqHUdkZwK3OWwEYy7RtD2dow==", - "dev": true, - "requires": {} - }, "@esbuild-kit/cjs-loader": { "version": "2.4.2", "resolved": "https://registry.npmjs.org/@esbuild-kit/cjs-loader/-/cjs-loader-2.4.2.tgz", @@ -5768,11 +5693,10 @@ "dev": true }, "cdktf": { - "version": "0.15.5", - "resolved": "https://registry.npmjs.org/cdktf/-/cdktf-0.15.5.tgz", - "integrity": "sha512-fcamLs7SKz+kTbQFf+fOXDGvmwT5bH4bHwp+jkVKjGTRsu6C8z5oFVAjKYm+aP1tC7sSWG967+ihSx6+uPNAGw==", + "version": "0.17.0", + "resolved": "https://registry.npmjs.org/cdktf/-/cdktf-0.17.0.tgz", + "integrity": "sha512-4R57uBLBqeb8NgfKZdn/az8UE3yXxGHyzH6Xjsz1Oo9kNvSkPibX7YqNLUpuCgdYNVgU2fdaNoHj9h4LXc6iCw==", "dev": true, - "peer": true, "requires": { "archiver": "5.3.1", "json-stable-stringify": "^1.0.2", @@ -5783,7 +5707,6 @@ "version": "5.3.1", "bundled": true, "dev": true, - "peer": true, "requires": { "archiver-utils": "^2.1.0", "async": "^3.2.3", @@ -5798,7 +5721,6 @@ "version": "2.1.0", "bundled": true, "dev": true, - "peer": true, "requires": { "glob": "^7.1.4", "graceful-fs": "^4.2.0", @@ -5816,7 +5738,6 @@ "version": "2.3.7", "bundled": true, "dev": true, - "peer": true, "requires": { "core-util-is": "~1.0.0", "inherits": "~2.0.3", @@ -5831,7 +5752,6 @@ "version": "1.1.1", "bundled": true, "dev": true, - "peer": true, "requires": { "safe-buffer": "~5.1.0" } @@ -5841,26 +5761,22 @@ "async": { "version": "3.2.4", "bundled": true, - "dev": true, - "peer": true + "dev": true }, "balanced-match": { "version": "1.0.2", "bundled": true, - "dev": true, - "peer": true + "dev": true }, "base64-js": { "version": "1.5.1", "bundled": true, - "dev": true, - "peer": true + "dev": true }, "bl": { "version": "4.1.0", "bundled": true, "dev": true, - "peer": true, "requires": { "buffer": "^5.5.0", "inherits": "^2.0.4", @@ -5871,7 +5787,6 @@ "version": "2.0.1", "bundled": true, "dev": true, - "peer": true, "requires": { "balanced-match": "^1.0.0" } @@ -5880,7 +5795,6 @@ "version": "5.7.1", "bundled": true, "dev": true, - "peer": true, "requires": { "base64-js": "^1.3.1", "ieee754": "^1.1.13" @@ -5889,14 +5803,12 @@ "buffer-crc32": { "version": "0.2.13", "bundled": true, - "dev": true, - "peer": true + "dev": true }, "compress-commons": { "version": "4.1.1", "bundled": true, "dev": true, - "peer": true, "requires": { "buffer-crc32": "^0.2.13", "crc32-stream": "^4.0.2", @@ -5907,26 +5819,22 @@ "concat-map": { "version": "0.0.1", "bundled": true, - "dev": true, - "peer": true + "dev": true }, "core-util-is": { "version": "1.0.3", "bundled": true, - "dev": true, - "peer": true + "dev": true }, "crc-32": { "version": "1.2.2", "bundled": true, - "dev": true, - "peer": true + "dev": true }, "crc32-stream": { "version": "4.0.2", "bundled": true, "dev": true, - "peer": true, "requires": { "crc-32": "^1.2.0", "readable-stream": "^3.4.0" @@ -5936,7 +5844,6 @@ "version": "1.4.4", "bundled": true, "dev": true, - "peer": true, "requires": { "once": "^1.4.0" } @@ -5944,20 +5851,17 @@ "fs-constants": { "version": "1.0.0", "bundled": true, - "dev": true, - "peer": true + "dev": true }, "fs.realpath": { "version": "1.0.0", "bundled": true, - "dev": true, - "peer": true + "dev": true }, "glob": { "version": "7.2.3", "bundled": true, "dev": true, - "peer": true, "requires": { "fs.realpath": "^1.0.0", "inflight": "^1.0.4", @@ -5971,7 +5875,6 @@ "version": "1.1.11", "bundled": true, "dev": true, - "peer": true, "requires": { "balanced-match": "^1.0.0", "concat-map": "0.0.1" @@ -5981,7 +5884,6 @@ "version": "3.1.2", "bundled": true, "dev": true, - "peer": true, "requires": { "brace-expansion": "^1.1.7" } @@ -5991,20 +5893,17 @@ "graceful-fs": { "version": "4.2.10", "bundled": true, - "dev": true, - "peer": true + "dev": true }, "ieee754": { "version": "1.2.1", "bundled": true, - "dev": true, - "peer": true + "dev": true }, "inflight": { "version": "1.0.6", "bundled": true, "dev": true, - "peer": true, "requires": { "once": "^1.3.0", "wrappy": "1" @@ -6013,20 +5912,17 @@ "inherits": { "version": "2.0.4", "bundled": true, - "dev": true, - "peer": true + "dev": true }, "isarray": { "version": "1.0.0", "bundled": true, - "dev": true, - "peer": true + "dev": true }, "json-stable-stringify": { "version": "1.0.2", "bundled": true, "dev": true, - "peer": true, "requires": { "jsonify": "^0.0.1" } @@ -6034,14 +5930,12 @@ "jsonify": { "version": "0.0.1", "bundled": true, - "dev": true, - "peer": true + "dev": true }, "lazystream": { "version": "1.0.1", "bundled": true, "dev": true, - "peer": true, "requires": { "readable-stream": "^2.0.5" }, @@ -6050,7 +5944,6 @@ "version": "2.3.7", "bundled": true, "dev": true, - "peer": true, "requires": { "core-util-is": "~1.0.0", "inherits": "~2.0.3", @@ -6065,7 +5958,6 @@ "version": "1.1.1", "bundled": true, "dev": true, - "peer": true, "requires": { "safe-buffer": "~5.1.0" } @@ -6075,38 +5967,32 @@ "lodash.defaults": { "version": "4.2.0", "bundled": true, - "dev": true, - "peer": true + "dev": true }, "lodash.difference": { "version": "4.5.0", "bundled": true, - "dev": true, - "peer": true + "dev": true }, "lodash.flatten": { "version": "4.4.0", "bundled": true, - "dev": true, - "peer": true + "dev": true }, "lodash.isplainobject": { "version": "4.0.6", "bundled": true, - "dev": true, - "peer": true + "dev": true }, "lodash.union": { "version": "4.6.0", "bundled": true, - "dev": true, - "peer": true + "dev": true }, "lru-cache": { "version": "6.0.0", "bundled": true, "dev": true, - "peer": true, "requires": { "yallist": "^4.0.0" } @@ -6115,7 +6001,6 @@ "version": "5.1.0", "bundled": true, "dev": true, - "peer": true, "requires": { "brace-expansion": "^2.0.1" } @@ -6123,14 +6008,12 @@ "normalize-path": { "version": "3.0.0", "bundled": true, - "dev": true, - "peer": true + "dev": true }, "once": { "version": "1.4.0", "bundled": true, "dev": true, - "peer": true, "requires": { "wrappy": "1" } @@ -6138,20 +6021,17 @@ "path-is-absolute": { "version": "1.0.1", "bundled": true, - "dev": true, - "peer": true + "dev": true }, "process-nextick-args": { "version": "2.0.1", "bundled": true, - "dev": true, - "peer": true + "dev": true }, "readable-stream": { "version": "3.6.0", "bundled": true, "dev": true, - "peer": true, "requires": { "inherits": "^2.0.3", "string_decoder": "^1.1.1", @@ -6162,7 +6042,6 @@ "version": "1.1.2", "bundled": true, "dev": true, - "peer": true, "requires": { "minimatch": "^5.1.0" } @@ -6170,14 +6049,12 @@ "safe-buffer": { "version": "5.1.2", "bundled": true, - "dev": true, - "peer": true + "dev": true }, "semver": { "version": "7.3.8", "bundled": true, "dev": true, - "peer": true, "requires": { "lru-cache": "^6.0.0" } @@ -6186,7 +6063,6 @@ "version": "1.3.0", "bundled": true, "dev": true, - "peer": true, "requires": { "safe-buffer": "~5.2.0" }, @@ -6194,8 +6070,7 @@ "safe-buffer": { "version": "5.2.1", "bundled": true, - "dev": true, - "peer": true + "dev": true } } }, @@ -6203,7 +6078,6 @@ "version": "2.2.0", "bundled": true, "dev": true, - "peer": true, "requires": { "bl": "^4.0.3", "end-of-stream": "^1.4.1", @@ -6215,26 +6089,22 @@ "util-deprecate": { "version": "1.0.2", "bundled": true, - "dev": true, - "peer": true + "dev": true }, "wrappy": { "version": "1.0.2", "bundled": true, - "dev": true, - "peer": true + "dev": true }, "yallist": { "version": "4.0.0", "bundled": true, - "dev": true, - "peer": true + "dev": true }, "zip-stream": { "version": "4.1.0", "bundled": true, "dev": true, - "peer": true, "requires": { "archiver-utils": "^2.1.0", "compress-commons": "^4.1.0", @@ -6281,9 +6151,9 @@ } }, "constructs": { - "version": "10.2.55", - "resolved": "https://registry.npmjs.org/constructs/-/constructs-10.2.55.tgz", - "integrity": "sha512-TjH8BRN9qpmjZqq0ixH1NqgPHam0tQJcMQ6puffM0Sj0dRPXaJAzOtbHpn24rhjE+90vIQ8jBAUO8v8Sdp1uAQ==", + "version": "10.2.60", + "resolved": "https://registry.npmjs.org/constructs/-/constructs-10.2.60.tgz", + "integrity": "sha512-rO9EHXhUZpA1Gz5wk5ewCVaol6anSilDzS7uv4Fmgx+tKTcxchAl10z8ObjZMjcQYNw+5FBVIzSagSKJanbHdQ==", "dev": true, "peer": true }, diff --git a/tools/hangar/package.json b/tools/hangar/package.json index 7d1b7cba591..e9f071c8a68 100644 --- a/tools/hangar/package.json +++ b/tools/hangar/package.json @@ -12,11 +12,11 @@ "author": "Monada", "license": "Apache-2.0", "devDependencies": { + "cdktf": "^0.17.0", "execa": "^7.1.1", "npm": "^9.6.4", "tsx": "^3.12.6", "vitest": "^0.30.1", - "yaml": "^2.2.1", - "@cdktf/provider-aws": "^12.0.13" + "yaml": "^2.2.1" } } \ No newline at end of file diff --git a/tools/hangar/src/package.setup.ts b/tools/hangar/src/package.setup.ts index 103e1990ac3..2a961a1abc1 100644 --- a/tools/hangar/src/package.setup.ts +++ b/tools/hangar/src/package.setup.ts @@ -7,6 +7,10 @@ import { targetWingSDKSpec, targetWingCompilerSpec, targetWingSpec, + targetWingConsoleAppSpec, + targetWingConsoleServerSpec, + targetWingConsoleDesignSystemSpec, + targetWingConsoleUiSpec, tmpDir, wingBin, } from "./paths"; @@ -44,6 +48,10 @@ export default async function () { targetWingSDKSpec, targetWingCompilerSpec, targetWingSpec, + targetWingConsoleAppSpec, + targetWingConsoleServerSpec, + targetWingConsoleDesignSystemSpec, + targetWingConsoleUiSpec, ]; const installResult = await execa(npmBin, installArgs, { cwd: tmpDir, diff --git a/tools/hangar/src/paths.ts b/tools/hangar/src/paths.ts index 2002e584de3..feddd50e7b9 100644 --- a/tools/hangar/src/paths.ts +++ b/tools/hangar/src/paths.ts @@ -3,8 +3,8 @@ import * as fs from "fs"; export const repoRoot = path.resolve(__dirname, "../../.."); export const testDir = path.join(repoRoot, "examples/tests"); -export const pluginsDir = path.join(repoRoot, "examples/plugins"); export const validTestDir = path.join(testDir, "valid"); +export const pluginsDir = path.join(validTestDir, "plugins"); export const sdkTests = path.join(testDir, "sdk_tests"); export const invalidTestDir = path.join(testDir, "invalid"); export const benchmarksTestDir = path.join(validTestDir, "benchmarks"); @@ -20,6 +20,18 @@ export const snapshotDir = path.join(hangarDir, "__snapshots__"); export const targetWingSpec = process.env.HANGAR_WING_SPEC ?? `file:${path.join(repoRoot, `apps/wing`)}`; +export const targetWingConsoleAppSpec = + process.env.HANGAR_WINGCONSOLE_APP_SPEC ?? + `file:${path.join(repoRoot, `apps/wing-console/console/app`)}`; +export const targetWingConsoleServerSpec = + process.env.HANGAR_WINGCONSOLE_SERVER_SPEC ?? + `file:${path.join(repoRoot, `apps/wing-console/console/server`)}`; +export const targetWingConsoleDesignSystemSpec = + process.env.HANGAR_WINGCONSOLE_DESIGN_SYSTEM_SPEC ?? + `file:${path.join(repoRoot, `apps/wing-console/console/design-system`)}`; +export const targetWingConsoleUiSpec = + process.env.HANGAR_WINGCONSOLE_UI_SPEC ?? + `file:${path.join(repoRoot, `apps/wing-console/console/ui`)}`; export const targetWingCompilerSpec = process.env.HANGAR_WINGCOMPILER_SPEC ?? `file:${path.join(repoRoot, `libs/wingcompiler`)}`; diff --git a/tools/hangar/src/plugins.test.ts b/tools/hangar/src/plugins.test.ts index a120718468d..13a2d8ad6e8 100644 --- a/tools/hangar/src/plugins.test.ts +++ b/tools/hangar/src/plugins.test.ts @@ -7,7 +7,7 @@ import { sanitize_json_paths, tfResourcesOfCount, } from "./utils"; -import * as cdktf from "cdktf"; +import { Testing } from "cdktf"; describe("Plugin examples", () => { const app = "app.w"; @@ -38,7 +38,7 @@ describe("Plugin examples", () => { expect(terraformOutput).toMatchSnapshot(); expect( - cdktf.Testing.toHaveResourceWithProperties( + Testing.toHaveResourceWithProperties( terraformOutputString, "aws_iam_role", {