├── .devcontainer ├── Dockerfile ├── devcontainer.json └── scripts │ ├── godeps.sh │ ├── install.sh │ └── prepare.sh ├── .github ├── dockerimg │ ├── Dockerfile │ ├── encore-entrypoint.bash │ └── rename-binary-if-needed.bash └── workflows │ ├── ci.yml │ ├── makefile │ ├── release-2.yml │ ├── release.yml │ ├── semgrep-to-rdjson.jq │ └── staticcheck-to-rdjsonl.jq ├── .gitignore ├── .prettierrc.toml ├── .reviewdog.yml ├── CODE_OF_CONDUCT.md ├── CONTRIBUTING.md ├── Cargo.lock ├── Cargo.toml ├── Cross.toml ├── LICENSE ├── README.md ├── check.bash ├── cli ├── cmd │ ├── encore │ │ ├── app │ │ │ ├── app.go │ │ │ ├── clone.go │ │ │ ├── create.go │ │ │ ├── create_form.go │ │ │ ├── create_test.go │ │ │ ├── initialize.go │ │ │ └── link.go │ │ ├── auth │ │ │ └── auth.go │ │ ├── bits │ │ │ ├── add.go │ │ │ ├── api.go │ │ │ ├── bits.go │ │ │ └── list.go │ │ ├── build.go │ │ ├── check.go │ │ ├── cmdutil │ │ │ ├── autocompletes.go │ │ │ ├── cmdutil.go │ │ │ ├── daemon.go │ │ │ ├── output.go │ │ │ └── stream.go │ │ ├── config │ │ │ └── config.go │ │ ├── daemon.go │ │ ├── daemon │ │ │ ├── daemon.go │ │ │ └── migrations │ │ │ │ ├── 1_initial_schema.up.sql │ │ │ │ ├── 2_infra_namespaces.up.sql │ │ │ │ └── 3_test_tracing.up.sql │ │ ├── db.go │ │ ├── debug.go │ │ ├── deploy.go │ │ ├── exec.go │ │ ├── gen.go │ │ ├── init_windows.go │ │ ├── k8s │ │ │ ├── auth.go │ │ │ ├── config.go │ │ │ ├── kubernetes.go │ │ │ └── types │ │ │ │ ├── KUBERNETES_LICENSE.txt │ │ │ │ ├── README.md │ │ │ │ ├── clientauthentication_types.go │ │ │ │ ├── homedir.go │ │ │ │ ├── meta_types.go │ │ │ │ └── runtime_types.go │ │ ├── logs.go │ │ ├── main.go │ │ ├── mcp.go │ │ ├── namespace │ │ │ └── namespace.go │ │ ├── rand.go │ │ ├── root │ │ │ └── rootcmd.go │ │ ├── run.go │ │ ├── secrets │ │ │ ├── archive.go │ │ │ ├── list.go │ │ │ ├── secrets.go │ │ │ └── set.go │ │ ├── sqlc.go │ │ ├── telemetry.go │ │ ├── test.go │ │ └── version.go │ ├── git-remote-encore │ │ └── main.go │ └── tsbundler-encore │ │ └── main.go ├── daemon │ ├── apps │ │ └── apps.go │ ├── check.go │ ├── common.go │ ├── create.go │ ├── daemon.go │ ├── dash │ │ ├── ai │ │ │ ├── assembler.go │ │ │ ├── client.go │ │ │ ├── codegen.go │ │ │ ├── conv.go │ │ │ ├── manager.go │ │ │ ├── overlay.go │ │ │ ├── parser.go │ │ │ ├── sql.go │ │ │ ├── types.go │ │ │ └── types_test.go │ │ ├── apiproxy │ │ │ └── apiproxy.go │ │ ├── dash.go │ │ ├── dash_test.go │ │ ├── dashproxy │ │ │ └── dashproxy.go │ │ ├── json_list_encoder.go │ │ ├── json_list_encoder_test.go │ │ ├── protojson.go │ │ └── server.go │ ├── db.go │ ├── debug.go │ ├── engine │ │ ├── runtime.go │ │ ├── trace │ │ │ ├── parse_test.go │ │ │ └── trace.go │ │ └── trace2 │ │ │ ├── recorder.go │ │ │ ├── sqlite │ │ │ ├── read.go │ │ │ └── write.go │ │ │ └── store.go │ ├── exec_script.go │ ├── export.go │ ├── export │ │ ├── download.go │ │ ├── export.go │ │ └── infra_config.go │ ├── internal │ │ ├── runlog │ │ │ └── runlog.go │ │ └── sym │ │ │ ├── sym.go │ │ │ ├── sym_darwin.go │ │ │ ├── sym_elf.go │ │ │ └── sym_windows.go │ ├── mcp │ │ ├── api_tools.go │ │ ├── bucket_tools.go │ │ ├── cache_tools.go │ │ ├── cron_tools.go │ │ ├── db_tools.go │ │ ├── docs_tools.go │ │ ├── mcp.go │ │ ├── metrics_tools.go │ │ ├── pubsub_tools.go │ │ ├── schema_json.go │ │ ├── secret_tools.go │ │ ├── src_tools.go │ │ ├── trace_tools.go │ │ └── util.go │ ├── namespace.go │ ├── namespace │ │ └── namespace.go │ ├── objects │ │ ├── manager.go │ │ ├── objects.go │ │ └── public.go │ ├── pubsub │ │ ├── nsq.go │ │ └── utils.go │ ├── redis │ │ └── redis.go │ ├── run.go │ ├── run │ │ ├── call.go │ │ ├── check.go │ │ ├── errors.go │ │ ├── exec_command.go │ │ ├── exec_script.go │ │ ├── http.go │ │ ├── infra │ │ │ ├── encorecloudtesting.go │ │ │ └── infra.go │ │ ├── manager.go │ │ ├── proc_groups.go │ │ ├── run.go │ │ ├── runtime_config2.go │ │ ├── tests.go │ │ └── watch.go │ ├── schema.go │ ├── secret │ │ └── secret.go │ ├── sqldb │ │ ├── cluster.go │ │ ├── db.go │ │ ├── db_test.go │ │ ├── docker │ │ │ └── docker.go │ │ ├── driver.go │ │ ├── external │ │ │ └── external.go │ │ ├── manager.go │ │ ├── migrate.go │ │ ├── proxy.go │ │ ├── remote.go │ │ └── utils.go │ ├── telemetry.go │ ├── test.go │ ├── tracing.go │ ├── userfacing.go │ └── watch.go └── internal │ ├── browser │ └── browser.go │ ├── bubbles │ ├── checklist │ │ └── checklist.go │ └── selector │ │ └── selector.go │ ├── dedent │ ├── dedent.go │ └── dedent_test.go │ ├── gosym │ ├── pclntab.go │ ├── symtab.go │ ├── symtab_test.go │ └── testdata │ │ ├── main.go │ │ ├── pclinetest.h │ │ ├── pclinetest.s │ │ └── pcln115.gz │ ├── jsonrpc2 │ ├── conn.go │ ├── handler.go │ ├── jsonrpc2.go │ ├── jsonrpc2_test.go │ ├── messages.go │ ├── serve.go │ ├── serve_test.go │ ├── servertest │ │ ├── servertest.go │ │ └── servertest_test.go │ ├── stream.go │ ├── wire.go │ └── wire_test.go │ ├── login │ ├── deviceauth.go │ ├── interactive.go │ └── login.go │ ├── manifest │ └── manifest.go │ ├── onboarding │ └── onboarding.go │ ├── platform │ ├── api.go │ ├── client.go │ ├── gql │ │ ├── app.go │ │ ├── env.go │ │ └── secrets.go │ ├── jsoniter_ext.go │ ├── jsoniter_ext_test.go │ ├── login.go │ └── secrets.go │ ├── telemetry │ └── telemetry.go │ └── update │ └── update.go ├── clippy.toml ├── docs ├── go │ ├── cli │ │ ├── cli-reference.md │ │ ├── client-generation.md │ │ ├── config-reference.md │ │ ├── infra-namespaces.md │ │ ├── mcp.md │ │ └── telemetry.md │ ├── community │ │ ├── contribute.md │ │ ├── get-involved.md │ │ ├── open-source.md │ │ ├── principles.md │ │ └── submit-template.md │ ├── concepts │ │ ├── application-model.md │ │ └── benefits.md │ ├── develop │ │ ├── api-docs.md │ │ ├── auth.md │ │ ├── config.md │ │ ├── cors.md │ │ ├── metadata.md │ │ ├── middleware.md │ │ ├── mocking.md │ │ ├── testing.md │ │ └── validation.md │ ├── faq.md │ ├── how-to │ │ ├── assets │ │ │ ├── logto-api-resource.png │ │ │ └── logto-application-endpoints.png │ │ ├── atlas-gorm.md │ │ ├── auth0-auth.md │ │ ├── break-up-monolith.md │ │ ├── cgo.md │ │ ├── clerk-auth.md │ │ ├── debug.md │ │ ├── dependency-injection.md │ │ ├── entgo-orm.md │ │ ├── firebase-auth.md │ │ ├── grpc-connect.md │ │ ├── http-requests.md │ │ ├── integrate-frontend.mdx │ │ ├── logto-auth.md │ │ ├── pubsub-outbox.md │ │ └── temporal.md │ ├── install.md │ ├── migration │ │ └── migrate-away.md │ ├── observability │ │ ├── dev-dash.md │ │ ├── encore-flow.md │ │ ├── logging.md │ │ ├── service-catalog.md │ │ └── tracing.md │ ├── overview.md │ ├── primitives │ │ ├── api-calls.md │ │ ├── api-errors.md │ │ ├── api-schemas.md │ │ ├── app-structure.md │ │ ├── caching.md │ │ ├── change-db-schema.md │ │ ├── code-snippets.md │ │ ├── connect-existing-db.md │ │ ├── cron-jobs.md │ │ ├── database-extensions.md │ │ ├── database-troubleshooting.md │ │ ├── databases.md │ │ ├── defining-apis.md │ │ ├── insert-test-data-db.md │ │ ├── object-storage.md │ │ ├── pubsub.md │ │ ├── raw-endpoints.md │ │ ├── secrets.md │ │ ├── service-structs.md │ │ ├── services.md │ │ └── share-db-between-services.md │ ├── quick-start.mdx │ ├── self-host │ │ ├── ci-cd.md │ │ ├── configure-infra.md │ │ ├── deploy-to-digital-ocean-wip.md │ │ └── self-host.md │ └── tutorials │ │ ├── booking-system.mdx │ │ ├── graphql.mdx │ │ ├── incident-management-tool.md │ │ ├── meeting-notes.mdx │ │ ├── rest-api.mdx │ │ ├── slack-bot.md │ │ └── uptime.md ├── menu.cue ├── platform │ ├── deploy │ │ ├── deploying.md │ │ ├── environments.md │ │ ├── own-cloud.md │ │ ├── preview-environments.md │ │ └── security.md │ ├── infrastructure │ │ ├── aws.md │ │ ├── cloudflare.md │ │ ├── configuration.md │ │ ├── configure-kubectl.md │ │ ├── configure-network.md │ │ ├── gcp.md │ │ ├── import-cloud-sql.md │ │ ├── import-kubernetes-cluster.md │ │ ├── import-project.md │ │ ├── import-rds.md │ │ ├── infra.md │ │ ├── kubernetes.md │ │ ├── manage-db-users.md │ │ └── neon.md │ ├── integrations │ │ ├── api-reference.md │ │ ├── auth-keys.md │ │ ├── custom-domains.md │ │ ├── github.md │ │ ├── oauth-clients.md │ │ ├── terraform.md │ │ └── webhooks.md │ ├── introduction.md │ ├── management │ │ ├── billing.md │ │ ├── compliance.md │ │ ├── permissions.md │ │ ├── telemetry.md │ │ └── usage.md │ ├── migration │ │ ├── migrate-away.md │ │ ├── migrate-to-encore.md │ │ └── try-encore.md │ ├── observability │ │ ├── encore-flow.md │ │ ├── metrics.md │ │ ├── service-catalog.md │ │ └── tracing.md │ ├── other │ │ ├── vs-heroku.md │ │ ├── vs-supabase.md │ │ └── vs-terraform.md │ └── overview.md └── ts │ ├── cli │ ├── cli-reference.md │ ├── client-generation.md │ ├── config-reference.md │ ├── infra-namespaces.md │ ├── mcp.md │ └── telemetry.md │ ├── community │ ├── contribute.md │ ├── get-involved.md │ ├── open-source.md │ ├── principles.md │ └── submit-template.md │ ├── concepts │ ├── application-model.md │ ├── benefits.md │ └── hello-world.md │ ├── develop │ ├── auth.md │ ├── debug.md │ ├── metadata.md │ ├── middleware.md │ ├── multithreading.md │ ├── orms │ │ ├── drizzle.md │ │ ├── knex.md │ │ ├── overview.md │ │ ├── prisma.md │ │ └── sequelize.md │ ├── running-scripts.md │ └── testing.md │ ├── faq.md │ ├── frontend │ ├── cors.md │ ├── hosting.mdx │ ├── mono-vs-multi-repo.mdx │ ├── request-client.mdx │ └── template-engine.md │ ├── how-to │ ├── file-uploads.md │ └── nestjs.md │ ├── install.md │ ├── migration │ ├── express-migration.md │ └── migrate-away.md │ ├── observability │ ├── dev-dash.md │ ├── flow.md │ ├── logging.md │ ├── service-catalog.md │ └── tracing.md │ ├── overview.md │ ├── primitives │ ├── api-calls.mdx │ ├── app-structure.md │ ├── cookies.mdx │ ├── cron-jobs.md │ ├── database-extensions.md │ ├── databases.md │ ├── defining-apis.mdx │ ├── errors.md │ ├── graphql.mdx │ ├── object-storage.md │ ├── pubsub.md │ ├── raw-endpoints.mdx │ ├── secrets.md │ ├── services.mdx │ ├── static-assets.mdx │ ├── streaming-apis.mdx │ └── validation.mdx │ ├── quick-start.mdx │ ├── self-host │ ├── build.md │ ├── ci-cd.md │ ├── configure-infra.md │ ├── deploy-to-digital-ocean.md │ └── deploy-to-railway.md │ └── tutorials │ ├── graphql.mdx │ ├── rest-api.mdx │ ├── slack-bot.md │ └── uptime.md ├── e2e-tests ├── README.md ├── app_test.go ├── echo_app_test.go ├── testdata │ ├── echo │ │ ├── .gitignore │ │ ├── cache │ │ │ └── cache.go │ │ ├── di │ │ │ └── di.go │ │ ├── echo │ │ │ ├── config.cue │ │ │ ├── config.go │ │ │ ├── config_test.go │ │ │ ├── echo.go │ │ │ ├── echo_test.go │ │ │ └── encore.gen.cue │ │ ├── empty_cfg │ │ │ └── service.go │ │ ├── encore.app │ │ ├── endtoend │ │ │ └── endtoend.go │ │ ├── go.mod │ │ ├── go.sum │ │ ├── middleware │ │ │ ├── middleware.go │ │ │ └── middleware_test.go │ │ ├── test │ │ │ └── endpoints.go │ │ └── validation │ │ │ └── validation.go │ ├── echo_client │ │ ├── .eslintrc.cjs │ │ ├── .gitignore │ │ ├── go.mod │ │ ├── golang │ │ │ └── client │ │ │ │ └── goclient.go │ │ ├── js │ │ │ ├── client.js │ │ │ └── main.js │ │ ├── main.go │ │ ├── package-lock.json │ │ ├── package.json │ │ ├── ts │ │ │ ├── client.ts │ │ │ └── main.ts │ │ └── tsconfig.json │ └── testscript │ │ ├── encore_currentrequest.txt │ │ ├── et_mocking.txt │ │ ├── et_override_user.txt │ │ ├── et_override_user_authdata.txt │ │ ├── experiment_local_secrets_override.txtar │ │ ├── fallback_routes.txt │ │ ├── graceful_shutdown.txt │ │ ├── pubsub_method_handler.txt │ │ └── pubsub_ref.txt └── testscript_test.go ├── go.mod ├── go.sum ├── go_llm_instructions.txt ├── internal ├── conf │ └── conf.go ├── env │ └── env.go ├── etrace │ ├── etrace.go │ ├── gid.go │ └── protocol.go ├── gocodegen │ ├── helpers.go │ ├── marshalling.go │ └── package.go ├── goldfish │ └── goldfish.go ├── httpcache │ ├── LICENSE.txt │ ├── README.md │ ├── diskcache │ │ ├── diskcache.go │ │ └── diskcache_test.go │ ├── httpcache.go │ ├── httpcache_test.go │ └── test │ │ ├── test.go │ │ └── test_test.go ├── lookpath │ └── lookpath.go ├── optracker │ ├── async.go │ └── optracker.go ├── userconfig │ ├── config.go │ ├── def.go │ ├── docs.go │ ├── files.go │ ├── gendocs │ │ └── gendocs.go │ ├── reflect.go │ ├── value.go │ └── write.go └── version │ └── version.go ├── parser └── encoding │ └── rpc.go ├── pkg ├── ansi │ └── ansi.go ├── appfile │ └── appfile.go ├── bits │ ├── bits.go │ └── download.go ├── builder │ ├── builder.go │ └── builderimpl │ │ └── builders.go ├── clientgen │ ├── client.go │ ├── client_test.go │ ├── clientgentypes │ │ └── clientgentypes.go │ ├── errors.go │ ├── golang.go │ ├── javascript.go │ ├── openapi │ │ ├── openapi.go │ │ └── schema.go │ ├── testdata │ │ ├── README.md │ │ ├── goapp │ │ │ ├── expected_baseauth_golang.go │ │ │ ├── expected_baseauth_javascript.js │ │ │ ├── expected_baseauth_openapi.json │ │ │ ├── expected_baseauth_typescript.ts │ │ │ ├── expected_golang.go │ │ │ ├── expected_javascript.js │ │ │ ├── expected_noauth_golang.go │ │ │ ├── expected_noauth_javascript.js │ │ │ ├── expected_noauth_openapi.json │ │ │ ├── expected_noauth_typescript.ts │ │ │ ├── expected_openapi.json │ │ │ ├── expected_typescript.ts │ │ │ ├── input.go │ │ │ ├── input_baseauth.go │ │ │ ├── input_noauth.go │ │ │ └── tsconfig.json │ │ └── tsapp │ │ │ ├── expected_golang.go │ │ │ ├── expected_javascript.js │ │ │ ├── expected_list_of_union_javascript.js │ │ │ ├── expected_list_of_union_shared.ts │ │ │ ├── expected_list_of_union_typescript.ts │ │ │ ├── expected_shared.ts │ │ │ ├── expected_stream_javascript.js │ │ │ ├── expected_stream_shared.ts │ │ │ ├── expected_stream_typescript.ts │ │ │ ├── expected_typescript.ts │ │ │ ├── input.ts │ │ │ ├── input_list_of_union.ts │ │ │ ├── input_stream.ts │ │ │ └── tsconfig.json │ ├── types.go │ ├── typescript.go │ └── utils.go ├── cueutil │ ├── build.go │ └── types.go ├── dockerbuild │ ├── dockerbuild.go │ ├── dockerbuild_test.go │ ├── features.go │ ├── manifest.go │ ├── spec.go │ ├── spec_test.go │ └── tarcopy.go ├── editors │ ├── LICENSE │ ├── doc.go │ ├── encore_names.go │ ├── encore_urls.go │ ├── launch.go │ ├── lookup.go │ ├── lookup_darwin.go │ ├── lookup_linux.go │ ├── lookup_test.go │ ├── lookup_unsupported.go │ ├── lookup_windows.go │ └── utils.go ├── eerror │ ├── error.go │ ├── stack.go │ └── zerolog.go ├── emulators │ └── storage │ │ ├── LICENSE │ │ ├── gcsemu │ │ ├── batch.go │ │ ├── client.go │ │ ├── errors.go │ │ ├── filestore.go │ │ ├── filestore_test.go │ │ ├── gcsemu.go │ │ ├── gcsemu_test.go │ │ ├── http_wrappers.go │ │ ├── memstore.go │ │ ├── memstore_test.go │ │ ├── meta.go │ │ ├── multipart.go │ │ ├── parse.go │ │ ├── range.go │ │ ├── range_test.go │ │ ├── raw_http_test.go │ │ ├── remote_test.go │ │ ├── server.go │ │ ├── store.go │ │ ├── util.go │ │ └── walk.go │ │ └── gcsutil │ │ ├── counted_lock.go │ │ ├── doc.go │ │ ├── gcspagetoken.go │ │ ├── gcspagetoken.pb.go │ │ ├── gcspagetoken.proto │ │ ├── gcspagetoken_test.go │ │ ├── transient_lock_map.go │ │ └── transient_lock_map_test.go ├── encorebuild │ ├── buildconf │ │ └── config.go │ ├── buildutil │ │ └── buildutil.go │ ├── cmd │ │ ├── build-local-binary │ │ │ └── build-local-binary.go │ │ └── make-release │ │ │ └── make-release.go │ ├── compile │ │ └── compile.go │ ├── dist_builder.go │ ├── gentypedefs │ │ ├── gentypedefs.go │ │ └── napi.cjs.tmpl │ ├── githubrelease │ │ └── githubrelease.go │ ├── jsruntimebuild.go │ ├── supervisorbuild.go │ └── windows │ │ ├── .gitignore │ │ ├── build.bat │ │ ├── manifest.xml │ │ └── resources.rc ├── environ │ └── environ.go ├── errinsrc │ ├── characters.go │ ├── errinsrc.go │ ├── internal │ │ ├── cuelocation.go │ │ ├── golocation.go │ │ ├── helper.go │ │ └── location.go │ ├── list.go │ ├── setup_test.go │ ├── srcerrors │ │ ├── errors.go │ │ ├── helpers.go │ │ └── helptext.go │ ├── srcrender.go │ ├── srcrender_test.go │ ├── stack.go │ ├── stack_dev.go │ ├── stack_release.go │ ├── testdata │ │ ├── Test_renderSrc_MultipleSeperateInSameFile__on_following_lines_ascii.golden │ │ ├── Test_renderSrc_MultipleSeperateInSameFile__on_following_lines_unicode.golden │ │ ├── Test_renderSrc_MultipleSeperateInSameFile__on_same_line_ascii.golden │ │ ├── Test_renderSrc_MultipleSeperateInSameFile__on_same_line_unicode.golden │ │ ├── Test_renderSrc_MultipleSeperateInSameFile__spaced_apart_ascii.golden │ │ ├── Test_renderSrc_MultipleSeperateInSameFile__spaced_apart_unicode.golden │ │ ├── Test_renderSrc_MutlilineError_ascii.golden │ │ ├── Test_renderSrc_MutlilineError_unicode.golden │ │ ├── Test_renderSrc_Simple__error_no_text_ascii.golden │ │ ├── Test_renderSrc_Simple__error_no_text_unicode.golden │ │ ├── Test_renderSrc_Simple__multiline_message_ascii.golden │ │ ├── Test_renderSrc_Simple__multiline_message_unicode.golden │ │ ├── Test_renderSrc_Simple__simple_error_ascii.golden │ │ ├── Test_renderSrc_Simple__simple_error_unicode.golden │ │ ├── Test_renderSrc_Simple__simple_help_ascii.golden │ │ ├── Test_renderSrc_Simple__simple_help_unicode.golden │ │ ├── Test_renderSrc_Simple__simple_warning_ascii.golden │ │ ├── Test_renderSrc_Simple__simple_warning_unicode.golden │ │ ├── Test_renderSrc_Simple__single_character_error_ascii.golden │ │ ├── Test_renderSrc_Simple__single_character_error_unicode.golden │ │ ├── test.cue │ │ └── test.go │ └── utils.go ├── errlist │ └── errlist.go ├── errors │ ├── locations.go │ ├── range.go │ ├── template.go │ └── utils.go ├── fns │ └── fns.go ├── github │ └── github.go ├── golden │ └── golden.go ├── idents │ ├── identifiers.go │ └── identifiers_test.go ├── logging │ └── zerolog_adapter.go ├── make-release │ ├── compilers.go │ ├── dist_builder.go │ ├── js_packager.go │ ├── make-release.go │ ├── utils.go │ └── windows │ │ ├── .gitignore │ │ ├── build.bat │ │ ├── manifest.xml │ │ └── resources.rc ├── namealloc │ ├── namealloc.go │ └── namealloc_test.go ├── noopgateway │ ├── noopgateway.go │ └── retry_dialer.go ├── noopgwdesc │ └── gateway.go ├── option │ ├── option.go │ └── pkgfn.go ├── paths │ └── paths.go ├── pgproxy │ ├── README.md │ ├── pgproxy.go │ └── scram.go ├── promise │ └── prom.go ├── rtconfgen │ ├── base_builder.go │ ├── convert.go │ ├── infra_builder.go │ └── resource_map.go ├── scrub │ ├── benchmark_test.go │ ├── metascrub │ │ ├── metascrub.go │ │ └── metascrub_test.go │ ├── scanner.go │ ├── scanner_test.go │ ├── scrub.go │ ├── scrub_test.go │ └── token_string.go ├── supervisor │ ├── cmd │ │ └── supervisor-encore │ │ │ └── main.go │ └── supervisor.go ├── svcproxy │ ├── dialer.go │ ├── doc.go │ └── svcproxy.go ├── traceparser │ ├── binreader.go │ ├── parser.go │ └── parser_test.go ├── vcs │ ├── app.go │ └── vcs.go ├── vfs │ ├── directory.go │ ├── doc.go │ ├── file.go │ ├── node.go │ ├── testdata │ │ └── filteredglob │ │ │ ├── blahsvc │ │ │ ├── another.json │ │ │ └── test.json │ │ │ ├── foosystem │ │ │ ├── README.md │ │ │ ├── anotherservice │ │ │ │ └── test.txt │ │ │ └── barservice │ │ │ │ ├── blah.json │ │ │ │ └── test.txt │ │ │ └── nope │ │ │ └── ignored.txt │ ├── utils.go │ ├── vfs.go │ └── vfs_test.go ├── watcher │ ├── event.go │ ├── rlimit_nix.go │ ├── rlimit_noop.go │ ├── util.go │ └── watcher.go ├── words │ ├── funcs.go │ ├── shortwords.txt │ ├── words.go │ └── words_test.go └── xos │ ├── xos_unix.go │ └── xos_windows.go ├── proto ├── encore │ ├── daemon │ │ ├── daemon.pb.go │ │ ├── daemon.proto │ │ └── daemon_grpc.pb.go │ ├── engine │ │ ├── trace │ │ │ ├── trace.pb.go │ │ │ ├── trace.proto │ │ │ └── trace_util.go │ │ └── trace2 │ │ │ ├── trace2.pb.go │ │ │ ├── trace2.proto │ │ │ └── trace_util.go │ ├── parser │ │ ├── meta │ │ │ └── v1 │ │ │ │ ├── meta.pb.go │ │ │ │ ├── meta.pb.ts │ │ │ │ └── meta.proto │ │ └── schema │ │ │ └── v1 │ │ │ ├── schema.pb.go │ │ │ ├── schema.pb.ts │ │ │ ├── schema.proto │ │ │ ├── walk.go │ │ │ └── walk_test.go │ └── runtime │ │ └── v1 │ │ ├── infra.pb.go │ │ ├── infra.proto │ │ ├── runtime.pb.go │ │ ├── runtime.proto │ │ ├── secretdata.pb.go │ │ └── secretdata.proto ├── gen.go └── gen.sh ├── runtimes ├── core │ ├── Cargo.toml │ ├── build.rs │ ├── resources │ │ └── test │ │ │ ├── infra.config.json │ │ │ └── runtime.pb │ └── src │ │ ├── api │ │ ├── auth │ │ │ ├── local.rs │ │ │ ├── mod.rs │ │ │ └── remote.rs │ │ ├── call.rs │ │ ├── cors │ │ │ ├── cors_headers_config │ │ │ │ ├── LICENSE │ │ │ │ ├── allow_credentials.rs │ │ │ │ ├── allow_headers.rs │ │ │ │ ├── allow_methods.rs │ │ │ │ ├── allow_origin.rs │ │ │ │ ├── allow_private_network.rs │ │ │ │ ├── expose_headers.rs │ │ │ │ ├── max_age.rs │ │ │ │ ├── mod.rs │ │ │ │ └── vary.rs │ │ │ ├── mod.rs │ │ │ └── tests.rs │ │ ├── encore_routes │ │ │ ├── healthz.rs │ │ │ └── mod.rs │ │ ├── endpoint.rs │ │ ├── error.rs │ │ ├── gateway │ │ │ ├── mod.rs │ │ │ ├── router.rs │ │ │ └── websocket.rs │ │ ├── http.rs │ │ ├── http_server.rs │ │ ├── httputil.rs │ │ ├── jsonschema │ │ │ ├── de.rs │ │ │ ├── meta.rs │ │ │ ├── mod.rs │ │ │ ├── parse.rs │ │ │ ├── ser.rs │ │ │ └── validation.rs │ │ ├── manager.rs │ │ ├── mod.rs │ │ ├── paths.rs │ │ ├── pvalue.rs │ │ ├── reqauth │ │ │ ├── caller.rs │ │ │ ├── encoreauth │ │ │ │ ├── mod.rs │ │ │ │ ├── ophash.rs │ │ │ │ └── sign.rs │ │ │ ├── meta.rs │ │ │ ├── mod.rs │ │ │ ├── platform.rs │ │ │ └── svcauth.rs │ │ ├── schema │ │ │ ├── body.rs │ │ │ ├── cookie.rs │ │ │ ├── encoding.rs │ │ │ ├── header.rs │ │ │ ├── method.rs │ │ │ ├── mod.rs │ │ │ ├── path.rs │ │ │ └── query.rs │ │ ├── server.rs │ │ ├── snapshots │ │ │ ├── encore_runtime_core__api__paths__tests__basic.snap │ │ │ ├── encore_runtime_core__api__paths__tests__fallback.snap │ │ │ ├── encore_runtime_core__api__paths__tests__paths_to_register.snap │ │ │ ├── encore_runtime_core__api__paths__tests__tsr_conflict.snap │ │ │ └── encore_runtime_core__api__paths__tests__wildcard.snap │ │ ├── static_assets.rs │ │ ├── websocket.rs │ │ └── websocket_client.rs │ │ ├── base32.rs │ │ ├── error │ │ ├── conversions.rs │ │ └── mod.rs │ │ ├── infracfg.rs │ │ ├── lib.rs │ │ ├── log │ │ ├── consolewriter.rs │ │ ├── fields.rs │ │ ├── logger.rs │ │ ├── mod.rs │ │ └── writers.rs │ │ ├── meta │ │ └── mod.rs │ │ ├── model │ │ └── mod.rs │ │ ├── names.rs │ │ ├── objects │ │ ├── gcs │ │ │ ├── bucket.rs │ │ │ └── mod.rs │ │ ├── manager.rs │ │ ├── mod.rs │ │ ├── noop │ │ │ └── mod.rs │ │ └── s3 │ │ │ ├── bucket.rs │ │ │ └── mod.rs │ │ ├── proccfg.rs │ │ ├── pubsub │ │ ├── gcp │ │ │ ├── jwk.rs │ │ │ ├── mod.rs │ │ │ ├── push_sub.rs │ │ │ ├── sub.rs │ │ │ └── topic.rs │ │ ├── manager.rs │ │ ├── mod.rs │ │ ├── noop │ │ │ └── mod.rs │ │ ├── nsq │ │ │ ├── mod.rs │ │ │ ├── sub.rs │ │ │ └── topic.rs │ │ ├── push_registry.rs │ │ └── sqs_sns │ │ │ ├── fetcher.rs │ │ │ ├── mod.rs │ │ │ ├── sub.rs │ │ │ └── topic.rs │ │ ├── secrets │ │ └── mod.rs │ │ ├── sqldb │ │ ├── client.rs │ │ ├── manager.rs │ │ ├── mod.rs │ │ ├── transaction.rs │ │ └── val.rs │ │ └── trace │ │ ├── eventbuf.rs │ │ ├── log.rs │ │ ├── mod.rs │ │ ├── protocol.rs │ │ └── time_anchor.rs ├── go │ ├── README.md │ ├── appruntime │ │ ├── apisdk │ │ │ ├── api │ │ │ │ ├── auth.go │ │ │ │ ├── auth_remote.go │ │ │ │ ├── call_context.go │ │ │ │ ├── call_meta.go │ │ │ │ ├── call_meta_test.go │ │ │ │ ├── callers.go │ │ │ │ ├── capture.go │ │ │ │ ├── encore_routes.go │ │ │ │ ├── errmarshalling │ │ │ │ │ ├── fallback.go │ │ │ │ │ ├── jsonextension.go │ │ │ │ │ ├── marshal.go │ │ │ │ │ └── marshal_test.go │ │ │ │ ├── gateway.go │ │ │ │ ├── handler.go │ │ │ │ ├── handler_test.go │ │ │ │ ├── middleware.go │ │ │ │ ├── pubsub_push_proxy.go │ │ │ │ ├── reflection.go │ │ │ │ ├── reflection_test.go │ │ │ │ ├── registry.go │ │ │ │ ├── reqtrack.go │ │ │ │ ├── server.go │ │ │ │ ├── server_test.go │ │ │ │ ├── services.go │ │ │ │ ├── singleton.go │ │ │ │ ├── svcauth │ │ │ │ │ ├── doc.go │ │ │ │ │ ├── encoreauth.go │ │ │ │ │ ├── noop.go │ │ │ │ │ ├── pkgfn.go │ │ │ │ │ └── svcauth.go │ │ │ │ ├── transport │ │ │ │ │ ├── doc.go │ │ │ │ │ ├── eh2c.go │ │ │ │ │ ├── http.go │ │ │ │ │ ├── meta.go │ │ │ │ │ └── transport.go │ │ │ │ └── util.go │ │ │ ├── app │ │ │ │ ├── app.go │ │ │ │ ├── appinit │ │ │ │ │ └── appinit.go │ │ │ │ └── setup.go │ │ │ ├── cors │ │ │ │ ├── cors.go │ │ │ │ └── cors_test.go │ │ │ └── service │ │ │ │ ├── service.go │ │ │ │ └── singleton.go │ │ ├── doc.go │ │ ├── exported │ │ │ ├── config │ │ │ │ ├── config.go │ │ │ │ ├── infra │ │ │ │ │ ├── config.go │ │ │ │ │ ├── config_test.go │ │ │ │ │ ├── testdata │ │ │ │ │ │ ├── infra.config.json │ │ │ │ │ │ └── runtime.json │ │ │ │ │ └── validation.go │ │ │ │ ├── parse.go │ │ │ │ └── parse_test.go │ │ │ ├── experiments │ │ │ │ ├── cli.go │ │ │ │ ├── errors.go │ │ │ │ ├── names.go │ │ │ │ └── set.go │ │ │ ├── model │ │ │ │ ├── request.go │ │ │ │ └── trace.go │ │ │ ├── stack │ │ │ │ ├── stack.go │ │ │ │ ├── stack_app.go │ │ │ │ ├── stack_noapp.go │ │ │ │ └── stack_test.go │ │ │ ├── trace │ │ │ │ ├── events.go │ │ │ │ ├── http.go │ │ │ │ ├── log.go │ │ │ │ ├── logger.go │ │ │ │ ├── mock_trace │ │ │ │ │ └── mock_trace.go │ │ │ │ ├── mutex_app.go │ │ │ │ ├── mutex_noapp.go │ │ │ │ └── version.go │ │ │ └── trace2 │ │ │ │ ├── events.go │ │ │ │ ├── http.go │ │ │ │ ├── log.go │ │ │ │ ├── logger.go │ │ │ │ ├── mutex_app.go │ │ │ │ ├── mutex_noapp.go │ │ │ │ ├── timeanchor.go │ │ │ │ └── version.go │ │ ├── infrasdk │ │ │ ├── metadata │ │ │ │ ├── aws_collector.go │ │ │ │ ├── cloud_run_collector.go │ │ │ │ └── metadata.go │ │ │ ├── metrics │ │ │ │ ├── README.md │ │ │ │ ├── aws │ │ │ │ │ ├── cloudwatch.go │ │ │ │ │ └── cloudwatch_test.go │ │ │ │ ├── aws_cloudwatch_exporter.go │ │ │ │ ├── datadog │ │ │ │ │ └── datadog.go │ │ │ │ ├── datadog_exporter.go │ │ │ │ ├── encore_cloud_exporter.go │ │ │ │ ├── gcp │ │ │ │ │ ├── cloud_monitoring.go │ │ │ │ │ └── cloud_monitoring_test.go │ │ │ │ ├── gcp_cloud_monitoring_exporter.go │ │ │ │ ├── logs_based_exporter.go │ │ │ │ ├── logs_based_exporter_test.go │ │ │ │ ├── metrics.go │ │ │ │ ├── metrics_test.go │ │ │ │ ├── metricstest │ │ │ │ │ └── test_exporter.go │ │ │ │ ├── null_exporter.go │ │ │ │ ├── prometheus │ │ │ │ │ ├── prometheus.go │ │ │ │ │ ├── prometheus_test.go │ │ │ │ │ └── prompb │ │ │ │ │ │ ├── remote.pb.go │ │ │ │ │ │ ├── remote.proto │ │ │ │ │ │ ├── types.pb.go │ │ │ │ │ │ └── types.proto │ │ │ │ ├── prometheus_exporter.go │ │ │ │ ├── system │ │ │ │ │ └── system.go │ │ │ │ └── zzz_singleton_internal.go │ │ │ └── secrets │ │ │ │ ├── manager_internal.go │ │ │ │ └── secrets.go │ │ └── shared │ │ │ ├── appconf │ │ │ └── appconf.go │ │ │ ├── cfgutil │ │ │ └── svc.go │ │ │ ├── cloud │ │ │ └── clouds.go │ │ │ ├── cloudtrace │ │ │ ├── extractors.go │ │ │ ├── gcp.go │ │ │ └── logfields.go │ │ │ ├── encoreenv │ │ │ ├── app.go │ │ │ ├── encoreenv.go │ │ │ └── noapp.go │ │ │ ├── etype │ │ │ ├── marshal.go │ │ │ └── unmarshal.go │ │ │ ├── health │ │ │ ├── check.go │ │ │ ├── health.go │ │ │ └── singleton.go │ │ │ ├── jsonapi │ │ │ ├── jsonapi.go │ │ │ └── jsonapi_nonapp.go │ │ │ ├── logging │ │ │ └── logging.go │ │ │ ├── nativehist │ │ │ ├── PROMETHEUS_LICENSE.txt │ │ │ └── nativehist.go │ │ │ ├── platform │ │ │ ├── platform.go │ │ │ ├── singleton.go │ │ │ └── streaming_trace.go │ │ │ ├── reqtrack │ │ │ ├── impl.go │ │ │ ├── impl_app.go │ │ │ ├── impl_noapp.go │ │ │ ├── reqtrack.go │ │ │ ├── singleton.go │ │ │ └── trace_stream.go │ │ │ ├── serde │ │ │ └── utils.go │ │ │ ├── shutdown │ │ │ ├── shutdown.go │ │ │ └── singleton.go │ │ │ ├── syncutil │ │ │ ├── once.go │ │ │ ├── once_test.go │ │ │ └── syncutil.go │ │ │ ├── testsupport │ │ │ ├── runtimehooks_app.go │ │ │ ├── testconfig.go │ │ │ └── testsupport.go │ │ │ └── traceprovider │ │ │ ├── mock_trace │ │ │ ├── factory.go │ │ │ └── mock_trace.go │ │ │ └── traceprovider.go │ ├── beta │ │ ├── auth │ │ │ ├── auth.go │ │ │ └── pkgfn.go │ │ ├── errs │ │ │ ├── builder.go │ │ │ ├── codes.go │ │ │ ├── details.go │ │ │ ├── error.go │ │ │ └── errs_internal.go │ │ └── package.go │ ├── config │ │ ├── helpers_internal.go │ │ ├── manager_internal.go │ │ ├── pkgfn.go │ │ ├── test_internal.go │ │ └── types.go │ ├── cron │ │ └── cron.go │ ├── et │ │ ├── auth.go │ │ ├── config.go │ │ ├── manager_internal.go │ │ ├── mocking.go │ │ ├── package.go │ │ ├── pkgfn.go │ │ ├── pubsub.go │ │ ├── singleton_internal.go │ │ └── sqldb.go │ ├── example_test.go │ ├── go.mod │ ├── go.sum │ ├── internal │ │ ├── limiter │ │ │ ├── limiter.go │ │ │ └── noop.go │ │ └── platformauth │ │ │ └── platformauth.go │ ├── meta.go │ ├── metrics │ │ ├── bits_internal.go │ │ ├── histogram_internal.go │ │ ├── metrics.go │ │ ├── metrics_test.go │ │ ├── pkgfn.go │ │ ├── registry_internal.go │ │ ├── singleton_internal.go │ │ └── units.go │ ├── middleware │ │ ├── middleware.go │ │ └── middleware_internal.go │ ├── package.go │ ├── pkgfn.go │ ├── pubsub │ │ ├── internal │ │ │ ├── aws │ │ │ │ ├── manager.go │ │ │ │ ├── topic.go │ │ │ │ └── topic_test.go │ │ │ ├── azure │ │ │ │ ├── clients.go │ │ │ │ └── topic.go │ │ │ ├── encorecloud │ │ │ │ ├── manager.go │ │ │ │ └── topic.go │ │ │ ├── gcp │ │ │ │ ├── clients.go │ │ │ │ ├── push_handler.go │ │ │ │ └── topic.go │ │ │ ├── noop │ │ │ │ └── topic.go │ │ │ ├── nsq │ │ │ │ ├── log_adapter.go │ │ │ │ └── topic.go │ │ │ ├── test │ │ │ │ └── topic.go │ │ │ ├── types │ │ │ │ ├── private.go │ │ │ │ ├── public.go │ │ │ │ └── push_registry.go │ │ │ └── utils │ │ │ │ ├── contexts.go │ │ │ │ ├── utils.go │ │ │ │ ├── utils_test.go │ │ │ │ ├── workers.go │ │ │ │ └── workers_test.go │ │ ├── manager_internal.go │ │ ├── package.go │ │ ├── pkgfn.go │ │ ├── provider_aws.go │ │ ├── provider_azure.go │ │ ├── provider_encorecloud.go │ │ ├── provider_gcp.go │ │ ├── provider_nsq.go │ │ ├── refs.go │ │ ├── subscription.go │ │ ├── test_internal.go │ │ ├── topic.go │ │ ├── types.go │ │ └── zzz_singleton_internal.go │ ├── request.go │ ├── rlog │ │ ├── pkgfn.go │ │ ├── rlog.go │ │ └── rlog_test.go │ ├── shutdown │ │ └── shutdown.go │ ├── storage │ │ ├── cache │ │ │ ├── basic.go │ │ │ ├── basic_test.go │ │ │ ├── cache.go │ │ │ ├── cache_test.go │ │ │ ├── error_internal.go │ │ │ ├── list.go │ │ │ ├── list_test.go │ │ │ ├── manager_internal.go │ │ │ ├── noop_internal.go │ │ │ ├── pkgfn.go │ │ │ ├── set.go │ │ │ ├── set_test.go │ │ │ ├── struct.go │ │ │ └── zzz_singleton_internal.go │ │ ├── objects │ │ │ ├── bucket.go │ │ │ ├── internal │ │ │ │ ├── providers │ │ │ │ │ ├── gcs │ │ │ │ │ │ └── bucket.go │ │ │ │ │ ├── noop │ │ │ │ │ │ └── noop.go │ │ │ │ │ └── s3 │ │ │ │ │ │ ├── bucket.go │ │ │ │ │ │ ├── mock_client_test.go │ │ │ │ │ │ ├── uploader.go │ │ │ │ │ │ └── uploader_test.go │ │ │ │ └── types │ │ │ │ │ └── types.go │ │ │ ├── manager_internal.go │ │ │ ├── objects.go │ │ │ ├── options.go │ │ │ ├── package.go │ │ │ ├── path_escape.go │ │ │ ├── provider_gcs.go │ │ │ ├── provider_s3.go │ │ │ ├── refs.go │ │ │ ├── registry_internal.go │ │ │ └── zzz_singleton_internal.go │ │ └── sqldb │ │ │ ├── db.go │ │ │ ├── errors.go │ │ │ ├── errors_internal.go │ │ │ ├── errors_test.go │ │ │ ├── internal │ │ │ └── stdlibdriver │ │ │ │ ├── LICENSE │ │ │ │ └── stdlibdriver.go │ │ │ ├── manager_internal.go │ │ │ ├── pgx_tracer_internal.go │ │ │ ├── pkgfn.go │ │ │ ├── sqldb.go │ │ │ ├── sqldb_test.go │ │ │ ├── sqlerr │ │ │ └── sqlerr.go │ │ │ ├── stdlib.go │ │ │ ├── stdlib_noop_internal.go │ │ │ ├── stdlib_wrapper_internal.go │ │ │ ├── test_db.go │ │ │ └── zzz_singleton_internal.go │ └── types │ │ └── uuid │ │ ├── codec.go │ │ ├── codec_test.go │ │ ├── fuzz.go │ │ ├── generator.go │ │ ├── generator_test.go │ │ ├── sql.go │ │ ├── sql_test.go │ │ ├── uuid.go │ │ └── uuid_test.go └── js │ ├── .gitignore │ ├── Cargo.toml │ ├── build.rs │ ├── encore.dev │ ├── LICENSE │ ├── README.md │ ├── api │ │ ├── error.ts │ │ ├── gateway.ts │ │ ├── mod.ts │ │ └── stream.ts │ ├── app_meta.ts │ ├── auth │ │ └── mod.ts │ ├── config │ │ ├── mod.ts │ │ └── secrets.ts │ ├── cron │ │ └── mod.ts │ ├── internal │ │ ├── api │ │ │ ├── mod.ts │ │ │ └── node_http.ts │ │ ├── appinit │ │ │ └── mod.ts │ │ ├── auth │ │ │ └── mod.ts │ │ ├── codegen │ │ │ ├── api.ts │ │ │ ├── appinit.ts │ │ │ └── auth.ts │ │ ├── reqtrack │ │ │ └── mod.ts │ │ ├── runtime │ │ │ ├── .gitignore │ │ │ ├── .npmignore │ │ │ └── mod.ts │ │ ├── types │ │ │ └── mod.ts │ │ └── utils │ │ │ └── constraints.ts │ ├── log │ │ └── mod.ts │ ├── mod.ts │ ├── package-lock.json │ ├── package.json │ ├── pubsub │ │ ├── mod.ts │ │ ├── subscription.ts │ │ └── topic.ts │ ├── req_meta.ts │ ├── service │ │ └── mod.ts │ ├── storage │ │ ├── objects │ │ │ ├── bucket.ts │ │ │ ├── error.ts │ │ │ ├── mod.ts │ │ │ └── refs.ts │ │ └── sqldb │ │ │ ├── database.ts │ │ │ └── mod.ts │ ├── tsconfig.json │ └── validate │ │ └── mod.ts │ └── src │ ├── api.rs │ ├── cookies.rs │ ├── error.rs │ ├── gateway.rs │ ├── headers.rs │ ├── lib.rs │ ├── log.rs │ ├── meta.rs │ ├── napi_util.rs │ ├── objects.rs │ ├── pubsub.rs │ ├── pvalue.rs │ ├── raw_api.rs │ ├── request_meta.rs │ ├── runtime.rs │ ├── secret.rs │ ├── sqldb.rs │ ├── stream │ ├── mod.rs │ ├── read.rs │ └── write.rs │ ├── threadsafe_function.rs │ └── websocket_api.rs ├── rustfmt.toml ├── supervisor ├── Cargo.toml ├── build.rs └── src │ ├── bin │ └── supervisor-encore.rs │ ├── config.rs │ ├── lib.rs │ ├── proxy.rs │ └── supervisor.rs ├── tools ├── publicapigen │ └── main.go └── semgrep-rules │ ├── README.md │ └── semgrep-go │ ├── LICENSE │ ├── README.md │ ├── badexponentiation.yml │ ├── badnilguard.yml │ ├── close-sql-query-rows.yml │ ├── contextCancelable.yml │ ├── contextTODO.yml │ ├── ctx-time.yml │ ├── errclosed.yml │ ├── errnilcheck.yml │ ├── errtodo.yml │ ├── gofuzz.yml │ ├── hashsum.yml │ ├── hmac-bytes.yml │ ├── hmac-hash.yml │ ├── hostport.yml │ ├── http-ctx-goroutine.yml │ ├── ioutil-discard.yml │ ├── ioutil-nop-closer.yml │ ├── ioutil-readall.yml │ ├── ioutil-readdir.yml │ ├── ioutil-readfile.yml │ ├── ioutil-tmpdir.yml │ ├── ioutil-tmpfile.yml │ ├── ioutil-writefile.yml │ ├── joinpath.yml │ ├── json-writer.yml │ ├── mail-address.yml │ ├── marshaljson.yml │ ├── marshalyaml.yml │ ├── mathbits.yml │ ├── nilerr.yml │ ├── nrtxn.yml │ ├── oddbitwise.yml │ ├── oddcompare-subtract-eq-zero.yml │ ├── oddcompare-subtract-gt-zero.yml │ ├── oddcompare-subtract-gte-zero.yml │ ├── oddcompare-subtract-lt-zero.yml │ ├── oddcompare-subtract-lte-zero.yml │ ├── oddcompare-subtract-neq-zero.yml │ ├── oddcompare-xor-eq-zero.yml │ ├── oddcompare-xor-neq-zero.yml │ ├── oddcompound.yml │ ├── oddifsequence.yml │ ├── oddmathbits.yml │ ├── os-error-is-exist.yml │ ├── os-error-is-not-exist.yml │ ├── os-error-is-permission.yml │ ├── os-error-is-timeout.yml │ ├── parseint-downcast.yml │ ├── readeof.yml │ ├── readfull.yml │ ├── returnnil.yml │ ├── ruleguard.rules.go │ ├── sortslice.yml │ ├── sprinterr.yml │ ├── timeafter.yml │ ├── unixnano-after.yml │ ├── unixnano-before.yml │ ├── unmarshaljson.yml │ ├── unmarshalyaml.yml │ ├── use-fprintf-not-write-fsprint.yml │ ├── use-write-not-fprint.yml │ ├── use-writer-not-writestring.yml │ ├── wrongerrcall.yml │ └── wronglock.yml ├── ts_llm_instructions.txt ├── tsparser ├── Cargo.toml ├── build.rs ├── examples │ └── testparse.rs ├── litparser-derive │ ├── .gitignore │ ├── Cargo.lock │ ├── Cargo.toml │ ├── src │ │ └── lib.rs │ └── tests │ │ └── integration_tests.rs ├── litparser │ ├── .gitignore │ ├── Cargo.lock │ ├── Cargo.toml │ └── src │ │ └── lib.rs ├── src │ ├── app │ │ └── mod.rs │ ├── bin │ │ └── tsparser-encore.rs │ ├── builder │ │ ├── codegen.rs │ │ ├── compile.rs │ │ ├── mod.rs │ │ ├── package_mgmt.rs │ │ ├── parse.rs │ │ ├── prepare.rs │ │ ├── templates │ │ │ ├── catalog │ │ │ │ ├── auth │ │ │ │ │ ├── auth_ts.handlebars │ │ │ │ │ └── index_ts.handlebars │ │ │ │ └── clients │ │ │ │ │ ├── endpoints_d_ts.handlebars │ │ │ │ │ ├── endpoints_js.handlebars │ │ │ │ │ ├── endpoints_testing_js.handlebars │ │ │ │ │ ├── index_d_ts.handlebars │ │ │ │ │ └── index_js.handlebars │ │ │ └── entrypoints │ │ │ │ ├── combined │ │ │ │ └── main.handlebars │ │ │ │ ├── gateways │ │ │ │ └── main.handlebars │ │ │ │ └── services │ │ │ │ └── main.handlebars │ │ ├── test.rs │ │ └── transpiler.rs │ ├── legacymeta │ │ ├── api_schema.rs │ │ ├── mod.rs │ │ └── schema.rs │ ├── lib.rs │ ├── parser │ │ ├── doc_comments.rs │ │ ├── fileset.rs │ │ ├── mod.rs │ │ ├── module_loader.rs │ │ ├── parser.rs │ │ ├── resourceparser │ │ │ ├── bind.rs │ │ │ ├── mod.rs │ │ │ ├── paths.rs │ │ │ └── resource_parser.rs │ │ ├── resources │ │ │ ├── apis │ │ │ │ ├── api.rs │ │ │ │ ├── authhandler.rs │ │ │ │ ├── encoding.rs │ │ │ │ ├── gateway.rs │ │ │ │ ├── mod.rs │ │ │ │ ├── service.rs │ │ │ │ └── service_client.rs │ │ │ ├── infra │ │ │ │ ├── cron.rs │ │ │ │ ├── mod.rs │ │ │ │ ├── objects.rs │ │ │ │ ├── pubsub_subscription.rs │ │ │ │ ├── pubsub_topic.rs │ │ │ │ ├── secret.rs │ │ │ │ └── sqldb.rs │ │ │ ├── mod.rs │ │ │ └── parseutil.rs │ │ ├── respath.rs │ │ ├── service_discovery.rs │ │ ├── types │ │ │ ├── ast_id.rs │ │ │ ├── binding.rs │ │ │ ├── mod.rs │ │ │ ├── object.rs │ │ │ ├── resolved.rs │ │ │ ├── snapshots │ │ │ │ ├── encore_tsparser__parser__types__tests__resolve_types.snap │ │ │ │ ├── encore_tsparser__parser__types__tests__resolve_types@basic.ts.snap │ │ │ │ ├── encore_tsparser__parser__types__tests__resolve_types@export_default.ts.snap │ │ │ │ ├── encore_tsparser__parser__types__tests__resolve_types@export_wildcard.txt.snap │ │ │ │ ├── encore_tsparser__parser__types__tests__resolve_types@extends.ts.snap │ │ │ │ ├── encore_tsparser__parser__types__tests__resolve_types@generics.ts.snap │ │ │ │ ├── encore_tsparser__parser__types__tests__resolve_types@infer.txt.snap │ │ │ │ ├── encore_tsparser__parser__types__tests__resolve_types@keyofenum.ts.snap │ │ │ │ ├── encore_tsparser__parser__types__tests__resolve_types@qualified_name.ts.snap │ │ │ │ ├── encore_tsparser__parser__types__tests__resolve_types@reexport_single.txt.snap │ │ │ │ ├── encore_tsparser__parser__types__tests__resolve_types@reexport_wildcard.txt.snap │ │ │ │ ├── encore_tsparser__parser__types__tests__resolve_types@validation.ts.snap │ │ │ │ └── encore_tsparser__parser__types__tests__resolve_types@wirespec.ts.snap │ │ │ ├── testdata │ │ │ │ ├── basic.ts │ │ │ │ ├── export_default.ts │ │ │ │ ├── extends.ts │ │ │ │ ├── generics.ts │ │ │ │ ├── infer.txt │ │ │ │ ├── keyofenum.ts │ │ │ │ ├── qualified_name.ts │ │ │ │ ├── reexport_single.txt │ │ │ │ ├── reexport_wildcard.txt │ │ │ │ ├── validation.ts │ │ │ │ └── wirespec.ts │ │ │ ├── tests.rs │ │ │ ├── typ.rs │ │ │ ├── type_resolve.rs │ │ │ ├── type_string.rs │ │ │ ├── utils.rs │ │ │ ├── validation.rs │ │ │ └── visitor.rs │ │ ├── universe.ts │ │ └── usageparser │ │ │ └── mod.rs │ ├── runtimeresolve │ │ ├── exports.rs │ │ ├── mod.rs │ │ ├── node.rs │ │ └── tsconfig.rs │ ├── span_err.rs │ └── testutil │ │ ├── mod.rs │ │ ├── testparse.rs │ │ ├── testresolve.rs │ │ └── typeparse.rs ├── tests │ ├── common │ │ └── mod.rs │ ├── parse_tests.rs │ └── testdata │ │ ├── builtins.txt │ │ ├── mapped_types.txt │ │ ├── query_header.txt │ │ └── tsconfig.txt └── txtar │ ├── .gitignore │ ├── Cargo.lock │ ├── Cargo.toml │ ├── LICENSE-APACHE │ ├── LICENSE-MIT │ ├── README.md │ └── src │ ├── error.rs │ └── lib.rs └── v2 ├── app ├── api_framework.go ├── apiframework │ └── apiframework.go ├── app.go ├── errors.go ├── gateway.go ├── legacymeta │ ├── legacymeta.go │ ├── schema.go │ ├── selector_lookup.go │ └── trace_nodes.go ├── resource_usage.go ├── service.go ├── service_discovery.go ├── service_discovery_test.go ├── setup_test.go ├── testdata │ ├── auth_handler_call.txt │ ├── auth_handler_data.txt │ ├── auth_handler_invalid_builtin.txt │ ├── auth_handler_invalid_field_source.txt │ ├── auth_handler_invalid_named_type.txt │ ├── auth_handler_multiple.txt │ ├── auth_handler_reference.txt │ ├── auth_handler_simple.txt │ ├── auth_handler_struct.txt │ ├── auth_handler_svc_struct.txt │ ├── cache_cluster_outside_svc.txt │ ├── cache_definition.txt │ ├── cache_err_duplicate_cluster.txt │ ├── cache_err_duplicate_paths.txt │ ├── cache_err_generic_type_nonbasic.txt │ ├── cache_err_keyspace_invalid.txt │ ├── cache_err_keyspace_outside_svc.txt │ ├── cache_generic_type.txt │ ├── config.txt │ ├── config_err_unexported_field.txt │ ├── config_err_use_from_other_service.txt │ ├── config_err_wrapper_used_in_wrapper.txt │ ├── cron_job_definition.txt │ ├── cron_job_definition_init.txt │ ├── cron_job_definition_repeat.txt │ ├── cron_job_definition_rpc.txt │ ├── cron_job_err_not_api.txt │ ├── et.txt │ ├── et_err_outside_of_test.txt │ ├── metrics_counter.txt │ ├── metrics_gauge.txt │ ├── middleware.txt │ ├── middleware_err_no_matches.txt │ ├── middleware_err_not_in_service.txt │ ├── missing_generic_param.txt │ ├── pubsub.txt │ ├── pubsub_err_attributes_not_start_encore.txt │ ├── pubsub_err_duplicate_subscription_names.txt │ ├── pubsub_err_import_aliased_and_used_in_func.txt │ ├── pubsub_err_missing_delivery_guarantee.txt │ ├── pubsub_err_new_topic_func_aliased.txt │ ├── pubsub_err_ordering_attribute_missing.txt │ ├── pubsub_err_subscriber_different_service.txt │ ├── pubsub_err_subscriber_missing_handler.txt │ ├── pubsub_err_subscriber_nil_handler.txt │ ├── pubsub_err_subscriber_not_function.txt │ ├── pubsub_err_subscription_func_not_in_service.txt │ ├── pubsub_err_subscription_name_invalid.txt │ ├── pubsub_err_topic_declared_in_func.txt │ ├── pubsub_err_topic_invalid_usage.txt │ ├── pubsub_err_topic_must_be_unique.txt │ ├── pubsub_err_topic_name_invalid.txt │ ├── pubsub_publish_in_middleware.txt │ ├── pubsub_subscriber_creates_service.txt │ ├── pubsub_subscriber_in_same_service.txt │ ├── recursive_types.txt │ ├── rlog_call_outside_svc.txt │ ├── rpc_auth.txt │ ├── rpc_auth_no_authhandler.txt │ ├── rpc_call_selector.txt │ ├── rpc_err_any.txt │ ├── rpc_invalid_header_type.txt │ ├── rpc_invalid_path_param_name.txt │ ├── rpc_invalid_path_param_type.txt │ ├── rpc_invalid_path_too_few_params.txt │ ├── rpc_invalid_query_type.txt │ ├── rpc_legacy_syntax.txt │ ├── rpc_method.txt │ ├── rpc_non_raw_path.txt │ ├── rpc_outside_service.txt │ ├── rpc_path_params.txt │ ├── rpc_raw_call.txt │ ├── rpc_raw_custom_path.txt │ ├── rpc_raw_duplicate_path.txt │ ├── rpc_raw_internal.txt │ ├── rpc_raw_public.txt │ ├── rpc_receiver_invalid.txt │ ├── rpc_receiver_typo.txt │ ├── rpc_without_calling.txt │ ├── secrets.txt │ ├── secrets_non_string.txt │ ├── servicestruct_creates_service.txt │ ├── servicestruct_duplicate.txt │ ├── servicestruct_ref.txt │ ├── sqldb_cross_service.txt │ ├── sqldb_err_unknown_db.txt │ ├── sqldb_err_unknown_db_stdlib.txt │ ├── sqldb_helper.txt │ ├── sqldb_outside_ref.txt │ ├── sqldb_outside_svc.txt │ ├── sqldb_outside_svc_test.txt │ ├── sqldb_success.txt │ ├── sqldb_without_call.txt │ ├── struct_duplicate_json_ignore.txt │ ├── svc_migration_db.txt │ └── type_ref_non_svc.txt ├── validate.go ├── validate_apis.go ├── validate_authhandlers.go ├── validate_caches.go ├── validate_config.go ├── validate_crons.go ├── validate_databases.go ├── validate_middleware.go ├── validate_objects.go ├── validate_pubsub.go ├── validate_servicestructs.go ├── validate_test.go └── validate_types.go ├── codegen ├── apigen │ ├── apigen.go │ ├── apigenutil │ │ └── apigenutil.go │ ├── authhandlergen │ │ ├── authhandlergen.go │ │ ├── authhandlergen_test.go │ │ └── testdata │ │ │ ├── authdata.txt │ │ │ ├── basic.txt │ │ │ ├── servicestruct.txt │ │ │ └── struct.txt │ ├── endpointgen │ │ ├── api_calls.go │ │ ├── endpointgen.go │ │ ├── endpointgen_test.go │ │ ├── handlers.go │ │ ├── request.go │ │ ├── response.go │ │ └── testdata │ │ │ ├── api_call.txt │ │ │ ├── api_call_servicestruct.txt │ │ │ ├── basic.txt │ │ │ ├── complex_omitempty.txt │ │ │ ├── endpoint_tags.txt │ │ │ ├── fallback_path.txt │ │ │ ├── path_params.txt │ │ │ ├── raw_endpoint.txt │ │ │ ├── recursive.txt │ │ │ ├── request_headers.txt │ │ │ ├── request_params.txt │ │ │ ├── request_query.txt │ │ │ ├── response_headers.txt │ │ │ ├── response_params.txt │ │ │ ├── service_struct.txt │ │ │ └── unexported.txt │ ├── maingen │ │ ├── load_app.go │ │ ├── maingen.go │ │ ├── maingen_test.go │ │ ├── testdata │ │ │ ├── auth_handler.txt │ │ │ ├── basic.txt │ │ │ ├── multiple_services.txt │ │ │ ├── service_struct.txt │ │ │ └── subscription.txt │ │ └── testgen.go │ ├── middlewaregen │ │ ├── middlewaregen.go │ │ ├── middlewaregen_test.go │ │ └── testdata │ │ │ ├── basic.txt │ │ │ ├── global.txt │ │ │ └── service_struct.txt │ ├── servicestructgen │ │ ├── servicestructgen.go │ │ ├── servicestructgen_test.go │ │ └── testdata │ │ │ ├── basic.txt │ │ │ └── init_svc.txt │ └── userfacinggen │ │ ├── testdata │ │ └── service_struct.txt │ │ ├── userfacinggen.go │ │ └── userfacinggen_test.go ├── config.go ├── cuegen │ ├── definition_generator.go │ ├── errors.go │ ├── generator.go │ ├── generator_test.go │ ├── service.go │ ├── testdata │ │ ├── basic_config.txt │ │ ├── basic_config_svc.cue │ │ ├── basic_inline_struct.txt │ │ ├── basic_inline_struct_svc.cue │ │ ├── basic_lists.txt │ │ ├── basic_lists_svc.cue │ │ ├── basic_maps.txt │ │ ├── basic_maps_svc.cue │ │ ├── basic_named_struct_multiple_uses.txt │ │ ├── basic_named_struct_multiple_uses_svc.cue │ │ ├── basic_named_struct_single_use.txt │ │ ├── basic_named_struct_single_use_svc.cue │ │ ├── basic_no_config.txt │ │ ├── basic_no_config_svc.cue │ │ ├── basic_with_cue_imports.txt │ │ ├── basic_with_cue_imports_svc.cue │ │ ├── basic_wrappers.txt │ │ ├── basic_wrappers_svc.cue │ │ ├── cue_optional_tag.txt │ │ ├── cue_optional_tag_svc.cue │ │ ├── cue_tags.txt │ │ ├── cue_tags_svc.cue │ │ ├── generic_named_types.txt │ │ ├── generic_named_types_svc.cue │ │ ├── generic_top_level_type.txt │ │ ├── generic_top_level_type_svc.cue │ │ ├── json_tags.txt │ │ ├── json_tags_svc.cue │ │ ├── merge_identical_comments.txt │ │ ├── merge_identical_comments_svc.cue │ │ ├── multiple_configs_in_service.txt │ │ ├── multiple_configs_in_service_svc.cue │ │ ├── types_from_multiple_packages.txt │ │ └── types_from_multiple_packages_svc.cue │ └── utils.go ├── decls.go ├── errors.go ├── gen.go ├── infragen │ ├── cachegen │ │ └── cachegen.go │ ├── configgen │ │ ├── configgen.go │ │ ├── configgen_test.go │ │ └── testdata │ │ │ ├── basic_config.txt │ │ │ ├── basic_inline_struct.txt │ │ │ ├── basic_lists.txt │ │ │ ├── basic_maps.txt │ │ │ ├── basic_named_struct_multiple_uses.txt │ │ │ ├── basic_named_struct_single_use.txt │ │ │ ├── basic_no_config.txt │ │ │ ├── basic_with_cue_imports.txt │ │ │ ├── basic_wrappers.txt │ │ │ ├── cue_optional_tag.txt │ │ │ ├── cue_tags.txt │ │ │ ├── generics.txt │ │ │ ├── json_tags.txt │ │ │ ├── merge_identical_comments.txt │ │ │ ├── multi_package.txt │ │ │ ├── multiple_configs_in_service.txt │ │ │ └── name_conflicts.txt │ ├── infragen.go │ ├── metricsgen │ │ └── metricsgen.go │ ├── pubsubgen │ │ ├── pubsubgen.go │ │ ├── pubsubgen_test.go │ │ └── testdata │ │ │ ├── basic.txt │ │ │ └── method_handler.txt │ └── secretsgen │ │ └── secretsgen.go ├── internal │ ├── codegentest │ │ └── codegentest.go │ └── genutil │ │ ├── etype.go │ │ └── types.go └── rewrite │ ├── rewrite.go │ └── rewrite_test.go ├── compiler └── build │ ├── build.go │ ├── build_test.go │ ├── errors.go │ ├── testdata │ ├── basic.txt │ ├── overlay.txt │ └── rewrite.txt │ └── tests.go ├── internals ├── overlay │ └── overlay.go ├── parsectx │ └── pctx.go ├── perr │ ├── aserror.go │ └── perr.go ├── pkginfo │ ├── errors.go │ ├── loader.go │ ├── loader_test.go │ ├── modresolve.go │ ├── modresolve_test.go │ ├── names.go │ ├── names_test.go │ ├── pkgparse.go │ └── types.go ├── posmap │ └── posmap.go ├── resourcepaths │ ├── errors.go │ ├── paths.go │ └── paths_test.go ├── scan │ ├── collect.go │ ├── collect_test.go │ ├── errors.go │ ├── scan.go │ └── scan_test.go ├── schema │ ├── decls.go │ ├── errors.go │ ├── schema_parser.go │ ├── schema_parser_test.go │ ├── schematest │ │ └── schematest.go │ ├── schemautil │ │ ├── astutil.go │ │ ├── astutil_test.go │ │ ├── errors.go │ │ └── schemautil.go │ ├── types.go │ └── types_string.go └── testutil │ ├── testutil.go │ ├── update_archive_file.go │ └── utils.go ├── parser ├── apis │ ├── api │ │ ├── api.go │ │ ├── api_test.go │ │ ├── apienc │ │ │ ├── encoding.go │ │ │ └── errors.go │ │ ├── errors.go │ │ └── usage.go │ ├── authhandler │ │ ├── authhandler.go │ │ ├── authhandler_test.go │ │ ├── errors.go │ │ └── usage.go │ ├── directive │ │ ├── directive.go │ │ ├── directive_test.go │ │ ├── errors.go │ │ └── fields.go │ ├── errors.go │ ├── middleware │ │ ├── errors.go │ │ ├── middleware.go │ │ └── middleware_test.go │ ├── parser.go │ ├── selector │ │ ├── errors.go │ │ ├── selector.go │ │ └── selector_test.go │ └── servicestruct │ │ ├── errors.go │ │ ├── servicestruct.go │ │ ├── servicestruct_test.go │ │ └── usage.go ├── infra │ ├── caches │ │ ├── cache_test.go │ │ ├── cluster.go │ │ ├── errors.go │ │ ├── keyspace.go │ │ ├── keyspace_test.go │ │ ├── testdata │ │ │ └── cluster.txt │ │ └── usage.go │ ├── config │ │ ├── config.go │ │ ├── errors.go │ │ └── usage.go │ ├── crons │ │ ├── cron.go │ │ ├── cron_test.go │ │ └── errors.go │ ├── internal │ │ ├── literals │ │ │ ├── constants.go │ │ │ ├── decode.go │ │ │ ├── decode_test.go │ │ │ ├── errors.go │ │ │ ├── literals.go │ │ │ └── literals_test.go │ │ ├── locations │ │ │ ├── locations.go │ │ │ └── locations_test.go │ │ └── parseutil │ │ │ ├── aststringer.go │ │ │ ├── errors.go │ │ │ ├── names.go │ │ │ ├── parseutil.go │ │ │ └── reference.go │ ├── metrics │ │ ├── errors.go │ │ ├── metrics.go │ │ ├── metrics_string.go │ │ └── metrics_test.go │ ├── objects │ │ ├── bucket.go │ │ ├── errors.go │ │ ├── usage.go │ │ └── usage_test.go │ ├── pubsub │ │ ├── errors.go │ │ ├── subscription.go │ │ ├── topic.go │ │ ├── usage.go │ │ └── usage_test.go │ ├── secrets │ │ ├── errors.go │ │ └── secrets.go │ └── sqldb │ │ ├── errors.go │ │ ├── implicit.go │ │ ├── named.go │ │ ├── sqldb.go │ │ ├── sqldb_test.go │ │ └── usage.go ├── internal │ └── utils │ │ └── prettyprint.go ├── parser.go ├── parser_test.go ├── resource │ ├── bind.go │ ├── resource.go │ ├── resource_string.go │ ├── resourceparser │ │ ├── registry.go │ │ └── resourceparser.go │ ├── resourcetest │ │ └── resourcetest.go │ └── usage │ │ ├── resolver.go │ │ ├── testdata │ │ ├── pubsub_usage.txt │ │ ├── secret_usage.txt │ │ └── sqldb_usage.txt │ │ ├── usage.go │ │ ├── usage_test.go │ │ └── usagetest │ │ └── usagetest.go └── result.go ├── tsbuilder └── tsbuilder.go └── v2builder └── v2builder.go /.devcontainer/Dockerfile: -------------------------------------------------------------------------------- 1 | FROM golang:1.23 2 | 3 | RUN apt-get update && apt-get install -y sudo 4 | RUN curl -fsSL https://deb.nodesource.com/setup_16.x | sudo -E bash - && \ 5 | apt-get install -y nodejs 6 | 7 | ADD scripts /scripts 8 | RUN bash /scripts/install.sh 9 | RUN bash /scripts/godeps.sh 10 | 11 | ENV ENCORE_GOROOT=/encore-release/encore-go 12 | -------------------------------------------------------------------------------- /.devcontainer/devcontainer.json: -------------------------------------------------------------------------------- 1 | { 2 | "build": {"dockerfile": "Dockerfile"}, 3 | "containerEnv": { 4 | "ENCORE_DAEMON_DEV": "1", 5 | "ENCORE_RUNTIMES_PATH": "${containerWorkspaceFolder}/runtimes" 6 | }, 7 | "extensions": ["golang.go"], 8 | "postCreateCommand": "bash /scripts/prepare.sh", 9 | "forwardPorts": [4000, 9400] 10 | } 11 | -------------------------------------------------------------------------------- /.devcontainer/scripts/godeps.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env 2 | set -ex 3 | 4 | go install github.com/uudashr/gopkgs/v2/cmd/gopkgs@latest 5 | go install github.com/ramya-rao-a/go-outline@latest 6 | go install github.com/cweill/gotests/gotests@latest 7 | go install github.com/fatih/gomodifytags@latest 8 | go install github.com/josharian/impl@latest 9 | go install github.com/haya14busa/goplay/cmd/goplay@latest 10 | go install github.com/go-delve/delve/cmd/dlv@latest 11 | go install honnef.co/go/tools/cmd/staticcheck@master 12 | go install golang.org/x/tools/gopls@latest 13 | 14 | GOBIN=/tmp/ go install github.com/go-delve/delve/cmd/dlv@master 15 | mv /tmp/dlv $GOPATH/bin/dlv-dap 16 | -------------------------------------------------------------------------------- /.devcontainer/scripts/prepare.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | set -e 4 | set -x 5 | 6 | go mod download 7 | -------------------------------------------------------------------------------- /.github/dockerimg/Dockerfile: -------------------------------------------------------------------------------- 1 | # syntax=docker/dockerfile:1.4 2 | FROM --platform=$TARGETPLATFORM ubuntu:22.04 AS build 3 | ARG TARGETPLATFORM 4 | ARG RELEASE_VERSION 5 | RUN mkdir /encore 6 | ADD rename-binary-if-needed.bash rename-binary-if-needed.bash 7 | ADD artifacts /artifacts 8 | RUN /bin/bash -c 'SRC=encore-$(echo $TARGETPLATFORM | tr '/' '_'); tar -C /encore -xzf /artifacts/$SRC.tar.gz' 9 | RUN /bin/bash rename-binary-if-needed.bash 10 | 11 | FROM --platform=$TARGETPLATFORM ubuntu:22.04 12 | RUN apt-get update && apt-get install -y -f ca-certificates 13 | ENV PATH="/encore/bin:${PATH}" 14 | WORKDIR /src 15 | ADD encore-entrypoint.bash /bin/encore-entrypoint.bash 16 | ENTRYPOINT ["/bin/encore-entrypoint.bash"] 17 | COPY --from=build /encore /encore 18 | -------------------------------------------------------------------------------- /.github/dockerimg/encore-entrypoint.bash: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | set -eo pipefail 3 | 4 | # If the ENCORE_AUTHKEY environment variable is set, log in with it. 5 | if [ -n "$ENCORE_AUTHKEY" ]; then 6 | echo "Logging in to Encore using provided auth key..." 7 | encore auth login --auth-key "$ENCORE_AUTHKEY" 8 | fi 9 | 10 | # Run the encore command. 11 | encore "$@" 12 | -------------------------------------------------------------------------------- /.github/dockerimg/rename-binary-if-needed.bash: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | set -eo pipefail 3 | 4 | # Check if `encore-nightly`, `encore-beta` or `encore-develop` are present, and if one of them are, rename it to `encore`. 5 | for binary in encore-nightly encore-beta encore-develop; do 6 | if [ -f "/encore/bin/$binary" ]; then 7 | echo "Renaming $binary to encore..." 8 | mv /encore/bin/$binary /encore/bin/encore 9 | fi 10 | done 11 | 12 | # Sanity check that /ecore/bin/encore exists. 13 | if [ ! -f "/encore/bin/encore" ]; then 14 | echo "ERROR: /encore/bin/encore does not exist. Did you mount the Encore binary directory to /encore/bin?" 15 | exit 1 16 | fi 17 | -------------------------------------------------------------------------------- /.github/workflows/staticcheck-to-rdjsonl.jq: -------------------------------------------------------------------------------- 1 | # See https://github.com/reviewdog/reviewdog/tree/master/proto/rdf 2 | { 3 | source: { 4 | name: "staticcheck", 5 | url: "https://staticcheck.io" 6 | }, 7 | message: .message, 8 | code: {value: .code, url: "https://staticcheck.io/docs/checks#\(.code)"}, 9 | location: { 10 | path: .location.file, 11 | range: { 12 | start: { 13 | line: .location.line, 14 | column: .location.column 15 | } 16 | } 17 | }, 18 | severity: ((.severity|ascii_upcase|select(match("ERROR|WARNING|INFO")))//null) 19 | } 20 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # Prevent built binaries from being checked in accidentally. 2 | /dist 3 | /encore 4 | /git-remote-encore 5 | /target 6 | 7 | # Don't commit dotfiles 8 | /.encore 9 | /.vscode 10 | 11 | # Build artifact that must be placed alongside go files for Windows 12 | *.syso 13 | 14 | # JetBrains 15 | .idea 16 | .fleet 17 | .run 18 | 19 | # MacOS 20 | .DS_Store 21 | 22 | runtimes/supervisor-encore 23 | 24 | runtimes/supervisor-encore-linux-amd64 25 | 26 | encore-runtime.node-linux-amd64 27 | -------------------------------------------------------------------------------- /.prettierrc.toml: -------------------------------------------------------------------------------- 1 | trailingComma = "none" 2 | -------------------------------------------------------------------------------- /Cross.toml: -------------------------------------------------------------------------------- 1 | [build] 2 | pre-build = [ 3 | "apt-get install unzip &&", 4 | "curl -LO https://github.com/protocolbuffers/protobuf/releases/download/v24.4/protoc-24.4-linux-x86_64.zip &&", 5 | "unzip protoc-24.4-linux-x86_64.zip -d /usr/local &&", 6 | "rm protoc-24.4-linux-x86_64.zip &&", 7 | "export PATH=$PATH:/usr/local/bin", 8 | ] 9 | 10 | [build.env] 11 | volumes = ["ENCORE_WORKDIR"] 12 | passthrough = ["TYPE_DEF_TMP_PATH", "ENCORE_VERSION"] -------------------------------------------------------------------------------- /cli/cmd/encore/app/app.go: -------------------------------------------------------------------------------- 1 | package app 2 | 3 | import ( 4 | "github.com/spf13/cobra" 5 | 6 | "encr.dev/cli/cmd/encore/root" 7 | ) 8 | 9 | // These can be overwritten using 10 | // `go build -ldflags "-X encr.dev/cli/cmd/encore/app.defaultGitRemoteName=encore"`. 11 | var ( 12 | defaultGitRemoteName = "encore" 13 | defaultGitRemoteURL = "encore://" 14 | ) 15 | 16 | var appCmd = &cobra.Command{ 17 | Use: "app", 18 | Short: "Commands to create and link Encore apps", 19 | } 20 | 21 | func init() { 22 | root.Cmd.AddCommand(appCmd) 23 | } 24 | -------------------------------------------------------------------------------- /cli/cmd/encore/bits/bits.go: -------------------------------------------------------------------------------- 1 | package bits 2 | 3 | import ( 4 | "github.com/spf13/cobra" 5 | 6 | "encr.dev/cli/cmd/encore/root" 7 | ) 8 | 9 | var bitsCmd = &cobra.Command{ 10 | Use: "bits", 11 | Short: "Commands to manage encore bits, reusable functionality for Encore applications", 12 | } 13 | 14 | func init() { 15 | root.Cmd.AddCommand(bitsCmd) 16 | } 17 | -------------------------------------------------------------------------------- /cli/cmd/encore/daemon/migrations/2_infra_namespaces.up.sql: -------------------------------------------------------------------------------- 1 | CREATE TABLE IF NOT EXISTS namespace ( 2 | id TEXT PRIMARY KEY, -- uuid 3 | app_id TEXT NOT NULL, -- platform_id or local_id 4 | name TEXT NOT NULL, 5 | active BOOL NOT NULL DEFAULT FALSE, 6 | created_at TIMESTAMP NOT NULL, 7 | last_active_at TIMESTAMP NULL, 8 | UNIQUE (app_id, name) 9 | ); 10 | 11 | -- Ensure there's a single active namespace per app. 12 | CREATE UNIQUE INDEX active_namespace ON namespace (app_id) WHERE active = true; 13 | -------------------------------------------------------------------------------- /cli/cmd/encore/daemon/migrations/3_test_tracing.up.sql: -------------------------------------------------------------------------------- 1 | ALTER TABLE trace_span_index ADD COLUMN test_skipped BOOLEAN NOT NULL DEFAULT FALSE; 2 | ALTER TABLE trace_span_index ADD COLUMN src_file TEXT NULL; 3 | ALTER TABLE trace_span_index ADD COLUMN src_line INTEGER NULL; 4 | -------------------------------------------------------------------------------- /cli/cmd/encore/init_windows.go: -------------------------------------------------------------------------------- 1 | //go:build windows 2 | // +build windows 3 | 4 | package main 5 | 6 | import ( 7 | "golang.org/x/sys/windows" 8 | ) 9 | 10 | // init activates virtual terminal feature on "windows", this enables colored 11 | // terminal output. 12 | func init() { 13 | setConsoleMode(windows.Stdout, windows.ENABLE_VIRTUAL_TERMINAL_PROCESSING) 14 | setConsoleMode(windows.Stderr, windows.ENABLE_VIRTUAL_TERMINAL_PROCESSING) 15 | } 16 | 17 | // setConsoleMode enables VT processing on stout and stderr. 18 | func setConsoleMode(handle windows.Handle, flag uint32) { 19 | var mode uint32 20 | if err := windows.GetConsoleMode(handle, &mode); err == nil { 21 | windows.SetConsoleMode(handle, mode|flag) 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /cli/cmd/encore/k8s/kubernetes.go: -------------------------------------------------------------------------------- 1 | package k8s 2 | 3 | import ( 4 | "github.com/spf13/cobra" 5 | 6 | "encr.dev/cli/cmd/encore/root" 7 | ) 8 | 9 | var kubernetesCmd = &cobra.Command{ 10 | Use: "kubernetes", 11 | Short: "Kubernetes management commands", 12 | Aliases: []string{"k8s"}, 13 | } 14 | 15 | func init() { 16 | root.Cmd.AddCommand(kubernetesCmd) 17 | } 18 | -------------------------------------------------------------------------------- /cli/cmd/encore/k8s/types/README.md: -------------------------------------------------------------------------------- 1 | # Kubernetes Types 2 | 3 | This package contains types copied directly from the [Kubernetes](https://github.com/kubernetes/kubernetes) project, this 4 | is to prevent the Encore CLI needing to have a dependency on the Kubernetes project for just these types. 5 | -------------------------------------------------------------------------------- /cli/cmd/encore/secrets/secrets.go: -------------------------------------------------------------------------------- 1 | package secrets 2 | 3 | import ( 4 | "github.com/spf13/cobra" 5 | 6 | "encr.dev/cli/cmd/encore/root" 7 | ) 8 | 9 | var secretCmd = &cobra.Command{ 10 | Use: "secret", 11 | Short: "Secret management commands", 12 | Aliases: []string{"secrets"}, 13 | } 14 | 15 | func init() { 16 | root.Cmd.AddCommand(secretCmd) 17 | } 18 | -------------------------------------------------------------------------------- /cli/daemon/create.go: -------------------------------------------------------------------------------- 1 | package daemon 2 | 3 | import ( 4 | "context" 5 | 6 | "encr.dev/cli/daemon/apps" 7 | daemonpb "encr.dev/proto/encore/daemon" 8 | ) 9 | 10 | // CreateApp adds tracking for a new app 11 | func (s *Server) CreateApp(ctx context.Context, req *daemonpb.CreateAppRequest) (*daemonpb.CreateAppResponse, error) { 12 | var options []apps.TrackOption 13 | if req.Tutorial { 14 | options = append(options, apps.WithTutorial(req.Template)) 15 | } 16 | app, err := s.apps.Track(req.AppRoot, options...) 17 | if err != nil { 18 | return nil, err 19 | } 20 | return &daemonpb.CreateAppResponse{AppId: app.PlatformOrLocalID()}, nil 21 | } 22 | -------------------------------------------------------------------------------- /cli/daemon/internal/runlog/runlog.go: -------------------------------------------------------------------------------- 1 | package runlog 2 | 3 | import ( 4 | "io" 5 | "os" 6 | ) 7 | 8 | type Log interface { 9 | Stdout(buffered bool) io.Writer 10 | Stderr(buffered bool) io.Writer 11 | } 12 | 13 | type oslog struct{} 14 | 15 | func (oslog) Stdout(buffered bool) io.Writer { return os.Stdout } 16 | func (oslog) Stderr(buffered bool) io.Writer { return os.Stderr } 17 | 18 | func OS() Log { 19 | return oslog{} 20 | } 21 | -------------------------------------------------------------------------------- /cli/daemon/internal/sym/sym.go: -------------------------------------------------------------------------------- 1 | // Package sym parses symbol tables from Go binaries. 2 | package sym 3 | 4 | import ( 5 | "fmt" 6 | "io" 7 | 8 | "encr.dev/cli/internal/gosym" 9 | ) 10 | 11 | type Table struct { 12 | *gosym.Table 13 | BaseOffset uint64 14 | } 15 | 16 | func Load(r io.ReaderAt) (*Table, error) { 17 | tbl, err := load(r) 18 | if err != nil { 19 | return nil, fmt.Errorf("sym.Load: %v", err) 20 | } 21 | return tbl, nil 22 | } 23 | -------------------------------------------------------------------------------- /cli/daemon/mcp/util.go: -------------------------------------------------------------------------------- 1 | package mcp 2 | 3 | import ( 4 | "time" 5 | 6 | metav1 "encr.dev/proto/encore/parser/meta/v1" 7 | ) 8 | 9 | // findServiceNameForPackage returns the service name for a given package path 10 | func findServiceNameForPackage(md *metav1.Data, pkgPath string) string { 11 | for _, pkg := range md.Pkgs { 12 | if pkg.RelPath == pkgPath && pkg.ServiceName != "" { 13 | return pkg.ServiceName 14 | } 15 | } 16 | return "" 17 | } 18 | 19 | // formatDuration formats a nanosecond duration into a human-readable string 20 | func formatDuration(nanos int64) string { 21 | duration := time.Duration(nanos) * time.Nanosecond 22 | return duration.String() 23 | } 24 | -------------------------------------------------------------------------------- /cli/daemon/pubsub/utils.go: -------------------------------------------------------------------------------- 1 | package pubsub 2 | 3 | import ( 4 | meta "encr.dev/proto/encore/parser/meta/v1" 5 | ) 6 | 7 | // IsUsed reports whether the application uses pubsub at all. 8 | func IsUsed(md *meta.Data) bool { 9 | return len(md.PubsubTopics) > 0 10 | } 11 | -------------------------------------------------------------------------------- /cli/daemon/run/errors.go: -------------------------------------------------------------------------------- 1 | package run 2 | 3 | import ( 4 | "errors" 5 | 6 | "encr.dev/pkg/errlist" 7 | "encr.dev/v2/internals/perr" 8 | ) 9 | 10 | func AsErrorList(err error) *errlist.List { 11 | if errList := errlist.Convert(err); errList != nil { 12 | return errList 13 | } 14 | 15 | list := &perr.ListAsErr{} 16 | if errors.As(err, &list) { 17 | return &errlist.List{List: list.ErrorList()} 18 | } 19 | return nil 20 | } 21 | -------------------------------------------------------------------------------- /cli/daemon/telemetry.go: -------------------------------------------------------------------------------- 1 | package daemon 2 | 3 | import ( 4 | "context" 5 | 6 | "google.golang.org/protobuf/types/known/emptypb" 7 | 8 | "encr.dev/cli/internal/telemetry" 9 | daemonpb "encr.dev/proto/encore/daemon" 10 | ) 11 | 12 | func (s *Server) Telemetry(ctx context.Context, req *daemonpb.TelemetryConfig) (*emptypb.Empty, error) { 13 | telemetry.UpdateConfig(req.AnonId, req.Enabled, req.Debug) 14 | return new(emptypb.Empty), nil 15 | } 16 | -------------------------------------------------------------------------------- /cli/daemon/tracing.go: -------------------------------------------------------------------------------- 1 | package daemon 2 | 3 | import ( 4 | "context" 5 | "path/filepath" 6 | 7 | "encr.dev/internal/etrace" 8 | ) 9 | 10 | func (s *Server) beginTracing(ctx context.Context, appRoot, workingDir string, traceFile *string) (context.Context, *etrace.Tracer, error) { 11 | if traceFile == nil { 12 | return ctx, nil, nil 13 | } 14 | 15 | var dst string 16 | if filepath.IsAbs(*traceFile) { 17 | dst = *traceFile 18 | } else { 19 | dst = filepath.Join(appRoot, workingDir, *traceFile) 20 | } 21 | return etrace.WithFileTracer(ctx, dst) 22 | } 23 | -------------------------------------------------------------------------------- /cli/internal/gosym/testdata/main.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | func linefrompc() 4 | func pcfromline() 5 | 6 | func main() { 7 | // Prevent GC of our test symbols 8 | linefrompc() 9 | pcfromline() 10 | } 11 | -------------------------------------------------------------------------------- /cli/internal/gosym/testdata/pclinetest.h: -------------------------------------------------------------------------------- 1 | // +build ignore 2 | 3 | // Empty include file to generate z symbols 4 | 5 | 6 | 7 | 8 | 9 | // EOF 10 | -------------------------------------------------------------------------------- /cli/internal/gosym/testdata/pcln115.gz: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/encoredev/encore/688fc65052cbb36c9016e632a52f95d68fe588f0/cli/internal/gosym/testdata/pcln115.gz -------------------------------------------------------------------------------- /cli/internal/jsonrpc2/jsonrpc2.go: -------------------------------------------------------------------------------- 1 | // Copyright 2018 The Go Authors. All rights reserved. 2 | // Use of this source code is governed by a BSD-style 3 | // license that can be found in the LICENSE file. 4 | 5 | // Package jsonrpc2 is a minimal implementation of the JSON RPC 2 spec. 6 | // https://www.jsonrpc.org/specification 7 | // It is intended to be compatible with other implementations at the wire level. 8 | package jsonrpc2 9 | 10 | const ( 11 | // ErrIdleTimeout is returned when serving timed out waiting for new connections. 12 | ErrIdleTimeout = constError("timed out waiting for new connections") 13 | ) 14 | 15 | type constError string 16 | 17 | func (e constError) Error() string { return string(e) } 18 | -------------------------------------------------------------------------------- /cli/internal/platform/gql/app.go: -------------------------------------------------------------------------------- 1 | package gql 2 | 3 | import ( 4 | "encoding/json" 5 | "fmt" 6 | ) 7 | 8 | type App struct { 9 | ID string 10 | Slug string 11 | } 12 | 13 | type Error struct { 14 | Message string `json:"message"` 15 | Path []string `json:"path"` 16 | Extensions map[string]json.RawMessage `json:"extensions"` 17 | } 18 | 19 | func (e *Error) Error() string { 20 | return e.Message 21 | } 22 | 23 | type ErrorList []*Error 24 | 25 | func (err ErrorList) Error() string { 26 | if len(err) == 0 { 27 | return "no errors" 28 | } else if len(err) == 1 { 29 | return err[0].Error() 30 | } 31 | return fmt.Sprintf("%s (and %d more errors)", err[0].Error(), len(err)-1) 32 | } 33 | -------------------------------------------------------------------------------- /cli/internal/platform/gql/env.go: -------------------------------------------------------------------------------- 1 | package gql 2 | 3 | type Env struct { 4 | ID string 5 | App *App 6 | Name string 7 | } 8 | -------------------------------------------------------------------------------- /clippy.toml: -------------------------------------------------------------------------------- 1 | ignore-interior-mutability = ["bytes::Bytes", "http::header::HeaderName"] 2 | 3 | -------------------------------------------------------------------------------- /docs/go/how-to/assets/logto-api-resource.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/encoredev/encore/688fc65052cbb36c9016e632a52f95d68fe588f0/docs/go/how-to/assets/logto-api-resource.png -------------------------------------------------------------------------------- /docs/go/how-to/assets/logto-application-endpoints.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/encoredev/encore/688fc65052cbb36c9016e632a52f95d68fe588f0/docs/go/how-to/assets/logto-application-endpoints.png -------------------------------------------------------------------------------- /e2e-tests/README.md: -------------------------------------------------------------------------------- 1 | # End to End Tests 2 | 3 | This folder contains end to end tests for Encore, which test everything in Encore 4 | as an end user would use it. 5 | 6 | The tests will: 7 | 1. Effectively run `encore run` on the [echo test app](./testdata/echo) 8 | 2. Perform some basic requests against the running app to verify behaviour 9 | 3. Generate the front end clients for the app 10 | 4. Run tests against using generated clients against the running app 11 | 5. Shutdown the running app 12 | -------------------------------------------------------------------------------- /e2e-tests/testdata/echo/.gitignore: -------------------------------------------------------------------------------- 1 | encore.gen.go 2 | /.encore 3 | encore.gen.cue 4 | -------------------------------------------------------------------------------- /e2e-tests/testdata/echo/echo/config.cue: -------------------------------------------------------------------------------- 1 | import "encoding/base64" 2 | 3 | ReadOnlyMode: true 4 | PublicKey: base64.Decode(null, "aGVsbG8gd29ybGQK") // "hello world" in Base64 5 | 6 | SubConfig: SubKey: MaxCount: [ 7 | if #Meta.Environment.Type == "test" { 3 }, 8 | if #Meta.Environment.Cloud == "local" { 2 }, 9 | 1 10 | ][0] 11 | 12 | AdminUsers: [ 13 | "foo", 14 | "bar", 15 | ] 16 | -------------------------------------------------------------------------------- /e2e-tests/testdata/echo/echo/config_test.go: -------------------------------------------------------------------------------- 1 | package echo 2 | 3 | import ( 4 | "context" 5 | "testing" 6 | ) 7 | 8 | func TestConfigValues(t *testing.T) { 9 | values, err := ConfigValues(context.Background()) 10 | if err != nil { 11 | t.Fatalf("unexpected error: %v", err) 12 | } 13 | 14 | if values.SubKeyCount != 3 { 15 | t.Fatalf("expected 1, got %d", values.SubKeyCount) 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /e2e-tests/testdata/echo/echo/echo_test.go: -------------------------------------------------------------------------------- 1 | package echo 2 | 3 | import ( 4 | "os" 5 | "strings" 6 | "testing" 7 | ) 8 | 9 | // TestEnvsProvided tests that 'go test' was invoked with the envs we expect. 10 | func TestEnvsProvided(t *testing.T) { 11 | envs := os.Environ() 12 | want := map[string]string{ 13 | "FOO": "bar", 14 | "BAR": "baz", 15 | } 16 | for _, env := range envs { 17 | key, val, _ := strings.Cut(env, "=") 18 | if wantVal, ok := want[key]; ok { 19 | if val != wantVal { 20 | t.Errorf("got env %s=%s, want value %s", key, val, wantVal) 21 | } 22 | } 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /e2e-tests/testdata/echo/empty_cfg/service.go: -------------------------------------------------------------------------------- 1 | package emptycfg 2 | 3 | import ( 4 | "context" 5 | 6 | "encore.dev/config" 7 | ) 8 | 9 | type cfg struct { 10 | 11 | } 12 | 13 | var Config = config.Load[*cfg]() 14 | 15 | //encore:api public 16 | func AnAPI(ctx context.Context) error { 17 | return nil 18 | } 19 | -------------------------------------------------------------------------------- /e2e-tests/testdata/echo/encore.app: -------------------------------------------------------------------------------- 1 | {} -------------------------------------------------------------------------------- /e2e-tests/testdata/echo/go.mod: -------------------------------------------------------------------------------- 1 | module encore.app 2 | 3 | go 1.21.0 4 | 5 | require encore.dev v1.9.3 6 | -------------------------------------------------------------------------------- /e2e-tests/testdata/echo/go.sum: -------------------------------------------------------------------------------- 1 | encore.dev v1.9.3 h1:EyAw58b7lBRQipL/p27gRXKwyopwyGsUuIpqZpTIOzw= 2 | encore.dev v1.9.3/go.mod h1:AyQpBJoalNCFScvYfjzLtOJh/KEYue/pNljoz/aA6UQ= 3 | -------------------------------------------------------------------------------- /e2e-tests/testdata/echo/validation/validation.go: -------------------------------------------------------------------------------- 1 | package validation 2 | 3 | import ( 4 | "context" 5 | "errors" 6 | ) 7 | 8 | type Request struct { 9 | Msg string 10 | } 11 | 12 | func (req *Request) Validate() error { 13 | if req.Msg == "fail" { 14 | return errors.New("bad message") 15 | } 16 | return nil 17 | } 18 | 19 | //encore:api public 20 | func TestOne(ctx context.Context, msg *Request) error { 21 | return nil 22 | } 23 | -------------------------------------------------------------------------------- /e2e-tests/testdata/echo_client/.eslintrc.cjs: -------------------------------------------------------------------------------- 1 | /* .eslintrc.js */ 2 | module.exports = { 3 | root: true, 4 | parser: '@typescript-eslint/parser', 5 | plugins: [ 6 | '@typescript-eslint', 7 | ], 8 | env: { 9 | browser: true, 10 | es6: true, 11 | node: true, 12 | commonjs: true 13 | }, 14 | extends: [ 15 | 'eslint:recommended', 16 | 'plugin:@typescript-eslint/eslint-recommended', 17 | 'plugin:@typescript-eslint/recommended', 18 | ], 19 | } 20 | -------------------------------------------------------------------------------- /e2e-tests/testdata/echo_client/.gitignore: -------------------------------------------------------------------------------- 1 | node_modules/ 2 | -------------------------------------------------------------------------------- /e2e-tests/testdata/echo_client/go.mod: -------------------------------------------------------------------------------- 1 | module echo_client 2 | 3 | go 1.18 4 | -------------------------------------------------------------------------------- /e2e-tests/testdata/echo_client/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "private": true, 3 | "type": "module", 4 | "scripts": { 5 | "test": "node --trace-warnings --experimental-specifier-resolution=node --loader ts-node/esm ./ts/main.ts", 6 | "test:js": "node --trace-warnings --experimental-specifier-resolution=node ./js/main.js", 7 | "lint": "tsc --noEmit && eslint \"**/*.{ts,js}\"" 8 | }, 9 | "devDependencies": { 10 | "@types/node": "^17.0.35", 11 | "@typescript-eslint/eslint-plugin": "^5.26.0", 12 | "@typescript-eslint/parser": "^5.26.0", 13 | "eslint": "^8.16.0", 14 | "ts-node": "^10.8.0", 15 | "typescript": "^4.6.4" 16 | }, 17 | "dependencies": { 18 | "isomorphic-fetch": "^3.0.0" 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /e2e-tests/testdata/testscript/experiment_local_secrets_override.txtar: -------------------------------------------------------------------------------- 1 | env ENCORE_EXPERIMENT=local-secrets-override 2 | run 3 | call GET /svc.GetFoo 4 | checkresp '{"Data": "bar"}' 5 | 6 | -- svc/svc.go -- 7 | package svc 8 | 9 | import "context" 10 | 11 | type Resp struct { 12 | Data string 13 | } 14 | 15 | var secrets struct { 16 | Foo string 17 | } 18 | 19 | //encore:api public 20 | func GetFoo(ctx context.Context) (*Resp, error) { 21 | return &Resp{Data: secrets.Foo}, nil 22 | } 23 | 24 | -- .secrets.local.cue -- 25 | Foo: "bar" 26 | -------------------------------------------------------------------------------- /e2e-tests/testdata/testscript/graceful_shutdown.txt: -------------------------------------------------------------------------------- 1 | run 2 | shutdown 3 | checklog '{"message": "shutting down"}' 4 | 5 | -- svc/svc.go -- 6 | package svc 7 | 8 | import ( 9 | "encore.dev/shutdown" 10 | "encore.dev/rlog" 11 | ) 12 | 13 | //encore:service 14 | type Service struct{} 15 | 16 | func (s *Service) Shutdown(p shutdown.Progress) error { 17 | rlog.Info("shutting down") 18 | return nil 19 | } 20 | -------------------------------------------------------------------------------- /internal/gocodegen/package.go: -------------------------------------------------------------------------------- 1 | // Package gocodegen contains shared code used for generating Go code by both the 2 | // compilers code generator, and the CLI's client generator. 3 | package gocodegen 4 | -------------------------------------------------------------------------------- /internal/httpcache/diskcache/diskcache_test.go: -------------------------------------------------------------------------------- 1 | package diskcache 2 | 3 | import ( 4 | "io/ioutil" 5 | "os" 6 | "testing" 7 | 8 | "encr.dev/internal/httpcache/test" 9 | ) 10 | 11 | func TestDiskCache(t *testing.T) { 12 | tempDir, err := ioutil.TempDir("", "httpcache") 13 | if err != nil { 14 | t.Fatalf("TempDir: %v", err) 15 | } 16 | defer os.RemoveAll(tempDir) 17 | 18 | test.Cache(t, New(tempDir)) 19 | } 20 | -------------------------------------------------------------------------------- /internal/httpcache/test/test.go: -------------------------------------------------------------------------------- 1 | package test 2 | 3 | import ( 4 | "bytes" 5 | "testing" 6 | 7 | "encr.dev/internal/httpcache" 8 | ) 9 | 10 | // Cache excercises a httpcache.Cache implementation. 11 | func Cache(t *testing.T, cache httpcache.Cache) { 12 | key := "testKey" 13 | _, ok := cache.Get(key) 14 | if ok { 15 | t.Fatal("retrieved key before adding it") 16 | } 17 | 18 | val := []byte("some bytes") 19 | cache.Set(key, val) 20 | 21 | retVal, ok := cache.Get(key) 22 | if !ok { 23 | t.Fatal("could not retrieve an element we just added") 24 | } 25 | if !bytes.Equal(retVal, val) { 26 | t.Fatal("retrieved a different value than what we put in") 27 | } 28 | 29 | cache.Delete(key) 30 | 31 | _, ok = cache.Get(key) 32 | if ok { 33 | t.Fatal("deleted key still present") 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /internal/httpcache/test/test_test.go: -------------------------------------------------------------------------------- 1 | package test_test 2 | 3 | import ( 4 | "testing" 5 | 6 | "encr.dev/internal/httpcache" 7 | "encr.dev/internal/httpcache/test" 8 | ) 9 | 10 | func TestMemoryCache(t *testing.T) { 11 | test.Cache(t, httpcache.NewMemoryCache()) 12 | } 13 | -------------------------------------------------------------------------------- /internal/userconfig/config.go: -------------------------------------------------------------------------------- 1 | package userconfig 2 | 3 | // Config describes the configuration structure we support. 4 | type Config struct { 5 | // Whether to open the Local Development Dashboard in the browser on `encore run`. 6 | // If set to "auto", the browser will be opened if the dashboard is not already open. 7 | RunBrowser string `koanf:"run.browser" oneof:"always,never,auto" default:"auto"` 8 | } 9 | -------------------------------------------------------------------------------- /pkg/builder/builderimpl/builders.go: -------------------------------------------------------------------------------- 1 | package builderimpl 2 | 3 | import ( 4 | "encore.dev/appruntime/exported/experiments" 5 | "encr.dev/pkg/appfile" 6 | "encr.dev/pkg/builder" 7 | "encr.dev/v2/tsbuilder" 8 | "encr.dev/v2/v2builder" 9 | ) 10 | 11 | func Resolve(lang appfile.Lang, expSet *experiments.Set) builder.Impl { 12 | if lang == appfile.LangTS || experiments.TypeScript.Enabled(expSet) { 13 | return tsbuilder.New() 14 | } 15 | return v2builder.BuilderImpl{} 16 | } 17 | -------------------------------------------------------------------------------- /pkg/clientgen/testdata/README.md: -------------------------------------------------------------------------------- 1 | # Update Golden Tests 2 | 3 | Instead of manually updating the golden tests, once you've verified the output of the tests is correct, then you 4 | can simply update all the `expected output files` files by running 5 | 6 | ```bash 7 | go test ./internal/clientgen -golden-update 8 | ``` 9 | -------------------------------------------------------------------------------- /pkg/clientgen/testdata/goapp/input_noauth.go: -------------------------------------------------------------------------------- 1 | -- go.mod -- 2 | module app 3 | 4 | -- encore.app -- 5 | {"id": ""} 6 | 7 | -- svc/svc.go -- 8 | package svc 9 | 10 | type Request struct { 11 | Message string 12 | } 13 | 14 | -- svc/api.go -- 15 | package svc 16 | 17 | import ( 18 | "context" 19 | "net/http" 20 | ) 21 | 22 | // DummyAPI is a dummy endpoint. 23 | //encore:api public 24 | func DummyAPI(ctx context.Context, req *Request) error { 25 | return nil 26 | } 27 | -------------------------------------------------------------------------------- /pkg/clientgen/testdata/goapp/tsconfig.json: -------------------------------------------------------------------------------- 1 | // Note: this config is here purely to remove errors about promises not being present in IDE's when viewing the expected_typescript.ts file 2 | { 3 | "compilerOptions": { 4 | "target": "es2021" 5 | } 6 | } 7 | -------------------------------------------------------------------------------- /pkg/clientgen/testdata/tsapp/input_list_of_union.ts: -------------------------------------------------------------------------------- 1 | -- encore.app -- 2 | {"id": ""} 3 | 4 | -- package.json -- 5 | {"name": "ts-test-app"} 6 | 7 | -- svc/svc.ts -- 8 | import { api } from "encore.dev/api"; 9 | 10 | export const dummy = api( 11 | { expose: true, method: "GET", path: "/dummy" }, 12 | async (req: Request) => {}, 13 | ); 14 | 15 | 16 | interface Request { 17 | listOfUnion: ("a" | "b")[] 18 | } 19 | 20 | -------------------------------------------------------------------------------- /pkg/clientgen/testdata/tsapp/tsconfig.json: -------------------------------------------------------------------------------- 1 | // Note: this config is here purely to remove errors about promises not being present in IDE's when viewing the expected_typescript.ts file 2 | { 3 | "compilerOptions": { 4 | "target": "es2022", 5 | "paths": { 6 | "~backend/*": ["./*"] 7 | }, 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /pkg/dockerbuild/features.go: -------------------------------------------------------------------------------- 1 | package dockerbuild 2 | 3 | type FeatureFlag string 4 | 5 | const ( 6 | NewRuntimeConfig FeatureFlag = "new_runtime_config" 7 | ) 8 | -------------------------------------------------------------------------------- /pkg/dockerbuild/manifest.go: -------------------------------------------------------------------------------- 1 | package dockerbuild 2 | 3 | type ImageManifestFile struct { 4 | Manifests []*ImageManifest 5 | } 6 | 7 | type ImageManifest struct { 8 | // The Docker Image reference, e.g. "gcr.io/my-project/my-image:sha256:abcdef..." 9 | Reference string 10 | 11 | // Services and gateways bundled in this image. 12 | BundledServices []string 13 | BundledGateways []string 14 | 15 | // FeatureFlags captures feature flags enabled for this image. 16 | FeatureFlags map[FeatureFlag]bool 17 | } 18 | -------------------------------------------------------------------------------- /pkg/editors/doc.go: -------------------------------------------------------------------------------- 1 | // Package editors is a Go Port of [GitHub Desktop's editor code](https://github.com/desktop/desktop/tree/development/app/src/lib/editors) 2 | // 3 | // It was taken at this commit [a1ece18](https://github.com/desktop/desktop/tree/a1ece186bae3a742f206c5edeb0762e78fba2f7c/app/src/lib/editors) 4 | package editors 5 | -------------------------------------------------------------------------------- /pkg/editors/lookup_test.go: -------------------------------------------------------------------------------- 1 | package editors 2 | 3 | import ( 4 | "context" 5 | "fmt" 6 | "testing" 7 | 8 | qt "github.com/frankban/quicktest" 9 | ) 10 | 11 | func TestResolve(t *testing.T) { 12 | c := qt.New(t) 13 | 14 | editors, err := Resolve(context.Background()) 15 | c.Assert(err, qt.IsNil) 16 | fmt.Printf("Found editors:\n%+v\n", editors) 17 | } 18 | -------------------------------------------------------------------------------- /pkg/editors/lookup_unsupported.go: -------------------------------------------------------------------------------- 1 | //go:build !darwin && !linux && !windows 2 | 3 | package editors 4 | 5 | import ( 6 | "context" 7 | ) 8 | 9 | // Returns no editors as we don't know how to find them on this platform. 10 | func getAvailableEditors(ctx context.Context) ([]FoundEditor, error) { 11 | return []FoundEditor{}, nil 12 | } 13 | -------------------------------------------------------------------------------- /pkg/editors/utils.go: -------------------------------------------------------------------------------- 1 | package editors 2 | 3 | import ( 4 | "errors" 5 | "io/fs" 6 | "os" 7 | ) 8 | 9 | // Checks if the given path exists. 10 | func pathExists(path string) bool { 11 | _, err := os.Stat(path) 12 | return !errors.Is(err, fs.ErrNotExist) 13 | } 14 | -------------------------------------------------------------------------------- /pkg/emulators/storage/gcsemu/range_test.go: -------------------------------------------------------------------------------- 1 | package gcsemu 2 | 3 | import ( 4 | "testing" 5 | 6 | "gotest.tools/v3/assert" 7 | ) 8 | 9 | func TestParseByteRange(t *testing.T) { 10 | tcs := []struct { 11 | in string 12 | expect byteRange 13 | }{ 14 | {in: "bytes 0-8388607/*", expect: byteRange{lo: 0, hi: 8388607, sz: -1}}, 15 | {in: "bytes 8388608-10485759/10485760", expect: byteRange{lo: 8388608, hi: 10485759, sz: 10485760}}, 16 | {in: "bytes */10485760", expect: byteRange{lo: -1, hi: -1, sz: 10485760}}, 17 | } 18 | 19 | for _, tc := range tcs { 20 | t.Logf("test case: %s", tc.in) 21 | assert.Equal(t, tc.expect, *parseByteRange(tc.in)) 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /pkg/emulators/storage/gcsutil/doc.go: -------------------------------------------------------------------------------- 1 | // Package gcsutil contains some generic utilities to support gcsemu. 2 | // TODO(dragonsinth): consider open sourcing these separately, or finding open source replacements. 3 | package gcsutil 4 | -------------------------------------------------------------------------------- /pkg/emulators/storage/gcsutil/gcspagetoken.proto: -------------------------------------------------------------------------------- 1 | syntax = "proto3"; 2 | 3 | package gcsutil; 4 | 5 | option go_package = "encr.dev/pkg/emulators/storage/gcsutil"; 6 | 7 | message GcsPageToken{ 8 | // The full name of the last result file, when returned from the server. 9 | // When sent as a cursor, interpreted as "return files greater than this value". 10 | string LastFile = 1; 11 | } 12 | -------------------------------------------------------------------------------- /pkg/encorebuild/windows/.gitignore: -------------------------------------------------------------------------------- 1 | /.deps -------------------------------------------------------------------------------- /pkg/encorebuild/windows/resources.rc: -------------------------------------------------------------------------------- 1 | /* SPDX-License-Identifier: MIT 2 | * 3 | * Copyright (C) 2019-2021 WireGuard LLC. All Rights Reserved. 4 | */ 5 | 6 | #pragma code_page(65001) // UTF-8 7 | CREATEPROCESS_MANIFEST_RESOURCE_ID RT_MANIFEST manifest.xml 8 | wintun.dll RCDATA wintun.dll -------------------------------------------------------------------------------- /pkg/errinsrc/internal/helper.go: -------------------------------------------------------------------------------- 1 | package internal 2 | 3 | // ErrParams are used to create *errinsrc.ErrInSrc objects. 4 | // 5 | // It exists within an `internal` package so that it can only 6 | // be used by other packages within the `errinsrc` folder. 7 | // This is enforce through the Go compiler that all 8 | // errors are created inside the `srcerrors` subpackage. 9 | type ErrParams struct { 10 | Code int `json:"code"` 11 | Title string `json:"title"` 12 | Summary string `json:"summary"` 13 | Detail string `json:"detail,omitempty"` 14 | Cause error `json:"-"` 15 | Locations SrcLocations `json:"locations,omitempty"` 16 | } 17 | -------------------------------------------------------------------------------- /pkg/errinsrc/setup_test.go: -------------------------------------------------------------------------------- 1 | package errinsrc 2 | 3 | import ( 4 | "os" 5 | "path" 6 | "testing" 7 | 8 | "encr.dev/pkg/golden" 9 | ) 10 | 11 | var testDataFullPath string 12 | 13 | func TestMain(m *testing.M) { 14 | ColoursInErrors(false) 15 | golden.TestMain(m) 16 | } 17 | 18 | func init() { 19 | var err error 20 | testDataFullPath, err = os.Getwd() 21 | if err != nil { 22 | panic(err) 23 | } 24 | 25 | testDataFullPath = path.Join(testDataFullPath, "testdata") 26 | } 27 | -------------------------------------------------------------------------------- /pkg/errinsrc/stack_dev.go: -------------------------------------------------------------------------------- 1 | //go:build dev_build 2 | 3 | package errinsrc 4 | 5 | // IncludeStackByDefault is whether to include the stack by default on all errors. 6 | // This is exported to allow Encore's CI platform to set this to true for CI/CD builds. 7 | var IncludeStackByDefault = true 8 | -------------------------------------------------------------------------------- /pkg/errinsrc/stack_release.go: -------------------------------------------------------------------------------- 1 | //go:build !dev_build 2 | 3 | package errinsrc 4 | 5 | // IncludeStackByDefault is whether to include the stack by default on all errors. 6 | // This is exported to allow Encore's CI platform to set this to true for CI/CD builds. 7 | var IncludeStackByDefault = false 8 | -------------------------------------------------------------------------------- /pkg/errinsrc/testdata/Test_renderSrc_MultipleSeperateInSameFile__on_following_lines_ascii.golden: -------------------------------------------------------------------------------- 1 | 2 | -- simple test error ----------------------------------------------------------------------[E0001]-- 3 | 4 | There has been a simple error in your code 5 | 6 | ,-[ /test.cue:5:7 ] 7 | | 8 | 3 | // This is a sample file 9 | 4 | blah: { 10 | 5 | foo: bool 11 | : -v-- 12 | : `- this is weird 13 | 6 | bar: int | *3 14 | : v- 15 | : `- so is this! 16 | 7 | } 17 | 8 | 18 | ---' 19 | 20 | For more information please visit our great help documentation 21 | 22 | -------------------------------------------------------------------------------- /pkg/errinsrc/testdata/Test_renderSrc_MultipleSeperateInSameFile__on_following_lines_unicode.golden: -------------------------------------------------------------------------------- 1 | 2 | ── simple test error ──────────────────────────────────────────────────────────────────────[E0001]── 3 | 4 | There has been a simple error in your code 5 | 6 | ╭─[ /test.cue:5:7 ] 7 | │ 8 | 3 │ // This is a sample file 9 | 4 │ blah: { 10 | 5 │ foo: bool 11 | ⋮ ─┬── 12 | ⋮ ╰─ this is weird 13 | 6 │ bar: int | *3 14 | ⋮ ┬─ 15 | ⋮ ╰─ so is this! 16 | 7 │ } 17 | 8 │ 18 | ───╯ 19 | 20 | For more information please visit our great help documentation 21 | 22 | -------------------------------------------------------------------------------- /pkg/errinsrc/testdata/Test_renderSrc_MultipleSeperateInSameFile__on_same_line_ascii.golden: -------------------------------------------------------------------------------- 1 | 2 | -- simple test error ----------------------------------------------------------------------[E0001]-- 3 | 4 | There has been a simple error in your code 5 | 6 | ,-[ /test.cue:5:2 ] 7 | | 8 | 3 | // This is a sample file 9 | 4 | blah: { 10 | 5 | foo: bool 11 | : ----v---- 12 | : `- wrong type here 13 | 6 | bar: int | *3 14 | 7 | } 15 | ---' 16 | 17 | ,-[ /test.cue:5:7 ] 18 | | 19 | 3 | // This is a sample file 20 | 4 | blah: { 21 | 5 | foo: bool 22 | : -v-- 23 | : `- hint: change this to an int 24 | 6 | bar: int | *3 25 | 7 | } 26 | ---' 27 | 28 | For more information please visit our great help documentation 29 | 30 | -------------------------------------------------------------------------------- /pkg/errinsrc/testdata/Test_renderSrc_MultipleSeperateInSameFile__on_same_line_unicode.golden: -------------------------------------------------------------------------------- 1 | 2 | ── simple test error ──────────────────────────────────────────────────────────────────────[E0001]── 3 | 4 | There has been a simple error in your code 5 | 6 | ╭─[ /test.cue:5:2 ] 7 | │ 8 | 3 │ // This is a sample file 9 | 4 │ blah: { 10 | 5 │ foo: bool 11 | ⋮ ────┬──── 12 | ⋮ ╰─ wrong type here 13 | 6 │ bar: int | *3 14 | 7 │ } 15 | ───╯ 16 | 17 | ╭─[ /test.cue:5:7 ] 18 | │ 19 | 3 │ // This is a sample file 20 | 4 │ blah: { 21 | 5 │ foo: bool 22 | ⋮ ─┬── 23 | ⋮ ╰─ hint: change this to an int 24 | 6 │ bar: int | *3 25 | 7 │ } 26 | ───╯ 27 | 28 | For more information please visit our great help documentation 29 | 30 | -------------------------------------------------------------------------------- /pkg/errinsrc/testdata/Test_renderSrc_MultipleSeperateInSameFile__spaced_apart_ascii.golden: -------------------------------------------------------------------------------- 1 | 2 | -- simple test error ----------------------------------------------------------------------[E0001]-- 3 | 4 | There has been a simple error in your code 5 | 6 | ,-[ /test.cue:5:7 ] 7 | | 8 | 3 | // This is a sample file 9 | 4 | blah: { 10 | 5 | foo: bool 11 | : -v-- 12 | : `- defined as a boolean here 13 | * 14 | * 15 | 11 | 16 | 12 | // If foo then bar is 12 17 | 13 | if blah.foo { 18 | : -v- 19 | : `- referenced here 20 | 14 | blah: bar: 12 21 | 15 | } 22 | ----' 23 | 24 | For more information please visit our great help documentation 25 | 26 | -------------------------------------------------------------------------------- /pkg/errinsrc/testdata/Test_renderSrc_MultipleSeperateInSameFile__spaced_apart_unicode.golden: -------------------------------------------------------------------------------- 1 | 2 | ── simple test error ──────────────────────────────────────────────────────────────────────[E0001]── 3 | 4 | There has been a simple error in your code 5 | 6 | ╭─[ /test.cue:5:7 ] 7 | │ 8 | 3 │ // This is a sample file 9 | 4 │ blah: { 10 | 5 │ foo: bool 11 | ⋮ ─┬── 12 | ⋮ ╰─ defined as a boolean here 13 | · 14 | · 15 | 11 │ 16 | 12 │ // If foo then bar is 12 17 | 13 │ if blah.foo { 18 | ⋮ ─┬─ 19 | ⋮ ╰─ referenced here 20 | 14 │ blah: bar: 12 21 | 15 │ } 22 | ────╯ 23 | 24 | For more information please visit our great help documentation 25 | 26 | -------------------------------------------------------------------------------- /pkg/errinsrc/testdata/Test_renderSrc_MutlilineError_ascii.golden: -------------------------------------------------------------------------------- 1 | 2 | -- simple test error ----------------------------------------------------------------------[E0001]-- 3 | 4 | There has been a simple error in your code 5 | 6 | ,-[ /test.cue:4:7 ] 7 | | 8 | 2 | 9 | 3 | // This is a sample file 10 | 4 | blah: { 11 | : ^ 12 | : ,---------' 13 | 5 | | foo: bool 14 | 6 | | bar: int | *3 15 | 7 | |-> } 16 | : `- this is an error which spans multiple lines 17 | : like this so we can test alignment 18 | 8 | 19 | 9 | // Let's set foo to true 20 | ----' 21 | 22 | For more information please visit our great help documentation 23 | 24 | -------------------------------------------------------------------------------- /pkg/errinsrc/testdata/Test_renderSrc_MutlilineError_unicode.golden: -------------------------------------------------------------------------------- 1 | 2 | ── simple test error ──────────────────────────────────────────────────────────────────────[E0001]── 3 | 4 | There has been a simple error in your code 5 | 6 | ╭─[ /test.cue:4:7 ] 7 | │ 8 | 2 │ 9 | 3 │ // This is a sample file 10 | 4 │ blah: { 11 | ⋮ ▲ 12 | ⋮ ╭─────────╯ 13 | 5 │ │ foo: bool 14 | 6 │ │ bar: int | *3 15 | 7 │ ├─▶ } 16 | ⋮ ╰─ this is an error which spans multiple lines 17 | ⋮ like this so we can test alignment 18 | 8 │ 19 | 9 │ // Let's set foo to true 20 | ────╯ 21 | 22 | For more information please visit our great help documentation 23 | 24 | -------------------------------------------------------------------------------- /pkg/errinsrc/testdata/Test_renderSrc_Simple__error_no_text_ascii.golden: -------------------------------------------------------------------------------- 1 | 2 | -- simple test error ----------------------------------------------------------------------[E0001]-- 3 | 4 | There has been a simple error in your code 5 | 6 | ,-[ /test.cue:5:7 ] 7 | | 8 | 3 | // This is a sample file 9 | 4 | blah: { 10 | 5 | foo: bool 11 | : ---- 12 | 6 | bar: int | *3 13 | 7 | } 14 | ---' 15 | 16 | For more information please visit our great help documentation 17 | 18 | -------------------------------------------------------------------------------- /pkg/errinsrc/testdata/Test_renderSrc_Simple__error_no_text_unicode.golden: -------------------------------------------------------------------------------- 1 | 2 | ── simple test error ──────────────────────────────────────────────────────────────────────[E0001]── 3 | 4 | There has been a simple error in your code 5 | 6 | ╭─[ /test.cue:5:7 ] 7 | │ 8 | 3 │ // This is a sample file 9 | 4 │ blah: { 10 | 5 │ foo: bool 11 | ⋮ ──── 12 | 6 │ bar: int | *3 13 | 7 │ } 14 | ───╯ 15 | 16 | For more information please visit our great help documentation 17 | 18 | -------------------------------------------------------------------------------- /pkg/errinsrc/testdata/Test_renderSrc_Simple__simple_error_ascii.golden: -------------------------------------------------------------------------------- 1 | 2 | -- simple test error ----------------------------------------------------------------------[E0001]-- 3 | 4 | There has been a simple error in your code 5 | 6 | ,-[ /test.cue:5:2 ] 7 | | 8 | 3 | // This is a sample file 9 | 4 | blah: { 10 | 5 | foo: bool 11 | : ----v---- 12 | : `- What is a foo? 13 | 6 | bar: int | *3 14 | 7 | } 15 | ---' 16 | 17 | For more information please visit our great help documentation 18 | 19 | -------------------------------------------------------------------------------- /pkg/errinsrc/testdata/Test_renderSrc_Simple__simple_error_unicode.golden: -------------------------------------------------------------------------------- 1 | 2 | ── simple test error ──────────────────────────────────────────────────────────────────────[E0001]── 3 | 4 | There has been a simple error in your code 5 | 6 | ╭─[ /test.cue:5:2 ] 7 | │ 8 | 3 │ // This is a sample file 9 | 4 │ blah: { 10 | 5 │ foo: bool 11 | ⋮ ────┬──── 12 | ⋮ ╰─ What is a foo? 13 | 6 │ bar: int | *3 14 | 7 │ } 15 | ───╯ 16 | 17 | For more information please visit our great help documentation 18 | 19 | -------------------------------------------------------------------------------- /pkg/errinsrc/testdata/Test_renderSrc_Simple__simple_help_ascii.golden: -------------------------------------------------------------------------------- 1 | 2 | -- simple test error ----------------------------------------------------------------------[E0001]-- 3 | 4 | There has been a simple error in your code 5 | 6 | ,-[ /test.cue:13:4 ] 7 | | 8 | 11 | 9 | 12 | // If foo then bar is 12 10 | 13 | if blah.foo { 11 | : ---v---- 12 | : `- help: try a switch statement here 13 | 14 | blah: bar: 12 14 | 15 | } 15 | ----' 16 | 17 | For more information please visit our great help documentation 18 | 19 | -------------------------------------------------------------------------------- /pkg/errinsrc/testdata/Test_renderSrc_Simple__simple_help_unicode.golden: -------------------------------------------------------------------------------- 1 | 2 | ── simple test error ──────────────────────────────────────────────────────────────────────[E0001]── 3 | 4 | There has been a simple error in your code 5 | 6 | ╭─[ /test.cue:13:4 ] 7 | │ 8 | 11 │ 9 | 12 │ // If foo then bar is 12 10 | 13 │ if blah.foo { 11 | ⋮ ───┬──── 12 | ⋮ ╰─ help: try a switch statement here 13 | 14 │ blah: bar: 12 14 | 15 │ } 15 | ────╯ 16 | 17 | For more information please visit our great help documentation 18 | 19 | -------------------------------------------------------------------------------- /pkg/errinsrc/testdata/Test_renderSrc_Simple__simple_warning_ascii.golden: -------------------------------------------------------------------------------- 1 | 2 | -- simple test error ----------------------------------------------------------------------[E0001]-- 3 | 4 | There has been a simple error in your code 5 | 6 | ,-[ /test.cue:10:7 ] 7 | | 8 | 8 | 9 | 9 | // Let's set foo to true 10 | 10 | blah: foo: true 11 | : -v- 12 | : `- You sure about this? 13 | 11 | 14 | 12 | // If foo then bar is 12 15 | ----' 16 | 17 | For more information please visit our great help documentation 18 | 19 | -------------------------------------------------------------------------------- /pkg/errinsrc/testdata/Test_renderSrc_Simple__simple_warning_unicode.golden: -------------------------------------------------------------------------------- 1 | 2 | ── simple test error ──────────────────────────────────────────────────────────────────────[E0001]── 3 | 4 | There has been a simple error in your code 5 | 6 | ╭─[ /test.cue:10:7 ] 7 | │ 8 | 8 │ 9 | 9 │ // Let's set foo to true 10 | 10 │ blah: foo: true 11 | ⋮ ─┬─ 12 | ⋮ ╰─ You sure about this? 13 | 11 │ 14 | 12 │ // If foo then bar is 12 15 | ────╯ 16 | 17 | For more information please visit our great help documentation 18 | 19 | -------------------------------------------------------------------------------- /pkg/errinsrc/testdata/Test_renderSrc_Simple__single_character_error_ascii.golden: -------------------------------------------------------------------------------- 1 | 2 | -- simple test error ----------------------------------------------------------------------[E0001]-- 3 | 4 | There has been a simple error in your code 5 | 6 | ,-[ /test.cue:6:11 ] 7 | | 8 | 4 | blah: { 9 | 5 | foo: bool 10 | 6 | bar: int | *3 11 | : ^ 12 | : `- This looks dodgy 13 | 7 | } 14 | 8 | 15 | ---' 16 | 17 | For more information please visit our great help documentation 18 | 19 | -------------------------------------------------------------------------------- /pkg/errinsrc/testdata/Test_renderSrc_Simple__single_character_error_unicode.golden: -------------------------------------------------------------------------------- 1 | 2 | ── simple test error ──────────────────────────────────────────────────────────────────────[E0001]── 3 | 4 | There has been a simple error in your code 5 | 6 | ╭─[ /test.cue:6:11 ] 7 | │ 8 | 4 │ blah: { 9 | 5 │ foo: bool 10 | 6 │ bar: int | *3 11 | ⋮ ▲ 12 | ⋮ ╰─ This looks dodgy 13 | 7 │ } 14 | 8 │ 15 | ───╯ 16 | 17 | For more information please visit our great help documentation 18 | 19 | -------------------------------------------------------------------------------- /pkg/errinsrc/testdata/test.cue: -------------------------------------------------------------------------------- 1 | package test_cue 2 | 3 | // This is a sample file 4 | blah: { 5 | foo: bool 6 | bar: int | *3 7 | } 8 | 9 | // Let's set foo to true 10 | blah: foo: true 11 | 12 | // If foo then bar is 12 13 | if blah.foo { 14 | blah: bar: 12 15 | } 16 | -------------------------------------------------------------------------------- /pkg/errinsrc/testdata/test.go: -------------------------------------------------------------------------------- 1 | package testdata 2 | 3 | import ( 4 | "context" 5 | 6 | "encore.dev/config" 7 | ) 8 | 9 | type Config struct { 10 | Blah struct { 11 | Foo config.Bool `json:"foo"` 12 | Bar config.Int `json:"bar"` 13 | } `json:"blah"` 14 | } 15 | 16 | var cfg = config.Load[Config]() 17 | 18 | type WhatIsBarResponse struct { 19 | Bar int 20 | } 21 | 22 | //encore:api public 23 | func WhatIsBar(ctx context.Context) (*WhatIsBarResponse, error) { 24 | return &WhatIsBarResponse{ 25 | Bar: cfg.Blah.Bar(), 26 | }, nil 27 | } 28 | -------------------------------------------------------------------------------- /pkg/errors/utils.go: -------------------------------------------------------------------------------- 1 | package errors 2 | 3 | import ( 4 | "go/ast" 5 | 6 | "encr.dev/pkg/option" 7 | ) 8 | 9 | // AtOptionalNode returns an error at the given node if it is present. 10 | // Otherwise, it returns the error unchanged. 11 | func AtOptionalNode[T ast.Node](err Template, opt option.Option[T]) Template { 12 | if node, ok := opt.Get(); ok { 13 | return err.AtGoNode(node) 14 | } 15 | return err 16 | } 17 | -------------------------------------------------------------------------------- /pkg/logging/zerolog_adapter.go: -------------------------------------------------------------------------------- 1 | package logging 2 | 3 | import ( 4 | "log" 5 | 6 | "github.com/rs/zerolog" 7 | ) 8 | 9 | type zeroLogWriter struct { 10 | logger zerolog.Logger 11 | level zerolog.Level 12 | } 13 | 14 | func (z *zeroLogWriter) Write(p []byte) (n int, err error) { 15 | z.logger.WithLevel(z.level).CallerSkipFrame(3).Msg(string(p)) 16 | return len(p), nil 17 | } 18 | 19 | // NewZeroLogAdapter returns a new log.Logger that writes to the given zerolog.Logger at the given level. 20 | func NewZeroLogAdapter(logger zerolog.Logger, level zerolog.Level) *log.Logger { 21 | zlw := &zeroLogWriter{logger, level} 22 | return log.New(zlw, "", 0) 23 | } 24 | -------------------------------------------------------------------------------- /pkg/make-release/windows/.gitignore: -------------------------------------------------------------------------------- 1 | /.deps -------------------------------------------------------------------------------- /pkg/make-release/windows/resources.rc: -------------------------------------------------------------------------------- 1 | /* SPDX-License-Identifier: MIT 2 | * 3 | * Copyright (C) 2019-2021 WireGuard LLC. All Rights Reserved. 4 | */ 5 | 6 | #pragma code_page(65001) // UTF-8 7 | CREATEPROCESS_MANIFEST_RESOURCE_ID RT_MANIFEST manifest.xml 8 | wintun.dll RCDATA wintun.dll -------------------------------------------------------------------------------- /pkg/pgproxy/README.md: -------------------------------------------------------------------------------- 1 | # pgproxy 2 | 3 | pgproxy is a flexible proxy for the Postgres wire protocol that allows for customizing authentication and backend selection by breaking apart the startup message flow between frontend and backend. 4 | 5 | Once authenticated, it falls back to being a dumb proxy 6 | that simple shuffles bytes back and forth. 7 | -------------------------------------------------------------------------------- /pkg/svcproxy/doc.go: -------------------------------------------------------------------------------- 1 | // Package svcproxy provides an HTTP proxy which allows the daemon to 2 | // serve HTTP requests on behalf of services within the app and forward 3 | // then to the appropriate process. 4 | package svcproxy 5 | -------------------------------------------------------------------------------- /pkg/vfs/doc.go: -------------------------------------------------------------------------------- 1 | // Package vfs represents a virtual filesystem 2 | package vfs 3 | -------------------------------------------------------------------------------- /pkg/vfs/node.go: -------------------------------------------------------------------------------- 1 | package vfs 2 | 3 | import ( 4 | "time" 5 | ) 6 | 7 | type node struct { 8 | name string // The name of this node 9 | parent *directoryContents 10 | modTime time.Time 11 | } 12 | -------------------------------------------------------------------------------- /pkg/vfs/testdata/filteredglob/blahsvc/another.json: -------------------------------------------------------------------------------- 1 | { 2 | "foo": false 3 | } 4 | -------------------------------------------------------------------------------- /pkg/vfs/testdata/filteredglob/blahsvc/test.json: -------------------------------------------------------------------------------- 1 | { 2 | "foo": "blah" 3 | } 4 | -------------------------------------------------------------------------------- /pkg/vfs/testdata/filteredglob/foosystem/README.md: -------------------------------------------------------------------------------- 1 | This is a example file 2 | -------------------------------------------------------------------------------- /pkg/vfs/testdata/filteredglob/foosystem/anotherservice/test.txt: -------------------------------------------------------------------------------- 1 | another 2 | -------------------------------------------------------------------------------- /pkg/vfs/testdata/filteredglob/foosystem/barservice/blah.json: -------------------------------------------------------------------------------- 1 | { 2 | "foo": "bar" 3 | } 4 | -------------------------------------------------------------------------------- /pkg/vfs/testdata/filteredglob/foosystem/barservice/test.txt: -------------------------------------------------------------------------------- 1 | Hello world 2 | -------------------------------------------------------------------------------- /pkg/vfs/testdata/filteredglob/nope/ignored.txt: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/encoredev/encore/688fc65052cbb36c9016e632a52f95d68fe588f0/pkg/vfs/testdata/filteredglob/nope/ignored.txt -------------------------------------------------------------------------------- /pkg/watcher/rlimit_nix.go: -------------------------------------------------------------------------------- 1 | //go:build linux || darwin 2 | 3 | package watcher 4 | 5 | import ( 6 | "syscall" 7 | 8 | "github.com/rs/zerolog/log" 9 | ) 10 | 11 | // BumpRLimitSoftToHardLimit bumps the soft limit of the rlimit to the hard limit. 12 | // 13 | // To go higher the user will need to update their kernel settings which can be viewed: 14 | // 15 | // sysctl -a | grep kern.maxfile 16 | func BumpRLimitSoftToHardLimit() { 17 | var rLimit syscall.Rlimit 18 | err := syscall.Getrlimit(syscall.RLIMIT_NOFILE, &rLimit) 19 | if err != nil { 20 | log.Error().Err(err).Msg("failed to get rlimit") 21 | } 22 | rLimit.Cur = rLimit.Max 23 | err = syscall.Setrlimit(syscall.RLIMIT_NOFILE, &rLimit) 24 | if err != nil { 25 | log.Error().Err(err).Msg("failed to set rlimit") 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /pkg/watcher/rlimit_noop.go: -------------------------------------------------------------------------------- 1 | //go:build !linux && !darwin 2 | 3 | package watcher 4 | 5 | // BumpRLimitSoftToHardLimit bumps the soft limit of the rlimit to the hard limit. 6 | // 7 | // To go higher the user will need to update their kernel settings which can be viewed: 8 | // 9 | // sysctl -a | grep kern.maxfile 10 | func BumpRLimitSoftToHardLimit() { 11 | // no-op 12 | } 13 | -------------------------------------------------------------------------------- /pkg/words/funcs.go: -------------------------------------------------------------------------------- 1 | package words 2 | 3 | import ( 4 | "crypto/rand" 5 | "fmt" 6 | "math/big" 7 | ) 8 | 9 | // Select selects n random words from the short word list. 10 | func Select(n int) ([]string, error) { 11 | selected := make([]string, n) 12 | words := shortWords.Get() 13 | max := big.NewInt(int64(len(words))) 14 | for i := 0; i < n; i++ { 15 | j, err := rand.Int(rand.Reader, max) 16 | if err != nil { 17 | return nil, fmt.Errorf("wordlist.Select %d: %v", n, err) 18 | } 19 | selected[i] = words[j.Int64()] 20 | } 21 | return selected, nil 22 | } 23 | -------------------------------------------------------------------------------- /pkg/words/words.go: -------------------------------------------------------------------------------- 1 | package words 2 | 3 | import ( 4 | _ "embed" // for go:embed 5 | "strings" 6 | "sync" 7 | ) 8 | 9 | type wordList struct { 10 | raw string 11 | once sync.Once 12 | words []string 13 | } 14 | 15 | func (w *wordList) Get() []string { 16 | w.once.Do(func() { 17 | raw := strings.TrimSpace(w.raw) 18 | w.words = strings.Split(raw, "\n") 19 | }) 20 | return w.words 21 | } 22 | 23 | var ( 24 | //go:embed shortwords.txt 25 | shortRaw string 26 | 27 | shortWords = wordList{raw: shortRaw} 28 | ) 29 | -------------------------------------------------------------------------------- /pkg/words/words_test.go: -------------------------------------------------------------------------------- 1 | package words 2 | 3 | import ( 4 | "strings" 5 | "testing" 6 | ) 7 | 8 | func TestWords(t *testing.T) { 9 | list := shortWords.Get() 10 | if len(list) != 1295 { 11 | t.Errorf("expected 1295 words, got %d", len(list)) 12 | } 13 | 14 | seen := make(map[string]bool) 15 | for _, w := range list { 16 | if seen[w] { 17 | t.Errorf("duplicate word %q", w) 18 | } else if len(w) < 3 || len(w) > 5 { 19 | t.Errorf("expected word to be 3-5 5 characters, got %q", w) 20 | } else if strings.TrimSpace(w) != w { 21 | t.Errorf("expected word to be trimmed, got %q", w) 22 | } 23 | seen[w] = true 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /proto/encore/engine/trace/trace_util.go: -------------------------------------------------------------------------------- 1 | package trace 2 | 3 | func (id *TraceID) IsZero() bool { 4 | return id == nil || (id.Low == 0 && id.High == 0) 5 | } 6 | -------------------------------------------------------------------------------- /proto/encore/engine/trace2/trace_util.go: -------------------------------------------------------------------------------- 1 | package trace2 2 | 3 | func (id *TraceID) IsZero() bool { 4 | return id == nil || (id.Low == 0 && id.High == 0) 5 | } 6 | -------------------------------------------------------------------------------- /proto/gen.go: -------------------------------------------------------------------------------- 1 | package pb 2 | 3 | //go:generate ./gen.sh 4 | -------------------------------------------------------------------------------- /runtimes/core/resources/test/runtime.pb: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/encoredev/encore/688fc65052cbb36c9016e632a52f95d68fe588f0/runtimes/core/resources/test/runtime.pb -------------------------------------------------------------------------------- /runtimes/core/src/api/encore_routes/mod.rs: -------------------------------------------------------------------------------- 1 | use axum::routing; 2 | 3 | use crate::pubsub; 4 | 5 | pub mod healthz; 6 | 7 | pub struct Desc { 8 | pub healthz: healthz::Handler, 9 | pub push_registry: pubsub::PushHandlerRegistry, 10 | } 11 | 12 | impl Desc { 13 | pub fn router(self) -> axum::Router<()> { 14 | axum::Router::new() 15 | .route("/__encore/healthz", routing::any(self.healthz)) 16 | .route( 17 | "/__encore/pubsub/push/:subscription_id", 18 | routing::any(self.push_registry), 19 | ) 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /runtimes/core/src/api/mod.rs: -------------------------------------------------------------------------------- 1 | pub mod auth; 2 | pub mod call; 3 | mod cors; 4 | mod encore_routes; 5 | mod endpoint; 6 | mod error; 7 | pub mod gateway; 8 | mod http_server; 9 | mod httputil; 10 | pub mod jsonschema; 11 | mod manager; 12 | mod paths; 13 | mod pvalue; 14 | pub mod reqauth; 15 | pub mod schema; 16 | mod server; 17 | mod static_assets; 18 | pub mod websocket; 19 | pub mod websocket_client; 20 | 21 | pub use endpoint::*; 22 | pub use error::*; 23 | pub use manager::*; 24 | pub use pvalue::*; 25 | -------------------------------------------------------------------------------- /runtimes/core/src/api/reqauth/encoreauth/mod.rs: -------------------------------------------------------------------------------- 1 | mod ophash; 2 | mod sign; 3 | 4 | pub use ophash::OperationHash; 5 | pub use sign::{sign, sign_for_verification, InvalidSignature, SignatureComponents}; 6 | -------------------------------------------------------------------------------- /runtimes/core/src/api/snapshots/encore_runtime_core__api__paths__tests__basic.snap: -------------------------------------------------------------------------------- 1 | --- 2 | source: runtimes/core/src/api/paths.rs 3 | expression: paths 4 | --- 5 | main: 6 | a: 7 | - - one 8 | - - /foo 9 | - /foo/ 10 | - - two 11 | - - /foo/bar 12 | - /foo/bar/ 13 | fallback: {} 14 | -------------------------------------------------------------------------------- /runtimes/core/src/api/snapshots/encore_runtime_core__api__paths__tests__fallback.snap: -------------------------------------------------------------------------------- 1 | --- 2 | source: runtimes/core/src/api/paths.rs 3 | expression: paths 4 | --- 5 | main: {} 6 | fallback: 7 | a: 8 | - - one 9 | - - / 10 | - /*foo 11 | -------------------------------------------------------------------------------- /runtimes/core/src/api/snapshots/encore_runtime_core__api__paths__tests__paths_to_register.snap: -------------------------------------------------------------------------------- 1 | --- 2 | source: runtimes/core/src/api/paths.rs 3 | expression: paths 4 | --- 5 | main: 6 | a: 7 | - endpoint: 8 | key: a 9 | path: /a 10 | routes: 11 | - /a 12 | - /a/ 13 | fallback: {} 14 | -------------------------------------------------------------------------------- /runtimes/core/src/api/snapshots/encore_runtime_core__api__paths__tests__tsr_conflict.snap: -------------------------------------------------------------------------------- 1 | --- 2 | source: runtimes/core/src/api/paths.rs 3 | expression: paths 4 | --- 5 | main: 6 | a: 7 | - - one 8 | - - /foo/ 9 | b: 10 | - - two 11 | - - /foo 12 | fallback: {} 13 | -------------------------------------------------------------------------------- /runtimes/core/src/api/snapshots/encore_runtime_core__api__paths__tests__wildcard.snap: -------------------------------------------------------------------------------- 1 | --- 2 | source: runtimes/core/src/api/paths.rs 3 | expression: paths 4 | --- 5 | main: 6 | a: 7 | - - one 8 | - - / 9 | - /*foo 10 | fallback: {} 11 | -------------------------------------------------------------------------------- /runtimes/core/src/sqldb/mod.rs: -------------------------------------------------------------------------------- 1 | mod client; 2 | mod manager; 3 | mod transaction; 4 | mod val; 5 | 6 | pub use client::{Connection, Cursor, Pool, Row}; 7 | pub use manager::{Database, DatabaseImpl, Manager, ManagerConfig}; 8 | pub use transaction::Transaction; 9 | pub use val::RowValue; 10 | -------------------------------------------------------------------------------- /runtimes/core/src/trace/mod.rs: -------------------------------------------------------------------------------- 1 | mod eventbuf; 2 | mod log; 3 | pub mod protocol; 4 | mod time_anchor; 5 | 6 | pub use log::{streaming_tracer, ReporterConfig}; 7 | pub use protocol::Tracer; 8 | -------------------------------------------------------------------------------- /runtimes/core/src/trace/time_anchor.rs: -------------------------------------------------------------------------------- 1 | /// Correlates a system time with a time instant. 2 | #[derive(Debug, Clone)] 3 | pub struct TimeAnchor { 4 | /// The system time. 5 | pub system_time: chrono::DateTime, 6 | 7 | /// The time instant. 8 | pub instant: tokio::time::Instant, 9 | } 10 | 11 | impl TimeAnchor { 12 | pub fn new() -> Self { 13 | TimeAnchor { 14 | system_time: chrono::Utc::now(), 15 | instant: tokio::time::Instant::now(), 16 | } 17 | } 18 | 19 | pub fn trace_header(&self) -> String { 20 | // Format the system as with RFC3339Nano. 21 | let dt = self 22 | .system_time 23 | .to_rfc3339_opts(chrono::SecondsFormat::AutoSi, true); 24 | 25 | format!("0 {}", dt) 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /runtimes/go/appruntime/apisdk/api/call_context.go: -------------------------------------------------------------------------------- 1 | //go:build encore_app 2 | 3 | package api 4 | 5 | import ( 6 | "context" 7 | ) 8 | 9 | func NewCallContext(ctx context.Context) CallContext { 10 | return Singleton.NewCallContext(ctx) 11 | } 12 | -------------------------------------------------------------------------------- /runtimes/go/appruntime/apisdk/api/call_meta_test.go: -------------------------------------------------------------------------------- 1 | package api 2 | 3 | import ( 4 | "fmt" 5 | "testing" 6 | 7 | "github.com/frankban/quicktest" 8 | 9 | "encore.dev/appruntime/exported/model" 10 | ) 11 | 12 | func TestParseTraceParent(t *testing.T) { 13 | q := quicktest.New(t) 14 | 15 | expTraceID, _ := model.GenTraceID() 16 | expSpanID, _ := model.GenSpanID() 17 | expSampled := "01" 18 | 19 | traceID, spanID, sampled, ok := parseTraceParent(fmt.Sprintf("00-%x-%x-%s", expTraceID[:], expSpanID[:], expSampled)) 20 | q.Assert(ok, quicktest.IsTrue) 21 | q.Assert(traceID, quicktest.DeepEquals, expTraceID) 22 | q.Assert(spanID, quicktest.DeepEquals, expSpanID) 23 | q.Assert(sampled, quicktest.Equals, true) 24 | } 25 | -------------------------------------------------------------------------------- /runtimes/go/appruntime/apisdk/api/middleware.go: -------------------------------------------------------------------------------- 1 | package api 2 | 3 | import "encore.dev/middleware" 4 | 5 | type Middleware struct { 6 | ID string 7 | PkgName string 8 | Name string 9 | Global bool 10 | DefLoc uint32 11 | Invoke middleware.Signature 12 | } 13 | 14 | // Validator is the interface implemented by types 15 | // that can validate incoming requests. 16 | type Validator interface { 17 | Validate() error 18 | } 19 | -------------------------------------------------------------------------------- /runtimes/go/appruntime/apisdk/api/singleton.go: -------------------------------------------------------------------------------- 1 | //go:build encore_app 2 | 3 | package api 4 | 5 | import ( 6 | "github.com/benbjohnson/clock" 7 | 8 | encore "encore.dev" 9 | "encore.dev/appruntime/shared/appconf" 10 | "encore.dev/appruntime/shared/health" 11 | "encore.dev/appruntime/shared/jsonapi" 12 | "encore.dev/appruntime/shared/logging" 13 | "encore.dev/appruntime/shared/platform" 14 | "encore.dev/appruntime/shared/reqtrack" 15 | "encore.dev/appruntime/shared/testsupport" 16 | "encore.dev/metrics" 17 | "encore.dev/pubsub" 18 | ) 19 | 20 | var Singleton = NewServer( 21 | appconf.Static, appconf.Runtime, reqtrack.Singleton, platform.Singleton, 22 | encore.Singleton, pubsub.Singleton, logging.RootLogger, metrics.Singleton, 23 | health.Singleton, testsupport.Singleton, 24 | jsonapi.Default, clock.New(), 25 | ) 26 | -------------------------------------------------------------------------------- /runtimes/go/appruntime/apisdk/api/svcauth/doc.go: -------------------------------------------------------------------------------- 1 | // Package svcauth provides various authentication mechanisms for Encore services 2 | // to use verify the identity of incoming requests from other Encore services within 3 | // the same application. 4 | package svcauth 5 | -------------------------------------------------------------------------------- /runtimes/go/appruntime/apisdk/api/svcauth/noop.go: -------------------------------------------------------------------------------- 1 | package svcauth 2 | 3 | import ( 4 | "encore.dev/appruntime/apisdk/api/transport" 5 | ) 6 | 7 | // noop is a ServiceAuth implementation that does not perform any authentication. 8 | // 9 | // It is intended to be used for local development or where services are running within their own 10 | // private network and there is no threat model resulting in the need to authenticate requests. 11 | type noop struct{} 12 | 13 | var Noop noop 14 | 15 | var _ ServiceAuth = noop{} 16 | 17 | func (n noop) method() string { 18 | return "noop" 19 | } 20 | 21 | func (n noop) verify(transport.Transport) error { 22 | return nil 23 | } 24 | 25 | func (n noop) sign(transport.Transport) error { 26 | return nil 27 | } 28 | -------------------------------------------------------------------------------- /runtimes/go/appruntime/apisdk/api/svcauth/svcauth.go: -------------------------------------------------------------------------------- 1 | package svcauth 2 | 3 | import ( 4 | "encore.dev/appruntime/apisdk/api/transport" 5 | ) 6 | 7 | // ServiceAuth is an interface that provides authentication for internal service to service 8 | // calls within the same Encore application. 9 | type ServiceAuth interface { 10 | // Method returns the name of the authentication method. 11 | method() string 12 | 13 | // Verify verifies the authenticity of the request. 14 | // If the request is not authentic, an error is returned. 15 | verify(req transport.Transport) error 16 | 17 | // Sign signs the request. 18 | // If the request cannot be signed, an error is returned. 19 | sign(req transport.Transport) error 20 | } 21 | -------------------------------------------------------------------------------- /runtimes/go/appruntime/apisdk/api/transport/doc.go: -------------------------------------------------------------------------------- 1 | // Package transport provides an abstraction over the transport layer 2 | // which allows us to add and read metadata from the transport without 3 | // having to know the underlying transport implementation. 4 | package transport 5 | -------------------------------------------------------------------------------- /runtimes/go/appruntime/apisdk/api/transport/meta.go: -------------------------------------------------------------------------------- 1 | package transport 2 | 3 | // These are predefined keys for metadata that we use in Encore. 4 | // 5 | // which allow each transport method know about them and handle them 6 | // in a transport specific way if needed (including renaming them) 7 | const ( 8 | TraceParentKey = "Traceparent" 9 | TraceStateKey = "Tracestate" 10 | CorrelationIDKey = "Correlation-ID" 11 | ) 12 | -------------------------------------------------------------------------------- /runtimes/go/appruntime/apisdk/api/util.go: -------------------------------------------------------------------------------- 1 | package api 2 | 3 | import ( 4 | "strconv" 5 | 6 | "encore.dev/beta/errs" 7 | ) 8 | 9 | func clampTo64Chars(str string) string { 10 | if len(str) > 64 { 11 | return str[:64] 12 | } 13 | return str 14 | } 15 | 16 | func Code(err error, httpStatus int) string { 17 | if err != nil { 18 | e := errs.Convert(err).(*errs.Error) 19 | return e.Code.String() 20 | } 21 | 22 | if httpStatus == 0 { 23 | return errs.OK.String() 24 | } 25 | 26 | if code := errs.HTTPStatusToCode(httpStatus); code != errs.Unknown { 27 | return code.String() 28 | } 29 | return "http_" + strconv.Itoa(httpStatus) 30 | } 31 | -------------------------------------------------------------------------------- /runtimes/go/appruntime/apisdk/app/appinit/appinit.go: -------------------------------------------------------------------------------- 1 | //go:build encore_app 2 | 3 | package appinit 4 | 5 | import ( 6 | "io" 7 | 8 | "encore.dev/appruntime/apisdk/api" 9 | "encore.dev/appruntime/apisdk/app" 10 | "encore.dev/appruntime/apisdk/service" 11 | "encore.dev/appruntime/shared/appconf" 12 | "encore.dev/appruntime/shared/logging" 13 | "encore.dev/appruntime/shared/shutdown" 14 | ) 15 | 16 | // AppMain is the entrypoint to the Encore Application. 17 | func AppMain() { 18 | inst := app.New(appconf.Runtime, service.Singleton, api.Singleton, shutdown.Singleton, logging.RootLogger) 19 | if err := inst.Run(); err != nil && err != io.EOF { 20 | logging.RootLogger.Fatal().Err(err).Msg("could not run") 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /runtimes/go/appruntime/apisdk/app/setup.go: -------------------------------------------------------------------------------- 1 | package app 2 | 3 | import ( 4 | "net" 5 | "net/netip" 6 | "os" 7 | "strconv" 8 | 9 | "encore.dev/appruntime/shared/encoreenv" 10 | ) 11 | 12 | func Listen() (net.Listener, error) { 13 | listenAddr := encoreenv.Get("ENCORE_LISTEN_ADDR") 14 | if listenAddr != "" { 15 | addrPort, err := netip.ParseAddrPort(listenAddr) 16 | if err != nil { 17 | return nil, err 18 | } 19 | return net.Listen("tcp", addrPort.String()) 20 | } 21 | 22 | port, _ := strconv.Atoi(os.Getenv("PORT")) 23 | if port == 0 { 24 | port = 8080 25 | } 26 | return net.Listen("tcp", ":"+strconv.Itoa(port)) 27 | } 28 | -------------------------------------------------------------------------------- /runtimes/go/appruntime/doc.go: -------------------------------------------------------------------------------- 1 | // Package appruntime provides internal functionality for use by 2 | // Encore to run Encore applications. Packages within this directory 3 | // are intended exclusively for use by the Encore compiler and should 4 | // not be called directly from Encore applications. The APIs can change 5 | // at any time. 6 | package appruntime 7 | -------------------------------------------------------------------------------- /runtimes/go/appruntime/exported/experiments/errors.go: -------------------------------------------------------------------------------- 1 | package experiments 2 | 3 | // UnknownExperimentError is an error returned when an app tries to use 4 | // an experiment that is not known to the current version of Encore. 5 | type UnknownExperimentError struct { 6 | Name Name 7 | } 8 | 9 | func (e *UnknownExperimentError) Error() string { 10 | return "unknown experiment: " + string(e.Name) 11 | } 12 | -------------------------------------------------------------------------------- /runtimes/go/appruntime/exported/stack/stack_app.go: -------------------------------------------------------------------------------- 1 | //go:build encore_app 2 | 3 | package stack 4 | 5 | import _ "unsafe" // for go:linkname 6 | 7 | //go:linkname encoreCallers runtime.encoreCallers 8 | func encoreCallers(skip int, pc []uintptr) (n int, off uintptr) 9 | -------------------------------------------------------------------------------- /runtimes/go/appruntime/exported/stack/stack_noapp.go: -------------------------------------------------------------------------------- 1 | //go:build !encore_app 2 | 3 | package stack 4 | 5 | import "runtime" 6 | 7 | func encoreCallers(skip int, pc []uintptr) (n int, off uintptr) { 8 | n = runtime.Callers(skip, pc) 9 | 10 | // Outside of an Encore app we can't easily determine the offset. 11 | // This is only relevant to be able to construct ASLR-independent 12 | // program counters for doing PC lookups from other processes, 13 | // such as during trace rendering. This is not something we need 14 | // to worry about when not running inside an Encore app. 15 | off = 0 16 | 17 | return 18 | } 19 | -------------------------------------------------------------------------------- /runtimes/go/appruntime/exported/stack/stack_test.go: -------------------------------------------------------------------------------- 1 | package stack 2 | 3 | import ( 4 | "testing" 5 | ) 6 | 7 | func BenchmarkBuild(b *testing.B) { 8 | sum := 0 9 | for i := 0; i < b.N; i++ { 10 | n := __encore_foo() 11 | sum += n 12 | } 13 | b.Log(sum) 14 | } 15 | 16 | func __encore_foo() int { 17 | return userCode() 18 | } 19 | 20 | func userCode() int { 21 | s := Build(2) 22 | return len(s.Frames) 23 | } 24 | -------------------------------------------------------------------------------- /runtimes/go/appruntime/exported/trace/mutex_app.go: -------------------------------------------------------------------------------- 1 | //go:build encore_app 2 | 3 | package trace 4 | 5 | import _ "unsafe" // for go:linkname 6 | 7 | // mutex must exactly match implementation in the runtime. 8 | type mutex struct { 9 | key uintptr 10 | } 11 | 12 | //go:linkname mutexLock runtime.lock 13 | func mutexLock(mut *mutex) 14 | 15 | //go:linkname mutexUnlock runtime.unlock 16 | func mutexUnlock(mut *mutex) 17 | -------------------------------------------------------------------------------- /runtimes/go/appruntime/exported/trace/mutex_noapp.go: -------------------------------------------------------------------------------- 1 | //go:build !encore_app 2 | 3 | package trace 4 | 5 | import "sync" 6 | 7 | type mutex struct { 8 | mut sync.Mutex 9 | } 10 | 11 | func mutexLock(m *mutex) { m.mut.Lock() } 12 | 13 | func mutexUnlock(m *mutex) { m.mut.Unlock() } 14 | -------------------------------------------------------------------------------- /runtimes/go/appruntime/exported/trace/version.go: -------------------------------------------------------------------------------- 1 | package trace 2 | 3 | type Version int 4 | 5 | // CurrentVersion is the trace protocol version this package produces traces in. 6 | const CurrentVersion Version = 13 7 | -------------------------------------------------------------------------------- /runtimes/go/appruntime/exported/trace2/mutex_app.go: -------------------------------------------------------------------------------- 1 | //go:build encore_app 2 | 3 | package trace2 4 | 5 | import _ "unsafe" // for go:linkname 6 | 7 | // mutex must exactly match implementation in the runtime. 8 | type mutex struct { 9 | key uintptr 10 | } 11 | 12 | //go:linkname mutexLock runtime.lock 13 | func mutexLock(mut *mutex) 14 | 15 | //go:linkname mutexUnlock runtime.unlock 16 | func mutexUnlock(mut *mutex) 17 | -------------------------------------------------------------------------------- /runtimes/go/appruntime/exported/trace2/mutex_noapp.go: -------------------------------------------------------------------------------- 1 | //go:build !encore_app 2 | 3 | package trace2 4 | 5 | import "sync" 6 | 7 | type mutex struct { 8 | mut sync.Mutex 9 | } 10 | 11 | func mutexLock(m *mutex) { m.mut.Lock() } 12 | 13 | func mutexUnlock(m *mutex) { m.mut.Unlock() } 14 | -------------------------------------------------------------------------------- /runtimes/go/appruntime/exported/trace2/version.go: -------------------------------------------------------------------------------- 1 | package trace2 2 | 3 | type Version int 4 | 5 | // CurrentVersion is the trace protocol version this package produces traces in. 6 | const CurrentVersion Version = 15 7 | -------------------------------------------------------------------------------- /runtimes/go/appruntime/infrasdk/metrics/null_exporter.go: -------------------------------------------------------------------------------- 1 | package metrics 2 | 3 | import ( 4 | "context" 5 | 6 | "encore.dev/appruntime/shared/shutdown" 7 | "encore.dev/metrics" 8 | ) 9 | 10 | type NullMetricsExporter struct{} 11 | 12 | func NewNullMetricsExporter() *NullMetricsExporter { 13 | return &NullMetricsExporter{} 14 | } 15 | 16 | func (e *NullMetricsExporter) Export(ctx context.Context, metrics []metrics.CollectedMetric) error { 17 | return nil 18 | } 19 | 20 | func (e *NullMetricsExporter) Shutdown(p *shutdown.Process) error { return nil } 21 | -------------------------------------------------------------------------------- /runtimes/go/appruntime/infrasdk/metrics/zzz_singleton_internal.go: -------------------------------------------------------------------------------- 1 | //go:build encore_app 2 | 3 | package metrics 4 | 5 | import ( 6 | "encore.dev/appruntime/shared/appconf" 7 | "encore.dev/appruntime/shared/logging" 8 | "encore.dev/appruntime/shared/shutdown" 9 | usermetrics "encore.dev/metrics" 10 | ) 11 | 12 | // This file is named "zzz_singleton_internal.go" so that it is the last file 13 | // in the package, to ensure all other init functions are run before 14 | // we instantiate the manager. 15 | 16 | // publicapigen:drop 17 | var Singleton *Manager 18 | 19 | func init() { 20 | Singleton = NewManager(usermetrics.Singleton, appconf.Static, appconf.Runtime, logging.RootLogger) 21 | shutdown.Singleton.RegisterShutdownHandler(Singleton.Shutdown) 22 | go Singleton.BeginCollection() 23 | } 24 | -------------------------------------------------------------------------------- /runtimes/go/appruntime/infrasdk/secrets/secrets.go: -------------------------------------------------------------------------------- 1 | //go:build encore_app 2 | 3 | package secrets 4 | 5 | import ( 6 | "encore.dev/appruntime/shared/appconf" 7 | "encore.dev/appruntime/shared/encoreenv" 8 | ) 9 | 10 | var singleton = NewManager( 11 | appconf.Runtime, 12 | encoreenv.Get("ENCORE_INFRA_CONFIG_PATH"), 13 | encoreenv.Get("ENCORE_APP_SECRETS"), 14 | ) 15 | 16 | func Load(key string, inService string) string { 17 | return singleton.Load(key, inService) 18 | } 19 | -------------------------------------------------------------------------------- /runtimes/go/appruntime/shared/cloud/clouds.go: -------------------------------------------------------------------------------- 1 | // Package cloud contains some helpers for referring to different cloud implementations 2 | package cloud 3 | 4 | // CloudProvider represents the cloud provider this application is running in. 5 | // 6 | // Additional cloud providers may be added in the future. 7 | type CloudProvider = string 8 | 9 | const ( 10 | AWS CloudProvider = "aws" 11 | GCP CloudProvider = "gcp" 12 | Azure CloudProvider = "azure" 13 | 14 | // Encore is Encore's own cloud offering, and the default provider for new Environments. 15 | Encore CloudProvider = "encore" 16 | 17 | // Local is used when an application is running from the Encore CLI by using either 'encore run' or 'encore test' 18 | Local CloudProvider = "local" 19 | ) 20 | -------------------------------------------------------------------------------- /runtimes/go/appruntime/shared/encoreenv/app.go: -------------------------------------------------------------------------------- 1 | //go:build encore_app 2 | 3 | package encoreenv 4 | 5 | // isApp is true if the current build is an app build. 6 | const isApp = true 7 | -------------------------------------------------------------------------------- /runtimes/go/appruntime/shared/encoreenv/encoreenv.go: -------------------------------------------------------------------------------- 1 | package encoreenv 2 | 3 | import ( 4 | "os" 5 | "strings" 6 | ) 7 | 8 | func Get(env string) string { 9 | return envs[env] 10 | } 11 | 12 | func Set(env, val string) { 13 | envs[env] = val 14 | } 15 | 16 | var envs map[string]string 17 | 18 | func init() { 19 | envs = make(map[string]string) 20 | for _, e := range os.Environ() { 21 | if strings.HasPrefix(e, "ENCORE_") { 22 | key, val, _ := strings.Cut(e, "=") 23 | envs[key] = val 24 | 25 | // Unset ENCORE_ environment variables if we're running 26 | // inside the Encore application. 27 | if isApp { 28 | _ = os.Unsetenv(key) 29 | } 30 | } 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /runtimes/go/appruntime/shared/encoreenv/noapp.go: -------------------------------------------------------------------------------- 1 | //go:build !encore_app 2 | 3 | package encoreenv 4 | 5 | // isApp is true if the current build is an app build. 6 | const isApp = false 7 | -------------------------------------------------------------------------------- /runtimes/go/appruntime/shared/health/singleton.go: -------------------------------------------------------------------------------- 1 | //go:build encore_app 2 | 3 | package health 4 | 5 | // Singleton is the singleton instance of the health check registry 6 | // for a running Encore application. 7 | var Singleton = NewCheckRegistry() 8 | -------------------------------------------------------------------------------- /runtimes/go/appruntime/shared/jsonapi/jsonapi.go: -------------------------------------------------------------------------------- 1 | //go:build encore_app 2 | 3 | package jsonapi 4 | 5 | import ( 6 | jsoniter "github.com/json-iterator/go" 7 | 8 | "encore.dev/appruntime/exported/config" 9 | "encore.dev/appruntime/shared/appconf" 10 | ) 11 | 12 | var Default = jsonAPI(appconf.Runtime) 13 | 14 | func jsonAPI(rt *config.Runtime) jsoniter.API { 15 | indentStep := 2 16 | if rt.EnvType == "production" { 17 | indentStep = 0 18 | } 19 | return jsoniter.Config{ 20 | EscapeHTML: false, 21 | IndentionStep: indentStep, 22 | SortMapKeys: true, 23 | ValidateJsonRawMessage: true, 24 | }.Froze() 25 | } 26 | -------------------------------------------------------------------------------- /runtimes/go/appruntime/shared/jsonapi/jsonapi_nonapp.go: -------------------------------------------------------------------------------- 1 | //go:build !encore_app 2 | 3 | package jsonapi 4 | 5 | // Note: This version of the file exists so we can run `go test` on the runtime module. 6 | // This is because during those test we skip anything flagged as `encore_app` as we are 7 | // not running inside an Encore application and so don't have access to things like 8 | // configuration or compiled overlays. 9 | 10 | import ( 11 | jsoniter "github.com/json-iterator/go" 12 | ) 13 | 14 | var Default = jsonAPI() 15 | 16 | func jsonAPI() jsoniter.API { 17 | return jsoniter.Config{ 18 | EscapeHTML: false, 19 | IndentionStep: 2, 20 | SortMapKeys: true, 21 | ValidateJsonRawMessage: true, 22 | }.Froze() 23 | } 24 | -------------------------------------------------------------------------------- /runtimes/go/appruntime/shared/platform/singleton.go: -------------------------------------------------------------------------------- 1 | //go:build encore_app 2 | 3 | package platform 4 | 5 | import "encore.dev/appruntime/shared/appconf" 6 | 7 | var Singleton = NewClient(appconf.Static, appconf.Runtime) 8 | -------------------------------------------------------------------------------- /runtimes/go/appruntime/shared/reqtrack/singleton.go: -------------------------------------------------------------------------------- 1 | //go:build encore_app 2 | 3 | package reqtrack 4 | 5 | import ( 6 | "encore.dev/appruntime/shared/appconf" 7 | "encore.dev/appruntime/shared/logging" 8 | "encore.dev/appruntime/shared/platform" 9 | "encore.dev/appruntime/shared/traceprovider" 10 | ) 11 | 12 | var Singleton *RequestTracker 13 | 14 | func init() { 15 | var traceFactory traceprovider.Factory 16 | tracingEnabled := appconf.Runtime.TraceEndpoint != "" && len(appconf.Runtime.AuthKeys) > 0 17 | if tracingEnabled { 18 | traceFactory = &traceprovider.DefaultFactory{ 19 | SampleRate: appconf.Runtime.TraceSamplingRate, 20 | } 21 | } 22 | 23 | Singleton = New(logging.RootLogger, platform.Singleton, traceFactory) 24 | } 25 | -------------------------------------------------------------------------------- /runtimes/go/appruntime/shared/shutdown/singleton.go: -------------------------------------------------------------------------------- 1 | //go:build encore_app 2 | 3 | package shutdown 4 | 5 | import ( 6 | "encore.dev/appruntime/shared/health" 7 | 8 | "encore.dev/appruntime/shared/appconf" 9 | "encore.dev/appruntime/shared/logging" 10 | ) 11 | 12 | var Singleton *Tracker 13 | 14 | func init() { 15 | Singleton = NewTracker(appconf.Runtime, logging.RootLogger) 16 | health.Singleton.Register(Singleton) 17 | Singleton.WatchForShutdownSignals() 18 | } 19 | -------------------------------------------------------------------------------- /runtimes/go/appruntime/shared/traceprovider/mock_trace/factory.go: -------------------------------------------------------------------------------- 1 | package mock_trace 2 | 3 | import ( 4 | "encore.dev/appruntime/exported/trace2" 5 | "encore.dev/appruntime/shared/traceprovider" 6 | ) 7 | 8 | func NewMockFactory(log *MockLogger) traceprovider.Factory { 9 | return &mockFactory{log} 10 | } 11 | 12 | type mockFactory struct { 13 | log *MockLogger 14 | } 15 | 16 | func (f *mockFactory) NewLogger() trace2.Logger { 17 | return f.log 18 | } 19 | 20 | func (f *mockFactory) SampleTrace() bool { 21 | return true 22 | } 23 | -------------------------------------------------------------------------------- /runtimes/go/appruntime/shared/traceprovider/traceprovider.go: -------------------------------------------------------------------------------- 1 | package traceprovider 2 | 3 | import ( 4 | "math/rand/v2" 5 | 6 | "encore.dev/appruntime/exported/trace2" 7 | ) 8 | 9 | type Factory interface { 10 | NewLogger() trace2.Logger 11 | SampleTrace() bool 12 | } 13 | 14 | type DefaultFactory struct { 15 | // SampleRate is the rate at which to sample traces, between [0, 1]. 16 | // If nil, 100% of traces are sampled. 17 | SampleRate *float64 18 | } 19 | 20 | func (f *DefaultFactory) NewLogger() trace2.Logger { 21 | return trace2.NewLog() 22 | } 23 | 24 | func (f *DefaultFactory) SampleTrace() bool { 25 | if f.SampleRate == nil { 26 | return true 27 | } else { 28 | sample := rand.Float64() < *f.SampleRate 29 | return sample 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /runtimes/go/beta/errs/details.go: -------------------------------------------------------------------------------- 1 | package errs 2 | 3 | // ErrDetails is a marker interface for telling Encore 4 | // the type is used for reporting error details. 5 | // 6 | // We require a marker method (as opposed to using interface{}) 7 | // to facilitate static analysis and to ensure the type 8 | // can be properly serialized across the network. 9 | type ErrDetails interface { 10 | ErrDetails() // marker method; it need not do anything 11 | } 12 | -------------------------------------------------------------------------------- /runtimes/go/beta/package.go: -------------------------------------------------------------------------------- 1 | // Package beta contains packages which can be used in Encore applications, however their APIs are not stable 2 | // and may change in future releases. 3 | package beta 4 | -------------------------------------------------------------------------------- /runtimes/go/et/auth.go: -------------------------------------------------------------------------------- 1 | package et 2 | 3 | import ( 4 | "fmt" 5 | 6 | "encore.dev/appruntime/apisdk/api" 7 | "encore.dev/beta/auth" 8 | ) 9 | 10 | func (mgr *Manager) OverrideAuthInfo(uid auth.UID, authData any) { 11 | if curr := mgr.rt.Current(); curr.Req != nil { 12 | if err := api.CheckAuthData(uid, authData); err != nil { 13 | panic(fmt.Errorf("override auth info: %v", err)) 14 | } 15 | if rpcData := curr.Req.RPCData; rpcData != nil { 16 | rpcData.UserID = uid 17 | rpcData.AuthData = authData 18 | } else if testData := curr.Req.Test; testData != nil { 19 | testData.UserID = uid 20 | testData.AuthData = authData 21 | } 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /runtimes/go/et/config.go: -------------------------------------------------------------------------------- 1 | //go:build encore_app 2 | 3 | package et 4 | 5 | import ( 6 | "reflect" 7 | 8 | "encore.dev/config" 9 | ) 10 | 11 | // SetCfg changes the value of cfg to newValue within the current test and any subtests. 12 | // Other tests running will not be affected. 13 | // 14 | // It does not support setting slices and panics if given a config value that is a slice. 15 | func SetCfg[T any](cfg config.Value[T], newValue T) { 16 | rt := reflect.TypeOf(newValue) 17 | switch rt.Kind() { 18 | case reflect.Slice: 19 | panic("et.SetCfg does not support setting slices") 20 | case reflect.Array: 21 | panic("et.SetCfg does not support setting arrays") 22 | } 23 | 24 | config.SetValueForTest[T](cfg, newValue) 25 | } 26 | -------------------------------------------------------------------------------- /runtimes/go/et/manager_internal.go: -------------------------------------------------------------------------------- 1 | package et 2 | 3 | import ( 4 | "encore.dev/appruntime/apisdk/api" 5 | "encore.dev/appruntime/exported/config" 6 | "encore.dev/appruntime/shared/reqtrack" 7 | "encore.dev/appruntime/shared/testsupport" 8 | "encore.dev/storage/sqldb" 9 | ) 10 | 11 | //publicapigen:drop 12 | type Manager struct { 13 | static *config.Static 14 | rt *reqtrack.RequestTracker 15 | testMgr *testsupport.Manager 16 | server *api.Server 17 | db *sqldb.Manager 18 | } 19 | 20 | //publicapigen:drop 21 | func NewManager(static *config.Static, rt *reqtrack.RequestTracker, testMgr *testsupport.Manager, server *api.Server, db *sqldb.Manager) *Manager { 22 | return &Manager{static, rt, testMgr, server, db} 23 | } 24 | -------------------------------------------------------------------------------- /runtimes/go/et/package.go: -------------------------------------------------------------------------------- 1 | // Package et stands for Encore Tests and provides a number of functions and tools for writing fully integrated 2 | // test suites for Encore applications. 3 | package et 4 | -------------------------------------------------------------------------------- /runtimes/go/et/pubsub.go: -------------------------------------------------------------------------------- 1 | package et 2 | 3 | import ( 4 | "encore.dev/pubsub" 5 | ) 6 | 7 | // Topic returns a TopicHelper for the given topic. 8 | func Topic[T any](topic *pubsub.Topic[T]) TopicHelpers[T] { 9 | return pubsub.GetTestTopicInstance(topic).(TopicHelpers[T]) 10 | } 11 | 12 | // TopicHelpers provides functions for interacting with the backing topic implementation 13 | // during unit tests. It is designed to help test code that uses the pubsub.Topic 14 | // 15 | // Note all functions on this TopicHelpers are scoped to the current test 16 | // and will only impact and observe state from the current test 17 | type TopicHelpers[T any] interface { 18 | // PublishedMessages returns a slice of all messages published during this test on this topic. 19 | PublishedMessages() []T 20 | } 21 | -------------------------------------------------------------------------------- /runtimes/go/et/singleton_internal.go: -------------------------------------------------------------------------------- 1 | //go:build encore_app 2 | 3 | package et 4 | 5 | import ( 6 | "encore.dev/appruntime/apisdk/api" 7 | "encore.dev/appruntime/shared/appconf" 8 | "encore.dev/appruntime/shared/reqtrack" 9 | "encore.dev/appruntime/shared/testsupport" 10 | "encore.dev/storage/sqldb" 11 | ) 12 | 13 | //publicapigen:drop 14 | var Singleton = NewManager(appconf.Static, reqtrack.Singleton, testsupport.Singleton, api.Singleton, sqldb.Singleton) 15 | -------------------------------------------------------------------------------- /runtimes/go/et/sqldb.go: -------------------------------------------------------------------------------- 1 | package et 2 | 3 | import ( 4 | "context" 5 | 6 | "encore.dev/storage/sqldb" 7 | ) 8 | 9 | func (mgr *Manager) NewTestDatabase(ctx context.Context, name string) (*sqldb.Database, error) { 10 | return mgr.db.NewTestDatabase(ctx, name) 11 | } 12 | -------------------------------------------------------------------------------- /runtimes/go/internal/limiter/noop.go: -------------------------------------------------------------------------------- 1 | package limiter 2 | 3 | import ( 4 | "context" 5 | ) 6 | 7 | // noopLimiter is a Limiter that never limits the request 8 | type noopLimiter struct{} 9 | 10 | var _ Limiter = noopLimiter{} 11 | 12 | func (n noopLimiter) Wait(ctx context.Context) error { 13 | // We return the context error here, so if the context was cancelled, we'll 14 | // behave the same as a rate limiter would. 15 | return ctx.Err() 16 | } 17 | -------------------------------------------------------------------------------- /runtimes/go/metrics/singleton_internal.go: -------------------------------------------------------------------------------- 1 | //go:build encore_app 2 | 3 | package metrics 4 | 5 | import ( 6 | "encore.dev/appruntime/shared/appconf" 7 | "encore.dev/appruntime/shared/reqtrack" 8 | ) 9 | 10 | var Singleton = NewRegistry(reqtrack.Singleton, len(appconf.Static.BundledServices)) 11 | -------------------------------------------------------------------------------- /runtimes/go/metrics/units.go: -------------------------------------------------------------------------------- 1 | package metrics 2 | 3 | // TODO Document 4 | 5 | type Value interface { 6 | uint64 | int64 | float64 7 | } 8 | -------------------------------------------------------------------------------- /runtimes/go/middleware/middleware_internal.go: -------------------------------------------------------------------------------- 1 | package middleware 2 | 3 | import ( 4 | "context" 5 | "sync" 6 | 7 | encore "encore.dev" 8 | ) 9 | 10 | func newReqCache(fn func() *encore.Request) *reqCache { 11 | return &reqCache{load: fn} 12 | } 13 | 14 | type reqCache struct { 15 | loadOnce sync.Once 16 | load func() *encore.Request 17 | req *encore.Request 18 | } 19 | 20 | func (r *reqCache) Get() *encore.Request { 21 | r.loadOnce.Do(func() { r.req = r.load() }) 22 | return r.req 23 | } 24 | 25 | func NewLazyRequest(ctx context.Context, fn func() *encore.Request) Request { 26 | return Request{ctx: ctx, cache: newReqCache(fn)} 27 | } 28 | -------------------------------------------------------------------------------- /runtimes/go/pubsub/internal/types/push_registry.go: -------------------------------------------------------------------------------- 1 | package types 2 | 3 | import "net/http" 4 | 5 | type SubscriptionID string 6 | 7 | type PushEndpointHandler func(req *http.Request) error 8 | 9 | type PushEndpointRegistry interface { 10 | RegisterPushSubscriptionHandler(id SubscriptionID, handler http.HandlerFunc) 11 | } 12 | -------------------------------------------------------------------------------- /runtimes/go/pubsub/package.go: -------------------------------------------------------------------------------- 1 | // Package pubsub provides Encore applications with the ability 2 | // to create Pub/Sub Topics and multiple Subscriptions on those 3 | // topics in a cloud-agnostic manner. 4 | // 5 | // For more information see https://encore.dev/docs/develop/pubsub 6 | package pubsub 7 | -------------------------------------------------------------------------------- /runtimes/go/pubsub/provider_aws.go: -------------------------------------------------------------------------------- 1 | //go:build !encore_no_aws 2 | 3 | package pubsub 4 | 5 | import "encore.dev/pubsub/internal/aws" 6 | 7 | func init() { 8 | registerProvider(func(mgr *Manager) provider { 9 | return aws.NewManager(mgr.ctxs) 10 | }) 11 | } 12 | -------------------------------------------------------------------------------- /runtimes/go/pubsub/provider_azure.go: -------------------------------------------------------------------------------- 1 | //go:build !encore_no_azure 2 | 3 | package pubsub 4 | 5 | import "encore.dev/pubsub/internal/azure" 6 | 7 | func init() { 8 | registerProvider(func(mgr *Manager) provider { 9 | return azure.NewManager(mgr.ctxs) 10 | }) 11 | } 12 | -------------------------------------------------------------------------------- /runtimes/go/pubsub/provider_encorecloud.go: -------------------------------------------------------------------------------- 1 | //go:build !encore_no_encorecloud 2 | 3 | package pubsub 4 | 5 | import ( 6 | "encore.dev/pubsub/internal/encorecloud" 7 | ) 8 | 9 | func init() { 10 | registerProvider(func(mgr *Manager) provider { 11 | return encorecloud.NewManager(mgr.ctxs, mgr.runtime, mgr) 12 | }) 13 | } 14 | -------------------------------------------------------------------------------- /runtimes/go/pubsub/provider_gcp.go: -------------------------------------------------------------------------------- 1 | //go:build !encore_no_gcp 2 | 3 | package pubsub 4 | 5 | import ( 6 | "encore.dev/pubsub/internal/gcp" 7 | ) 8 | 9 | func init() { 10 | registerProvider(func(mgr *Manager) provider { 11 | return gcp.NewManager(mgr.ctxs, mgr.static, mgr.runtime, mgr) 12 | }) 13 | } 14 | -------------------------------------------------------------------------------- /runtimes/go/pubsub/provider_nsq.go: -------------------------------------------------------------------------------- 1 | //go:build !encore_no_local 2 | 3 | package pubsub 4 | 5 | import ( 6 | "encore.dev/pubsub/internal/nsq" 7 | ) 8 | 9 | func init() { 10 | registerProvider(func(mgr *Manager) provider { 11 | return nsq.NewManager(mgr.ctxs, mgr.rt) 12 | }) 13 | } 14 | -------------------------------------------------------------------------------- /runtimes/go/pubsub/test_internal.go: -------------------------------------------------------------------------------- 1 | package pubsub 2 | 3 | import ( 4 | "encore.dev/pubsub/internal/test" 5 | ) 6 | 7 | // GetTestTopicInstance is an internal API for Encore. This function should 8 | // never be directly called as it is considered an unstable API and Encore 9 | // can change it at any time 10 | func GetTestTopicInstance[T any](topic *Topic[T]) any { 11 | testTopic, ok := topic.topic.(*test.TestTopic[T]) 12 | if !ok { 13 | panic("testTopic not called with a test topic") 14 | } 15 | 16 | req := topic.mgr.rt.Current().Req 17 | if req == nil || req.Test == nil { 18 | panic("testTopic called outside of test") 19 | } 20 | return testTopic.TestInstance(req.Test.Current) 21 | } 22 | -------------------------------------------------------------------------------- /runtimes/go/storage/cache/pkgfn.go: -------------------------------------------------------------------------------- 1 | //go:build encore_app 2 | 3 | package cache 4 | 5 | // NewCluster declares a new cache cluster. 6 | // 7 | // See https://encore.dev/docs/develop/caching for more information. 8 | func NewCluster(name string, cfg ClusterConfig) *Cluster { 9 | return &Cluster{ 10 | cfg: cfg, 11 | mgr: Singleton, 12 | cl: Singleton.getClient(name), 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /runtimes/go/storage/cache/zzz_singleton_internal.go: -------------------------------------------------------------------------------- 1 | //go:build encore_app 2 | 3 | package cache 4 | 5 | import ( 6 | "encore.dev/appruntime/shared/appconf" 7 | "encore.dev/appruntime/shared/jsonapi" 8 | "encore.dev/appruntime/shared/reqtrack" 9 | "encore.dev/appruntime/shared/shutdown" 10 | "encore.dev/appruntime/shared/testsupport" 11 | ) 12 | 13 | // Initialize the singleton instance. 14 | // NOTE: This file is named zzz_singleton_internal.go so that 15 | // the init function is initialized after all the providers 16 | // have been registered. 17 | 18 | //publicapigen:drop 19 | var Singleton *Manager 20 | 21 | func init() { 22 | Singleton = NewManager(appconf.Static, appconf.Runtime, reqtrack.Singleton, testsupport.Singleton, jsonapi.Default) 23 | shutdown.Singleton.RegisterShutdownHandler(Singleton.Shutdown) 24 | } 25 | -------------------------------------------------------------------------------- /runtimes/go/storage/objects/objects.go: -------------------------------------------------------------------------------- 1 | //go:build encore_app 2 | 3 | package objects 4 | 5 | // NewBucket declares a new object storage bucket. 6 | // 7 | // See https://encore.dev/docs/primitives/object-storage for more information. 8 | func NewBucket(name string, cfg BucketConfig) *Bucket { 9 | return newBucket(Singleton, name) 10 | } 11 | 12 | // constStr is a string that can only be provided as a constant. 13 | // 14 | //publicapigen:keep 15 | type constStr string 16 | 17 | // Named returns a database object connected to the database with the given name. 18 | // 19 | // The name must be a string literal constant, to facilitate static analysis. 20 | func Named(name constStr) *Bucket { 21 | return newBucket(Singleton, string(name)) 22 | } 23 | -------------------------------------------------------------------------------- /runtimes/go/storage/objects/package.go: -------------------------------------------------------------------------------- 1 | // Package objects provides Encore applications with the ability 2 | // to create and use Object Storage buckets (like for example Amazon S3) 3 | // for storing and retrieving files in a cloud-agnostic manner. 4 | // 5 | // For more information see https://encore.dev/docs/primitives/object-storage 6 | package objects 7 | -------------------------------------------------------------------------------- /runtimes/go/storage/objects/provider_gcs.go: -------------------------------------------------------------------------------- 1 | //go:build !encore_no_gcp || !encore_no_encorecloud || !encore_no_local 2 | 3 | package objects 4 | 5 | import ( 6 | "context" 7 | 8 | "encore.dev/appruntime/exported/config" 9 | "encore.dev/storage/objects/internal/providers/gcs" 10 | ) 11 | 12 | func init() { 13 | registerProvider(func(ctx context.Context, runtimeCfg *config.Runtime) provider { 14 | return gcs.NewManager(ctx, runtimeCfg) 15 | }) 16 | } 17 | -------------------------------------------------------------------------------- /runtimes/go/storage/objects/provider_s3.go: -------------------------------------------------------------------------------- 1 | //go:build !encore_no_aws 2 | 3 | package objects 4 | 5 | import ( 6 | "context" 7 | 8 | "encore.dev/appruntime/exported/config" 9 | "encore.dev/storage/objects/internal/providers/s3" 10 | ) 11 | 12 | func init() { 13 | registerProvider(func(ctx context.Context, runtimeCfg *config.Runtime) provider { 14 | return s3.NewManager(ctx, runtimeCfg) 15 | }) 16 | } 17 | -------------------------------------------------------------------------------- /runtimes/go/storage/objects/registry_internal.go: -------------------------------------------------------------------------------- 1 | package objects 2 | 3 | import ( 4 | "context" 5 | 6 | "encore.dev/appruntime/exported/config" 7 | "encore.dev/storage/objects/internal/types" 8 | ) 9 | 10 | type provider interface { 11 | ProviderName() string 12 | Matches(providerCfg *config.BucketProvider) bool 13 | NewBucket(providerCfg *config.BucketProvider, runtimeCfg *config.Bucket) types.BucketImpl 14 | } 15 | 16 | var providerRegistry []func(context.Context, *config.Runtime) provider 17 | 18 | func registerProvider(p func(context.Context, *config.Runtime) provider) { 19 | providerRegistry = append(providerRegistry, p) 20 | } 21 | -------------------------------------------------------------------------------- /runtimes/go/storage/sqldb/errors_test.go: -------------------------------------------------------------------------------- 1 | package sqldb 2 | 3 | import ( 4 | "errors" 5 | "fmt" 6 | "io" 7 | "testing" 8 | 9 | "encore.dev/storage/sqldb/sqlerr" 10 | ) 11 | 12 | func TestErrCode(t *testing.T) { 13 | tests := []struct { 14 | err error 15 | want sqlerr.Code 16 | }{ 17 | {err: nil, want: sqlerr.Other}, 18 | {err: io.EOF, want: sqlerr.Other}, 19 | {err: errors.New("some error"), want: sqlerr.Other}, 20 | {err: &Error{Code: sqlerr.UniqueViolation}, want: sqlerr.UniqueViolation}, 21 | {err: fmt.Errorf("wrapped: %w", &Error{Code: sqlerr.UniqueViolation}), want: sqlerr.UniqueViolation}, 22 | } 23 | for _, tt := range tests { 24 | if got := ErrCode(tt.err); got != tt.want { 25 | t.Errorf("ErrCode(%v) = %v, want %v", tt.err, got, tt.want) 26 | } 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /runtimes/go/storage/sqldb/zzz_singleton_internal.go: -------------------------------------------------------------------------------- 1 | //go:build encore_app 2 | 3 | package sqldb 4 | 5 | import ( 6 | "encore.dev/appruntime/shared/appconf" 7 | "encore.dev/appruntime/shared/reqtrack" 8 | "encore.dev/appruntime/shared/shutdown" 9 | "encore.dev/appruntime/shared/testsupport" 10 | ) 11 | 12 | // Initialize the singleton instance. 13 | // NOTE: This file is named zzz_singleton_internal.go so that 14 | // the init function is initialized after all the providers 15 | // have been registered. 16 | 17 | //publicapigen:drop 18 | var Singleton *Manager 19 | 20 | func init() { 21 | Singleton = NewManager(appconf.Runtime, reqtrack.Singleton, testsupport.Singleton) 22 | shutdown.Singleton.RegisterShutdownHandler(Singleton.Shutdown) 23 | } 24 | -------------------------------------------------------------------------------- /runtimes/js/.gitignore: -------------------------------------------------------------------------------- 1 | encore-runtime.node* 2 | node_modules 3 | dist 4 | .turbo 5 | -------------------------------------------------------------------------------- /runtimes/js/build.rs: -------------------------------------------------------------------------------- 1 | extern crate napi_build; 2 | 3 | fn main() -> std::io::Result<()> { 4 | napi_build::setup(); 5 | Ok(()) 6 | } 7 | -------------------------------------------------------------------------------- /runtimes/js/encore.dev/README.md: -------------------------------------------------------------------------------- 1 | # Encore JavaScript/TypeScript SDK 2 | 3 | This package contains the Encore JavaScript/TypeScript SDK, it is intended for you to use in your applications to develop 4 | against the Encore API. 5 | -------------------------------------------------------------------------------- /runtimes/js/encore.dev/auth/mod.ts: -------------------------------------------------------------------------------- 1 | export type AuthHandler< 2 | Params extends object, 3 | AuthData extends { userID: string }, 4 | > = ((params: Params) => Promise) & AuthHandlerBrand; 5 | 6 | export type AuthHandlerBrand = { readonly __authHandlerBrand: unique symbol }; 7 | 8 | export function authHandler< 9 | Params extends object, 10 | AuthData extends { userID: string }, 11 | >( 12 | fn: (params: Params) => Promise, 13 | ): AuthHandler { 14 | return fn as any; 15 | } 16 | -------------------------------------------------------------------------------- /runtimes/js/encore.dev/config/mod.ts: -------------------------------------------------------------------------------- 1 | export type { Secret, AnySecret } from "./secrets"; 2 | export { secret } from "./secrets"; 3 | -------------------------------------------------------------------------------- /runtimes/js/encore.dev/cron/mod.ts: -------------------------------------------------------------------------------- 1 | /* eslint-disable */ 2 | 3 | import { DurationString } from "../internal/types/mod"; 4 | 5 | export class CronJob { 6 | public readonly name: string; 7 | public readonly cfg: CronJobConfig; 8 | constructor(name: string, cfg: CronJobConfig) { 9 | this.name = name; 10 | this.cfg = cfg; 11 | } 12 | } 13 | 14 | export type CronJobConfig = { 15 | endpoint: () => Promise; 16 | title?: string; 17 | } & ({ every: DurationString } | { schedule: string }); 18 | -------------------------------------------------------------------------------- /runtimes/js/encore.dev/internal/auth/mod.ts: -------------------------------------------------------------------------------- 1 | import {getCurrentRequest} from "../reqtrack/mod"; 2 | 3 | export function getAuthData(): T | null { 4 | const authData = getCurrentRequest()?.getAuthData(); 5 | if (!authData) { 6 | return null; 7 | } else { 8 | return authData as T; 9 | } 10 | } 11 | -------------------------------------------------------------------------------- /runtimes/js/encore.dev/internal/codegen/api.ts: -------------------------------------------------------------------------------- 1 | export { apiCall, streamIn, streamOut, streamInOut } from "../api/mod"; 2 | -------------------------------------------------------------------------------- /runtimes/js/encore.dev/internal/codegen/appinit.ts: -------------------------------------------------------------------------------- 1 | export {registerGateways, registerHandlers, registerTestHandler, run, type Handler} from "../appinit/mod"; -------------------------------------------------------------------------------- /runtimes/js/encore.dev/internal/codegen/auth.ts: -------------------------------------------------------------------------------- 1 | export {getAuthData} from "../auth/mod"; -------------------------------------------------------------------------------- /runtimes/js/encore.dev/internal/reqtrack/mod.ts: -------------------------------------------------------------------------------- 1 | import * as runtime from "../runtime/mod"; 2 | import { AsyncLocalStorage } from "node:async_hooks"; 3 | 4 | const asyncLocalStorage = new AsyncLocalStorage(); 5 | 6 | export function setCurrentRequest(req: runtime.Request) { 7 | asyncLocalStorage.enterWith(req); 8 | } 9 | 10 | export function getCurrentRequest(): runtime.Request | null { 11 | return (asyncLocalStorage.getStore() as runtime.Request) ?? null; 12 | } 13 | -------------------------------------------------------------------------------- /runtimes/js/encore.dev/internal/runtime/.gitignore: -------------------------------------------------------------------------------- 1 | /napi 2 | -------------------------------------------------------------------------------- /runtimes/js/encore.dev/internal/runtime/.npmignore: -------------------------------------------------------------------------------- 1 | # Intentionally left blank, because we want the napi directory 2 | # to be included in packages, but we don't want it committed to the repository. 3 | # If this file does not exist then the npm packaging code will use the .gitignore file instead. 4 | -------------------------------------------------------------------------------- /runtimes/js/encore.dev/internal/runtime/mod.ts: -------------------------------------------------------------------------------- 1 | import { Runtime } from "./napi/napi.cjs"; 2 | 3 | export * from "./napi/napi.cjs"; 4 | 5 | const testMode = process.env.NODE_ENV === "test"; 6 | 7 | export const RT = new Runtime({ 8 | testMode, 9 | }); 10 | -------------------------------------------------------------------------------- /runtimes/js/encore.dev/internal/types/mod.ts: -------------------------------------------------------------------------------- 1 | type durationUnit = "ns" | "µs" | "ms" | "s" | "m" | "h"; 2 | type durationComponent = `${number}${durationUnit}`; 3 | 4 | /** 5 | * A duration is a string representing a length of time. 6 | */ 7 | export type DurationString = 8 | | durationComponent 9 | | `${durationComponent}${durationComponent}` 10 | | `${durationComponent} ${durationComponent}`; 11 | -------------------------------------------------------------------------------- /runtimes/js/encore.dev/internal/utils/constraints.ts: -------------------------------------------------------------------------------- 1 | type UnUnion = T extends S ? ([S] extends [T] ? T : never) : never; 2 | type NotUnion = UnUnion; 3 | 4 | /** 5 | * Literal requires that the given type is a literal value, and not a union of literals. 6 | */ 7 | export type Literal = OfType extends Value 8 | ? never // But the type must not extend the value (i.e. the two must not be equal) 9 | : NotUnion; // And the type must not be a union of literals 10 | 11 | /** Value must be a single string literal */ 12 | export type StringLiteral = Literal; 13 | -------------------------------------------------------------------------------- /runtimes/js/encore.dev/mod.ts: -------------------------------------------------------------------------------- 1 | export { appMeta } from "./app_meta"; 2 | export type { 3 | AppMeta, 4 | BuildMeta, 5 | CloudProvider, 6 | DeployMeta, 7 | EnvironmentMeta, 8 | EnvironmentType 9 | } from "./app_meta"; 10 | 11 | export { currentRequest } from "./req_meta"; 12 | export type { 13 | APICallMeta, 14 | APIDesc, 15 | Method, 16 | PubSubMessageMeta, 17 | RequestMeta, 18 | TraceData 19 | } from "./req_meta"; 20 | -------------------------------------------------------------------------------- /runtimes/js/encore.dev/service/mod.ts: -------------------------------------------------------------------------------- 1 | import { Middleware } from "../api/mod"; 2 | 3 | /** 4 | * Defines an Encore backend service. 5 | * 6 | * Use this class to define a new backend service with the given name. 7 | * The scope of the service is its containing directory, and all subdirectories. 8 | * 9 | * It must be called from files named `encore.service.ts`, to enable Encore to 10 | * efficiently identify possible service definitions. 11 | */ 12 | export class Service { 13 | public readonly name: string; 14 | public readonly cfg: ServiceConfig; 15 | 16 | constructor(name: string, cfg?: ServiceConfig) { 17 | this.name = name; 18 | this.cfg = cfg ?? {}; 19 | } 20 | } 21 | 22 | export interface ServiceConfig { 23 | middlewares?: Middleware[]; 24 | } 25 | -------------------------------------------------------------------------------- /runtimes/js/encore.dev/storage/objects/mod.ts: -------------------------------------------------------------------------------- 1 | export { Bucket } from "./bucket"; 2 | export type { BucketConfig, ObjectAttrs, UploadOptions } from "./bucket"; 3 | export { ObjectsError, ObjectNotFound, PreconditionFailed } from "./error"; 4 | export type { BucketPerms, Uploader, SignedUploader, Downloader, SignedDownloader, Attrser, Lister, ReadWriter, PublicUrler } from "./refs"; 5 | -------------------------------------------------------------------------------- /runtimes/js/encore.dev/storage/sqldb/mod.ts: -------------------------------------------------------------------------------- 1 | export { SQLDatabase } from "./database"; 2 | export type { SQLDatabaseConfig, Row as ResultRow } from "./database"; 3 | -------------------------------------------------------------------------------- /runtimes/js/src/lib.rs: -------------------------------------------------------------------------------- 1 | #![deny(clippy::all)] 2 | 3 | pub mod api; 4 | mod cookies; 5 | mod error; 6 | mod gateway; 7 | mod headers; 8 | mod log; 9 | mod meta; 10 | mod napi_util; 11 | pub mod objects; 12 | pub mod pubsub; 13 | mod pvalue; 14 | mod raw_api; 15 | mod request_meta; 16 | pub mod runtime; 17 | mod secret; 18 | mod sqldb; 19 | mod stream; 20 | mod threadsafe_function; 21 | mod websocket_api; 22 | -------------------------------------------------------------------------------- /runtimes/js/src/stream/mod.rs: -------------------------------------------------------------------------------- 1 | pub mod read; 2 | pub mod write; 3 | -------------------------------------------------------------------------------- /rustfmt.toml: -------------------------------------------------------------------------------- 1 | tab_spaces = 4 2 | edition = "2021" 3 | -------------------------------------------------------------------------------- /supervisor/build.rs: -------------------------------------------------------------------------------- 1 | use std::io::Result; 2 | 3 | fn main() -> Result<()> { 4 | prost_build::compile_protos( 5 | &[ 6 | "../proto/encore/runtime/v1/runtime.proto", 7 | "../proto/encore/parser/meta/v1/meta.proto", 8 | ], 9 | &["../proto/"], 10 | )?; 11 | Ok(()) 12 | } 13 | -------------------------------------------------------------------------------- /supervisor/src/lib.rs: -------------------------------------------------------------------------------- 1 | pub mod config; 2 | pub mod proxy; 3 | pub mod supervisor; 4 | -------------------------------------------------------------------------------- /tools/semgrep-rules/README.md: -------------------------------------------------------------------------------- 1 | # SemGrep Rules 2 | 3 | This directory contains a set of Semgrep rules we run against Encore's source code. You can find more information about the syntax of rules in the [Semgrep documentation](https://semgrep.dev/docs/writing-rules/overview/). 4 | -------------------------------------------------------------------------------- /tools/semgrep-rules/semgrep-go/badexponentiation.yml: -------------------------------------------------------------------------------- 1 | rules: 2 | - id: bad-exponentiation 3 | patterns: 4 | - pattern-either: 5 | - pattern: 10 ^ $X 6 | - pattern: 2 ^ $X 7 | message: "Caret (^) is not exponentiation" 8 | languages: [go] 9 | severity: ERROR 10 | -------------------------------------------------------------------------------- /tools/semgrep-rules/semgrep-go/badnilguard.yml: -------------------------------------------------------------------------------- 1 | rules: 2 | - id: bad-nil-guard 3 | patterns: 4 | - pattern-either: 5 | - pattern: $X == nil && <... $X.$F ...> 6 | - pattern: $X != nil || <... $X.$F ...> 7 | - pattern: <... $X.$F ...> && $X != nil 8 | - pattern: <... $X.$F ...> || $X == nil 9 | - pattern: <... $X.$F ...> && $X == nil 10 | - pattern: <... $X.$F ...> || $X != nil 11 | message: "Bad nil guard" 12 | languages: [go] 13 | severity: ERROR 14 | -------------------------------------------------------------------------------- /tools/semgrep-rules/semgrep-go/contextTODO.yml: -------------------------------------------------------------------------------- 1 | rules: 2 | - id: context-todo 3 | patterns: 4 | - pattern-either: 5 | - pattern: | 6 | context.TODO() 7 | message: "Consider to use well-defined context" 8 | languages: [go] 9 | severity: WARNING 10 | -------------------------------------------------------------------------------- /tools/semgrep-rules/semgrep-go/ctx-time.yml: -------------------------------------------------------------------------------- 1 | rules: 2 | - id: ctx-done-and-timers 3 | patterns: 4 | - pattern-either: 5 | - pattern: | 6 | select { 7 | case <-ctx.Done(): 8 | $BODY 9 | case <-time.After(...): 10 | $BODY 11 | } 12 | - pattern: | 13 | $T := time.NewTicker(...) 14 | ... 15 | select { 16 | case <-ctx.Done(): 17 | $BODY 18 | case <-$T.C: 19 | $BODY 20 | } 21 | message: "ctx.Done() and time.After/time.NewTicker" 22 | languages: [go] 23 | severity: ERROR 24 | 25 | -------------------------------------------------------------------------------- /tools/semgrep-rules/semgrep-go/errclosed.yml: -------------------------------------------------------------------------------- 1 | rules: 2 | - id: use-net-errclosed 3 | patterns: 4 | - pattern: strings.Contains($ERR.Error(), $X) 5 | - metavariable-regex: 6 | metavariable: $X 7 | regex: '".*closed network connection.*"' 8 | message: "Use errors.Is($ERR, net.ErrClosed) instead" 9 | languages: [go] 10 | severity: ERROR 11 | -------------------------------------------------------------------------------- /tools/semgrep-rules/semgrep-go/errtodo.yml: -------------------------------------------------------------------------------- 1 | rules: 2 | - id: err-todo 3 | patterns: 4 | - pattern-either: 5 | - patterns: 6 | - pattern-inside: 7 | if err != nil { 8 | ... 9 | } 10 | - pattern-regex: // ?(TODO|FIXME).* 11 | 12 | - pattern-either: 13 | - patterns: 14 | - pattern-inside: | 15 | if ... ; err != nil { 16 | ... 17 | } 18 | - pattern-regex: // ?(TODO|FIXME).* 19 | 20 | message: "TODO in error handling code" 21 | languages: [go] 22 | severity: ERROR 23 | -------------------------------------------------------------------------------- /tools/semgrep-rules/semgrep-go/gofuzz.yml: -------------------------------------------------------------------------------- 1 | rules: 2 | - id: go-fuzz-to-native-fuzzing 3 | patterns: 4 | - pattern: func Fuzz($DATA []byte) int { $...BODY } 5 | fix: | 6 | // remove gofuzz build tag 7 | // rename file to _test.go 8 | // convert corpus with file2fuzz 9 | func FuzzData(f *testing.F) { 10 | f.Fuzz(func(t *testing.T, $DATA []byte) { 11 | func() int { 12 | $...BODY 13 | }() 14 | }) 15 | } 16 | message: "old-style go-fuzz fuzz function found" 17 | languages: [go] 18 | severity: ERROR 19 | -------------------------------------------------------------------------------- /tools/semgrep-rules/semgrep-go/hmac-bytes.yml: -------------------------------------------------------------------------------- 1 | rules: 2 | - id: use-hmac-equal 3 | patterns: 4 | - pattern-either: 5 | - pattern: | 6 | $MAC = hmac.New(...) 7 | ... 8 | $H = $MAC.Sum(...) 9 | ... 10 | bytes.Equal($H, ...) 11 | - pattern: | 12 | $MAC = hmac.New(...) 13 | ... 14 | $H = $MAC.Sum(...) 15 | ... 16 | bytes.Equal(..., $H) 17 | message: "Comparing a MAC with bytes.Equal()" 18 | languages: [go] 19 | severity: ERROR 20 | -------------------------------------------------------------------------------- /tools/semgrep-rules/semgrep-go/hmac-hash.yml: -------------------------------------------------------------------------------- 1 | rules: 2 | - id: hmac-needs-new 3 | patterns: 4 | - pattern-either: 5 | - pattern: | 6 | $H := $HASH.New() 7 | ... 8 | $FUNC := func() hash.Hash { return $H } 9 | ... 10 | hmac.New($FUNC, ...) 11 | - pattern: | 12 | $H := $HASH.New() 13 | ... 14 | hmac.New(func() hash.Hash { return $H }, ...) 15 | 16 | - pattern: | 17 | hmac.New(func() hash.Hash { return ( $H : hash.Hash) }, ...) 18 | 19 | message: "calling hmac.New with unchanging hash.New" 20 | languages: [go] 21 | severity: ERROR 22 | -------------------------------------------------------------------------------- /tools/semgrep-rules/semgrep-go/http-ctx-goroutine.yml: -------------------------------------------------------------------------------- 1 | 2 | rules: 3 | - id: http-request-go-context 4 | patterns: 5 | - pattern-either: 6 | - pattern: | 7 | $CTX := ($R : *http.Request).Context() 8 | ... 9 | go $F($CTX, ...) 10 | - pattern: | 11 | go $F(($R : *http.Request).Context(), ...) 12 | message: "passing an http-request scoped Context to a goroutine" 13 | languages: [go] 14 | severity: ERROR 15 | -------------------------------------------------------------------------------- /tools/semgrep-rules/semgrep-go/ioutil-discard.yml: -------------------------------------------------------------------------------- 1 | rules: 2 | - id: deprecated-ioutil-discard 3 | pattern: ioutil.Discard 4 | fix: io.Discard 5 | message: ioutil.Discard is deprecated 6 | languages: [go] 7 | severity: ERROR 8 | -------------------------------------------------------------------------------- /tools/semgrep-rules/semgrep-go/ioutil-nop-closer.yml: -------------------------------------------------------------------------------- 1 | rules: 2 | - id: deprecated-ioutil-nopcloser 3 | pattern: ioutil.NopCloser($R) 4 | fix: io.NopCloser($R) 5 | message: ioutil.NopCloser is deprecated 6 | languages: [go] 7 | severity: ERROR 8 | -------------------------------------------------------------------------------- /tools/semgrep-rules/semgrep-go/ioutil-readall.yml: -------------------------------------------------------------------------------- 1 | rules: 2 | - id: deprecated-ioutil-readall 3 | pattern: ioutil.ReadAll($R) 4 | fix: io.ReadAll($R) 5 | message: ioutil.ReadAll is deprecated 6 | languages: [go] 7 | severity: ERROR 8 | -------------------------------------------------------------------------------- /tools/semgrep-rules/semgrep-go/ioutil-readdir.yml: -------------------------------------------------------------------------------- 1 | 2 | rules: 3 | - id: deprecated-ioutil-readdir 4 | pattern: ioutil.ReadDir($D) 5 | message: ioutil.ReadDir is deprecated 6 | languages: [go] 7 | severity: ERROR 8 | -------------------------------------------------------------------------------- /tools/semgrep-rules/semgrep-go/ioutil-readfile.yml: -------------------------------------------------------------------------------- 1 | rules: 2 | - id: deprecated-ioutil-readfile 3 | pattern: ioutil.ReadFile($F) 4 | fix: os.ReadFile($F) 5 | message: ioutil.ReadFile is deprecated 6 | languages: [go] 7 | severity: ERROR 8 | -------------------------------------------------------------------------------- /tools/semgrep-rules/semgrep-go/ioutil-tmpdir.yml: -------------------------------------------------------------------------------- 1 | rules: 2 | - id: deprecated-ioutil-tempdir 3 | pattern: ioutil.TempDir($D, $P) 4 | fix: os.MkdirTemp($D, $P) 5 | message: ioutil.TempDir is deprecated 6 | languages: [go] 7 | severity: ERROR 8 | -------------------------------------------------------------------------------- /tools/semgrep-rules/semgrep-go/ioutil-tmpfile.yml: -------------------------------------------------------------------------------- 1 | rules: 2 | - id: deprecated-ioutil-tempfile 3 | pattern: ioutil.TempFile($D, $P) 4 | fix: os.CreateTemp($D, $P) 5 | message: ioutil.TempFile is deprecated 6 | languages: [go] 7 | severity: ERROR 8 | -------------------------------------------------------------------------------- /tools/semgrep-rules/semgrep-go/ioutil-writefile.yml: -------------------------------------------------------------------------------- 1 | rules: 2 | - id: deprecated-ioutil-writefile 3 | pattern: ioutil.WriteFile($F, $D, $P) 4 | fix: os.WriteFile($F, $D, $P) 5 | message: ioutil.WriteFile is deprecated 6 | languages: [go] 7 | severity: ERROR 8 | -------------------------------------------------------------------------------- /tools/semgrep-rules/semgrep-go/joinpath.yml: -------------------------------------------------------------------------------- 1 | rules: 2 | - id: use-strings-join-path 3 | patterns: 4 | - pattern-either: 5 | - pattern: strings.Join(..., "/") 6 | - pattern: strings.Join(..., "\\") 7 | - pattern: strings.Join(..., `\`) 8 | - pattern: strings.Join(..., os.PathSeparator) 9 | message: "did you want path.Join() or filepath.Join()?" 10 | languages: [go] 11 | severity: ERROR 12 | -------------------------------------------------------------------------------- /tools/semgrep-rules/semgrep-go/mail-address.yml: -------------------------------------------------------------------------------- 1 | rules: 2 | - id: sprintf-mail-address 3 | pattern-either: 4 | - pattern: fmt.Sprintf(`"%s" <%s>`, $NAME, $EMAIL) 5 | - pattern: fmt.Sprintf(`"%s"<%s>`, $NAME, $EMAIL) 6 | - pattern: fmt.Sprintf("\"%s\"<%s>", $NAME, $EMAIL) 7 | - pattern: fmt.Sprintf("\"%s\" <%s>", $NAME, $EMAIL) 8 | - pattern: fmt.Sprintf("%s<%s>", $NAME, $EMAIL) 9 | message: "use net/mail Address.String() instead of fmt.Sprintf()" 10 | fix: "(&mail.Address{Name:$NAME, Address:$EMAIL}).String()" 11 | languages: [go] 12 | severity: ERROR 13 | -------------------------------------------------------------------------------- /tools/semgrep-rules/semgrep-go/marshaljson.yml: -------------------------------------------------------------------------------- 1 | rules: 2 | - id: marshal-json-misspell 3 | pattern-either: 4 | - patterns: 5 | - pattern-regex: (?i)func \((.+)\) marshal[l]?json\((.*)\) 6 | - pattern-not-regex: func \(.+\) MarshalJSON\( 7 | fix: func ($1) MarshalJSON($2) 8 | message: | 9 | Misspelling of MarshalJSON. 10 | languages: [go] 11 | severity: ERROR 12 | -------------------------------------------------------------------------------- /tools/semgrep-rules/semgrep-go/marshalyaml.yml: -------------------------------------------------------------------------------- 1 | rules: 2 | - id: marshal-yaml-misspell 3 | pattern-either: 4 | - patterns: 5 | - pattern-regex: (?i)func \((.+)\) marshal[l]?yaml\((.*)\) 6 | - pattern-not-regex: func \(.+\) MarshalYAML\( 7 | fix: func ($1) MarshalYAML($2) 8 | message: | 9 | Misspelling of MarshalYAML. 10 | languages: [go] 11 | severity: ERROR 12 | -------------------------------------------------------------------------------- /tools/semgrep-rules/semgrep-go/nilerr.yml: -------------------------------------------------------------------------------- 1 | rules: 2 | - id: return-nil-err 3 | patterns: 4 | - pattern-either: 5 | - pattern: | 6 | if err == nil { 7 | return err 8 | } 9 | - pattern: | 10 | if err == nil { 11 | return ..., err 12 | } 13 | message: "return nil err instead of nil value" 14 | languages: [go] 15 | severity: ERROR 16 | -------------------------------------------------------------------------------- /tools/semgrep-rules/semgrep-go/nrtxn.yml: -------------------------------------------------------------------------------- 1 | rules: 2 | - id: newrelic-start-without-end 3 | patterns: 4 | - pattern-not-inside: | 5 | $TXN := $NR.StartTransaction($N) 6 | ... 7 | defer $TXN.End() 8 | - pattern-not-inside: | 9 | $TXN := $NR.StartTransaction($N) 10 | ... 11 | $TXN.End() 12 | - pattern-either: 13 | - pattern: $TXN := $NR.StartTransaction($N) 14 | message: "missing new relic end transaction" 15 | languages: [go] 16 | severity: ERROR 17 | -------------------------------------------------------------------------------- /tools/semgrep-rules/semgrep-go/oddbitwise.yml: -------------------------------------------------------------------------------- 1 | rules: 2 | - id: odd-bitwise 3 | patterns: 4 | - pattern-either: 5 | - pattern: $X | $X 6 | - pattern: $X | ^$X 7 | - pattern: ^$X | $X 8 | - pattern: $X & $X 9 | - pattern: $X & ^$X 10 | - pattern: ^$X & $X 11 | - pattern: $X &^ $X 12 | message: "Odd bitwise expression" 13 | languages: [go] 14 | severity: ERROR 15 | -------------------------------------------------------------------------------- /tools/semgrep-rules/semgrep-go/oddcompare-subtract-eq-zero.yml: -------------------------------------------------------------------------------- 1 | # flag these odd comparisons as they all have simpler 2 | # equivalents with just $X and $Y and no zero term 3 | rules: 4 | - id: odd-comparison-subtract-eq-zero 5 | patterns: 6 | - pattern: $X - $Y == 0 7 | fix: $X == $Y 8 | message: "Odd comparison" 9 | languages: [go] 10 | severity: ERROR 11 | -------------------------------------------------------------------------------- /tools/semgrep-rules/semgrep-go/oddcompare-subtract-gt-zero.yml: -------------------------------------------------------------------------------- 1 | # flag these odd comparisons as they all have simpler 2 | # equivalents with just $X and $Y and no zero term 3 | rules: 4 | - id: odd-comparison-subtract-gt-zero 5 | patterns: 6 | - pattern: $X - $Y > 0 7 | fix: $X > $Y 8 | message: "Odd comparison" 9 | languages: [go] 10 | severity: ERROR 11 | -------------------------------------------------------------------------------- /tools/semgrep-rules/semgrep-go/oddcompare-subtract-gte-zero.yml: -------------------------------------------------------------------------------- 1 | # flag these odd comparisons as they all have simpler 2 | # equivalents with just $X and $Y and no zero term 3 | rules: 4 | - id: odd-comparison-subtract-gte-zero 5 | patterns: 6 | - pattern: $X - $Y >= 0 7 | fix: $X >= $Y 8 | message: "Odd comparison" 9 | languages: [go] 10 | severity: ERROR 11 | -------------------------------------------------------------------------------- /tools/semgrep-rules/semgrep-go/oddcompare-subtract-lt-zero.yml: -------------------------------------------------------------------------------- 1 | # flag these odd comparisons as they all have simpler 2 | # equivalents with just $X and $Y and no zero term 3 | rules: 4 | - id: odd-comparison-subtract-lt-zero 5 | patterns: 6 | - pattern: $X - $Y < 0 7 | fix: $Y > $X 8 | message: "Odd comparison" 9 | languages: [go] 10 | severity: ERROR 11 | -------------------------------------------------------------------------------- /tools/semgrep-rules/semgrep-go/oddcompare-subtract-lte-zero.yml: -------------------------------------------------------------------------------- 1 | # flag these odd comparisons as they all have simpler 2 | # equivalents with just $X and $Y and no zero term 3 | rules: 4 | - id: odd-comparison-subtract-lte-zero 5 | patterns: 6 | - pattern: $X - $Y <= 0 7 | fix: $Y >= $X 8 | message: "Odd comparison" 9 | languages: [go] 10 | severity: ERROR 11 | -------------------------------------------------------------------------------- /tools/semgrep-rules/semgrep-go/oddcompare-subtract-neq-zero.yml: -------------------------------------------------------------------------------- 1 | # flag these odd comparisons as they all have simpler 2 | # equivalents with just $X and $Y and no zero term 3 | rules: 4 | - id: odd-comparison-subtract-neq-zero 5 | patterns: 6 | - pattern: $X - $Y != 0 7 | fix: $X != $Y 8 | message: "Odd comparison" 9 | languages: [go] 10 | severity: ERROR 11 | -------------------------------------------------------------------------------- /tools/semgrep-rules/semgrep-go/oddcompare-xor-eq-zero.yml: -------------------------------------------------------------------------------- 1 | # flag these odd comparisons as they all have simpler 2 | # equivalents with just $X and $Y and no zero term 3 | rules: 4 | - id: odd-comparison-xor-eq-zero 5 | patterns: 6 | - pattern: $X ^ $Y == 0 7 | fix: $X == $Y 8 | message: "Odd comparison" 9 | languages: [go] 10 | severity: ERROR 11 | -------------------------------------------------------------------------------- /tools/semgrep-rules/semgrep-go/oddcompare-xor-neq-zero.yml: -------------------------------------------------------------------------------- 1 | # flag these odd comparisons as they all have simpler 2 | # equivalents with just $X and $Y and no zero term 3 | rules: 4 | - id: odd-comparison-xor-neq-zero 5 | patterns: 6 | - pattern: $X ^ $Y != 0 7 | fix: $X != $Y 8 | message: "Odd comparison" 9 | languages: [go] 10 | severity: ERROR 11 | -------------------------------------------------------------------------------- /tools/semgrep-rules/semgrep-go/oddcompound.yml: -------------------------------------------------------------------------------- 1 | rules: 2 | - id: odd-compound-expression 3 | patterns: 4 | - pattern-either: 5 | - pattern: $X += $X + $Y 6 | - pattern: $X += $X - $Y 7 | - pattern: $X -= $X + $Y 8 | - pattern: $X -= $X - $Y 9 | message: "Odd compound += or -= expression" 10 | languages: [go] 11 | severity: ERROR 12 | -------------------------------------------------------------------------------- /tools/semgrep-rules/semgrep-go/oddmathbits.yml: -------------------------------------------------------------------------------- 1 | rules: 2 | - id: odd-bits-leadingzeros 3 | patterns: 4 | - pattern-either: 5 | - pattern: 64 - bits.LeadingZeros64($X) 6 | - pattern: 32 - bits.LeadingZeros32($X) 7 | - pattern: 16 - bits.LeadingZeros16($X) 8 | - pattern: 8 - bits.LeadingZeros8($X) 9 | message: "Odd bits.LeadingZeros() expression should perhaps be bits.Len()" 10 | languages: [go] 11 | severity: ERROR 12 | -------------------------------------------------------------------------------- /tools/semgrep-rules/semgrep-go/os-error-is-exist.yml: -------------------------------------------------------------------------------- 1 | rules: 2 | - id: os-error-is-exist 3 | patterns: 4 | - pattern: os.IsExist($ERR) 5 | fix: errors.Is($ERR, fs.ErrExist) 6 | message: "New code should use errors.Is with the appropriate error type" 7 | languages: [go] 8 | severity: ERROR 9 | -------------------------------------------------------------------------------- /tools/semgrep-rules/semgrep-go/os-error-is-not-exist.yml: -------------------------------------------------------------------------------- 1 | rules: 2 | - id: os-error-is-not-exist 3 | patterns: 4 | - pattern: os.IsNotExist($ERR) 5 | fix: errors.Is($ERR, fs.ErrNotExist) 6 | message: "New code should use errors.Is with the appropriate error type" 7 | languages: [go] 8 | severity: ERROR 9 | -------------------------------------------------------------------------------- /tools/semgrep-rules/semgrep-go/os-error-is-permission.yml: -------------------------------------------------------------------------------- 1 | rules: 2 | - id: os-error-is-permission 3 | patterns: 4 | - pattern: os.IsPermission($ERR) 5 | fix: errors.Is($ERR, fs.ErrPermission) 6 | message: "New code should use errors.Is with the appropriate error type" 7 | languages: [go] 8 | severity: ERROR 9 | -------------------------------------------------------------------------------- /tools/semgrep-rules/semgrep-go/os-error-is-timeout.yml: -------------------------------------------------------------------------------- 1 | rules: 2 | - id: os-error-is-timeout 3 | patterns: 4 | - pattern: os.IsTimeout(...) 5 | message: "New code should use errors.Is with the appropriate error type" 6 | languages: [go] 7 | severity: ERROR 8 | -------------------------------------------------------------------------------- /tools/semgrep-rules/semgrep-go/readeof.yml: -------------------------------------------------------------------------------- 1 | rules: 2 | - id: read-io-eof 3 | patterns: 4 | - pattern: | 5 | $N, $ERR := $R.Read(($SLICE : []byte)) 6 | if $ERR != nil { 7 | return ... 8 | } 9 | - pattern-not: | 10 | $N, $ERR := rand.Read(($SLICE : []byte)) 11 | if $ERR != nil { 12 | return ... 13 | } 14 | message: "Read() can return n bytes and io.EOF" 15 | languages: [go] 16 | severity: ERROR 17 | -------------------------------------------------------------------------------- /tools/semgrep-rules/semgrep-go/readfull.yml: -------------------------------------------------------------------------------- 1 | rules: 2 | - id: io-readfull-n 3 | patterns: 4 | - pattern-either: 5 | - pattern: | 6 | $N, $ERR = io.ReadFull($R, $SLICE) 7 | if $ERR != nil || $N != len($SLICE) { 8 | ... 9 | } 10 | - pattern: | 11 | $N, $ERR = io.ReadFull($R, $SLICE) 12 | if $N != len($SLICE) || $ERR != nil { 13 | ... 14 | } 15 | message: "io.ReadFull() returns err == nil iff n == len(slice)" 16 | languages: [go] 17 | severity: ERROR 18 | -------------------------------------------------------------------------------- /tools/semgrep-rules/semgrep-go/returnnil.yml: -------------------------------------------------------------------------------- 1 | rules: 2 | - id: return-nil 3 | patterns: 4 | - pattern-either: 5 | - pattern: | 6 | if $X == nil { 7 | return $X 8 | } 9 | - pattern: | 10 | if $X != nil { 11 | return ... 12 | } 13 | return $X 14 | message: "return nil instead of nil value" 15 | languages: [go] 16 | severity: ERROR 17 | -------------------------------------------------------------------------------- /tools/semgrep-rules/semgrep-go/timeafter.yml: -------------------------------------------------------------------------------- 1 | rules: 2 | - id: leaky-time-after 3 | patterns: 4 | - pattern-either: 5 | - pattern: | 6 | for { 7 | ... 8 | select { 9 | case <- time.After(...): 10 | ... 11 | } 12 | ... 13 | } 14 | message: "Leaky use of time.After in for-select, see: https://groups.google.com/g/golang-nuts/c/cCdm0Ixwi9A/m/jMiJJScAEAAJ" 15 | languages: [go] 16 | severity: ERROR 17 | -------------------------------------------------------------------------------- /tools/semgrep-rules/semgrep-go/unixnano-after.yml: -------------------------------------------------------------------------------- 1 | rules: 2 | - id: not-after 3 | patterns: 4 | - pattern: $T1.UnixNano() <= $T2.UnixNano() 5 | message: > 6 | unless checking for wall clock inconsistencies, use !$T1.After($T2) 7 | languages: [go] 8 | severity: ERROR 9 | -------------------------------------------------------------------------------- /tools/semgrep-rules/semgrep-go/unixnano-before.yml: -------------------------------------------------------------------------------- 1 | rules: 2 | - id: not-before 3 | patterns: 4 | - pattern: $T1.UnixNano() >= $T2.UnixNano() 5 | message: > 6 | unless checking for wall clock inconsistencies, use !$T1.Before($T2) 7 | languages: [go] 8 | severity: ERROR 9 | -------------------------------------------------------------------------------- /tools/semgrep-rules/semgrep-go/unmarshaljson.yml: -------------------------------------------------------------------------------- 1 | rules: 2 | - id: unmarshal-json-misspell 3 | pattern-either: 4 | - patterns: 5 | - pattern-regex: (?i)func \((.+)\) unmarshal[l]?json\((.*)\) 6 | - pattern-not-regex: func \(.+\) UnmarshalJSON\( 7 | fix: func ($1) UnmarshalJSON($2) 8 | message: | 9 | Misspelling of UnmarshalJSON. 10 | languages: [go] 11 | severity: ERROR 12 | -------------------------------------------------------------------------------- /tools/semgrep-rules/semgrep-go/unmarshalyaml.yml: -------------------------------------------------------------------------------- 1 | rules: 2 | - id: unmarshal-yaml-misspell 3 | pattern-either: 4 | - patterns: 5 | - pattern-regex: (?i)func \((.+)\) unmarshal[l]?yaml\((.*)\) 6 | - pattern-not-regex: func \(.+\) UnmarshalYAML\( 7 | fix: func ($1) UnmarshalYAML($2) 8 | message: | 9 | Misspelling of UnmarshalYAML. 10 | languages: [go] 11 | severity: ERROR 12 | -------------------------------------------------------------------------------- /tools/semgrep-rules/semgrep-go/use-fprintf-not-write-fsprint.yml: -------------------------------------------------------------------------------- 1 | rules: 2 | - id: use-fprintf-not-write-fsprint 3 | patterns: 4 | - pattern: $W.Write([]byte(fmt.Sprintf($...VALS))) 5 | message: "use fmt.Fprintf($W, $...VALS) instead of fmt.Sprintf and []byte conversion" 6 | languages: [go] 7 | severity: ERROR 8 | -------------------------------------------------------------------------------- /tools/semgrep-rules/semgrep-go/use-write-not-fprint.yml: -------------------------------------------------------------------------------- 1 | rules: 2 | - id: use-write-not-fprint 3 | patterns: 4 | - pattern: fmt.Fprint($W, string($VAR)) 5 | message: "use $W.Write($VAR) instead of fmt.Fprint when $VAR is []byte" 6 | languages: [go] 7 | severity: ERROR 8 | -------------------------------------------------------------------------------- /tools/semgrep-rules/semgrep-go/use-writer-not-writestring.yml: -------------------------------------------------------------------------------- 1 | rules: 2 | - id: use-writer-not-writestring 3 | patterns: 4 | - pattern: io.WriteString($W, string($VAR)) 5 | message: "use $W.Write($VAR) instead of io.WriteString when $VAR is []byte" 6 | languages: [go] 7 | severity: ERROR 8 | -------------------------------------------------------------------------------- /tools/semgrep-rules/semgrep-go/wrongerrcall.yml: -------------------------------------------------------------------------------- 1 | rules: 2 | - id: maybe-wrong-err 3 | patterns: 4 | - pattern-either: 5 | - pattern: | 6 | if $F.Err() != nil { 7 | return ..., <... err ...> 8 | } 9 | - pattern: | 10 | if $F.Err() != nil { 11 | return <... err ...> 12 | } 13 | 14 | message: "maybe returning wrong error" 15 | languages: [go] 16 | severity: ERROR 17 | -------------------------------------------------------------------------------- /tools/semgrep-rules/semgrep-go/wronglock.yml: -------------------------------------------------------------------------------- 1 | rules: 2 | - id: wrong-lock-unlock 3 | patterns: 4 | - pattern-either: 5 | - pattern: | 6 | $M.Lock() 7 | defer $M.RUnlock() 8 | - pattern: | 9 | $M.RLock() 10 | defer $M.Unlock() 11 | - pattern: | 12 | $M.Lock() 13 | defer $M.Lock() 14 | - pattern: | 15 | $M.RLock() 16 | defer $M.RLock() 17 | message: "Wrong lock/unlock pair?" 18 | languages: [go] 19 | severity: ERROR 20 | -------------------------------------------------------------------------------- /tsparser/build.rs: -------------------------------------------------------------------------------- 1 | use std::io::Result; 2 | 3 | fn main() -> Result<()> { 4 | prost_build::compile_protos( 5 | &["../proto/encore/parser/meta/v1/meta.proto"], 6 | &["../proto/"], 7 | )?; 8 | Ok(()) 9 | } 10 | -------------------------------------------------------------------------------- /tsparser/litparser-derive/.gitignore: -------------------------------------------------------------------------------- 1 | /target 2 | -------------------------------------------------------------------------------- /tsparser/litparser-derive/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "litparser-derive" 3 | version = "0.1.0" 4 | edition = "2021" 5 | 6 | [lib] 7 | proc-macro = true 8 | 9 | # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html 10 | 11 | [dependencies] 12 | syn = { version = "2.0", features = ["extra-traits"] } 13 | quote = "1.0" 14 | proc-macro2 = "1.0.67" 15 | anyhow = "1.0" 16 | litparser = { version = "0.1.0", path = "../litparser" } 17 | swc_ecma_parser = { version = "0.141.21", features = ["typescript"] } 18 | swc_ecma_ast = "0.110.9" 19 | swc_common = { version = "0.33.8", features = ["tty-emitter"] } 20 | 21 | [dev-dependencies] 22 | prettyplease = "0.2" 23 | -------------------------------------------------------------------------------- /tsparser/litparser/.gitignore: -------------------------------------------------------------------------------- 1 | /target 2 | -------------------------------------------------------------------------------- /tsparser/litparser/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "litparser" 3 | version = "0.1.0" 4 | edition = "2021" 5 | 6 | [dependencies] 7 | anyhow = "1.0" 8 | duration-string = "0.3.0" 9 | swc_ecma_ast = "0.110.9" 10 | swc_common = { version = "0.33.8", features = ["tty-emitter"] } 11 | clean-path = "0.2.1" 12 | num-bigint = "0.4.5" 13 | num-integer = "0.1.46" 14 | num-traits = "0.2.19" 15 | -------------------------------------------------------------------------------- /tsparser/src/builder/templates/catalog/auth/index_ts.handlebars: -------------------------------------------------------------------------------- 1 | export {type AuthData, getAuthData} from "../internal/auth/auth"; -------------------------------------------------------------------------------- /tsparser/src/builder/templates/catalog/clients/index_d_ts.handlebars: -------------------------------------------------------------------------------- 1 | {{#each services}} 2 | export * as {{encoreNameToIdent name}} from "../internal/clients/{{name}}/endpoints"; 3 | {{/each}} 4 | -------------------------------------------------------------------------------- /tsparser/src/builder/templates/catalog/clients/index_js.handlebars: -------------------------------------------------------------------------------- 1 | {{#each services}} 2 | export * as {{encoreNameToIdent name}} from "../internal/clients/{{name}}/endpoints.js"; 3 | {{/each}} 4 | -------------------------------------------------------------------------------- /tsparser/src/builder/templates/entrypoints/gateways/main.handlebars: -------------------------------------------------------------------------------- 1 | import { registerGateways, run } from "encore.dev/internal/codegen/appinit"; 2 | import { Worker, isMainThread } from "node:worker_threads"; 3 | import { fileURLToPath } from "node:url"; 4 | import { availableParallelism } from "node:os"; 5 | 6 | {{#each gateways}} 7 | import { {{bind_name}} as {{encoreNameToIdent encore_name}}Impl } from {{toJSON import_path}}; 8 | {{/each}} 9 | 10 | const gateways = [ 11 | {{#each gateways}} 12 | {{encoreNameToIdent encore_name}}Impl, 13 | {{/each}} 14 | ]; 15 | 16 | registerGateways(gateways); 17 | 18 | await run(import.meta.url); 19 | -------------------------------------------------------------------------------- /tsparser/src/legacymeta/api_schema.rs: -------------------------------------------------------------------------------- 1 | use crate::parser::respath::Path; 2 | use crate::parser::types::{FieldName, Interface}; 3 | 4 | pub(super) fn strip_path_params(path: &Path, typ: &mut Interface) { 5 | if !path.has_dynamic_segments() { 6 | return; 7 | } 8 | 9 | let is_path_param = |name: &str| path.dynamic_segments().any(|seg| seg.lit_or_name() == name); 10 | 11 | // Drop any fields whose type is Path. 12 | typ.fields.retain(|f| { 13 | if let FieldName::String(name) = &f.name { 14 | if is_path_param(name) { 15 | return false; 16 | } 17 | } 18 | true 19 | }); 20 | } 21 | -------------------------------------------------------------------------------- /tsparser/src/lib.rs: -------------------------------------------------------------------------------- 1 | pub mod app; 2 | pub mod builder; 3 | mod legacymeta; 4 | pub mod parser; 5 | mod span_err; 6 | 7 | pub mod encore { 8 | pub mod parser { 9 | pub mod meta { 10 | pub mod v1 { 11 | include!(concat!(env!("OUT_DIR"), "/encore.parser.meta.v1.rs")); 12 | } 13 | } 14 | 15 | pub mod schema { 16 | pub mod v1 { 17 | include!(concat!(env!("OUT_DIR"), "/encore.parser.schema.v1.rs")); 18 | } 19 | } 20 | } 21 | } 22 | 23 | mod runtimeresolve; 24 | #[cfg(test)] 25 | pub mod testutil; 26 | -------------------------------------------------------------------------------- /tsparser/src/parser/mod.rs: -------------------------------------------------------------------------------- 1 | mod doc_comments; 2 | mod fileset; 3 | pub mod module_loader; 4 | #[allow(clippy::module_inception)] 5 | pub mod parser; 6 | pub mod resourceparser; 7 | pub mod resources; 8 | pub mod respath; 9 | mod service_discovery; 10 | pub mod types; 11 | pub mod usageparser; 12 | 13 | pub use fileset::{FilePath, FileSet, Pos, Range, ZERO_RANGE}; 14 | -------------------------------------------------------------------------------- /tsparser/src/parser/resourceparser/paths.rs: -------------------------------------------------------------------------------- 1 | /// A path to a package, e.g. `@foo/bar`. 2 | #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] 3 | pub struct PkgPath<'a>(pub &'a str); 4 | 5 | /// A path to a specific object in a package, e.g. 'Moo' in '@foo/bar'. 6 | #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] 7 | pub struct PkgObj<'a>(pub PkgPath<'a>, pub &'a str); 8 | -------------------------------------------------------------------------------- /tsparser/src/parser/resources/apis/mod.rs: -------------------------------------------------------------------------------- 1 | pub mod api; 2 | pub mod authhandler; 3 | pub mod encoding; 4 | pub mod gateway; 5 | pub mod service; 6 | pub mod service_client; 7 | -------------------------------------------------------------------------------- /tsparser/src/parser/resources/infra/mod.rs: -------------------------------------------------------------------------------- 1 | pub mod cron; 2 | pub mod objects; 3 | pub mod pubsub_subscription; 4 | pub mod pubsub_topic; 5 | pub mod secret; 6 | pub mod sqldb; 7 | -------------------------------------------------------------------------------- /tsparser/src/parser/types/mod.rs: -------------------------------------------------------------------------------- 1 | mod ast_id; 2 | mod binding; 3 | mod object; 4 | mod typ; 5 | mod type_resolve; 6 | mod type_string; 7 | mod utils; 8 | pub mod visitor; 9 | 10 | mod resolved; 11 | #[cfg(test)] 12 | mod tests; 13 | pub mod validation; 14 | 15 | pub use object::{Object, ObjectId, ObjectKind, ResolveState}; 16 | pub use typ::*; 17 | pub use type_resolve::TypeChecker; 18 | pub use utils::*; 19 | -------------------------------------------------------------------------------- /tsparser/src/parser/types/snapshots/encore_tsparser__parser__types__tests__resolve_types@export_default.ts.snap: -------------------------------------------------------------------------------- 1 | --- 2 | source: tsparser/src/parser/types/tests.rs 3 | expression: result 4 | input_file: tsparser/src/parser/types/testdata/export_default.ts 5 | --- 6 | { 7 | "default": Interface( 8 | Interface { 9 | fields: [ 10 | InterfaceField { 11 | name: String( 12 | "name", 13 | ), 14 | optional: false, 15 | typ: Basic( 16 | String, 17 | ), 18 | }, 19 | ], 20 | index: None, 21 | call: None, 22 | }, 23 | ), 24 | } 25 | -------------------------------------------------------------------------------- /tsparser/src/parser/types/snapshots/encore_tsparser__parser__types__tests__resolve_types@export_wildcard.txt.snap: -------------------------------------------------------------------------------- 1 | --- 2 | source: tsparser/src/parser/types/tests.rs 3 | expression: result 4 | input_file: tsparser/src/parser/types/testdata/export_wildcard.txt 5 | --- 6 | { 7 | "foo": Interface( 8 | Interface { 9 | fields: [ 10 | InterfaceField { 11 | name: String( 12 | "bar", 13 | ), 14 | optional: false, 15 | typ: Basic( 16 | String, 17 | ), 18 | }, 19 | ], 20 | index: None, 21 | call: None, 22 | }, 23 | ), 24 | } 25 | -------------------------------------------------------------------------------- /tsparser/src/parser/types/snapshots/encore_tsparser__parser__types__tests__resolve_types@qualified_name.ts.snap: -------------------------------------------------------------------------------- 1 | --- 2 | source: tsparser/src/parser/types/tests.rs 3 | expression: result 4 | input_file: tsparser/src/parser/types/testdata/qualified_name.ts 5 | --- 6 | { 7 | "T1": Basic( 8 | String, 9 | ), 10 | "T2": Basic( 11 | Number, 12 | ), 13 | } 14 | -------------------------------------------------------------------------------- /tsparser/src/parser/types/snapshots/encore_tsparser__parser__types__tests__resolve_types@reexport_single.txt.snap: -------------------------------------------------------------------------------- 1 | --- 2 | source: tsparser/src/parser/types/tests.rs 3 | expression: result 4 | input_file: tsparser/src/parser/types/testdata/reexport_single.txt 5 | --- 6 | { 7 | "foo": Interface( 8 | Interface { 9 | fields: [ 10 | InterfaceField { 11 | name: String( 12 | "bar", 13 | ), 14 | optional: false, 15 | typ: Basic( 16 | String, 17 | ), 18 | }, 19 | ], 20 | index: None, 21 | call: None, 22 | }, 23 | ), 24 | } 25 | -------------------------------------------------------------------------------- /tsparser/src/parser/types/snapshots/encore_tsparser__parser__types__tests__resolve_types@reexport_wildcard.txt.snap: -------------------------------------------------------------------------------- 1 | --- 2 | source: tsparser/src/parser/types/tests.rs 3 | expression: result 4 | input_file: tsparser/src/parser/types/testdata/reexport_wildcard.txt 5 | --- 6 | { 7 | "foo": Literal( 8 | String( 9 | "foo", 10 | ), 11 | ), 12 | } 13 | -------------------------------------------------------------------------------- /tsparser/src/parser/types/testdata/export_default.ts: -------------------------------------------------------------------------------- 1 | export default interface foo { 2 | name: string; 3 | } 4 | -------------------------------------------------------------------------------- /tsparser/src/parser/types/testdata/extends.ts: -------------------------------------------------------------------------------- 1 | export interface Foo { 2 | foo: string | number | null; 3 | bar: number; 4 | optional?: boolean; 5 | } 6 | 7 | export interface Bar extends Foo { 8 | foo: string | null; // now never a number 9 | optional: boolean; // now required 10 | moo: string; 11 | } 12 | 13 | export interface Generic { 14 | foo: T | null; 15 | } 16 | 17 | export interface ExtendGeneric extends Generic { 18 | bar: string; 19 | } 20 | 21 | export interface MergeGeneric extends Generic { 22 | foo: 5 | null; 23 | } 24 | -------------------------------------------------------------------------------- /tsparser/src/parser/types/testdata/generics.ts: -------------------------------------------------------------------------------- 1 | export type Generic1 = { 2 | cond: T extends string ? "literal" : number; 3 | } 4 | 5 | export type Generic2 = { 6 | value: T; 7 | cond: T extends string ? "literal" : number; 8 | } 9 | 10 | export type Concrete1 = { 11 | one: Generic1; 12 | two: Generic1<"test">; 13 | three: Generic2; 14 | four: Generic2>; 15 | five: GenericIface>; 16 | } 17 | 18 | export interface GenericIface { 19 | foo: T; 20 | } 21 | -------------------------------------------------------------------------------- /tsparser/src/parser/types/testdata/infer.txt: -------------------------------------------------------------------------------- 1 | export type Iface = T extends { X: infer A } ? A : never; 2 | 3 | export type Infer1 = Iface<{ X: string }>; // string 4 | export type Infer2 = Iface<{ Y: string }>; // never 5 | export type Infer3 = { X: string } extends { X: infer A } ? A : never; // string 6 | -------------------------------------------------------------------------------- /tsparser/src/parser/types/testdata/keyofenum.ts: -------------------------------------------------------------------------------- 1 | export type ObjectValues = T[keyof T]; 2 | 3 | export const MY_ENUM = { 4 | VARIANT_1: "VARIANT_1", 5 | VARIANT_2: "VARIANT_2", 6 | VARIANT_3: "VARIANT_3" 7 | } as const; 8 | 9 | export type MyEnum = ObjectValues; 10 | -------------------------------------------------------------------------------- /tsparser/src/parser/types/testdata/qualified_name.ts: -------------------------------------------------------------------------------- 1 | namespace Foo { 2 | export type Bar = string; 3 | 4 | export namespace Nested { 5 | export type Baz = number; 6 | } 7 | }; 8 | 9 | 10 | export type T1 = Foo.Bar; 11 | export type T2 = Foo.Nested.Baz; 12 | -------------------------------------------------------------------------------- /tsparser/src/parser/types/testdata/reexport_single.txt: -------------------------------------------------------------------------------- 1 | export { foo } from "./foo"; 2 | 3 | -- foo.ts -- 4 | export interface foo { 5 | bar: string; 6 | } 7 | -------------------------------------------------------------------------------- /tsparser/src/parser/types/testdata/reexport_wildcard.txt: -------------------------------------------------------------------------------- 1 | export { foo } from "./foo"; 2 | 3 | -- foo.ts -- 4 | export * from "./bar"; 5 | 6 | -- bar.ts -- 7 | export const foo = "foo"; 8 | export interface bar { 9 | num: number; 10 | } 11 | -------------------------------------------------------------------------------- /tsparser/src/parser/types/testdata/validation.ts: -------------------------------------------------------------------------------- 1 | import { Min, Max, MinLen, MaxLen, IsURL, IsEmail } from "encore.dev/validate"; 2 | 3 | export interface Params { 4 | // A number between 3 and 1000 (inclusive). 5 | foo: number & (Min<3> & Max<1000>); 6 | 7 | // A string between 5 and 20 characters long. 8 | bar: string & (MinLen<5> & MaxLen<20>); 9 | 10 | // A string that is either a URL or an email address. 11 | urlOrEmail: string & (IsURL | IsEmail); 12 | 13 | // An array of up to 10 email addresses. 14 | emails: Array & MaxLen<10>; 15 | } 16 | -------------------------------------------------------------------------------- /tsparser/src/parser/types/testdata/wirespec.ts: -------------------------------------------------------------------------------- 1 | import { Query, Header } from "encore.dev/api"; 2 | import { MinLen, Max } from "encore.dev/validate"; 3 | 4 | export interface Foo { 5 | a: Query; 6 | b: Query & Max<10>; 7 | c: Query & MinLen<3>; 8 | d: Header<"X-Header"> & MinLen<3>; 9 | } 10 | -------------------------------------------------------------------------------- /tsparser/src/runtimeresolve/mod.rs: -------------------------------------------------------------------------------- 1 | mod exports; 2 | mod node; 3 | mod tsconfig; 4 | 5 | pub use node::EncoreRuntimeResolver; 6 | pub use tsconfig::TsConfigPathResolver; 7 | -------------------------------------------------------------------------------- /tsparser/src/testutil/mod.rs: -------------------------------------------------------------------------------- 1 | use duct::cmd; 2 | use once_cell::sync::Lazy; 3 | use std::path::PathBuf; 4 | 5 | pub mod testparse; 6 | pub mod testresolve; 7 | pub mod typeparse; 8 | 9 | pub static JS_RUNTIME_PATH: Lazy = Lazy::new(js_runtime_path); 10 | 11 | fn js_runtime_path() -> PathBuf { 12 | let repo_root = cmd!("git", "rev-parse", "--show-toplevel") 13 | .stdout_capture() 14 | .read() 15 | .unwrap(); 16 | PathBuf::from(repo_root.trim()).join("runtimes").join("js") 17 | } 18 | -------------------------------------------------------------------------------- /tsparser/src/testutil/testparse.rs: -------------------------------------------------------------------------------- 1 | use std::rc::Rc; 2 | use swc_common::sync::Lrc; 3 | 4 | use crate::parser::module_loader::Module; 5 | use crate::parser::parser::ParseContext; 6 | use assert_fs::TempDir; 7 | use swc_common::errors::Handler; 8 | use swc_common::SourceMap; 9 | 10 | pub fn test_parse(src: &str) -> Lrc { 11 | let root = TempDir::new().unwrap(); 12 | 13 | let cm: Rc = Default::default(); 14 | let errs = Rc::new(Handler::with_tty_emitter( 15 | swc_common::errors::ColorConfig::Auto, 16 | true, 17 | false, 18 | Some(cm.clone()), 19 | )); 20 | 21 | let pc = ParseContext::new(root.to_path_buf(), None, cm, errs).unwrap(); 22 | pc.loader.inject_file("test.ts".into(), src).unwrap() 23 | } 24 | -------------------------------------------------------------------------------- /tsparser/tests/common/mod.rs: -------------------------------------------------------------------------------- 1 | use clean_path::Clean; 2 | use std::path::PathBuf; 3 | 4 | pub fn js_runtime_path() -> PathBuf { 5 | PathBuf::from(env!("CARGO_MANIFEST_DIR")) 6 | .join("../runtimes/js") 7 | .clean() 8 | } 9 | -------------------------------------------------------------------------------- /tsparser/tests/testdata/builtins.txt: -------------------------------------------------------------------------------- 1 | -- foo/foo.ts -- 2 | import { api } from "encore.dev/api"; 3 | 4 | type Params = Record; 5 | 6 | export const ping = api({}, () => {}); 7 | 8 | -- package.json -- 9 | { 10 | "name": "foo", 11 | "type": "module", 12 | "dependencies": { 13 | "encore.dev": "^1.35.0" 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /tsparser/tests/testdata/mapped_types.txt: -------------------------------------------------------------------------------- 1 | -- foo/foo.ts -- 2 | import { api } from "encore.dev/api"; 3 | 4 | type OnlyBoolsAndHorses = { 5 | [key: string]: boolean | number; 6 | }; 7 | 8 | interface Params { 9 | blah: OnlyBoolsAndHorses; 10 | }; 11 | 12 | export const ping = api({}, () => {}); 13 | 14 | -- package.json -- 15 | { 16 | "name": "foo", 17 | "type": "module", 18 | "dependencies": { 19 | "encore.dev": "^1.35.0" 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /tsparser/tests/testdata/query_header.txt: -------------------------------------------------------------------------------- 1 | -- foo/foo.ts -- 2 | import { api, Query, Header } from "encore.dev/api"; 3 | 4 | interface Params { 5 | q1: Query; 6 | q2: Query; 7 | q3: Query<"my-query">; 8 | q4: Query; 9 | 10 | h1: Header; 11 | h2: Header; 12 | h3: Header<"my-header">; 13 | h4: Header; 14 | }; 15 | 16 | export const t1 = api({}, () => {}); 17 | export const t2 = api({}, () => {}); 18 | export const t3 = api({}, () => {}); 19 | 20 | -- package.json -- 21 | { 22 | "name": "foo", 23 | "type": "module", 24 | "dependencies": { 25 | "encore.dev": "^1.35.0" 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /tsparser/tests/testdata/tsconfig.txt: -------------------------------------------------------------------------------- 1 | -- foo/foo.ts -- 2 | import { api } from "encore.dev/api"; 3 | import { blah } from "@bar/bar"; 4 | 5 | export const ping = api({}, () => {}); 6 | 7 | -- bar/bar.ts -- 8 | 9 | export const blah = 5; 10 | 11 | -- package.json -- 12 | { 13 | "type": "module", 14 | "dependencies": { 15 | "encore.dev": "^1.35.0" 16 | } 17 | } 18 | 19 | -- tsconfig.json -- 20 | { 21 | "compilerOptions": { 22 | "paths": { 23 | "~encore/*": ["./encore.gen/*"], 24 | "@bar/*": ["./bar/*"] 25 | } 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /tsparser/txtar/.gitignore: -------------------------------------------------------------------------------- 1 | /target 2 | -------------------------------------------------------------------------------- /tsparser/txtar/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "txtar" 3 | version = "1.0.0" 4 | edition = "2021" 5 | authors = ["Frank de Jong "] 6 | description = "A Rust implementation of the txtar Go package" 7 | license = "MIT/Apache-2.0" 8 | readme = "README.md" 9 | repository = "https://gitlab.com/foo-jin/txtar" 10 | documentation = "https://docs.rs/txtar/latest/txtar/" 11 | categories = ["filesystem", "development-tools::testing"] 12 | keywords = ["fs", "filesystem", "txtar", "tempfs"] 13 | exclude = [".gitignore"] 14 | 15 | # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html 16 | 17 | [dependencies] 18 | clean-path = "0.2.1" 19 | thiserror = "1.0" 20 | 21 | [dev-dependencies] 22 | assert_fs = "1.0.7" 23 | predicates = "2.1.1" 24 | similar-asserts = "1.2.0" 25 | -------------------------------------------------------------------------------- /tsparser/txtar/src/error.rs: -------------------------------------------------------------------------------- 1 | use std::io; 2 | 3 | use thiserror::Error; 4 | 5 | #[derive(Error, Debug)] 6 | pub enum MaterializeError { 7 | #[error("{0}")] 8 | Io(#[from] io::Error), 9 | #[error("{0}: outside parent directory")] 10 | DirEscape(String), 11 | } 12 | -------------------------------------------------------------------------------- /v2/app/gateway.go: -------------------------------------------------------------------------------- 1 | package app 2 | 3 | // Gateway describes an Encore gateway. 4 | type Gateway struct { 5 | // EncoreName is the encore-name of the gateway. 6 | EncoreName string 7 | } 8 | -------------------------------------------------------------------------------- /v2/app/testdata/auth_handler_data.txt: -------------------------------------------------------------------------------- 1 | parse 2 | 3 | -- svc/svc.go -- 4 | package svc 5 | 6 | import ( 7 | "context" 8 | "encore.dev/beta/auth" 9 | ) 10 | 11 | type MyData struct { 12 | Name string 13 | } 14 | 15 | //encore:authhandler 16 | func MyAuth(ctx context.Context, token string) (auth.UID, *MyData, error) { return "", nil, nil } -------------------------------------------------------------------------------- /v2/app/testdata/auth_handler_simple.txt: -------------------------------------------------------------------------------- 1 | parse 2 | 3 | -- svc/svc.go -- 4 | package svc 5 | 6 | import ( 7 | "context" 8 | "encore.dev/beta/auth" 9 | ) 10 | 11 | //encore:authhandler 12 | func MyAuth(ctx context.Context, token string) (auth.UID, error) { return "", nil } -------------------------------------------------------------------------------- /v2/app/testdata/auth_handler_struct.txt: -------------------------------------------------------------------------------- 1 | parse 2 | 3 | -- svc/svc.go -- 4 | package svc 5 | 6 | import ( 7 | "context" 8 | "encore.dev/beta/auth" 9 | ) 10 | 11 | type FooParams struct{} 12 | 13 | //encore:api public 14 | func Foo(ctx context.Context, p *FooParams) error { return nil } 15 | 16 | type Params struct { 17 | Authorization string `header:"Authorization"` 18 | } 19 | 20 | //encore:authhandler 21 | func MyAuth(ctx context.Context, p *Params) (auth.UID, error) { return "", nil } 22 | -------------------------------------------------------------------------------- /v2/app/testdata/auth_handler_svc_struct.txt: -------------------------------------------------------------------------------- 1 | parse 2 | 3 | -- svc/svc.go -- 4 | package svc 5 | 6 | import ( 7 | "context" 8 | "encore.dev/beta/auth" 9 | ) 10 | 11 | type FooParams struct{} 12 | 13 | //encore:api public 14 | func Foo(ctx context.Context, p *FooParams) error { return nil } 15 | 16 | type Params struct { 17 | Authorization string `header:"Authorization"` 18 | } 19 | 20 | //encore:service 21 | type Service struct{} 22 | 23 | //encore:authhandler 24 | func (s *Service) MyAuth(ctx context.Context, p *Params) (auth.UID, error) { return "", nil } 25 | -------------------------------------------------------------------------------- /v2/app/testdata/cache_cluster_outside_svc.txt: -------------------------------------------------------------------------------- 1 | parse 2 | 3 | -- svc/svc.go -- 4 | package svc 5 | 6 | import ( 7 | "context" 8 | 9 | "encore.dev/storage/cache" 10 | "test/lib" 11 | ) 12 | 13 | type Key[T any] struct { 14 | Foo T 15 | } 16 | 17 | var keyspace = cache.NewStringKeyspace[Key[string]](lib.Cluster, cache.KeyspaceConfig{ 18 | KeyPattern: "foo/:Foo", 19 | }) 20 | 21 | //encore:api public 22 | func Foo(ctx context.Context) error { return nil } 23 | 24 | -- lib/lib.go -- 25 | package lib 26 | 27 | import ( 28 | "context" 29 | 30 | "encore.dev/storage/cache" 31 | ) 32 | 33 | var Cluster = cache.NewCluster("cluster", cache.ClusterConfig{}) 34 | -------------------------------------------------------------------------------- /v2/app/testdata/cache_definition.txt: -------------------------------------------------------------------------------- 1 | parse 2 | 3 | -- svc/svc.go -- 4 | package svc 5 | 6 | import ( 7 | "context" 8 | 9 | "encore.dev/storage/cache" 10 | ) 11 | 12 | var cluster = cache.NewCluster("cluster", cache.ClusterConfig{}) 13 | 14 | var keyspace = cache.NewStringKeyspace[string](cluster, cache.KeyspaceConfig{ 15 | KeyPattern: "foo/:key", 16 | DefaultExpiry: cache.ExpireIn(10 * time.Second), 17 | }) 18 | 19 | //encore:api public 20 | func Foo(context.Context) error { 21 | return nil 22 | } 23 | -------------------------------------------------------------------------------- /v2/app/testdata/cache_generic_type.txt: -------------------------------------------------------------------------------- 1 | parse 2 | 3 | -- svc/svc.go -- 4 | package svc 5 | 6 | import ( 7 | "context" 8 | 9 | "encore.dev/storage/cache" 10 | ) 11 | 12 | var cluster = cache.NewCluster("cluster", cache.ClusterConfig{}) 13 | 14 | type Key[T any] struct { 15 | Foo T 16 | } 17 | 18 | var keyspace = cache.NewStringKeyspace[Key[string]](cluster, cache.KeyspaceConfig{ 19 | KeyPattern: "foo/:Foo", 20 | }) 21 | 22 | //encore:api public 23 | func Foo(context.Context) error { 24 | return nil 25 | } 26 | -------------------------------------------------------------------------------- /v2/app/testdata/et.txt: -------------------------------------------------------------------------------- 1 | parse 2 | 3 | -- svc/svc.go -- 4 | package svc 5 | 6 | import ( 7 | "context" 8 | ) 9 | 10 | //encore:api public 11 | func Foo(context.Context) error { return nil } 12 | 13 | 14 | -- svc/svc_test.go -- 15 | package svc 16 | 17 | import ( 18 | "context" 19 | "testing" 20 | 21 | "encore.dev/et" 22 | ) 23 | 24 | func TestFoo(t *testing.T) { 25 | et.AuthHandler(MyAuth) 26 | } 27 | -------------------------------------------------------------------------------- /v2/app/testdata/et_err_outside_of_test.txt: -------------------------------------------------------------------------------- 1 | ! parse 2 | 3 | -- svc/svc.go -- 4 | package svc 5 | 6 | import ( 7 | "context" 8 | 9 | "encore.dev/et" 10 | ) 11 | 12 | //encore:api public 13 | func Foo(context.Context) error { return nil } 14 | -- want: errors -- 15 | 16 | ── Invalid use of encore.dev/et ───────────────────────────────────────────────────────────[E9999]── 17 | 18 | Encore's test packages can only be used inside tests and cannot otherwise be imported. 19 | 20 | ╭─[ svc/svc.go:6:5 ] 21 | │ 22 | 4 │ "context" 23 | 5 │ 24 | 6 │ "encore.dev/et" 25 | ⋮ ───────┬─────── 26 | ⋮ ╰─ imported here 27 | 7 │ ) 28 | 8 │ 29 | ───╯ 30 | -------------------------------------------------------------------------------- /v2/app/testdata/metrics_counter.txt: -------------------------------------------------------------------------------- 1 | parse 2 | output 'metric counter UINT64 COUNTER \[\]' 3 | output 'metric counter_with_labels UINT64 COUNTER \[label STRING Label doc string.\n\]' 4 | 5 | -- svc/svc.go -- 6 | package svc 7 | 8 | import ( 9 | "context" 10 | 11 | "encore.dev/metrics" 12 | ) 13 | 14 | var Counter = metrics.NewCounter[uint64]("counter", metrics.CounterConfig{}) 15 | 16 | type Labels struct { 17 | Label string // Label doc string. 18 | } 19 | 20 | var CounterWithLabels = metrics.NewCounterGroup[Labels, uint64]("counter_with_labels", metrics.CounterConfig{}) 21 | 22 | //encore:api public 23 | func Foo(context.Context) error { 24 | return nil 25 | } 26 | -------------------------------------------------------------------------------- /v2/app/testdata/metrics_gauge.txt: -------------------------------------------------------------------------------- 1 | parse 2 | output 'metric gauge FLOAT64 GAUGE \[\]' 3 | output 'metric gauge_with_labels FLOAT64 GAUGE \[label STRING Label doc string.\n\]' 4 | 5 | -- svc/svc.go -- 6 | package svc 7 | 8 | import ( 9 | "context" 10 | 11 | "encore.dev/metrics" 12 | ) 13 | 14 | var Gauge = metrics.NewGauge[float64]("gauge", metrics.CounterConfig{}) 15 | 16 | type Labels struct { 17 | Label string // Label doc string. 18 | } 19 | 20 | var GaugeWithLabels = metrics.NewGaugeGroup[Labels, float64]("gauge_with_labels", metrics.CounterConfig{}) 21 | 22 | //encore:api public 23 | func Foo(context.Context) error { 24 | return nil 25 | } -------------------------------------------------------------------------------- /v2/app/testdata/recursive_types.txt: -------------------------------------------------------------------------------- 1 | parse 2 | -- foo.go -- 3 | package foo 4 | 5 | import "context" 6 | 7 | // We must reference these types in an RPC parameter to actually validate them. 8 | type Params struct { 9 | A *SelfRecursive 10 | B *MutuallyRecursive 11 | C *Generic[Generic[MutuallyRecursive]] 12 | } 13 | 14 | //encore:api public 15 | func Dummy(ctx context.Context, p *Params) error { 16 | return nil 17 | } 18 | 19 | type SelfRecursive struct { 20 | A *SelfRecursive 21 | } 22 | 23 | type MutuallyRecursive struct { 24 | Other *Other 25 | } 26 | 27 | type Other struct { 28 | Original *MutuallyRecursive 29 | } 30 | 31 | type Generic[T any] struct { 32 | Val *T 33 | } 34 | -------------------------------------------------------------------------------- /v2/app/testdata/rlog_call_outside_svc.txt: -------------------------------------------------------------------------------- 1 | parse 2 | 3 | -- foo/foo.go -- 4 | package foo 5 | 6 | import "encore.dev/rlog" 7 | 8 | func Log() { 9 | rlog.Info("test") 10 | } 11 | 12 | -- bar/bar.go -- 13 | package bar 14 | 15 | import ( 16 | "context" 17 | 18 | "test/foo" 19 | ) 20 | 21 | //encore:api public 22 | func CallFoo(ctx context.Context) error { 23 | foo.Log() 24 | return nil 25 | } 26 | -------------------------------------------------------------------------------- /v2/app/testdata/rpc_auth.txt: -------------------------------------------------------------------------------- 1 | parse 2 | output 'rpc svc.API access=auth raw=false' 3 | 4 | -- svc/svc.go -- 5 | package svc 6 | 7 | import ( 8 | "context" 9 | 10 | "encore.dev/beta/auth" 11 | ) 12 | 13 | //encore:authhandler 14 | func MyAuthHandler(ctx context.Context, token string) (auth.UID, error) { 15 | return "", nil 16 | } 17 | 18 | //encore:api auth 19 | func API(ctx context.Context) error { return nil } -------------------------------------------------------------------------------- /v2/app/testdata/rpc_call_selector.txt: -------------------------------------------------------------------------------- 1 | # Verify that the parser isn't confusing t.Foo() with calling Foo() 2 | parse 3 | 4 | -- svc/svc.go -- 5 | package svc 6 | 7 | import ( 8 | "context" 9 | ) 10 | 11 | //encore:api public 12 | func Foo(ctx context.Context) error { 13 | var t typ 14 | t.Foo() 15 | return nil 16 | } 17 | 18 | type typ struct{} 19 | func (typ) Foo() { } -------------------------------------------------------------------------------- /v2/app/testdata/rpc_legacy_syntax.txt: -------------------------------------------------------------------------------- 1 | parse 2 | output 'svc.API access=private raw=false' 3 | 4 | -- svc/svc.go -- 5 | package svc 6 | 7 | import "context" 8 | 9 | // encore:api 10 | func API(ctx context.Context) error { return nil } -------------------------------------------------------------------------------- /v2/app/testdata/rpc_method.txt: -------------------------------------------------------------------------------- 1 | parse 2 | output 'rpc svc.Str access=public .* recv=\*Service' 3 | 4 | -- svc/svc.go -- 5 | package svc 6 | 7 | import ( 8 | "context" 9 | "encore.dev/types/uuid" 10 | ) 11 | 12 | //encore:service 13 | type Service struct {} 14 | 15 | type Params struct{} 16 | 17 | //encore:api public 18 | func (s *Service) Str(ctx context.Context, p *Params) error { return nil } 19 | -------------------------------------------------------------------------------- /v2/app/testdata/rpc_non_raw_path.txt: -------------------------------------------------------------------------------- 1 | parse 2 | 3 | -- svc/svc.go -- 4 | package svc 5 | 6 | import "context" 7 | 8 | //encore:api public path=/foo/bar 9 | func API(ctx context.Context) error { return nil } -------------------------------------------------------------------------------- /v2/app/testdata/rpc_path_params.txt: -------------------------------------------------------------------------------- 1 | parse 2 | 3 | -- svc/svc.go -- 4 | package svc 5 | 6 | import ( 7 | "context" 8 | "encore.dev/types/uuid" 9 | ) 10 | 11 | //encore:api public path=/str/:p 12 | func Str(ctx context.Context, p string) error { return nil } 13 | 14 | //encore:api public path=/int/:p 15 | func Int(ctx context.Context, p int) error { return nil } 16 | 17 | //encore:api public path=/uuid/:p 18 | func UUID(ctx context.Context, p uuid.UUID) error { return nil } -------------------------------------------------------------------------------- /v2/app/testdata/rpc_raw_custom_path.txt: -------------------------------------------------------------------------------- 1 | # Verify that one can use custom paths for raw endpoints 2 | 3 | parse 4 | output 'rpc svc.API access=public raw=true path=/foo' 5 | 6 | -- svc/svc.go -- 7 | package svc 8 | 9 | import "net/http" 10 | 11 | //encore:api public raw path=/foo 12 | func API(w http.ResponseWriter, req *http.Request) { } -------------------------------------------------------------------------------- /v2/app/testdata/rpc_raw_public.txt: -------------------------------------------------------------------------------- 1 | # Verify that one can use public and raw RPCs 2 | 3 | parse 4 | output 'rpc svc.API access=public raw=true' 5 | 6 | -- svc/svc.go -- 7 | package svc 8 | 9 | import "net/http" 10 | 11 | //encore:api public raw 12 | func API(w http.ResponseWriter, req *http.Request) { } -------------------------------------------------------------------------------- /v2/app/testdata/secrets.txt: -------------------------------------------------------------------------------- 1 | # Verify that secrets are parsed successfully 2 | 3 | parse 4 | 5 | -- svc/svc.go -- 6 | package svc 7 | 8 | import "context" 9 | 10 | var secrets struct { 11 | Foo string 12 | } 13 | 14 | //encore:api public 15 | func Foo(ctx context.Context) error { 16 | return nil 17 | } 18 | -------------------------------------------------------------------------------- /v2/app/testdata/secrets_non_string.txt: -------------------------------------------------------------------------------- 1 | # Verify that secret fields are of type string 2 | 3 | ! parse 4 | err 'field Foo is not of type string' 5 | 6 | -- svc/svc.go -- 7 | package svc 8 | 9 | var secrets struct { 10 | Foo int 11 | } 12 | 13 | -- want: errors -- 14 | 15 | ── Invalid secrets struct ─────────────────────────────────────────────────────────────────[E9999]── 16 | 17 | Secrets must be of type string. 18 | 19 | ╭─[ svc/svc.go:4:9 ] 20 | │ 21 | 2 │ 22 | 3 │ var secrets struct { 23 | 4 │ Foo int 24 | ⋮ ─┬─ 25 | ⋮ ╰─ got int 26 | 5 │ } 27 | 6 │ 28 | ───╯ 29 | 30 | For more information about how to use secrets, see https://encore.dev/docs/primitives/secrets 31 | -------------------------------------------------------------------------------- /v2/app/testdata/servicestruct_creates_service.txt: -------------------------------------------------------------------------------- 1 | # Verify that a service struct forces the creation of a service 2 | # even if it has no API's defined. 3 | 4 | parse 5 | output 'svc foobar ' 6 | 7 | -- foobar/svc.go -- 8 | package foobar 9 | 10 | import ( 11 | "context" 12 | ) 13 | 14 | //encore:service 15 | type Service struct {} 16 | -------------------------------------------------------------------------------- /v2/app/testdata/sqldb_cross_service.txt: -------------------------------------------------------------------------------- 1 | parse 2 | output 'svc svcb dbs=svca' 3 | 4 | -- svca/migrations/1_foo.up.sql -- 5 | -- svca/svca.go -- 6 | package svca 7 | 8 | import ( 9 | "context" 10 | 11 | "encore.dev/storage/sqldb" 12 | ) 13 | 14 | var Moo = sqldb.Named("svca") 15 | 16 | //encore:api public 17 | func Foo(ctx context.Context) error { 18 | return nil 19 | } 20 | -- svcb/svcb.go -- 21 | package svcb 22 | 23 | import ( 24 | "context" 25 | 26 | "test/svca" 27 | ) 28 | 29 | //encore:api public 30 | func Bar(ctx context.Context) error { 31 | _ = svca.Moo.Query() 32 | return nil 33 | } 34 | -------------------------------------------------------------------------------- /v2/app/testdata/sqldb_err_unknown_db_stdlib.txt: -------------------------------------------------------------------------------- 1 | ! parse 2 | 3 | -- svc/svc.go -- 4 | package svc 5 | 6 | import ( 7 | "context" 8 | 9 | "encore.dev/storage/sqldb" 10 | ) 11 | 12 | var Moo = sqldb.Named("unknown-db").Stdlib() 13 | 14 | //encore:api public 15 | func Foo(ctx context.Context) error { 16 | return nil 17 | } 18 | -- want: errors -- 19 | 20 | ── Unknown sqldb database ─────────────────────────────────────────────────────────────────[E9999]── 21 | 22 | No database named "unknown-db" was found in the application. Ensure it is created somewhere using 23 | sqldb.NewDatabase to be able to reference it. 24 | 25 | For more information about how to use databases in Encore, see 26 | https://encore.dev/docs/primitives/databases 27 | -------------------------------------------------------------------------------- /v2/app/testdata/sqldb_helper.txt: -------------------------------------------------------------------------------- 1 | parse 2 | output 'svc svc dbs=svc' 3 | output 'resource SQLDBResource svc.Moo db=svc' 4 | 5 | -- svc/migrations/1_dummy.up.sql -- 6 | -- svc/svc.go -- 7 | package svc 8 | 9 | import ( 10 | "context" 11 | "test/pkg" 12 | 13 | "encore.dev/storage/sqldb" 14 | ) 15 | 16 | var Moo = sqldb.Named("svc") 17 | 18 | //encore:api public 19 | func Foo(ctx context.Context) error { 20 | pkg.Foo(Moo) 21 | return nil 22 | } 23 | -- pkg/pkg.go -- 24 | package pkg 25 | 26 | import ( 27 | "context" 28 | 29 | "encore.dev/storage/sqldb" 30 | ) 31 | 32 | func Foo(db *sqldb.Database) { 33 | _ = db.Query 34 | } 35 | -------------------------------------------------------------------------------- /v2/app/testdata/sqldb_outside_svc.txt: -------------------------------------------------------------------------------- 1 | parse 2 | 3 | -- svc/migrations/1_dummy.up.sql -- 4 | -- svc/svc.go -- 5 | package svc 6 | 7 | import "context" 8 | 9 | //encore:api 10 | func Foo(ctx context.Context) error { return nil } 11 | -- pkg/pkg.go -- 12 | package pkg 13 | 14 | import ( 15 | "context" 16 | 17 | "encore.dev/storage/sqldb" 18 | ) 19 | 20 | var Moo = sqldb.Named("svc") 21 | -------------------------------------------------------------------------------- /v2/app/testdata/sqldb_outside_svc_test.txt: -------------------------------------------------------------------------------- 1 | parse 2 | 3 | -- svc/migrations/1_dummy.up.sql -- 4 | -- svc/svc.go -- 5 | package svc 6 | 7 | import "context" 8 | 9 | //encore:api 10 | func Foo(ctx context.Context) error { return nil } 11 | -- pkg/pkg_test.go -- 12 | package pkg 13 | 14 | import ( 15 | "context" 16 | 17 | "encore.dev/storage/sqldb" 18 | ) 19 | 20 | var Moo = sqldb.Named("svc") 21 | -------------------------------------------------------------------------------- /v2/app/testdata/sqldb_success.txt: -------------------------------------------------------------------------------- 1 | parse 2 | output 'svc myservice dbs=myservice' 3 | output 'resource SQLDBResource myservice.Moo db=myservice' 4 | 5 | -- myservice/migrations/1_foo.up.sql -- 6 | -- myservice/myservice.go -- 7 | package myservice 8 | 9 | import ( 10 | "context" 11 | 12 | "encore.dev/storage/sqldb" 13 | ) 14 | 15 | var Moo = sqldb.Named("myservice") 16 | 17 | //encore:api public 18 | func Foo(ctx context.Context) error { 19 | return nil 20 | } 21 | -- myservice/pkg/pkg.go -- 22 | package pkg 23 | 24 | import ( 25 | "context" 26 | "test/myservice" 27 | ) 28 | 29 | func Foo() { 30 | _ = myservice.Moo.Baz() 31 | } 32 | -------------------------------------------------------------------------------- /v2/app/testdata/sqldb_without_call.txt: -------------------------------------------------------------------------------- 1 | parse 2 | 3 | -- svc/migrations/1_dummy.up.sql -- 4 | -- svc/svc.go -- 5 | package svc 6 | 7 | import ( 8 | "context" 9 | 10 | "encore.dev/storage/sqldb" 11 | ) 12 | 13 | var Moo = sqldb.Named("svc") 14 | 15 | //encore:api public 16 | func Foo(ctx context.Context) error { 17 | return nil 18 | } 19 | -- svc/pkg/pkg.go -- 20 | package pkg 21 | 22 | import ( 23 | "context" 24 | "test/svc" 25 | ) 26 | 27 | func Foo() { 28 | _ = svc.Moo 29 | _ = svc.Moo.Query 30 | } 31 | -------------------------------------------------------------------------------- /v2/app/testdata/struct_duplicate_json_ignore.txt: -------------------------------------------------------------------------------- 1 | parse 2 | 3 | -- svc/svc.go -- 4 | package svc 5 | 6 | import ( 7 | "context" 8 | 9 | "encore.dev/beta/auth" 10 | ) 11 | 12 | type SomeStruct struct { 13 | A string `json:"-"` 14 | B string `json:"-"` 15 | } 16 | 17 | //encore:api public 18 | func Foo(ctx context.Context, p *SomeStruct) error { 19 | return nil 20 | } 21 | 22 | //encore:api public 23 | func Bar(ctx context.Context) (*SomeStruct, error) { 24 | return nil, nil 25 | } 26 | -------------------------------------------------------------------------------- /v2/app/testdata/type_ref_non_svc.txt: -------------------------------------------------------------------------------- 1 | parse 2 | 3 | -- svc/svc.go -- 4 | package svc 5 | 6 | import ( 7 | "context" 8 | "encore.dev/beta/auth" 9 | ) 10 | 11 | type FooParams struct { 12 | Name string 13 | } 14 | 15 | //encore:api public 16 | func Foo(ctx context.Context, p *FooParams) error { return nil } 17 | 18 | -- pkg/pkg.go -- 19 | package pkg 20 | 21 | import ( 22 | "context" 23 | "test/svc" 24 | ) 25 | 26 | func Test() { 27 | _ = &svc.FooParams{} 28 | } -------------------------------------------------------------------------------- /v2/app/validate_authhandlers.go: -------------------------------------------------------------------------------- 1 | package app 2 | 3 | import ( 4 | "encr.dev/v2/app/apiframework" 5 | "encr.dev/v2/internals/parsectx" 6 | ) 7 | 8 | func (d *Desc) validateAuthHandlers(pc *parsectx.Context, fw *apiframework.AppDesc) { 9 | handler, found := fw.AuthHandler.Get() 10 | if !found { 11 | return 12 | } 13 | 14 | // Validate the auth data can be marshalled 15 | // (the same validation we run on request/response types) 16 | if authData, found := handler.AuthData.Get(); found { 17 | d.validateType(pc, handler.Decl.AST.Type.Results.List[1].Type, authData.ToType()) 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /v2/codegen/apigen/middlewaregen/testdata/basic.txt: -------------------------------------------------------------------------------- 1 | -- basic.go -- 2 | package basic 3 | 4 | import ("context"; "encore.dev/middleware") 5 | 6 | //encore:middleware target=all 7 | func Middleware(req middleware.Request, next middleware.Next) middleware.Response { 8 | return next(req) 9 | } 10 | 11 | // Note: we need an API endpoint to be able to define service-specific middleware 12 | //encore:api 13 | func API(context.Context) error { return nil } 14 | -- want:encore_internal__middleware.go -- 15 | package basic 16 | 17 | import __api "encore.dev/appruntime/apisdk/api" 18 | 19 | var EncoreInternal_middleware_middleware_Middleware = &__api.Middleware{ 20 | DefLoc: uint32(0x0), 21 | Global: false, 22 | ID: "example.com.Middleware", 23 | Invoke: Middleware, 24 | Name: "Middleware", 25 | PkgName: "basic", 26 | } 27 | -------------------------------------------------------------------------------- /v2/codegen/apigen/middlewaregen/testdata/global.txt: -------------------------------------------------------------------------------- 1 | -- global.go -- 2 | package global 3 | 4 | import "encore.dev/middleware" 5 | 6 | //encore:middleware global target=all 7 | func Middleware(req middleware.Request, next middleware.Next) middleware.Response { 8 | return next(req) 9 | } 10 | -- want:encore_internal__middleware.go -- 11 | package global 12 | 13 | import __api "encore.dev/appruntime/apisdk/api" 14 | 15 | func init() { 16 | __api.RegisterGlobalMiddleware(EncoreInternal_middleware_middleware_Middleware) 17 | } 18 | 19 | var EncoreInternal_middleware_middleware_Middleware = &__api.Middleware{ 20 | DefLoc: uint32(0x0), 21 | Global: true, 22 | ID: "example.com.Middleware", 23 | Invoke: Middleware, 24 | Name: "Middleware", 25 | PkgName: "global", 26 | } 27 | -------------------------------------------------------------------------------- /v2/codegen/apigen/servicestructgen/servicestructgen_test.go: -------------------------------------------------------------------------------- 1 | package servicestructgen 2 | 3 | import ( 4 | "testing" 5 | 6 | "encr.dev/v2/app" 7 | "encr.dev/v2/codegen" 8 | "encr.dev/v2/codegen/internal/codegentest" 9 | ) 10 | 11 | func TestCodegen(t *testing.T) { 12 | fn := func(gen *codegen.Generator, desc *app.Desc) { 13 | svc := desc.Services[0] 14 | Gen(gen, svc, svc.Framework.MustGet().ServiceStruct.MustGet()) 15 | } 16 | 17 | codegentest.Run(t, fn) 18 | } 19 | -------------------------------------------------------------------------------- /v2/codegen/apigen/servicestructgen/testdata/basic.txt: -------------------------------------------------------------------------------- 1 | -- basic.go -- 2 | package basic 3 | 4 | import "context" 5 | 6 | //encore:service 7 | type Service struct { 8 | } 9 | 10 | //encore:api 11 | func API(context.Context) error { return nil } 12 | -- want:encore_internal__svcstruct.go -- 13 | package basic 14 | 15 | import __service "encore.dev/appruntime/apisdk/service" 16 | 17 | func init() { 18 | __service.Register(EncoreInternal_svcstruct_Service) 19 | } 20 | 21 | var EncoreInternal_svcstruct_Service = &__service.Decl[Service]{ 22 | Name: "Service", 23 | Service: "basic", 24 | Setup: nil, 25 | SetupDefLoc: uint32(0x0), 26 | } 27 | -------------------------------------------------------------------------------- /v2/codegen/apigen/servicestructgen/testdata/init_svc.txt: -------------------------------------------------------------------------------- 1 | -- basic.go -- 2 | package basic 3 | 4 | import "context" 5 | 6 | //encore:service 7 | type Service struct { 8 | } 9 | 10 | func initService() (*Service, error) { 11 | return nil, nil 12 | } 13 | 14 | //encore:api 15 | func API(context.Context) error { return nil } 16 | -- want:encore_internal__svcstruct.go -- 17 | package basic 18 | 19 | import __service "encore.dev/appruntime/apisdk/service" 20 | 21 | func init() { 22 | __service.Register(EncoreInternal_svcstruct_Service) 23 | } 24 | 25 | var EncoreInternal_svcstruct_Service = &__service.Decl[Service]{ 26 | Name: "Service", 27 | Service: "basic", 28 | Setup: initService, 29 | SetupDefLoc: uint32(0x0), 30 | } 31 | -------------------------------------------------------------------------------- /v2/codegen/apigen/userfacinggen/userfacinggen_test.go: -------------------------------------------------------------------------------- 1 | package userfacinggen 2 | 3 | import ( 4 | "testing" 5 | 6 | "encr.dev/pkg/option" 7 | "encr.dev/v2/app" 8 | "encr.dev/v2/codegen" 9 | "encr.dev/v2/codegen/apigen/servicestructgen" 10 | "encr.dev/v2/codegen/internal/codegentest" 11 | ) 12 | 13 | func TestCodegen(t *testing.T) { 14 | fn := func(gen *codegen.Generator, desc *app.Desc) { 15 | svc := desc.Services[0] 16 | var svcStruct option.Option[*codegen.VarDecl] 17 | if fw, ok := svc.Framework.Get(); ok { 18 | if ss, ok := fw.ServiceStruct.Get(); ok { 19 | decl := servicestructgen.Gen(gen, svc, ss) 20 | svcStruct = option.Some(decl) 21 | } 22 | } 23 | Gen(gen, svc, svcStruct) 24 | } 25 | codegentest.Run(t, fn) 26 | } 27 | -------------------------------------------------------------------------------- /v2/codegen/config.go: -------------------------------------------------------------------------------- 1 | package codegen 2 | 3 | import ( 4 | "encr.dev/v2/internals/pkginfo" 5 | ) 6 | 7 | // TestConfig describes common configuration for code generation 8 | // when running tests. 9 | type TestConfig struct { 10 | // Packages are the packages to generate test code for. 11 | Packages []*pkginfo.Package 12 | 13 | // EnvsToEmbed are the environment variables to embed inside 14 | // the test binaries themselves. This is useful when 15 | // building tests with "go test -c", where the binary is 16 | // built first and executed later (such as by GoLand). 17 | EnvsToEmbed map[string]string 18 | } 19 | -------------------------------------------------------------------------------- /v2/codegen/cuegen/errors.go: -------------------------------------------------------------------------------- 1 | package cuegen 2 | 3 | import "encr.dev/pkg/errors" 4 | 5 | var ( 6 | errRange = errors.Range( 7 | "cuegen", 8 | "", 9 | ) 10 | 11 | errNotNamedStruct = errRange.New( 12 | "Invalid type for config.Load", 13 | "The type argument passed to config.Load must be a named struct type.", 14 | ) 15 | 16 | errInvalidFieldLabel = errRange.New( 17 | "Invalid field label", 18 | "The field could not be rendered as a valid CUE label.", 19 | ) 20 | 21 | errInvalidCUEExpr = errRange.New( 22 | "Invalid CUE struct tag expression", 23 | "The struct tag expression is not a valid CUE expression.", 24 | ) 25 | ) 26 | -------------------------------------------------------------------------------- /v2/codegen/cuegen/testdata/basic_config.txt: -------------------------------------------------------------------------------- 1 | -- svc/svc.go -- 2 | package svc 3 | 4 | import ( 5 | "context" 6 | "time" 7 | 8 | "encore.dev/config" 9 | "encore.dev/types/uuid" 10 | ) 11 | 12 | type Config struct { 13 | Name string // The users name 14 | Port uint16 15 | ReadOnly bool // true if we're in read only mode 16 | 17 | // MagicNumber is complicated and requires 18 | // a multi-line comment to explain it. 19 | MagicNumber int 20 | 21 | ID uuid.UUID // An ID 22 | 23 | PublicKey []byte 24 | } 25 | 26 | var _ = config.Load[*Config]() 27 | 28 | //encore:api 29 | func MyAPI(ctx context.Context) (error) { 30 | return nil 31 | } 32 | -------------------------------------------------------------------------------- /v2/codegen/cuegen/testdata/basic_inline_struct.txt: -------------------------------------------------------------------------------- 1 | -- svc/svc.go -- 2 | package svc 3 | 4 | import ( 5 | "context" 6 | "time" 7 | 8 | "encore.dev/config" 9 | "encore.dev/types/uuid" 10 | ) 11 | 12 | type Config struct { 13 | // The options for the HTTP server 14 | HTTP struct { 15 | Enabled bool // Is this option enabled? 16 | Port uint32 // What port should we run on? 17 | } 18 | } 19 | 20 | var _ = config.Load[*Config]() 21 | 22 | //encore:api 23 | func MyAPI(ctx context.Context) (error) { 24 | return nil 25 | } 26 | -------------------------------------------------------------------------------- /v2/codegen/cuegen/testdata/basic_lists.txt: -------------------------------------------------------------------------------- 1 | -- svc/svc.go -- 2 | package svc 3 | 4 | import ( 5 | "context" 6 | "time" 7 | 8 | "encore.dev/config" 9 | "encore.dev/types/uuid" 10 | ) 11 | 12 | type Config struct { 13 | Ages []int32 14 | OtherBits []string 15 | } 16 | 17 | var _ = config.Load[*Config]() 18 | 19 | //encore:api 20 | func MyAPI(ctx context.Context) (error) { 21 | return nil 22 | } 23 | -------------------------------------------------------------------------------- /v2/codegen/cuegen/testdata/basic_maps.txt: -------------------------------------------------------------------------------- 1 | -- svc/svc.go -- 2 | package svc 3 | 4 | import ( 5 | "context" 6 | "time" 7 | 8 | "encore.dev/config" 9 | "encore.dev/types/uuid" 10 | ) 11 | 12 | type Config struct { 13 | Ages map[string]int 14 | } 15 | 16 | var _ = config.Load[*Config]() 17 | 18 | //encore:api 19 | func MyAPI(ctx context.Context) (error) { 20 | return nil 21 | } 22 | -------------------------------------------------------------------------------- /v2/codegen/cuegen/testdata/basic_named_struct_multiple_uses.txt: -------------------------------------------------------------------------------- 1 | -- svc/svc.go -- 2 | package svc 3 | 4 | import ( 5 | "context" 6 | "time" 7 | 8 | "encore.dev/config" 9 | "encore.dev/types/uuid" 10 | ) 11 | 12 | // ServerOptions represent options for a server 13 | type ServerOptions struct { 14 | Enabled bool // Is this option enabled? 15 | Port uint32 // What port should we run on? 16 | } 17 | 18 | type Config struct { 19 | HTTP ServerOptions // The options for the HTTP server 20 | TCP ServerOptions // The options for the TCP server 21 | GRPC ServerOptions // The options for the GRPC server 22 | } 23 | 24 | var _ = config.Load[*Config]() 25 | 26 | //encore:api 27 | func MyAPI(ctx context.Context) (error) { 28 | return nil 29 | } 30 | -------------------------------------------------------------------------------- /v2/codegen/cuegen/testdata/basic_named_struct_single_use.txt: -------------------------------------------------------------------------------- 1 | -- svc/svc.go -- 2 | package svc 3 | 4 | import ( 5 | "context" 6 | "time" 7 | 8 | "encore.dev/config" 9 | "encore.dev/types/uuid" 10 | ) 11 | 12 | type ServerOptions struct { 13 | Enabled bool // Is this option enabled? 14 | Port uint32 // What port should we run on? 15 | } 16 | 17 | type Config struct { 18 | HTTP ServerOptions // The options for the HTTP server 19 | } 20 | 21 | var _ = config.Load[*Config]() 22 | 23 | //encore:api 24 | func MyAPI(ctx context.Context) (error) { 25 | return nil 26 | } 27 | -------------------------------------------------------------------------------- /v2/codegen/cuegen/testdata/basic_no_config.txt: -------------------------------------------------------------------------------- 1 | -- svc/svc.go -- 2 | package svc 3 | 4 | import ( 5 | "context" 6 | ) 7 | 8 | //encore:api 9 | func MyAPI(ctx context.Context) (error) { 10 | return nil 11 | } 12 | -------------------------------------------------------------------------------- /v2/codegen/cuegen/testdata/basic_no_config_svc.cue: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/encoredev/encore/688fc65052cbb36c9016e632a52f95d68fe588f0/v2/codegen/cuegen/testdata/basic_no_config_svc.cue -------------------------------------------------------------------------------- /v2/codegen/cuegen/testdata/basic_with_cue_imports.txt: -------------------------------------------------------------------------------- 1 | -- svc/svc.go -- 2 | package svc 3 | 4 | import ( 5 | "context" 6 | "time" 7 | 8 | "encore.dev/config" 9 | ) 10 | 11 | type Config struct { 12 | SomeTime time.Time 13 | } 14 | 15 | var _ = config.Load[*Config]() 16 | 17 | //encore:api 18 | func MyAPI(ctx context.Context) (error) { 19 | return nil 20 | } 21 | -------------------------------------------------------------------------------- /v2/codegen/cuegen/testdata/cue_optional_tag.txt: -------------------------------------------------------------------------------- 1 | -- svc/svc.go -- 2 | package svc 3 | 4 | import ( 5 | "context" 6 | "time" 7 | 8 | "encore.dev/config" 9 | "encore.dev/types/uuid" 10 | ) 11 | 12 | type ServerOption struct { 13 | Option int64 14 | Disabled bool `cue:",opt"` // True if this is disabled 15 | } 16 | 17 | type Config struct { 18 | HTTP ServerOption 19 | Another ServerOption 20 | TCP ServerOption `cue:",opt"` 21 | GRPC ServerOption `cue:",opt"` 22 | } 23 | 24 | var _ = config.Load[*Config]() 25 | 26 | //encore:api 27 | func MyAPI(ctx context.Context) (error) { 28 | return nil 29 | } 30 | -------------------------------------------------------------------------------- /v2/codegen/cuegen/testdata/cue_tags.txt: -------------------------------------------------------------------------------- 1 | -- svc/svc.go -- 2 | package svc 3 | 4 | import ( 5 | "context" 6 | "time" 7 | 8 | "encore.dev/config" 9 | "encore.dev/types/uuid" 10 | ) 11 | 12 | type Config struct { 13 | A int 14 | B int `cue:"A+C"` 15 | C int `cue:"B-A"` 16 | } 17 | 18 | var _ = config.Load[*Config]() 19 | 20 | //encore:api 21 | func MyAPI(ctx context.Context) (error) { 22 | return nil 23 | } 24 | -------------------------------------------------------------------------------- /v2/codegen/cuegen/testdata/generic_top_level_type.txt: -------------------------------------------------------------------------------- 1 | -- svc/svc.go -- 2 | package svc 3 | 4 | import ( 5 | "context" 6 | "time" 7 | 8 | "encore.dev/config" 9 | "encore.dev/types/uuid" 10 | ) 11 | 12 | type Config[T int] struct { 13 | Value T `json:"value,omitempty"` // Some config 14 | } 15 | 16 | var _ = config.Load[*Config[uint]]() 17 | 18 | //encore:api 19 | func MyAPI(ctx context.Context) (error) { 20 | return nil 21 | } 22 | -------------------------------------------------------------------------------- /v2/codegen/cuegen/testdata/json_tags.txt: -------------------------------------------------------------------------------- 1 | -- svc/svc.go -- 2 | package svc 3 | 4 | import ( 5 | "context" 6 | "time" 7 | 8 | "encore.dev/config" 9 | "encore.dev/types/uuid" 10 | ) 11 | 12 | type ServerOption struct { 13 | Option int64 14 | Disabled bool `json:",omitempty"` // True if this is disabled 15 | } 16 | 17 | type Config struct { 18 | HTTP ServerOption 19 | Another ServerOption `json:"a_n_o_t_h_e_r"` 20 | TCP ServerOption `json:",omitempty"` 21 | GRPC ServerOption `json:",omitempty"` 22 | } 23 | 24 | var _ = config.Load[*Config]() 25 | 26 | //encore:api 27 | func MyAPI(ctx context.Context) (error) { 28 | return nil 29 | } 30 | -------------------------------------------------------------------------------- /v2/codegen/errors.go: -------------------------------------------------------------------------------- 1 | package codegen 2 | 3 | import "encr.dev/pkg/errors" 4 | 5 | var ( 6 | errRange = errors.Range( 7 | "codegen", 8 | "", 9 | ) 10 | 11 | errRender = errRange.New( 12 | "Failed to render codegen", 13 | "Generated code could not be parsed.", 14 | errors.MarkAsInternalError(), 15 | ) 16 | ) 17 | -------------------------------------------------------------------------------- /v2/codegen/infragen/configgen/configgen_test.go: -------------------------------------------------------------------------------- 1 | package configgen_test 2 | 3 | import ( 4 | "testing" 5 | 6 | "encr.dev/v2/app" 7 | "encr.dev/v2/codegen" 8 | "encr.dev/v2/codegen/infragen" 9 | "encr.dev/v2/codegen/internal/codegentest" 10 | ) 11 | 12 | func TestCodegen(t *testing.T) { 13 | fn := func(gen *codegen.Generator, desc *app.Desc) { 14 | infragen.Process(gen, desc) 15 | } 16 | 17 | codegentest.Run(t, fn) 18 | } 19 | -------------------------------------------------------------------------------- /v2/codegen/infragen/configgen/testdata/basic_no_config.txt: -------------------------------------------------------------------------------- 1 | -- svc/svc.go -- 2 | package svc 3 | 4 | import ( 5 | "context" 6 | ) 7 | 8 | //encore:api 9 | func MyAPI(ctx context.Context) (error) { 10 | return nil 11 | } 12 | -------------------------------------------------------------------------------- /v2/codegen/infragen/pubsubgen/pubsubgen_test.go: -------------------------------------------------------------------------------- 1 | package pubsubgen_test 2 | 3 | import ( 4 | "testing" 5 | 6 | "encr.dev/v2/app" 7 | "encr.dev/v2/codegen" 8 | "encr.dev/v2/codegen/infragen" 9 | "encr.dev/v2/codegen/internal/codegentest" 10 | ) 11 | 12 | func TestCodegen(t *testing.T) { 13 | fn := func(gen *codegen.Generator, desc *app.Desc) { 14 | infragen.Process(gen, desc) 15 | } 16 | 17 | codegentest.Run(t, fn) 18 | } 19 | -------------------------------------------------------------------------------- /v2/codegen/infragen/pubsubgen/testdata/basic.txt: -------------------------------------------------------------------------------- 1 | -- svc/svc.go -- 2 | package svc 3 | 4 | import ( 5 | "context" 6 | "encore.dev/pubsub" 7 | ) 8 | 9 | type Event struct {} 10 | 11 | var Topic = pubsub.NewTopic[*Event]("topic", pubsub.TopicConfig{ 12 | DeliveryGuarantee: pubsub.AtLeastOnce, 13 | }) 14 | 15 | var _ = pubsub.NewSubscription(Topic, "subscription", 16 | pubsub.SubscriptionConfig[*Event]{ 17 | Handler: func(ctx context.Context, event *Event) error { 18 | return nil 19 | }, 20 | }, 21 | ) 22 | -------------------------------------------------------------------------------- /v2/compiler/build/errors.go: -------------------------------------------------------------------------------- 1 | package build 2 | 3 | import ( 4 | "encr.dev/pkg/errors" 5 | ) 6 | 7 | var ( 8 | errRange = errors.Range("test", "", errors.WithRangeSize(20)) 9 | 10 | ErrTestFailed = errRange.New("Test Failure", "One or more more tests failed.") 11 | ) 12 | -------------------------------------------------------------------------------- /v2/compiler/build/testdata/basic.txt: -------------------------------------------------------------------------------- 1 | run example.com 2 | cmp stderr expected_output 3 | 4 | -- main.go -- 5 | package main 6 | func main() { 7 | println("Hello, world!") 8 | } 9 | -- go.mod -- 10 | module example.com 11 | 12 | -- expected_output -- 13 | Hello, world! 14 | -------------------------------------------------------------------------------- /v2/compiler/build/testdata/overlay.txt: -------------------------------------------------------------------------------- 1 | run example.com 2 | cmp stderr expected_output 3 | 4 | -- main.go -- 5 | package main 6 | func main() { 7 | } 8 | -- overlay:main.go -- 9 | package main 10 | func main() { 11 | OverlayPrint() // defined in overlay 12 | } 13 | -- overlay:print.go -- 14 | package main 15 | import ("fmt"; "os") 16 | func OverlayPrint() { 17 | fmt.Fprintln(os.Stderr, "Hello, overlay world!") 18 | } 19 | -- go.mod -- 20 | module example.com 21 | 22 | -- expected_output -- 23 | Hello, overlay world! 24 | -------------------------------------------------------------------------------- /v2/compiler/build/testdata/rewrite.txt: -------------------------------------------------------------------------------- 1 | run example.com 2 | cmp stderr expected_output 3 | 4 | -- main.go -- 5 | package main 6 | func main() { 7 | println("Hello, world!") 8 | } 9 | -- overlay:main.go -- 10 | package main 11 | func main() { 12 | println("Hello, rewritten world!") 13 | } 14 | -- go.mod -- 15 | module example.com 16 | 17 | -- expected_output -- 18 | Hello, rewritten world! 19 | -------------------------------------------------------------------------------- /v2/internals/pkginfo/errors.go: -------------------------------------------------------------------------------- 1 | package pkginfo 2 | 3 | import ( 4 | "encr.dev/pkg/errors" 5 | ) 6 | 7 | var ( 8 | errRange = errors.Range( 9 | "pkginfo", 10 | "", 11 | 12 | errors.WithRangeSize(25), 13 | ) 14 | 15 | errReadingGoMod = errRange.New( 16 | "Error Reading go.mod", 17 | "An error occurred while trying to read the go.mod file.", 18 | ) 19 | 20 | errInvalidModulePath = errRange.Newf( 21 | "Invalid Module Path", 22 | "The module path %q in the go.mod file is invalid.", 23 | ) 24 | 25 | errReadingFile = errRange.New( 26 | "Error Reading File", 27 | "An error occurred while trying to read a file.", 28 | ) 29 | 30 | errMatchingFile = errRange.New( 31 | "Error Matching File", 32 | "An error occurred while trying to match a file to the build.", 33 | ) 34 | ) 35 | -------------------------------------------------------------------------------- /v2/internals/scan/errors.go: -------------------------------------------------------------------------------- 1 | package scan 2 | 3 | import ( 4 | "encr.dev/pkg/errors" 5 | ) 6 | 7 | var ( 8 | errRange = errors.Range( 9 | "scan", 10 | "", 11 | errors.WithRangeSize(25), 12 | ) 13 | 14 | errResolvingModulePath = errRange.New( 15 | "Error Resolving Module Path", 16 | "An error occurred while trying to resolve the module path.", 17 | ) 18 | ) 19 | -------------------------------------------------------------------------------- /v2/internals/schema/errors.go: -------------------------------------------------------------------------------- 1 | package schema 2 | 3 | import ( 4 | "encr.dev/pkg/errors" 5 | ) 6 | 7 | var ( 8 | errRange = errors.Range( 9 | "schema", 10 | "For more information, see https://encore.dev/docs/develop/api-schemas", 11 | 12 | errors.WithRangeSize(10), 13 | ) 14 | 15 | errExpectedOnReciever = errRange.Newf( 16 | "Invalid receiver", 17 | "Expected exactly 1 receiver, got %d.", 18 | ) 19 | 20 | errUnknownIdentifier = errRange.Newf( 21 | "Unknown identifier", 22 | "Unknown identifier `%s`", 23 | ) 24 | 25 | errDeclIsntFunction = errRange.Newf( 26 | "Invalid declaration", 27 | "Declaration `%s` is not a function", 28 | ) 29 | ) 30 | -------------------------------------------------------------------------------- /v2/internals/schema/schemautil/astutil.go: -------------------------------------------------------------------------------- 1 | package schemautil 2 | 3 | import ( 4 | "go/ast" 5 | 6 | "encr.dev/pkg/option" 7 | ) 8 | 9 | // GetArgument gets the n'th argument from the field list. 10 | // It reports the name of the n'th argument if it has one. 11 | func GetArgument(fields *ast.FieldList, n int) (f *ast.Field, name option.Option[string]) { 12 | idx := 0 13 | for _, f := range fields.List { 14 | num := len(f.Names) 15 | if num == 0 { 16 | num = 1 17 | } 18 | for i := 0; i < num; i++ { 19 | if idx == n { 20 | var name option.Option[string] 21 | if hasName := i < len(f.Names); hasName { 22 | name = option.Some(f.Names[i].Name) 23 | } 24 | return f, name 25 | } 26 | idx++ 27 | } 28 | } 29 | return nil, option.None[string]() 30 | } 31 | -------------------------------------------------------------------------------- /v2/internals/schema/schemautil/errors.go: -------------------------------------------------------------------------------- 1 | package schemautil 2 | 3 | import ( 4 | "encr.dev/pkg/errors" 5 | ) 6 | 7 | var ( 8 | errRange = errors.Range( 9 | "schema", 10 | "For more information, see https://encore.dev/docs/develop/api-schemas", 11 | 12 | errors.WithRangeSize(10), 13 | ) 14 | 15 | errMissingTypeArg = errRange.New( 16 | "Missing type argument", 17 | "Missing type argument", 18 | ) 19 | ) 20 | -------------------------------------------------------------------------------- /v2/parser/apis/errors.go: -------------------------------------------------------------------------------- 1 | package apis 2 | 3 | import ( 4 | "encr.dev/pkg/errors" 5 | ) 6 | 7 | var ( 8 | errRange = errors.Range( 9 | "parser/apis", 10 | "", 11 | ) 12 | 13 | errUnexpectedDirective = errRange.Newf( 14 | "Invalid directive", 15 | "Unexpected directive %q on function declaration.", 16 | ) 17 | ) 18 | -------------------------------------------------------------------------------- /v2/parser/apis/selector/errors.go: -------------------------------------------------------------------------------- 1 | package selector 2 | 3 | import ( 4 | "encr.dev/pkg/errors" 5 | ) 6 | 7 | var ( 8 | errRange = errors.Range( 9 | "selector", 10 | "", 11 | 12 | errors.WithRangeSize(10), 13 | ) 14 | 15 | errMissingSelectorType = errRange.New( 16 | "Invalid Selector", 17 | "Missing selector type.", 18 | ) 19 | 20 | errUnknownSelectorType = errRange.Newf( 21 | "Invalid Selector", 22 | "Unknown selector type %q.", 23 | ) 24 | 25 | errInvalidSelectorValue = errRange.Newf( 26 | "Invalid Selector", 27 | "Invalid selector value %q.", 28 | ) 29 | ) 30 | -------------------------------------------------------------------------------- /v2/parser/apis/selector/selector_test.go: -------------------------------------------------------------------------------- 1 | package selector 2 | 3 | import "testing" 4 | 5 | func TestSet_ContainsAny(t *testing.T) { 6 | tests := []struct { 7 | name string 8 | set []Selector 9 | input []Selector 10 | want bool 11 | }{ 12 | { 13 | name: "empty_input", 14 | set: []Selector{{Type: All}}, 15 | input: nil, 16 | want: true, 17 | }, 18 | } 19 | for _, tt := range tests { 20 | t.Run(tt.name, func(t *testing.T) { 21 | s := NewSet(tt.set...) 22 | in := NewSet(tt.input...) 23 | if got := s.ContainsAny(in); got != tt.want { 24 | t.Errorf("ContainsAny() = %v, want %v", got, tt.want) 25 | } 26 | }) 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /v2/parser/apis/servicestruct/usage.go: -------------------------------------------------------------------------------- 1 | package servicestruct 2 | 3 | import ( 4 | "encr.dev/v2/parser/resource/usage" 5 | ) 6 | 7 | type Usage struct { 8 | usage.Base 9 | 10 | ServiceStruct *ServiceStruct 11 | } 12 | 13 | func ResolveServiceStructUsage(data usage.ResolveData, s *ServiceStruct) usage.Usage { 14 | return &Usage{ 15 | Base: usage.Base{ 16 | File: data.Expr.DeclaredIn(), 17 | Bind: data.Expr.ResourceBind(), 18 | Expr: data.Expr, 19 | }, 20 | ServiceStruct: s, 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /v2/parser/infra/caches/testdata/cluster.txt: -------------------------------------------------------------------------------- 1 | parse cache 2 | 3 | -- cluster.go -- 4 | package test 5 | 6 | import "encore.dev/storage/cache" 7 | 8 | var a = cache.NewCluster( // res CacheCluster: {"Name": "foo", "EvictionPolicy": "allkeys-lru"} 9 | "foo", cache.ClusterConfig{ 10 | EvictionPolicy: cache.AllKeysLRU, 11 | }, 12 | ) 13 | 14 | var b = cache.NewCluster( // ERR invalid "EvictionPolicy" value: "x" 15 | "foo", cache.ClusterConfig{ 16 | EvictionPolicy: "x", 17 | }, 18 | ) 19 | -------------------------------------------------------------------------------- /v2/parser/infra/caches/usage.go: -------------------------------------------------------------------------------- 1 | package caches 2 | 3 | import ( 4 | "encr.dev/v2/parser/resource/usage" 5 | ) 6 | 7 | type KeyspaceUsage struct { 8 | usage.Base 9 | 10 | Keyspace *Keyspace 11 | } 12 | 13 | func ResolveKeyspaceUsage(data usage.ResolveData, keyspace *Keyspace) usage.Usage { 14 | return &KeyspaceUsage{ 15 | Base: usage.Base{ 16 | File: data.Expr.DeclaredIn(), 17 | Bind: data.Expr.ResourceBind(), 18 | Expr: data.Expr, 19 | }, 20 | Keyspace: keyspace, 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /v2/parser/infra/config/usage.go: -------------------------------------------------------------------------------- 1 | package config 2 | 3 | import ( 4 | "encr.dev/v2/parser/resource/usage" 5 | ) 6 | 7 | type ReferenceUsage struct { 8 | usage.Base 9 | 10 | // Load is the config load being used. 11 | Cfg *Load 12 | } 13 | 14 | func ResolveConfigUsage(data usage.ResolveData, load *Load) usage.Usage { 15 | return &ReferenceUsage{ 16 | Base: usage.Base{ 17 | File: data.Expr.DeclaredIn(), 18 | Bind: data.Expr.ResourceBind(), 19 | Expr: data.Expr, 20 | }, 21 | Cfg: load, 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /v2/parser/infra/metrics/metrics_string.go: -------------------------------------------------------------------------------- 1 | // Code generated by "stringer -type=MetricType -output=metrics_string.go"; DO NOT EDIT. 2 | 3 | package metrics 4 | 5 | import "strconv" 6 | 7 | func _() { 8 | // An "invalid array index" compiler error signifies that the constant values have changed. 9 | // Re-run the stringer command to generate them again. 10 | var x [1]struct{} 11 | _ = x[Counter-0] 12 | _ = x[Gauge-1] 13 | } 14 | 15 | const _MetricType_name = "CounterGauge" 16 | 17 | var _MetricType_index = [...]uint8{0, 7, 12} 18 | 19 | func (i MetricType) String() string { 20 | if i < 0 || i >= MetricType(len(_MetricType_index)-1) { 21 | return "MetricType(" + strconv.FormatInt(int64(i), 10) + ")" 22 | } 23 | return _MetricType_name[_MetricType_index[i]:_MetricType_index[i+1]] 24 | } 25 | -------------------------------------------------------------------------------- /v2/parser/infra/sqldb/usage.go: -------------------------------------------------------------------------------- 1 | package sqldb 2 | 3 | import ( 4 | "encr.dev/v2/parser/resource/usage" 5 | ) 6 | 7 | type DatabaseUsage struct { 8 | usage.Base 9 | } 10 | 11 | func ResolveDatabaseUsage(data usage.ResolveData, db *Database) usage.Usage { 12 | return &DatabaseUsage{ 13 | Base: usage.Base{ 14 | File: data.Expr.DeclaredIn(), 15 | Bind: data.Expr.ResourceBind(), 16 | Expr: data.Expr, 17 | }, 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /v2/parser/resource/usage/testdata/pubsub_usage.txt: -------------------------------------------------------------------------------- 1 | -- svc/svc.go -- 2 | package svc 3 | 4 | import "encore.dev/pubsub" 5 | 6 | type Message struct{} 7 | 8 | var Topic = pubsub.NewTopic[*Message]("foo", pubsub.TopicConfig{ 9 | DeliveryGuarantee: pubsub.AtLeastOnce, 10 | }) 11 | 12 | var Sub = pubsub.NewSubscription(Topic, "bar", // use svc.Topic fn pubsub.NewSubscription arg 0 13 | pubsub.SubscriptionConfig{ 14 | Handler: func(m *Message) error { 15 | return nil 16 | }, 17 | }, 18 | ) 19 | 20 | func init() { 21 | Topic.Foo() // use svc.Topic call Foo 22 | } 23 | 24 | -- usage/usage.go -- 25 | package usage 26 | import "example.com/svc" 27 | 28 | var x = svc.Topic.Publish(svc.Message{}) // use svc.Topic call Publish 29 | var y = Topic.Publish(svc.Message{}) 30 | -------------------------------------------------------------------------------- /v2/parser/resource/usage/testdata/secret_usage.txt: -------------------------------------------------------------------------------- 1 | -- svc/svc.go -- 2 | package svc 3 | 4 | var secrets struct { 5 | Foo string 6 | } 7 | 8 | func init() { 9 | secrets.Foo // use svc.secrets field Foo 10 | x := secrets // use svc.secrets other 11 | } 12 | -------------------------------------------------------------------------------- /v2/parser/resource/usage/testdata/sqldb_usage.txt: -------------------------------------------------------------------------------- 1 | -- svc/migrations/1_foo.up.sql -- 2 | -- svc/svc.go -- 3 | package svc 4 | 5 | import "context" 6 | import "encore.dev/storage/sqldb" 7 | 8 | var DB = sqldb.Named("svc") 9 | 10 | func init() { 11 | DB.Foo() // use svc.DB call Foo 12 | DB.Foo // use svc.DB field Foo 13 | DB // use svc.DB other 14 | 15 | 1 + DB // use svc.DB other 16 | x = DB // use svc.DB other 17 | } 18 | 19 | //encore:api public 20 | func Dummy(context.Context) error { return nil } 21 | 22 | -- usage/usage.go -- 23 | package usage 24 | import "example.com/svc" 25 | 26 | var x = svc.DB.QueryRow() // use svc.DB call QueryRow 27 | var y = DB.Publish(svc.Message{}) 28 | --------------------------------------------------------------------------------