stacks 0.58.73 → 0.59.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/buddy/build.ts +38 -0
- package/{core/buddy → buddy}/compile.ts +1 -1
- package/buddy/dist/chunk-d2428b387d843985.js +2016 -0
- package/buddy/dist/cli.d.ts +1 -0
- package/{core/buddy → buddy}/dist/cli.js +23 -9
- package/buddy/dist/commands/build.d.ts +2 -0
- package/buddy/dist/commands/changelog.d.ts +2 -0
- package/buddy/dist/commands/clean.d.ts +2 -0
- package/buddy/dist/commands/cloud.d.ts +2 -0
- package/buddy/dist/commands/commit.d.ts +2 -0
- package/buddy/dist/commands/configure.d.ts +2 -0
- package/buddy/dist/commands/create.d.ts +2 -0
- package/buddy/dist/commands/deploy.d.ts +2 -0
- package/buddy/dist/commands/dev.d.ts +3 -0
- package/buddy/dist/commands/dns.d.ts +2 -0
- package/buddy/dist/commands/domains.d.ts +2 -0
- package/buddy/dist/commands/fresh.d.ts +2 -0
- package/buddy/dist/commands/generate.d.ts +2 -0
- package/buddy/dist/commands/http.d.ts +2 -0
- package/buddy/dist/commands/index.d.ts +31 -0
- package/buddy/dist/commands/install.d.ts +2 -0
- package/buddy/dist/commands/key.d.ts +2 -0
- package/buddy/dist/commands/lint.d.ts +2 -0
- package/buddy/dist/commands/list.d.ts +2 -0
- package/buddy/dist/commands/make.d.ts +2 -0
- package/buddy/dist/commands/migrate.d.ts +2 -0
- package/buddy/dist/commands/ports.d.ts +2 -0
- package/buddy/dist/commands/prepublish.d.ts +2 -0
- package/buddy/dist/commands/projects.d.ts +2 -0
- package/buddy/dist/commands/release.d.ts +2 -0
- package/buddy/dist/commands/seed.d.ts +2 -0
- package/buddy/dist/commands/setup.d.ts +4 -0
- package/buddy/dist/commands/test.d.ts +2 -0
- package/buddy/dist/commands/tinker.d.ts +2 -0
- package/buddy/dist/commands/types.d.ts +2 -0
- package/buddy/dist/commands/upgrade.d.ts +2 -0
- package/buddy/dist/commands/version.d.ts +2 -0
- package/buddy/dist/index.d.ts +1 -0
- package/{core/buddy → buddy}/dist/index.js +2 -5
- package/{core/buddy → buddy}/dist/stacks +0 -0
- package/{core/buddy → buddy}/package.json +1 -3
- package/{core/buddy → buddy}/src/cli.ts +18 -13
- package/{core/buddy → buddy}/src/commands/add.ts +1 -1
- package/{core/buddy → buddy}/src/commands/commit.ts +1 -1
- package/{core/buddy → buddy}/src/commands/deploy.ts +1 -1
- package/{core/buddy → buddy}/src/commands/dev.ts +1 -3
- package/{core/buddy → buddy}/src/commands/index.ts +0 -1
- package/{core/buddy → buddy}/src/commands/list.ts +1 -1
- package/{core/buddy → buddy}/src/commands/make.ts +28 -2
- package/buddy/src/commands/ports.ts +180 -0
- package/{core/buddy → buddy}/src/commands/prepublish.ts +1 -1
- package/{core/buddy → buddy}/src/commands/projects.ts +2 -3
- package/{core/buddy → buddy}/src/commands/setup.ts +1 -0
- package/{core/buddy → buddy}/src/commands/types.ts +1 -1
- package/buddy/tsconfig.tsbuildinfo +1 -0
- package/package.json +285 -285
- package/core/.simple-git-hooks.js +0 -3
- package/core/actions/README.md +0 -58
- package/core/actions/build.ts +0 -5
- package/core/actions/dist/src/add.js +0 -29
- package/core/actions/dist/src/build/component-libs.js +0 -6
- package/core/actions/dist/src/build/core.js +0 -21
- package/core/actions/dist/src/build/stacks.js +0 -8
- package/core/actions/dist/src/build.js +0 -219
- package/core/actions/dist/src/bump.js +0 -14
- package/core/actions/dist/src/changelog.js +0 -17
- package/core/actions/dist/src/clean.js +0 -6
- package/core/actions/dist/src/commit.js +0 -17
- package/core/actions/dist/src/copy-types.js +0 -14
- package/core/actions/dist/src/database/seed.js +0 -1
- package/core/actions/dist/src/deploy/index.js +0 -31
- package/core/actions/dist/src/dev/components.js +0 -11
- package/core/actions/dist/src/dev/docs.js +0 -7
- package/core/actions/dist/src/dev/index.js +0 -92
- package/core/actions/dist/src/examples.js +0 -43
- package/core/actions/dist/src/fresh.js +0 -18
- package/core/actions/dist/src/generate/component-meta.js +0 -59
- package/core/actions/dist/src/generate/ide-helpers.js +0 -91
- package/core/actions/dist/src/generate/index.js +0 -154
- package/core/actions/dist/src/generate/lib-entries.js +0 -170
- package/core/actions/dist/src/generate/vscode-custom-data.js +0 -91
- package/core/actions/dist/src/helpers/component-meta.js +0 -50
- package/core/actions/dist/src/helpers/index.js +0 -48
- package/core/actions/dist/src/helpers/lib-entries.js +0 -161
- package/core/actions/dist/src/helpers/package-json.js +0 -136
- package/core/actions/dist/src/helpers/utils.js +0 -48
- package/core/actions/dist/src/helpers/vscode-custom-data.js +0 -83
- package/core/actions/dist/src/index.js +0 -590
- package/core/actions/dist/src/key-generate.js +0 -10
- package/core/actions/dist/src/lint/fix.js +0 -12
- package/core/actions/dist/src/lint/index.js +0 -17
- package/core/actions/dist/src/make.js +0 -291
- package/core/actions/dist/src/prepublish.js +0 -14
- package/core/actions/dist/src/release.js +0 -559
- package/core/actions/dist/src/test/coverage.js +0 -6
- package/core/actions/dist/src/test/feature.js +0 -6
- package/core/actions/dist/src/test/ui.js +0 -6
- package/core/actions/dist/src/test/unit.js +0 -6
- package/core/actions/dist/src/test.js +0 -6
- package/core/actions/dist/src/tinker.js +0 -5
- package/core/actions/dist/src/typecheck.js +0 -6
- package/core/actions/dist/src/types.js +0 -21
- package/core/actions/dist/src/upgrade/dependencies.js +0 -6
- package/core/actions/dist/src/upgrade/framework.js +0 -1
- package/core/actions/dist/src/upgrade/index.js +0 -58
- package/core/actions/dist/src/upgrade.js +0 -47
- package/core/actions/package.json +0 -92
- package/core/actions/src/action.ts +0 -52
- package/core/actions/src/actions.ts +0 -2
- package/core/actions/src/add.ts +0 -27
- package/core/actions/src/ai/request-model-access.ts +0 -74
- package/core/actions/src/build/cli.ts +0 -7
- package/core/actions/src/build/component-libs.ts +0 -5
- package/core/actions/src/build/core.ts +0 -34
- package/core/actions/src/build/desktop.ts +0 -7
- package/core/actions/src/build/docs.ts +0 -7
- package/core/actions/src/build/server.ts +0 -9
- package/core/actions/src/build/stacks.ts +0 -7
- package/core/actions/src/build.ts +0 -89
- package/core/actions/src/bump.ts +0 -18
- package/core/actions/src/cdn/invalidate-cache.ts +0 -27
- package/core/actions/src/changelog.ts +0 -21
- package/core/actions/src/check/ports.ts +0 -24
- package/core/actions/src/clean.ts +0 -6
- package/core/actions/src/commit.ts +0 -14
- package/core/actions/src/copy-types.ts +0 -22
- package/core/actions/src/database/fields.ts +0 -111
- package/core/actions/src/database/migration-mysql.ts +0 -72
- package/core/actions/src/database/migration-sqlite.ts +0 -67
- package/core/actions/src/database/migration.ts +0 -10
- package/core/actions/src/database/seed.ts +0 -4
- package/core/actions/src/database/user-migration.ts +0 -20
- package/core/actions/src/deploy/create-receipt-rule.ts +0 -55
- package/core/actions/src/deploy/index.ts +0 -46
- package/core/actions/src/dev/api.ts +0 -18
- package/core/actions/src/dev/components.ts +0 -14
- package/core/actions/src/dev/dashboard.ts +0 -7
- package/core/actions/src/dev/desktop.ts +0 -7
- package/core/actions/src/dev/docs.ts +0 -7
- package/core/actions/src/dev/index.ts +0 -48
- package/core/actions/src/dev/system-tray.ts +0 -6
- package/core/actions/src/dev/views.ts +0 -7
- package/core/actions/src/domains/add.ts +0 -67
- package/core/actions/src/domains/purchase.ts +0 -76
- package/core/actions/src/domains/remove.ts +0 -38
- package/core/actions/src/examples.ts +0 -46
- package/core/actions/src/find-projects.ts +0 -21
- package/core/actions/src/fresh.ts +0 -20
- package/core/actions/src/generate/action-types.ts +0 -25
- package/core/actions/src/generate/caddyfile.ts +0 -44
- package/core/actions/src/generate/component-meta.ts +0 -19
- package/core/actions/src/generate/custom-cli-file.ts +0 -24
- package/core/actions/src/generate/env-files.ts +0 -89
- package/core/actions/src/generate/ide-helpers.ts +0 -18
- package/core/actions/src/generate/index.ts +0 -140
- package/core/actions/src/generate/lib-entries.ts +0 -18
- package/core/actions/src/generate/model-classes.ts +0 -299
- package/core/actions/src/generate/model-generate.ts +0 -12
- package/core/actions/src/generate/pkgx-file.ts +0 -72
- package/core/actions/src/generate/symlink-core.ts +0 -3
- package/core/actions/src/generate/types.ts +0 -6
- package/core/actions/src/generate/vscode-custom-data.ts +0 -19
- package/core/actions/src/generate/web-types.ts +0 -2
- package/core/actions/src/helpers/component-meta.ts +0 -93
- package/core/actions/src/helpers/index.ts +0 -1
- package/core/actions/src/helpers/lib-entries.ts +0 -139
- package/core/actions/src/helpers/package-json.ts +0 -96
- package/core/actions/src/helpers/utils.ts +0 -70
- package/core/actions/src/helpers/vscode-custom-data.ts +0 -35
- package/core/actions/src/index.ts +0 -29
- package/core/actions/src/key-generate.ts +0 -10
- package/core/actions/src/lint/fix.ts +0 -13
- package/core/actions/src/lint/index.ts +0 -27
- package/core/actions/src/make.ts +0 -322
- package/core/actions/src/migrate/database.ts +0 -1
- package/core/actions/src/migrate/dns.ts +0 -3
- package/core/actions/src/prepublish.ts +0 -17
- package/core/actions/src/release.ts +0 -18
- package/core/actions/src/start-caddy.ts +0 -13
- package/core/actions/src/test/coverage.ts +0 -5
- package/core/actions/src/test/feature.ts +0 -5
- package/core/actions/src/test/ui.ts +0 -5
- package/core/actions/src/test/unit.ts +0 -5
- package/core/actions/src/test.ts +0 -5
- package/core/actions/src/tinker.ts +0 -10
- package/core/actions/src/typecheck.ts +0 -5
- package/core/actions/src/types.ts +0 -20
- package/core/actions/src/upgrade/binary.ts +0 -43
- package/core/actions/src/upgrade/bun.ts +0 -4
- package/core/actions/src/upgrade/dependencies.ts +0 -0
- package/core/actions/src/upgrade/framework.ts +0 -30
- package/core/actions/src/upgrade/index.ts +0 -28
- package/core/actions/src/upgrade/shell.ts +0 -64
- package/core/actions/src/upgrade.ts +0 -68
- package/core/actions/tests/example.test.ts +0 -5
- package/core/ai/README.md +0 -67
- package/core/ai/build.ts +0 -9
- package/core/ai/dist/index.js +0 -10624
- package/core/ai/package.json +0 -60
- package/core/ai/src/chatbots.ts +0 -0
- package/core/ai/src/image-generation.ts +0 -0
- package/core/ai/src/index.ts +0 -8
- package/core/ai/src/personalization.ts +0 -0
- package/core/ai/src/search.ts +0 -0
- package/core/ai/src/text-generation.ts +0 -0
- package/core/ai/src/text-summary.ts +0 -0
- package/core/ai/src/utils/client-bedrock-runtime.ts +0 -38
- package/core/ai/src/utils/client-bedrock.ts +0 -53
- package/core/ai/tests/example.test.ts +0 -5
- package/core/ai/tsconfig.json +0 -3
- package/core/alias/README.md +0 -53
- package/core/alias/build.ts +0 -8
- package/core/alias/dist/index.js +0 -218
- package/core/alias/package.json +0 -52
- package/core/alias/src/index.ts +0 -220
- package/core/alias/tests/example.test.ts +0 -5
- package/core/alias/tsconfig.json +0 -3
- package/core/analytics/README.md +0 -55
- package/core/analytics/build.ts +0 -8
- package/core/analytics/dist/index.js +0 -5
- package/core/analytics/package.json +0 -55
- package/core/analytics/src/drivers/fathom.ts +0 -1
- package/core/analytics/src/drivers/index.ts +0 -1
- package/core/analytics/src/index.ts +0 -1
- package/core/analytics/tests/example.test.ts +0 -5
- package/core/analytics/tsconfig.json +0 -3
- package/core/api/build.ts +0 -7
- package/core/api/dist/index.js +0 -639
- package/core/api/package.json +0 -61
- package/core/api/src/index.ts +0 -115
- package/core/api/tsconfig.json +0 -3
- package/core/arrays/README.md +0 -59
- package/core/arrays/build.ts +0 -8
- package/core/arrays/dist/index.js +0 -469
- package/core/arrays/package.json +0 -60
- package/core/arrays/src/arr.ts +0 -3
- package/core/arrays/src/contains.ts +0 -87
- package/core/arrays/src/helpers.ts +0 -272
- package/core/arrays/src/index.ts +0 -3
- package/core/arrays/src/macro.ts +0 -131
- package/core/arrays/src/math.ts +0 -220
- package/core/arrays/tests/example.test.ts +0 -5
- package/core/arrays/tsconfig.json +0 -3
- package/core/auth/README.md +0 -59
- package/core/auth/build.ts +0 -8
- package/core/auth/dist/index.js +0 -5
- package/core/auth/package.json +0 -51
- package/core/auth/src/index.ts +0 -1
- package/core/auth/tests/example.test.ts +0 -5
- package/core/auth/tsconfig.json +0 -3
- package/core/buddy/build.ts +0 -8
- package/core/buddy/dist/chunk-1a569f35f66ae151.js +0 -10945
- package/core/buddy/dist/chunk-bf054cfbc9cf2201.js +0 -993
- package/core/buddy/src/commands/check.ts +0 -45
- package/core/buddy/src/commands/ports.ts +0 -73
- package/core/buddy/tsconfig.json +0 -3
- package/core/build/README.md +0 -59
- package/core/build/build.ts +0 -8
- package/core/build/dist/index.js +0 -19
- package/core/build/package.json +0 -64
- package/core/build/src/index.ts +0 -11
- package/core/build/tests/example.test.ts +0 -5
- package/core/build/tsconfig.json +0 -3
- package/core/build/web-types.config.cjs +0 -5
- package/core/build/web-types.ts +0 -15
- package/core/bun-create/bud/README.md +0 -45
- package/core/bun-create/bud/package.json +0 -151
- package/core/bun-create/buddy/README.md +0 -45
- package/core/bun-create/buddy/package.json +0 -150
- package/core/bun-create/stack/README.md +0 -45
- package/core/bun-create/stack/package.json +0 -150
- package/core/bun-create/stacks/README.md +0 -45
- package/core/bun-create/stacks/package.json +0 -150
- package/core/bun-create/stx/README.md +0 -45
- package/core/bun-create/stx/package.json +0 -151
- package/core/bun-plugin-yml/README.md +0 -56
- package/core/bun-plugin-yml/TODO.md +0 -1
- package/core/bun-plugin-yml/build.ts +0 -8
- package/core/bun-plugin-yml/dist/index.js +0 -2762
- package/core/bun-plugin-yml/package.json +0 -62
- package/core/bun-plugin-yml/src/index.ts +0 -21
- package/core/bun-plugin-yml/tests/example.test.ts +0 -5
- package/core/bun-plugin-yml/tsconfig.json +0 -3
- package/core/cache/README.md +0 -59
- package/core/cache/build.ts +0 -8
- package/core/cache/dist/index.js +0 -88
- package/core/cache/package.json +0 -66
- package/core/cache/src/drivers/dynamodb.ts +0 -119
- package/core/cache/src/drivers/index.ts +0 -2
- package/core/cache/src/drivers/redis.ts +0 -37
- package/core/cache/src/index.ts +0 -1
- package/core/cache/tests/DynamoDB.test.ts +0 -135
- package/core/cache/tests/Memcached.test.ts +0 -51
- package/core/cache/tests/Redis.test.ts +0 -84
- package/core/cache/tsconfig.json +0 -3
- package/core/chat/README.md +0 -83
- package/core/chat/build.ts +0 -8
- package/core/chat/dist/index.js +0 -42
- package/core/chat/package.json +0 -74
- package/core/chat/src/drivers/discord.ts +0 -15
- package/core/chat/src/drivers/slack.ts +0 -24
- package/core/chat/src/drivers/teams.ts +0 -24
- package/core/chat/src/index.ts +0 -3
- package/core/chat/tests/example.test.ts +0 -5
- package/core/chat/tsconfig.json +0 -3
- package/core/cli/README.md +0 -168
- package/core/cli/build.ts +0 -8
- package/core/cli/dist/index.js +0 -780
- package/core/cli/package.json +0 -92
- package/core/cli/src/actions/index.ts +0 -1
- package/core/cli/src/actions/install.ts +0 -40
- package/core/cli/src/cli.ts +0 -30
- package/core/cli/src/command.ts +0 -47
- package/core/cli/src/console.ts +0 -79
- package/core/cli/src/exec.ts +0 -114
- package/core/cli/src/helpers.ts +0 -80
- package/core/cli/src/index.ts +0 -10
- package/core/cli/src/parse.ts +0 -179
- package/core/cli/src/run.ts +0 -99
- package/core/cli/src/spinner.ts +0 -3
- package/core/cli/src/utils.ts +0 -82
- package/core/cli/tests/example.test.ts +0 -5
- package/core/cli/tsconfig.json +0 -3
- package/core/cloud/README.md +0 -67
- package/core/cloud/build.ts +0 -12
- package/core/cloud/dist/index.js +0 -2013
- package/core/cloud/dist/origin-request.js +0 -27
- package/core/cloud/package.json +0 -113
- package/core/cloud/src/cloud/ai.ts +0 -94
- package/core/cloud/src/cloud/aws-sdk-layer/nodejs/package-lock.json +0 -386
- package/core/cloud/src/cloud/aws-sdk-layer/nodejs/package.json +0 -15
- package/core/cloud/src/cloud/cache.ts +0 -0
- package/core/cloud/src/cloud/cdn.ts +0 -427
- package/core/cloud/src/cloud/cli.ts +0 -45
- package/core/cloud/src/cloud/compute.ts +0 -212
- package/core/cloud/src/cloud/dashboard.ts +0 -86
- package/core/cloud/src/cloud/database.ts +0 -0
- package/core/cloud/src/cloud/deployment.ts +0 -41
- package/core/cloud/src/cloud/dns.ts +0 -42
- package/core/cloud/src/cloud/docs.ts +0 -51
- package/core/cloud/src/cloud/email.ts +0 -339
- package/core/cloud/src/cloud/file-system.ts +0 -35
- package/core/cloud/src/cloud/index.ts +0 -135
- package/core/cloud/src/cloud/jump-box.ts +0 -48
- package/core/cloud/src/cloud/lambda/ask/index.js +0 -35
- package/core/cloud/src/cloud/lambda/cli-setup/index.js +0 -67
- package/core/cloud/src/cloud/lambda/summarize/index.js +0 -35
- package/core/cloud/src/cloud/network.ts +0 -32
- package/core/cloud/src/cloud/permissions.ts +0 -33
- package/core/cloud/src/cloud/queue.ts +0 -142
- package/core/cloud/src/cloud/redirects.ts +0 -45
- package/core/cloud/src/cloud/router-layer/nodejs/package.json +0 -15
- package/core/cloud/src/cloud/search-engine.ts +0 -108
- package/core/cloud/src/cloud/security.ts +0 -259
- package/core/cloud/src/cloud/storage.ts +0 -168
- package/core/cloud/src/edge/origin-request.ts +0 -49
- package/core/cloud/src/helpers.ts +0 -609
- package/core/cloud/src/index.ts +0 -2
- package/core/cloud/src/types.ts +0 -28
- package/core/cloud/tests/example.test.ts +0 -5
- package/core/cloud/tsconfig.json +0 -3
- package/core/cloud/zip.ts +0 -17
- package/core/collections/README.md +0 -71
- package/core/collections/build.ts +0 -8
- package/core/collections/dist/index.js +0 -6
- package/core/collections/package.json +0 -58
- package/core/collections/src/index.ts +0 -1
- package/core/collections/tests/example.test.ts +0 -5
- package/core/collections/tsconfig.json +0 -3
- package/core/config/README.md +0 -71
- package/core/config/build.ts +0 -8
- package/core/config/dist/index.js +0 -1823
- package/core/config/package.json +0 -54
- package/core/config/src/config.ts +0 -39
- package/core/config/src/defaults.ts +0 -481
- package/core/config/src/helpers.ts +0 -256
- package/core/config/src/index.ts +0 -2
- package/core/config/src/overrides.ts +0 -51
- package/core/config/tests/example.test.ts +0 -5
- package/core/config/tsconfig.json +0 -3
- package/core/custom-elements.json +0 -4
- package/core/database/README.md +0 -59
- package/core/database/build.ts +0 -8
- package/core/database/dist/index.js +0 -200
- package/core/database/package.json +0 -79
- package/core/database/src/index.ts +0 -63
- package/core/database/src/kysely-bun-worker/driver.ts +0 -144
- package/core/database/src/kysely-bun-worker/index.ts +0 -46
- package/core/database/src/kysely-bun-worker/mitt.ts +0 -24
- package/core/database/src/kysely-bun-worker/type.ts +0 -40
- package/core/database/src/kysely-bun-worker/worker.ts +0 -52
- package/core/database/src/migrations/index.ts +0 -73
- package/core/database/src/seeder/index.ts +0 -79
- package/core/database/tests/example.test.ts +0 -5
- package/core/database/tsconfig.json +0 -3
- package/core/datetime/README.md +0 -66
- package/core/datetime/build.ts +0 -8
- package/core/datetime/dist/index.js +0 -9
- package/core/datetime/package.json +0 -57
- package/core/datetime/src/index.ts +0 -7
- package/core/datetime/tests/example.test.ts +0 -5
- package/core/datetime/tsconfig.json +0 -3
- package/core/desktop/README.md +0 -49
- package/core/desktop/build.ts +0 -8
- package/core/desktop/dist/index.js +0 -3081
- package/core/desktop/package.json +0 -83
- package/core/desktop/src/index.ts +0 -43
- package/core/desktop/src/system-tray.ts +0 -1
- package/core/desktop/tests/example.test.ts +0 -5
- package/core/desktop/tsconfig.json +0 -3
- package/core/development/README.md +0 -27
- package/core/development/build.ts +0 -8
- package/core/development/dist/index.js +0 -6
- package/core/development/package.json +0 -77
- package/core/development/src/index.ts +0 -0
- package/core/development/tests/example.test.ts +0 -5
- package/core/development/tsconfig.json +0 -3
- package/core/dns/README.md +0 -56
- package/core/dns/build.ts +0 -8
- package/core/dns/dist/index.js +0 -166
- package/core/dns/package.json +0 -77
- package/core/dns/src/drivers/aws.ts +0 -224
- package/core/dns/src/index.ts +0 -20
- package/core/dns/tests/example.test.ts +0 -5
- package/core/dns/tsconfig.json +0 -3
- package/core/docs/README.md +0 -59
- package/core/docs/build.ts +0 -8
- package/core/docs/dist/index.js +0 -205
- package/core/docs/package.json +0 -70
- package/core/docs/src/index.ts +0 -67
- package/core/docs/src/meta.ts +0 -32
- package/core/docs/src/plugins.ts +0 -4
- package/core/docs/src/scripts/pwa.ts +0 -116
- package/core/docs/tests/example.test.ts +0 -5
- package/core/docs/tsconfig.json +0 -3
- package/core/email/README.md +0 -155
- package/core/email/build-inbound.ts +0 -8
- package/core/email/build.ts +0 -8
- package/core/email/dist/index.js +0 -306735
- package/core/email/email-forwarder.cjs +0 -407
- package/core/email/email-forwarder.zip +0 -0
- package/core/email/package.json +0 -69
- package/core/email/src/drivers/index.ts +0 -3
- package/core/email/src/drivers/mailgun.ts +0 -21
- package/core/email/src/drivers/nodemailer.ts +0 -23
- package/core/email/src/drivers/ses.ts +0 -22
- package/core/email/src/email.ts +0 -84
- package/core/email/src/index.ts +0 -3
- package/core/email/src/send.ts +0 -37
- package/core/email/src/server/converter.ts +0 -305
- package/core/email/src/server/inbound.ts +0 -406
- package/core/email/src/server/outbound.ts +0 -296
- package/core/email/src/template.ts +0 -18
- package/core/email/src/types.ts +0 -39
- package/core/email/src/utils/config.ts +0 -7
- package/core/email/tests/example.test.ts +0 -5
- package/core/email/tsconfig.json +0 -3
- package/core/enums/README.md +0 -54
- package/core/enums/build.ts +0 -8
- package/core/enums/dist/index.js +0 -105
- package/core/enums/package.json +0 -49
- package/core/enums/src/index.ts +0 -102
- package/core/enums/tests/example.test.ts +0 -5
- package/core/enums/tsconfig.json +0 -3
- package/core/env/README.md +0 -71
- package/core/env/build.ts +0 -8
- package/core/env/dist/index.js +0 -238
- package/core/env/package.json +0 -55
- package/core/env/src/index.ts +0 -76
- package/core/env/src/types.ts +0 -54
- package/core/env/src/utils.ts +0 -1
- package/core/env/tests/example.test.ts +0 -5
- package/core/env/tsconfig.json +0 -3
- package/core/error-handling/README.md +0 -131
- package/core/error-handling/build.ts +0 -8
- package/core/error-handling/dist/index.js +0 -432
- package/core/error-handling/package.json +0 -63
- package/core/error-handling/src/handler.ts +0 -51
- package/core/error-handling/src/index.ts +0 -2
- package/core/error-handling/tests/example.test.ts +0 -5
- package/core/error-handling/tsconfig.json +0 -3
- package/core/eslint-config/.gitattributes +0 -2
- package/core/eslint-config/README.md +0 -587
- package/core/eslint-config/build.ts +0 -8
- package/core/eslint-config/package.json +0 -122
- package/core/eslint-config/src/configs/comments.ts +0 -19
- package/core/eslint-config/src/configs/formatters.ts +0 -187
- package/core/eslint-config/src/configs/ignores.ts +0 -10
- package/core/eslint-config/src/configs/imports.ts +0 -46
- package/core/eslint-config/src/configs/index.ts +0 -21
- package/core/eslint-config/src/configs/javascript.ts +0 -226
- package/core/eslint-config/src/configs/jsdoc.ts +0 -42
- package/core/eslint-config/src/configs/jsonc.ts +0 -86
- package/core/eslint-config/src/configs/markdown.ts +0 -110
- package/core/eslint-config/src/configs/node.ts +0 -23
- package/core/eslint-config/src/configs/perfectionist.ts +0 -18
- package/core/eslint-config/src/configs/react.ts +0 -111
- package/core/eslint-config/src/configs/sort.ts +0 -223
- package/core/eslint-config/src/configs/stylistic.ts +0 -57
- package/core/eslint-config/src/configs/svelte.ts +0 -107
- package/core/eslint-config/src/configs/test.ts +0 -54
- package/core/eslint-config/src/configs/toml.ts +0 -72
- package/core/eslint-config/src/configs/typescript.ts +0 -157
- package/core/eslint-config/src/configs/unicorn.ts +0 -41
- package/core/eslint-config/src/configs/unocss.ts +0 -43
- package/core/eslint-config/src/configs/vue.ts +0 -168
- package/core/eslint-config/src/configs/yaml.ts +0 -72
- package/core/eslint-config/src/factory.ts +0 -255
- package/core/eslint-config/src/globs.ts +0 -91
- package/core/eslint-config/src/index.ts +0 -9
- package/core/eslint-config/src/plugins.ts +0 -10
- package/core/eslint-config/src/stub.d.ts +0 -3
- package/core/eslint-config/src/types.ts +0 -366
- package/core/eslint-config/src/utils.ts +0 -72
- package/core/eslint-config/src/vendor/prettier-types.ts +0 -136
- package/core/eslint-config/test/cli.spec.ts +0 -91
- package/core/eslint-config/test/fixtures.test.ts +0 -125
- package/core/eslint-config/tsconfig.json +0 -17
- package/core/eslint-config/tsup.config.ts +0 -8
- package/core/events/README.md +0 -76
- package/core/events/build.ts +0 -8
- package/core/events/dist/index.js +0 -63
- package/core/events/package.json +0 -53
- package/core/events/src/index.ts +0 -167
- package/core/events/tests/example.test.ts +0 -5
- package/core/events/tsconfig.json +0 -3
- package/core/faker/README.md +0 -53
- package/core/faker/build.ts +0 -8
- package/core/faker/dist/index.js +0 -6
- package/core/faker/package.json +0 -62
- package/core/faker/src/index.ts +0 -1
- package/core/faker/tests/example.test.ts +0 -5
- package/core/faker/tsconfig.json +0 -3
- package/core/git/README.md +0 -65
- package/core/git/build.ts +0 -8
- package/core/git/dist/index.js +0 -46
- package/core/git/package.json +0 -69
- package/core/git/src/index.ts +0 -63
- package/core/git/tests/example.test.ts +0 -5
- package/core/git/tsconfig.json +0 -3
- package/core/health/README.md +0 -56
- package/core/health/build.ts +0 -8
- package/core/health/dist/index.js +0 -9
- package/core/health/package.json +0 -59
- package/core/health/src/drivers/index.ts +0 -1
- package/core/health/src/drivers/ohdear.ts +0 -1
- package/core/health/src/index.ts +0 -2
- package/core/health/src/notifications/index.ts +0 -1
- package/core/health/tests/example.test.ts +0 -5
- package/core/health/tsconfig.json +0 -3
- package/core/http/README.md +0 -59
- package/core/http/build.ts +0 -8
- package/core/http/dist/index.js +0 -65
- package/core/http/package.json +0 -53
- package/core/http/src/index.ts +0 -71
- package/core/http/tsconfig.json +0 -3
- package/core/index.ts +0 -57
- package/core/lint/.eslintrc.json +0 -3
- package/core/lint/README.md +0 -73
- package/core/lint/build.ts +0 -8
- package/core/lint/dist/index.js +0 -6
- package/core/lint/package.json +0 -70
- package/core/lint/src/index.ts +0 -3
- package/core/lint/tests/example.test.ts +0 -5
- package/core/lint/tsconfig.json +0 -3
- package/core/logging/README.md +0 -58
- package/core/logging/build.ts +0 -8
- package/core/logging/dist/index.js +0 -90
- package/core/logging/package.json +0 -62
- package/core/logging/src/index.ts +0 -137
- package/core/logging/tests/example.test.ts +0 -5
- package/core/logging/tsconfig.json +0 -3
- package/core/notifications/README.md +0 -272
- package/core/notifications/build.ts +0 -8
- package/core/notifications/dist/index.js +0 -54
- package/core/notifications/package.json +0 -104
- package/core/notifications/src/drivers/chat.ts +0 -1
- package/core/notifications/src/drivers/email.ts +0 -1
- package/core/notifications/src/drivers/index.ts +0 -4
- package/core/notifications/src/drivers/push.ts +0 -1
- package/core/notifications/src/drivers/sms.ts +0 -1
- package/core/notifications/src/index.ts +0 -51
- package/core/notifications/src/tailwind.config.ts +0 -39
- package/core/notifications/src/utils/config.ts +0 -5
- package/core/notifications/src/utils/template.html +0 -8
- package/core/notifications/tests/chat/Slack.test.ts +0 -34
- package/core/notifications/tests/email/Mailgun.test.ts +0 -40
- package/core/notifications/tests/email/Sendgrid.test.ts +0 -40
- package/core/notifications/tests/sms/Twilio.test.ts +0 -37
- package/core/notifications/tsconfig.json +0 -3
- package/core/objects/README.md +0 -71
- package/core/objects/build.ts +0 -8
- package/core/objects/dist/index.js +0 -64
- package/core/objects/package.json +0 -64
- package/core/objects/src/index.ts +0 -145
- package/core/objects/tests/example.test.ts +0 -5
- package/core/objects/tsconfig.json +0 -3
- package/core/orm/README.md +0 -48
- package/core/orm/build.ts +0 -8
- package/core/orm/dist/index.js +0 -6
- package/core/orm/package.json +0 -60
- package/core/orm/src/index.ts +0 -49
- package/core/orm/tests/example.test.ts +0 -5
- package/core/orm/tsconfig.json +0 -3
- package/core/path/README.md +0 -64
- package/core/path/build.ts +0 -8
- package/core/path/dist/index.js +0 -587
- package/core/path/package.json +0 -55
- package/core/path/src/index.ts +0 -632
- package/core/path/tests/example.test.ts +0 -5
- package/core/path/tsconfig.json +0 -3
- package/core/payments/README.md +0 -64
- package/core/payments/build.ts +0 -8
- package/core/payments/dist/index.js +0 -6297
- package/core/payments/package.json +0 -61
- package/core/payments/src/drivers/stripe.ts +0 -116
- package/core/payments/src/index.ts +0 -1
- package/core/payments/tests/example.test.ts +0 -5
- package/core/payments/tsconfig.json +0 -3
- package/core/playwright.config.ts +0 -109
- package/core/push/README.md +0 -71
- package/core/push/build.ts +0 -9
- package/core/push/dist/index.js +0 -35
- package/core/push/package.json +0 -65
- package/core/push/src/drivers/expo.ts +0 -21
- package/core/push/src/drivers/fcm.ts +0 -21
- package/core/push/src/drivers/index.ts +0 -2
- package/core/push/src/index.ts +0 -1
- package/core/push/tests/example.test.ts +0 -5
- package/core/push/tsconfig.json +0 -3
- package/core/query-builder/README.md +0 -48
- package/core/query-builder/build.ts +0 -8
- package/core/query-builder/dist/index.js +0 -18
- package/core/query-builder/package.json +0 -60
- package/core/query-builder/src/index.ts +0 -1
- package/core/query-builder/src/kysely.ts +0 -38
- package/core/query-builder/tests/example.test.ts +0 -5
- package/core/query-builder/tsconfig.json +0 -3
- package/core/queue/README.md +0 -59
- package/core/queue/build.ts +0 -8
- package/core/queue/dist/index.js +0 -25
- package/core/queue/package.json +0 -56
- package/core/queue/src/index.ts +0 -23
- package/core/queue/tests/example.test.ts +0 -5
- package/core/queue/tsconfig.json +0 -3
- package/core/raycast/package.json +0 -9
- package/core/raycast/src/index.ts +0 -0
- package/core/realtime/README.md +0 -59
- package/core/realtime/build.ts +0 -8
- package/core/realtime/dist/index.js +0 -6
- package/core/realtime/package.json +0 -53
- package/core/realtime/src/drivers/index.ts +0 -1
- package/core/realtime/src/index.ts +0 -1
- package/core/realtime/tests/example.test.ts +0 -5
- package/core/realtime/tsconfig.json +0 -3
- package/core/repl/README.md +0 -53
- package/core/repl/build.ts +0 -8
- package/core/repl/dist/index.js +0 -6
- package/core/repl/package.json +0 -60
- package/core/repl/src/index.ts +0 -1
- package/core/repl/tests/example.test.ts +0 -5
- package/core/repl/tsconfig.json +0 -3
- package/core/router/README.md +0 -59
- package/core/router/build.ts +0 -8
- package/core/router/dist/index.js +0 -1544
- package/core/router/package.json +0 -64
- package/core/router/src/index.ts +0 -4
- package/core/router/src/middleware.ts +0 -34
- package/core/router/src/request.ts +0 -44
- package/core/router/src/router.ts +0 -310
- package/core/router/src/server.ts +0 -173
- package/core/router/tests/example.test.ts +0 -5
- package/core/router/tsconfig.json +0 -3
- package/core/scheduler/README.md +0 -137
- package/core/scheduler/build.ts +0 -8
- package/core/scheduler/dist/index.js +0 -742
- package/core/scheduler/package.json +0 -62
- package/core/scheduler/src/constants.ts +0 -81
- package/core/scheduler/src/errors.ts +0 -7
- package/core/scheduler/src/index.ts +0 -20
- package/core/scheduler/src/job.ts +0 -315
- package/core/scheduler/src/schedule.ts +0 -116
- package/core/scheduler/src/time.ts +0 -823
- package/core/scheduler/src/types/cron.ts +0 -98
- package/core/scheduler/src/types/utils.ts +0 -14
- package/core/scheduler/src/utils.ts +0 -19
- package/core/scheduler/tests/cron.fuzz.ts +0 -120
- package/core/scheduler/tests/cron.test.ts +0 -1243
- package/core/scheduler/tests/crontime.test.ts +0 -780
- package/core/scheduler/tsconfig.json +0 -3
- package/core/search-engine/README.md +0 -66
- package/core/search-engine/build.ts +0 -8
- package/core/search-engine/dist/index.js +0 -87
- package/core/search-engine/package.json +0 -68
- package/core/search-engine/src/drivers/index.ts +0 -1
- package/core/search-engine/src/drivers/meilisearch.ts +0 -124
- package/core/search-engine/src/drivers/opensearch.ts +0 -59
- package/core/search-engine/src/helpers.ts +0 -138
- package/core/search-engine/src/index.ts +0 -69
- package/core/search-engine/tests/example.test.ts +0 -5
- package/core/search-engine/tsconfig.json +0 -3
- package/core/security/README.md +0 -66
- package/core/security/build.ts +0 -8
- package/core/security/dist/index.js +0 -3285
- package/core/security/package.json +0 -66
- package/core/security/src/crypt.ts +0 -23
- package/core/security/src/hash.ts +0 -54
- package/core/security/src/index.ts +0 -3
- package/core/security/src/key.ts +0 -11
- package/core/security/tests/example.test.ts +0 -5
- package/core/security/tsconfig.json +0 -3
- package/core/server/README.md +0 -51
- package/core/server/build.ts +0 -8
- package/core/server/dist/index.js +0 -13591
- package/core/server/package.json +0 -68
- package/core/server/src/config.ts +0 -76
- package/core/server/src/index.ts +0 -1
- package/core/server/tests/example.test.ts +0 -5
- package/core/server/tsconfig.json +0 -3
- package/core/shell/README.md +0 -55
- package/core/shell/build.ts +0 -8
- package/core/shell/dist/index.js +0 -6
- package/core/shell/package.json +0 -39
- package/core/shell/src/buddy.plugin.zsh +0 -120
- package/core/shell/src/index.ts +0 -1
- package/core/signals/README.md +0 -105
- package/core/signals/build.ts +0 -8
- package/core/signals/dist/index.js +0 -9
- package/core/signals/package.json +0 -64
- package/core/signals/src/index.ts +0 -1
- package/core/signals/tests/example.test.ts +0 -5
- package/core/signals/tsconfig.json +0 -3
- package/core/slug/README.md +0 -59
- package/core/slug/build.ts +0 -8
- package/core/slug/dist/index.js +0 -5
- package/core/slug/package.json +0 -66
- package/core/slug/src/index.ts +0 -56
- package/core/slug/tests/example.test.ts +0 -5
- package/core/slug/tsconfig.json +0 -3
- package/core/sms/README.md +0 -137
- package/core/sms/build.ts +0 -9
- package/core/sms/dist/index.js +0 -240
- package/core/sms/package.json +0 -83
- package/core/sms/src/drivers/gupshup.ts +0 -21
- package/core/sms/src/drivers/index.ts +0 -8
- package/core/sms/src/drivers/nexmo.ts +0 -23
- package/core/sms/src/drivers/plivo.ts +0 -23
- package/core/sms/src/drivers/sms77.ts +0 -22
- package/core/sms/src/drivers/sns.ts +0 -22
- package/core/sms/src/drivers/telnyx.ts +0 -23
- package/core/sms/src/drivers/termii.ts +0 -22
- package/core/sms/src/drivers/twilio.ts +0 -23
- package/core/sms/src/index.ts +0 -1
- package/core/sms/tests/example.test.ts +0 -5
- package/core/sms/tsconfig.json +0 -3
- package/core/storage/README.md +0 -74
- package/core/storage/build.ts +0 -8
- package/core/storage/dist/index.js +0 -816
- package/core/storage/package.json +0 -78
- package/core/storage/src/copy.ts +0 -42
- package/core/storage/src/delete.ts +0 -131
- package/core/storage/src/drivers/aws.ts +0 -15
- package/core/storage/src/drivers/index.ts +0 -1
- package/core/storage/src/files.ts +0 -187
- package/core/storage/src/folders.ts +0 -51
- package/core/storage/src/fs.ts +0 -9
- package/core/storage/src/glob.ts +0 -1
- package/core/storage/src/hash.ts +0 -39
- package/core/storage/src/helpers.ts +0 -29
- package/core/storage/src/index.ts +0 -11
- package/core/storage/src/move.ts +0 -84
- package/core/storage/src/storage.ts +0 -10
- package/core/storage/src/visibility.ts +0 -6
- package/core/storage/src/zip.ts +0 -55
- package/core/storage/tests/example.test.ts +0 -5
- package/core/storage/tsconfig.json +0 -3
- package/core/strings/README.md +0 -137
- package/core/strings/build.ts +0 -9
- package/core/strings/dist/index.js +0 -393
- package/core/strings/package.json +0 -82
- package/core/strings/src/case.ts +0 -27
- package/core/strings/src/helpers.ts +0 -3
- package/core/strings/src/index.ts +0 -2
- package/core/strings/src/is.ts +0 -170
- package/core/strings/src/macro.ts +0 -131
- package/core/strings/src/pluralize.ts +0 -26
- package/core/strings/src/string.ts +0 -5
- package/core/strings/src/types.ts +0 -4
- package/core/strings/src/utils.ts +0 -117
- package/core/strings/tests/example.test.ts +0 -5
- package/core/strings/tsconfig.json +0 -3
- package/core/tables/README.md +0 -110
- package/core/tables/examples/vue/App.stx +0 -12
- package/core/tables/examples/vue/favicon.png +0 -0
- package/core/tables/examples/vue/index.html +0 -20
- package/core/tables/examples/web/favicon.png +0 -0
- package/core/tables/examples/web/index.html +0 -13
- package/core/tables/index.html +0 -13
- package/core/tables/package.json +0 -57
- package/core/tables/src/App.stx +0 -23
- package/core/tables/src/commands/index.ts +0 -1
- package/core/tables/src/components/Demo.stx +0 -84
- package/core/tables/src/components/README.md +0 -109
- package/core/tables/src/components/Table.stx +0 -342
- package/core/tables/src/components/TableBody.stx +0 -32
- package/core/tables/src/components/TableCellActionItems.stx +0 -9
- package/core/tables/src/components/TableFilters.stx +0 -704
- package/core/tables/src/components/TableHead.stx +0 -60
- package/core/tables/src/components/TablePagination.stx +0 -131
- package/core/tables/src/components/TableRow.stx +0 -73
- package/core/tables/src/components/TableSearch.stx +0 -39
- package/core/tables/src/components/Tooltip.stx +0 -10
- package/core/tables/src/components.d.ts +0 -24
- package/core/tables/src/config/tables.ts +0 -2
- package/core/tables/src/docs/index.md +0 -0
- package/core/tables/src/functions/README.md +0 -8
- package/core/tables/src/functions/dark.ts +0 -3
- package/core/tables/src/functions/index.ts +0 -2
- package/core/tables/src/functions/table.ts +0 -207
- package/core/tables/src/main.ts +0 -4
- package/core/tables/tests/example.test.ts +0 -5
- package/core/tables/tsconfig.json +0 -3
- package/core/testing/README.md +0 -59
- package/core/testing/build.ts +0 -8
- package/core/testing/dist/index.js +0 -15025
- package/core/testing/package.json +0 -65
- package/core/testing/src/index.ts +0 -13
- package/core/testing/tsconfig.json +0 -3
- package/core/tinker/package.json +0 -47
- package/core/tinker/src/index.ts +0 -1
- package/core/tinker/tsconfig.json +0 -3
- package/core/tmp.json +0 -0
- package/core/tsconfig.json +0 -83
- package/core/tunnel/README.md +0 -53
- package/core/tunnel/build.ts +0 -8
- package/core/tunnel/dist/index.js +0 -10
- package/core/tunnel/package.json +0 -58
- package/core/tunnel/src/index.ts +0 -6
- package/core/tunnel/tests/example.test.ts +0 -5
- package/core/tunnel/tsconfig.json +0 -3
- package/core/types/README.md +0 -59
- package/core/types/build.ts +0 -8
- package/core/types/dist/index.js +0 -2285
- package/core/types/package.json +0 -87
- package/core/types/src/ai.ts +0 -26
- package/core/types/src/analytics.ts +0 -21
- package/core/types/src/api.ts +0 -65
- package/core/types/src/app.ts +0 -151
- package/core/types/src/auto-imports.ts +0 -1
- package/core/types/src/binary.ts +0 -13
- package/core/types/src/build.ts +0 -2
- package/core/types/src/cache.ts +0 -98
- package/core/types/src/cdn.ts +0 -17
- package/core/types/src/chat.ts +0 -5
- package/core/types/src/cli.ts +0 -333
- package/core/types/src/cloud.ts +0 -105
- package/core/types/src/components.ts +0 -64
- package/core/types/src/configure.ts +0 -13
- package/core/types/src/cron-jobs.ts +0 -51
- package/core/types/src/database.ts +0 -45
- package/core/types/src/dependencies.ts +0 -69
- package/core/types/src/deploy.ts +0 -13
- package/core/types/src/dns.ts +0 -186
- package/core/types/src/docs.ts +0 -26
- package/core/types/src/email.ts +0 -19
- package/core/types/src/env.ts +0 -1
- package/core/types/src/errors.ts +0 -11
- package/core/types/src/events.ts +0 -30
- package/core/types/src/exit-code.ts +0 -10
- package/core/types/src/file-systems.ts +0 -70
- package/core/types/src/git.ts +0 -133
- package/core/types/src/hashing.ts +0 -131
- package/core/types/src/helpers.ts +0 -11
- package/core/types/src/i18n.ts +0 -19
- package/core/types/src/index.ts +0 -61
- package/core/types/src/inspect.ts +0 -10
- package/core/types/src/layout.ts +0 -8
- package/core/types/src/library.ts +0 -156
- package/core/types/src/logger.ts +0 -54
- package/core/types/src/manifest.ts +0 -9
- package/core/types/src/model.ts +0 -72
- package/core/types/src/money.ts +0 -3
- package/core/types/src/native.ts +0 -0
- package/core/types/src/notifications.ts +0 -147
- package/core/types/src/pages.ts +0 -10
- package/core/types/src/payments.ts +0 -65
- package/core/types/src/ports.ts +0 -19
- package/core/types/src/promise.ts +0 -1
- package/core/types/src/push.ts +0 -36
- package/core/types/src/pwa.ts +0 -8
- package/core/types/src/queue.ts +0 -38
- package/core/types/src/reactivity.ts +0 -1
- package/core/types/src/request.ts +0 -3
- package/core/types/src/router.ts +0 -73
- package/core/types/src/scheduler.ts +0 -1
- package/core/types/src/search-engine.ts +0 -136
- package/core/types/src/security.ts +0 -23
- package/core/types/src/services.ts +0 -44
- package/core/types/src/sms.ts +0 -5
- package/core/types/src/ssg.ts +0 -3
- package/core/types/src/stacks.ts +0 -246
- package/core/types/src/storage.ts +0 -13
- package/core/types/src/tables.ts +0 -57
- package/core/types/src/team.ts +0 -8
- package/core/types/src/ui.ts +0 -189
- package/core/types/src/utils.ts +0 -47
- package/core/types/tsconfig.json +0 -3
- package/core/ui/README.md +0 -66
- package/core/ui/build.ts +0 -8
- package/core/ui/dist/components.js +0 -68
- package/core/ui/dist/index.js +0 -121
- package/core/ui/package.json +0 -93
- package/core/ui/src/components/autocomplete.ts +0 -0
- package/core/ui/src/components/disclosure.ts +0 -5
- package/core/ui/src/components/menu.ts +0 -1
- package/core/ui/src/components/modal.ts +0 -6
- package/core/ui/src/components/popover.ts +0 -1
- package/core/ui/src/components/radio-group.ts +0 -5
- package/core/ui/src/components/select.ts +0 -6
- package/core/ui/src/components/tabs.ts +0 -1
- package/core/ui/src/components/toggle.ts +0 -1
- package/core/ui/src/components/transition.ts +0 -1
- package/core/ui/src/components.ts +0 -10
- package/core/ui/src/index.ts +0 -15
- package/core/ui/src/uno.config.ts +0 -66
- package/core/ui/tests/example.test.ts +0 -5
- package/core/ui/tsconfig.json +0 -3
- package/core/utils/build.ts +0 -8
- package/core/utils/dist/index.js +0 -3240
- package/core/utils/package.json +0 -111
- package/core/utils/scripts/export-size.ts +0 -94
- package/core/utils/src/base.ts +0 -12
- package/core/utils/src/clean.ts +0 -17
- package/core/utils/src/config.ts +0 -25
- package/core/utils/src/currency.ts +0 -29
- package/core/utils/src/debounce.ts +0 -1
- package/core/utils/src/delete.ts +0 -1
- package/core/utils/src/equal.ts +0 -27
- package/core/utils/src/export-size.ts +0 -1
- package/core/utils/src/find.ts +0 -91
- package/core/utils/src/function.ts +0 -32
- package/core/utils/src/git.ts +0 -11
- package/core/utils/src/glob.ts +0 -1
- package/core/utils/src/guards.ts +0 -39
- package/core/utils/src/hash.ts +0 -26
- package/core/utils/src/helpers.ts +0 -187
- package/core/utils/src/index.ts +0 -24
- package/core/utils/src/macroable.ts +0 -1
- package/core/utils/src/math.ts +0 -30
- package/core/utils/src/p.ts +0 -119
- package/core/utils/src/promise.ts +0 -117
- package/core/utils/src/regex.ts +0 -2
- package/core/utils/src/retry.ts +0 -33
- package/core/utils/src/sleep.ts +0 -60
- package/core/utils/src/throttle.ts +0 -44
- package/core/utils/src/vendors.ts +0 -258
- package/core/utils/src/versions.ts +0 -6
- package/core/utils/tests/example.test.ts +0 -5
- package/core/utils/tsconfig.json +0 -3
- package/core/validation/README.md +0 -53
- package/core/validation/build.ts +0 -5
- package/core/validation/dist/index.js +0 -187
- package/core/validation/package.json +0 -64
- package/core/validation/src/index.ts +0 -4
- package/core/validation/src/is.ts +0 -111
- package/core/validation/src/rules.ts +0 -126
- package/core/validation/src/types/index.ts +0 -7
- package/core/validation/src/types/money.ts +0 -17
- package/core/validation/src/validate.ts +0 -33
- package/core/validation/tests/example.test.ts +0 -5
- package/core/validation/tsconfig.json +0 -3
- package/core/vite/README.md +0 -59
- package/core/vite/build.ts +0 -9
- package/core/vite/dist/index.js +0 -644
- package/core/vite/package.json +0 -122
- package/core/vite/src/api.ts +0 -18
- package/core/vite/src/components.ts +0 -79
- package/core/vite/src/dashboard.ts +0 -100
- package/core/vite/src/desktop.ts +0 -3
- package/core/vite/src/example-vue.ts +0 -20
- package/core/vite/src/example-wc.ts +0 -24
- package/core/vite/src/functions.ts +0 -54
- package/core/vite/src/index.ts +0 -18
- package/core/vite/src/plugin/auto-imports.ts +0 -39
- package/core/vite/src/plugin/components.ts +0 -17
- package/core/vite/src/plugin/css-engine.ts +0 -18
- package/core/vite/src/plugin/devtools.ts +0 -1
- package/core/vite/src/plugin/docs.ts +0 -18
- package/core/vite/src/plugin/fonts.ts +0 -6
- package/core/vite/src/plugin/i18n.ts +0 -13
- package/core/vite/src/plugin/inspect.ts +0 -6
- package/core/vite/src/plugin/layouts.ts +0 -17
- package/core/vite/src/plugin/markdown.ts +0 -26
- package/core/vite/src/plugin/pages.ts +0 -34
- package/core/vite/src/plugin/presets.ts +0 -17
- package/core/vite/src/plugin/pwa.ts +0 -33
- package/core/vite/src/plugin/router.ts +0 -17
- package/core/vite/src/plugin/stacks.ts +0 -150
- package/core/vite/src/plugin/ui-engine.ts +0 -19
- package/core/vite/src/plugins.ts +0 -12
- package/core/vite/src/system-tray.ts +0 -100
- package/core/vite/src/views.ts +0 -97
- package/core/vite/src/web-components.ts +0 -67
- package/core/vite/tests/example.test.ts +0 -5
- package/core/vite/tsconfig.json +0 -3
- package/core/web-types.json +0 -67
- package/core/whois/README.md +0 -55
- package/core/whois/build.ts +0 -8
- package/core/whois/dist/index.js +0 -600
- package/core/whois/package.json +0 -61
- package/core/whois/src/index.ts +0 -499
- package/core/whois/src/parameters.ts +0 -4
- package/core/whois/src/servers.ts +0 -318
- package/core/whois/src/test.ts +0 -5
- package/core/whois/tests/example.test.ts +0 -5
- package/core/whois/tsconfig.json +0 -3
- package/core/x-ray/README.md +0 -55
- package/core/x-ray/index.html +0 -13
- package/core/x-ray/package.json +0 -53
- package/core/x-ray/routes/index.ts +0 -19
- package/core/x-ray/src/client.ts +0 -14
- package/core/x-ray/src/desktop/api/nitro.config.ts +0 -19
- package/core/x-ray/src/desktop/api/routes/api/logs.ts +0 -7
- package/core/x-ray/src/desktop/api/routes/api/store-logs.ts +0 -22
- package/core/x-ray/src/desktop/api/src/types.ts +0 -7
- package/core/x-ray/src/desktop/api/storage/index.ts +0 -7
- package/core/x-ray/src/desktop/app.stx +0 -377
- package/core/x-ray/src/desktop/functions/http.ts +0 -26
- package/core/x-ray/src/desktop/functions/types.ts +0 -7
- package/core/x-ray/src/desktop/main.ts +0 -8
- package/core/x-ray/src/desktop/modules/counter/mod.stx +0 -44
- package/core/x-ray/src/desktop/modules/fetcher/mod.stx +0 -63
- package/core/x-ray/src/desktop/plugins/unified/unified-app.ts +0 -5
- package/core/x-ray/src/desktop/plugins/unified/unified-styles.scss +0 -0
- package/core/x-ray/src/desktop/services/http.ts +0 -45
- package/core/x-ray/src/desktop/styles/app.scss +0 -0
- package/core/x-ray/src/http.ts +0 -26
- package/core/x-ray/src/index.ts +0 -42
- package/core/x-ray/src/ray.config.ts +0 -27
- package/core/x-ray/src/types.ts +0 -8
- package/core/x-ray/tests/example.test.ts +0 -5
- package/core/x-ray/tsconfig.json +0 -3
- package/ide/dictionary.txt +0 -333
- package/ide/jetbrains/.fleet/settings.json +0 -4
- package/ide/jetbrains/.idea/.name +0 -1
- package/ide/jetbrains/.idea/inspectionProfiles/Project_Default.xml +0 -6
- package/ide/jetbrains/.idea/jsLinters/eslint.xml +0 -7
- package/ide/jetbrains/.idea/modules.xml +0 -8
- package/ide/jetbrains/.idea/stacks.iml +0 -22
- package/ide/jetbrains/.idea/vcs.xml +0 -6
- package/ide/jetbrains/.idea/webResources.xml +0 -14
- package/ide/jetbrains/IntelliJ IDEA Global Settings +0 -0
- package/ide/jetbrains/installed.txt +0 -4
- package/ide/jetbrains/options/github-copilot.xml +0 -5
- package/ide/jetbrains/options/nodejs.xml +0 -7
- package/ide/jetbrains/options/templates.xml +0 -124
- package/ide/jetbrains/templates/JavaScript.xml +0 -6
- package/ide/jetbrains/templates/Stacks.xml +0 -8
- package/ide/vscode/.vscode/README.md +0 -23
- package/ide/vscode/.vscode/extensions.json +0 -5
- package/ide/vscode/.vscode/settings.json +0 -135
- package/ide/vscode/.vscode/stacks.code-snippets +0 -182
- package/ide/vscode/LICENSE.md +0 -21
- package/ide/vscode/README.md +0 -37
- package/ide/vscode/logo.png +0 -0
- package/ide/vscode/package.json +0 -63
- package/stubs/.gitkeep +0 -0
- package/stubs/TODO.md +0 -18
- package/vcs/github/CODE_OF_CONDUCT.md +0 -83
- package/vcs/github/CONTRIBUTING.md +0 -188
- package/vcs/github/EXPLANATIONS.md +0 -41
- package/vcs/github/FUNDING.yml +0 -1
- package/vcs/github/ISSUE_TEMPLATE/bug_report.yml +0 -49
- package/vcs/github/ISSUE_TEMPLATE/config.yml +0 -10
- package/vcs/github/ISSUE_TEMPLATE/feature_request.yml +0 -44
- package/vcs/github/SECURITY.md +0 -70
- package/vcs/github/renovate.json +0 -5
- package/vcs/github/stale.yml +0 -14
- package/vcs/github/workflows/README.md +0 -16
- package/vcs/github/workflows/ci.yml +0 -174
- package/vcs/github/workflows/export-size.yml +0 -23
- package/vcs/github/workflows/labeler.yml +0 -13
- package/vcs/github/workflows/release.yml +0 -69
- package/{core/README.md → README.md} +0 -0
- package/{core/buddy → buddy}/README.md +0 -0
- package/{core/buddy → buddy}/art/social.jpg +0 -0
- package/{core/buddy → buddy}/bin/cli.ts +0 -0
- package/{core/buddy/dist/chunk-0455e53fab4244b1.js → buddy/dist/chunk-970e033f764e29fc.js} +0 -0
- package/{core/buddy → buddy}/src/commands/build.ts +0 -0
- package/{core/buddy → buddy}/src/commands/changelog.ts +0 -0
- package/{core/buddy → buddy}/src/commands/clean.ts +0 -0
- package/{core/buddy → buddy}/src/commands/cloud.ts +0 -0
- package/{core/buddy → buddy}/src/commands/configure.ts +0 -0
- package/{core/buddy → buddy}/src/commands/create.ts +0 -0
- package/{core/buddy → buddy}/src/commands/dns.ts +0 -0
- package/{core/buddy → buddy}/src/commands/domains.ts +0 -0
- package/{core/buddy → buddy}/src/commands/fresh.ts +0 -0
- package/{core/buddy → buddy}/src/commands/generate.ts +0 -0
- package/{core/buddy → buddy}/src/commands/http.ts +0 -0
- package/{core/buddy → buddy}/src/commands/install.ts +0 -0
- package/{core/buddy → buddy}/src/commands/key.ts +1 -1
- /package/{core/buddy → buddy}/src/commands/lint.ts +0 -0
- /package/{core/buddy → buddy}/src/commands/migrate.ts +0 -0
- /package/{core/buddy → buddy}/src/commands/release.ts +0 -0
- /package/{core/buddy → buddy}/src/commands/seed.ts +0 -0
- /package/{core/buddy → buddy}/src/commands/test.ts +0 -0
- /package/{core/buddy → buddy}/src/commands/tinker.ts +0 -0
- /package/{core/buddy → buddy}/src/commands/upgrade.ts +0 -0
- /package/{core/buddy → buddy}/src/commands/version.ts +0 -0
- /package/{core/buddy → buddy}/src/custom-cli.ts +0 -0
- /package/{core/buddy → buddy}/src/index.ts +0 -0
- /package/{core/actions → buddy}/tsconfig.json +0 -0
package/core/cloud/dist/index.js
DELETED
|
@@ -1,2013 +0,0 @@
|
|
|
1
|
-
// @bun
|
|
2
|
-
// src/helpers.ts
|
|
3
|
-
import {CloudFormation} from "@aws-sdk/client-cloudformation";
|
|
4
|
-
import {CloudWatchLogsClient, DeleteLogGroupCommand, DescribeLogGroupsCommand} from "@aws-sdk/client-cloudwatch-logs";
|
|
5
|
-
import {EC2, _InstanceType as InstanceType} from "@aws-sdk/client-ec2";
|
|
6
|
-
import {DescribeFileSystemsCommand, EFSClient} from "@aws-sdk/client-efs";
|
|
7
|
-
import {IAM} from "@aws-sdk/client-iam";
|
|
8
|
-
import {SSM} from "@aws-sdk/client-ssm";
|
|
9
|
-
import {Lambda} from "@aws-sdk/client-lambda";
|
|
10
|
-
import {ContactType, Route53Domains} from "@aws-sdk/client-route-53-domains";
|
|
11
|
-
import {ListBucketsCommand, S3} from "@aws-sdk/client-s3";
|
|
12
|
-
import {config as config2} from "@stacksjs/config";
|
|
13
|
-
import {err, handleError, ok} from "@stacksjs/error-handling";
|
|
14
|
-
import {log} from "@stacksjs/logging";
|
|
15
|
-
import {path as p} from "@stacksjs/path";
|
|
16
|
-
import {rimraf} from "@stacksjs/utils";
|
|
17
|
-
import {slug} from "@stacksjs/strings";
|
|
18
|
-
async function getSecurityGroupId(securityGroupName) {
|
|
19
|
-
const ec2 = new EC2({ region: "us-east-1" });
|
|
20
|
-
const { SecurityGroups } = await ec2.describeSecurityGroups({
|
|
21
|
-
Filters: [{ Name: "group-name", Values: [securityGroupName] }]
|
|
22
|
-
});
|
|
23
|
-
if (!SecurityGroups)
|
|
24
|
-
return err(`Security group ${securityGroupName} not found`);
|
|
25
|
-
if (SecurityGroups[0])
|
|
26
|
-
return ok(SecurityGroups[0].GroupId);
|
|
27
|
-
return err(`Security group ${securityGroupName} not found`);
|
|
28
|
-
}
|
|
29
|
-
function purchaseDomain(domain, options) {
|
|
30
|
-
const route53domains = new Route53Domains({ region: "us-east-1" });
|
|
31
|
-
const contactType = options.contactType.toUpperCase();
|
|
32
|
-
const params = {
|
|
33
|
-
DomainName: domain,
|
|
34
|
-
DurationInYears: options.years || 1,
|
|
35
|
-
AutoRenew: options.autoRenew || true,
|
|
36
|
-
AdminContact: {
|
|
37
|
-
FirstName: options.adminFirstName,
|
|
38
|
-
LastName: options.adminLastName,
|
|
39
|
-
ContactType: contactType || ContactType.PERSON,
|
|
40
|
-
OrganizationName: options.adminOrganization,
|
|
41
|
-
AddressLine1: options.adminAddressLine1,
|
|
42
|
-
AddressLine2: options.adminAddressLine2,
|
|
43
|
-
City: options.adminCity,
|
|
44
|
-
State: options.adminState,
|
|
45
|
-
CountryCode: options.adminCountry,
|
|
46
|
-
ZipCode: options.adminZip.toString(),
|
|
47
|
-
PhoneNumber: options.adminPhone.toString().includes("+") ? options.adminPhone.toString() : `+${options.adminPhone.toString()}`,
|
|
48
|
-
Email: options.adminEmail
|
|
49
|
-
},
|
|
50
|
-
RegistrantContact: {
|
|
51
|
-
FirstName: options.registrantFirstName,
|
|
52
|
-
LastName: options.registrantLastName,
|
|
53
|
-
ContactType: contactType || ContactType.PERSON,
|
|
54
|
-
OrganizationName: options.registrantOrganization,
|
|
55
|
-
AddressLine1: options.registrantAddressLine1,
|
|
56
|
-
AddressLine2: options.registrantAddressLine2,
|
|
57
|
-
City: options.registrantCity,
|
|
58
|
-
State: options.registrantState,
|
|
59
|
-
CountryCode: options.registrantCountry,
|
|
60
|
-
ZipCode: options.registrantZip.toString(),
|
|
61
|
-
PhoneNumber: options.registrantPhone.toString().includes("+") ? options.registrantPhone.toString() : `+${options.registrantPhone.toString()}`,
|
|
62
|
-
Email: options.registrantEmail
|
|
63
|
-
},
|
|
64
|
-
TechContact: {
|
|
65
|
-
FirstName: options.techFirstName,
|
|
66
|
-
LastName: options.techLastName,
|
|
67
|
-
ContactType: contactType || ContactType.PERSON,
|
|
68
|
-
OrganizationName: options.techOrganization,
|
|
69
|
-
AddressLine1: options.techAddressLine1,
|
|
70
|
-
AddressLine2: options.techAddressLine2,
|
|
71
|
-
City: options.techCity,
|
|
72
|
-
State: options.techState,
|
|
73
|
-
CountryCode: options.techCountry,
|
|
74
|
-
ZipCode: options.techZip.toString(),
|
|
75
|
-
PhoneNumber: options.techPhone.toString().includes("+") ? options.techPhone.toString() : `+${options.techPhone.toString()}`,
|
|
76
|
-
Email: options.techEmail
|
|
77
|
-
},
|
|
78
|
-
PrivacyProtectAdminContact: options.privacyAdmin || options.privacy || true,
|
|
79
|
-
PrivacyProtectRegistrantContact: options.privacyRegistrant || options.privacy || true,
|
|
80
|
-
PrivacyProtectTechContact: options.privacyTech || options.privacy || true
|
|
81
|
-
};
|
|
82
|
-
try {
|
|
83
|
-
return ok(route53domains.registerDomain(params));
|
|
84
|
-
} catch (error) {
|
|
85
|
-
return err(error);
|
|
86
|
-
}
|
|
87
|
-
}
|
|
88
|
-
async function getJumpBoxInstanceId(name) {
|
|
89
|
-
if (!name)
|
|
90
|
-
name = `${cloudName}/JumpBox`;
|
|
91
|
-
const ec2 = new EC2({ region: "us-east-1" });
|
|
92
|
-
const data = await ec2.describeInstances({
|
|
93
|
-
Filters: [
|
|
94
|
-
{
|
|
95
|
-
Name: "tag:Name",
|
|
96
|
-
Values: [name]
|
|
97
|
-
}
|
|
98
|
-
]
|
|
99
|
-
});
|
|
100
|
-
if (data.Reservations && data.Reservations[0] && data.Reservations[0].Instances && data.Reservations[0].Instances[0])
|
|
101
|
-
return data.Reservations[0].Instances[0].InstanceId;
|
|
102
|
-
return;
|
|
103
|
-
}
|
|
104
|
-
async function deleteEc2Instance(id, stackName) {
|
|
105
|
-
if (!stackName)
|
|
106
|
-
stackName = cloudName;
|
|
107
|
-
if (!id)
|
|
108
|
-
return err(`Instance ${id} not found`);
|
|
109
|
-
const ec2 = new EC2({ region: "us-east-1" });
|
|
110
|
-
await ec2.terminateInstances({ InstanceIds: [id] });
|
|
111
|
-
return ok(`Instance ${id} is being terminated`);
|
|
112
|
-
}
|
|
113
|
-
async function deleteJumpBox(stackName) {
|
|
114
|
-
if (!stackName)
|
|
115
|
-
stackName = cloudName;
|
|
116
|
-
const jumpBoxId = await getJumpBoxInstanceId();
|
|
117
|
-
if (!jumpBoxId)
|
|
118
|
-
return err("Jump-box not found");
|
|
119
|
-
log.info(`Deleting jump-box ${jumpBoxId}...`);
|
|
120
|
-
return await deleteEc2Instance(jumpBoxId, stackName);
|
|
121
|
-
}
|
|
122
|
-
async function deleteIamUsers() {
|
|
123
|
-
const iam = new IAM({ region: "us-east-1" });
|
|
124
|
-
const data = await iam.listUsers({});
|
|
125
|
-
const teamName = slug(config2.team.name);
|
|
126
|
-
const users = data.Users?.filter((user) => {
|
|
127
|
-
const userNameLower = user.UserName?.toLowerCase();
|
|
128
|
-
return userNameLower !== "stacks" && userNameLower !== teamName.toLowerCase() && userNameLower?.includes(teamName.toLowerCase());
|
|
129
|
-
}) || [];
|
|
130
|
-
if (!users || users.length === 0)
|
|
131
|
-
return ok(`No Stacks IAM users found for team ${teamName}`);
|
|
132
|
-
const promises = users.map(async (user) => {
|
|
133
|
-
const userName = user.UserName || "";
|
|
134
|
-
log.info(`Deleting IAM user: ${userName}`);
|
|
135
|
-
const policies = await iam.listAttachedUserPolicies({ UserName: userName });
|
|
136
|
-
await Promise.all(policies.AttachedPolicies?.map((policy) => iam.detachUserPolicy({ UserName: userName, PolicyArn: policy.PolicyArn || "" })) || []);
|
|
137
|
-
const accessKeys = await iam.listAccessKeys({ UserName: userName });
|
|
138
|
-
await Promise.all(accessKeys.AccessKeyMetadata?.map((key) => iam.deleteAccessKey({ UserName: userName, AccessKeyId: key.AccessKeyId || "" })) || []);
|
|
139
|
-
return iam.deleteUser({ UserName: userName });
|
|
140
|
-
});
|
|
141
|
-
await Promise.all(promises).catch((error) => {
|
|
142
|
-
console.error(`Error deleting user: ${error}`);
|
|
143
|
-
return err(handleError("Error deleting Stacks IAM users", error));
|
|
144
|
-
});
|
|
145
|
-
return ok(`Stacks IAM users deleted for team ${teamName}`);
|
|
146
|
-
}
|
|
147
|
-
async function deleteStacksBuckets() {
|
|
148
|
-
try {
|
|
149
|
-
const s3 = new S3({ region: "us-east-1" });
|
|
150
|
-
const data = await s3.listBuckets({});
|
|
151
|
-
const stacksBuckets = data.Buckets?.filter((bucket) => bucket.Name?.includes("stacks"));
|
|
152
|
-
if (!stacksBuckets)
|
|
153
|
-
return err("No stacks buckets found");
|
|
154
|
-
const promises = stacksBuckets.map(async (bucket) => {
|
|
155
|
-
const bucketName = bucket.Name || "";
|
|
156
|
-
log.info(`Deleting bucket ${bucketName}...`);
|
|
157
|
-
const objects = await s3.listObjectsV2({ Bucket: bucketName });
|
|
158
|
-
log.info(`Finished listing bucket ${bucketName} objects`);
|
|
159
|
-
if (objects.Contents) {
|
|
160
|
-
log.info("Deleting bucket objects...");
|
|
161
|
-
await Promise.all(objects.Contents.map((object) => s3.deleteObject({ Bucket: bucketName, Key: object.Key || "" }).catch((error) => handleError(error))));
|
|
162
|
-
log.info(`Finished deleting objects from bucket ${bucketName}`);
|
|
163
|
-
}
|
|
164
|
-
log.info(`Deleting bucket ${bucketName} versions...`);
|
|
165
|
-
try {
|
|
166
|
-
const versions = await s3.listObjectVersions({ Bucket: bucketName });
|
|
167
|
-
if (versions.Versions) {
|
|
168
|
-
await Promise.all(versions.Versions.map((version) => s3.deleteObject({ Bucket: bucketName, Key: version.Key || "", VersionId: version.VersionId }))).catch((error) => handleError(error));
|
|
169
|
-
log.info(`Finished deleting versions from bucket ${bucketName}`);
|
|
170
|
-
}
|
|
171
|
-
log.info(`Deleting bucket ${bucketName} delete markers...`);
|
|
172
|
-
if (versions.DeleteMarkers) {
|
|
173
|
-
await Promise.all(versions.DeleteMarkers.map((marker) => s3.deleteObject({ Bucket: bucketName, Key: marker.Key || "", VersionId: marker.VersionId }))).catch((error) => handleError(error));
|
|
174
|
-
log.info(`Finished deleting delete markers from bucket ${bucketName}`);
|
|
175
|
-
}
|
|
176
|
-
const uploads = await s3.listMultipartUploads({ Bucket: bucketName });
|
|
177
|
-
if (uploads.Uploads) {
|
|
178
|
-
log.info("Aborting bucket multipart uploads...");
|
|
179
|
-
await Promise.all(uploads.Uploads.map((upload) => s3.abortMultipartUpload({ Bucket: bucketName, Key: upload.Key || "", UploadId: upload.UploadId }))).catch((error) => handleError(error));
|
|
180
|
-
log.info(`Finished aborting multipart uploads from bucket ${bucketName}`);
|
|
181
|
-
}
|
|
182
|
-
await s3.deleteBucket({ Bucket: bucketName }).catch((error) => handleError(error));
|
|
183
|
-
log.info(`Bucket ${bucketName} deleted`);
|
|
184
|
-
} catch (error) {
|
|
185
|
-
log.info(`Error listing bucket ${bucketName} versions`, error);
|
|
186
|
-
}
|
|
187
|
-
});
|
|
188
|
-
await Promise.all(promises).catch((error) => {
|
|
189
|
-
return err(handleError("Error deleting stacks buckets", error));
|
|
190
|
-
});
|
|
191
|
-
return ok("Stacks buckets deleted");
|
|
192
|
-
} catch (error) {
|
|
193
|
-
return err(handleError("Error deleting stacks buckets", error));
|
|
194
|
-
}
|
|
195
|
-
}
|
|
196
|
-
async function deleteStacksFunctions() {
|
|
197
|
-
const lambda = new Lambda({ region: "us-east-1" });
|
|
198
|
-
const data = await lambda.listFunctions({});
|
|
199
|
-
const stacksFunctions = data.Functions?.filter((func) => func.FunctionName?.includes("stacks")) || [];
|
|
200
|
-
if (!stacksFunctions || stacksFunctions.length === 0)
|
|
201
|
-
return ok("No stacks functions found");
|
|
202
|
-
const promises = stacksFunctions.map((func) => lambda.deleteFunction({ FunctionName: func.FunctionName || "" }));
|
|
203
|
-
await Promise.all(promises).catch((error) => {
|
|
204
|
-
if (error.message.includes("it is a replicated function")) {
|
|
205
|
-
log.info("Function is replicated, skipping...");
|
|
206
|
-
return ok("CloudFront is still deleting the some functions. Try again later.");
|
|
207
|
-
}
|
|
208
|
-
return err(handleError("Error deleting stacks functions", error));
|
|
209
|
-
});
|
|
210
|
-
return ok("Stacks functions deleted");
|
|
211
|
-
}
|
|
212
|
-
async function deleteLogGroups() {
|
|
213
|
-
try {
|
|
214
|
-
const client = new CloudWatchLogsClient({ region: "us-east-1" });
|
|
215
|
-
const logGroups = await client.send(new DescribeLogGroupsCommand({}));
|
|
216
|
-
if (!logGroups?.logGroups)
|
|
217
|
-
return err("No log groups found");
|
|
218
|
-
for (const group of logGroups.logGroups) {
|
|
219
|
-
if (group.logGroupName?.includes("stacks"))
|
|
220
|
-
await client.send(new DeleteLogGroupCommand({ logGroupName: group.logGroupName }));
|
|
221
|
-
}
|
|
222
|
-
return ok("Log groups deleted");
|
|
223
|
-
} catch (error) {
|
|
224
|
-
return err(handleError("Error deleting log groups", error));
|
|
225
|
-
}
|
|
226
|
-
}
|
|
227
|
-
async function deleteParameterStore() {
|
|
228
|
-
const ssm = new SSM({ region: "us-east-1" });
|
|
229
|
-
const data = await ssm.describeParameters({});
|
|
230
|
-
if (!data.Parameters)
|
|
231
|
-
return ok("No parameters found");
|
|
232
|
-
const stacksParameters = data.Parameters.filter((param) => param.Name?.includes("stacks")) || [];
|
|
233
|
-
if (!stacksParameters || stacksParameters.length === 0)
|
|
234
|
-
return ok("No stacks parameters found");
|
|
235
|
-
const promises = stacksParameters.map((param) => ssm.deleteParameter({ Name: param.Name || "" }));
|
|
236
|
-
await Promise.all(promises).catch((error) => {
|
|
237
|
-
return err(handleError("Error deleting parameter store", error));
|
|
238
|
-
});
|
|
239
|
-
return ok("Parameter store deleted");
|
|
240
|
-
}
|
|
241
|
-
async function deleteCdkRemnants() {
|
|
242
|
-
try {
|
|
243
|
-
return ok(await rimraf([
|
|
244
|
-
p.cloudPath("cdk.out/"),
|
|
245
|
-
p.cloudPath("cdk.context.json")
|
|
246
|
-
]));
|
|
247
|
-
} catch (error) {
|
|
248
|
-
return err(handleError("Error deleting CDK remnants", error));
|
|
249
|
-
}
|
|
250
|
-
}
|
|
251
|
-
async function hasBeenDeployed() {
|
|
252
|
-
const s3 = new S3({ region: "us-east-1" });
|
|
253
|
-
try {
|
|
254
|
-
const response = await s3.send(new ListBucketsCommand({}));
|
|
255
|
-
return ok(response.Buckets?.some((bucket) => bucket.Name?.includes(config2.app.name?.toLocaleLowerCase() || "stacks")) || false);
|
|
256
|
-
} catch (error) {
|
|
257
|
-
return err(handleError("Error checking if the app has been deployed", error));
|
|
258
|
-
}
|
|
259
|
-
}
|
|
260
|
-
async function getJumpBoxInstanceProfileName() {
|
|
261
|
-
const iam = new IAM({ region: "us-east-1" });
|
|
262
|
-
const data = await iam.listInstanceProfiles({});
|
|
263
|
-
const instanceProfile = data.InstanceProfiles?.find((profile) => profile.InstanceProfileName?.includes("JumpBox"));
|
|
264
|
-
if (!instanceProfile)
|
|
265
|
-
return err("Jump-box IAM instance profile not found");
|
|
266
|
-
return ok(instanceProfile?.InstanceProfileName);
|
|
267
|
-
}
|
|
268
|
-
async function addJumpBox(stackName) {
|
|
269
|
-
if (!stackName)
|
|
270
|
-
stackName = cloudName;
|
|
271
|
-
if (await getJumpBoxInstanceId())
|
|
272
|
-
return err("The jump\u2013box you are trying to add already exists. Please remove it & wait until it finished terminating.");
|
|
273
|
-
const ec2 = new EC2({ region: "us-east-1" });
|
|
274
|
-
const r = await getJumpBoxSecurityGroupName();
|
|
275
|
-
if (r.isErr())
|
|
276
|
-
return err(r.error);
|
|
277
|
-
if (!r.value)
|
|
278
|
-
return err("Security group not found when adding jump-box");
|
|
279
|
-
const result = await getSecurityGroupId(r.value);
|
|
280
|
-
let sgId;
|
|
281
|
-
if (result.isErr())
|
|
282
|
-
return err(result.error);
|
|
283
|
-
else
|
|
284
|
-
sgId = result.value;
|
|
285
|
-
if (!sgId)
|
|
286
|
-
return err("Security group not found when adding jump-box");
|
|
287
|
-
const client = new EFSClient({ region: "us-east-1" });
|
|
288
|
-
const command = new DescribeFileSystemsCommand({});
|
|
289
|
-
const data = await client.send(command);
|
|
290
|
-
const fileSystemName = `stacks-${config2.app.env}-efs`;
|
|
291
|
-
const fileSystem = data.FileSystems?.find((fs) => fs.Name === fileSystemName);
|
|
292
|
-
const fileSystemId = fileSystem?.FileSystemId;
|
|
293
|
-
if (!fileSystem || !fileSystemId)
|
|
294
|
-
return err(`EFS file system ${fileSystemName} not found`);
|
|
295
|
-
const userDataScript = `
|
|
296
|
-
#!/bin/bash
|
|
297
|
-
yum update -y
|
|
298
|
-
yum install -y amazon-efs-utils
|
|
299
|
-
yum install -y git
|
|
300
|
-
yum install -y https://s3.us-east-1.amazonaws.com/amazon-ssm-us-east-1/latest/linux_amd64/amazon-ssm-agent.rpm
|
|
301
|
-
mkdir /mnt/efs
|
|
302
|
-
mount -t efs ${fileSystemId}:/ /mnt/efs
|
|
303
|
-
git clone https://github.com/stacksjs/stacks.git /mnt/efs
|
|
304
|
-
`;
|
|
305
|
-
const base64UserData = btoa(userDataScript);
|
|
306
|
-
const res = await getJumpBoxInstanceProfileName();
|
|
307
|
-
if (res.isErr())
|
|
308
|
-
return err(res.error);
|
|
309
|
-
const jumpBoxInstanceProfileName = res.value;
|
|
310
|
-
if (!jumpBoxInstanceProfileName)
|
|
311
|
-
return err("Jump-box IAM instance profile not found");
|
|
312
|
-
const instance = await ec2.runInstances({
|
|
313
|
-
ImageId: "ami-03a6eaae9938c858c",
|
|
314
|
-
InstanceType: InstanceType.t2_micro,
|
|
315
|
-
MaxCount: 1,
|
|
316
|
-
MinCount: 1,
|
|
317
|
-
SecurityGroupIds: [sgId],
|
|
318
|
-
SubnetId: "subnet-004c5f196358b00f0",
|
|
319
|
-
TagSpecifications: [
|
|
320
|
-
{
|
|
321
|
-
ResourceType: "instance",
|
|
322
|
-
Tags: [
|
|
323
|
-
{
|
|
324
|
-
Key: "Name",
|
|
325
|
-
Value: `${cloudName}-jump-box`
|
|
326
|
-
}
|
|
327
|
-
]
|
|
328
|
-
}
|
|
329
|
-
],
|
|
330
|
-
UserData: base64UserData,
|
|
331
|
-
IamInstanceProfile: {
|
|
332
|
-
Name: jumpBoxInstanceProfileName
|
|
333
|
-
}
|
|
334
|
-
});
|
|
335
|
-
return instance.Instances && instance.Instances[0] ? ok(`Jump-box created with id ${instance.Instances[0].InstanceId}`) : err("Jump-box creation failed");
|
|
336
|
-
}
|
|
337
|
-
async function getJumpBoxSecurityGroupName() {
|
|
338
|
-
const jumpBoxId = await getJumpBoxInstanceId();
|
|
339
|
-
if (!jumpBoxId)
|
|
340
|
-
return err("Jump-box not found");
|
|
341
|
-
const ec2 = new EC2({ region: "us-east-1" });
|
|
342
|
-
const data = await ec2.describeInstances({ InstanceIds: [jumpBoxId] });
|
|
343
|
-
if (data.Reservations && data.Reservations[0] && data.Reservations[0].Instances && data.Reservations[0].Instances[0]) {
|
|
344
|
-
const instance = data.Reservations[0].Instances[0];
|
|
345
|
-
const securityGroups = instance.SecurityGroups;
|
|
346
|
-
if (securityGroups && securityGroups[0])
|
|
347
|
-
return ok(securityGroups[0].GroupName);
|
|
348
|
-
}
|
|
349
|
-
return err("Security group not found");
|
|
350
|
-
}
|
|
351
|
-
async function getSecurityGroupFromInstanceId(instanceId) {
|
|
352
|
-
const ec2 = new EC2({ region: "us-east-1" });
|
|
353
|
-
const data = await ec2.describeInstances({ InstanceIds: [instanceId] });
|
|
354
|
-
if (data.Reservations && data.Reservations[0] && data.Reservations[0].Instances && data.Reservations[0].Instances[0]) {
|
|
355
|
-
const instance = data.Reservations[0].Instances[0];
|
|
356
|
-
const securityGroups = instance.SecurityGroups;
|
|
357
|
-
if (securityGroups && securityGroups[0])
|
|
358
|
-
return securityGroups[0].GroupId;
|
|
359
|
-
}
|
|
360
|
-
return;
|
|
361
|
-
}
|
|
362
|
-
async function isFirstDeployment() {
|
|
363
|
-
const stackName = cloudName;
|
|
364
|
-
const cloudFormation = new CloudFormation;
|
|
365
|
-
const data = await cloudFormation.listStacks({ StackStatusFilter: ["CREATE_COMPLETE", "UPDATE_COMPLETE"] });
|
|
366
|
-
const isStacksCloudPresent = data.StackSummaries?.some((stack) => stack.StackName === stackName);
|
|
367
|
-
return !isStacksCloudPresent;
|
|
368
|
-
}
|
|
369
|
-
async function isFailedState() {
|
|
370
|
-
const cloudFormation = new CloudFormation;
|
|
371
|
-
const data = await cloudFormation.listStacks({ StackStatusFilter: ["CREATE_FAILED", "UPDATE_FAILED", "ROLLBACK_COMPLETE", "UPDATE_ROLLBACK_COMPLETE"] });
|
|
372
|
-
const isStacksCloudPresent = data.StackSummaries?.some((stack) => stack.StackName === cloudName);
|
|
373
|
-
return !isStacksCloudPresent;
|
|
374
|
-
}
|
|
375
|
-
async function getOrCreateTimestamp() {
|
|
376
|
-
const parameterName = `/stacks/timestamp`;
|
|
377
|
-
const ssm = new SSM({ region: "us-east-1" });
|
|
378
|
-
try {
|
|
379
|
-
const response = await ssm.getParameter({ Name: parameterName });
|
|
380
|
-
const timestamp = response.Parameter ? response.Parameter.Value : undefined;
|
|
381
|
-
if (!timestamp)
|
|
382
|
-
throw new Error("Timestamp parameter not found");
|
|
383
|
-
return timestamp;
|
|
384
|
-
} catch (error) {
|
|
385
|
-
const timestamp = new Date().getTime().toString();
|
|
386
|
-
log.debug(`Creating timestamp parameter ${parameterName} with value ${timestamp}`);
|
|
387
|
-
await ssm.putParameter({
|
|
388
|
-
Name: parameterName,
|
|
389
|
-
Value: timestamp,
|
|
390
|
-
Type: "String"
|
|
391
|
-
});
|
|
392
|
-
return timestamp;
|
|
393
|
-
}
|
|
394
|
-
}
|
|
395
|
-
var appEnv = config2.app.env === "local" ? "dev" : config2.app.env;
|
|
396
|
-
var cloudName = `stacks-cloud-${appEnv}`;
|
|
397
|
-
// src/cloud/index.ts
|
|
398
|
-
import {Stack as Stack2} from "aws-cdk-lib";
|
|
399
|
-
import {config as config20} from "@stacksjs/config";
|
|
400
|
-
|
|
401
|
-
// src/cloud/ai.ts
|
|
402
|
-
import {Duration, CfnOutput as Output, aws_iam as iam, aws_lambda as lambda} from "aws-cdk-lib";
|
|
403
|
-
import {config as config4} from "@stacksjs/config";
|
|
404
|
-
|
|
405
|
-
class AiStack {
|
|
406
|
-
askAiUrl;
|
|
407
|
-
summarizeAiUrl;
|
|
408
|
-
constructor(scope, props) {
|
|
409
|
-
const awsSdkLayer = new lambda.LayerVersion(scope, "AwsSdkLayer", {
|
|
410
|
-
code: lambda.Code.fromAsset("../core/cloud/src/cloud/aws-sdk-layer"),
|
|
411
|
-
compatibleRuntimes: [lambda.Runtime.NODEJS_20_X],
|
|
412
|
-
description: "Layer with aws-sdk"
|
|
413
|
-
});
|
|
414
|
-
const bedrockAccessPolicy = new iam.PolicyStatement({
|
|
415
|
-
effect: iam.Effect.ALLOW,
|
|
416
|
-
actions: [
|
|
417
|
-
"bedrock:InvokeModel",
|
|
418
|
-
"bedrock:InvokeModelWithResponseStream"
|
|
419
|
-
],
|
|
420
|
-
resources: config4.ai.models?.map((model) => `arn:aws:bedrock:us-east-1::foundation-model/${model}`)
|
|
421
|
-
});
|
|
422
|
-
const bedrockAccessRole = new iam.Role(scope, "BedrockAccessRole", {
|
|
423
|
-
assumedBy: new iam.ServicePrincipal("lambda.amazonaws.com"),
|
|
424
|
-
managedPolicies: [
|
|
425
|
-
iam.ManagedPolicy.fromAwsManagedPolicyName("service-role/AWSLambdaBasicExecutionRole")
|
|
426
|
-
]
|
|
427
|
-
});
|
|
428
|
-
bedrockAccessRole.addToPolicy(bedrockAccessPolicy);
|
|
429
|
-
const askAi = new lambda.Function(scope, "AskAiFunction", {
|
|
430
|
-
functionName: `${props.slug}-${props.appEnv}-ai-ask`,
|
|
431
|
-
description: "Lambda function to invoke the AI model",
|
|
432
|
-
runtime: lambda.Runtime.NODEJS_20_X,
|
|
433
|
-
handler: "index.handler",
|
|
434
|
-
code: lambda.Code.fromAsset("../core/cloud/src/cloud/lambda/ask"),
|
|
435
|
-
layers: [awsSdkLayer],
|
|
436
|
-
role: bedrockAccessRole,
|
|
437
|
-
timeout: Duration.seconds(30)
|
|
438
|
-
});
|
|
439
|
-
this.askAiUrl = new lambda.FunctionUrl(scope, "AskAiFunctionUrl", {
|
|
440
|
-
function: askAi,
|
|
441
|
-
authType: lambda.FunctionUrlAuthType.NONE,
|
|
442
|
-
cors: {
|
|
443
|
-
allowedOrigins: ["*"]
|
|
444
|
-
}
|
|
445
|
-
});
|
|
446
|
-
const summarizeAi = new lambda.Function(scope, "SummarizeAiFunction", {
|
|
447
|
-
functionName: `${props.slug}-${props.appEnv}-ai-summarize`,
|
|
448
|
-
description: "Lambda function to summarize any given text",
|
|
449
|
-
runtime: lambda.Runtime.NODEJS_20_X,
|
|
450
|
-
handler: "index.handler",
|
|
451
|
-
code: lambda.Code.fromAsset("../core/cloud/src/cloud/lambda/summarize"),
|
|
452
|
-
layers: [awsSdkLayer],
|
|
453
|
-
role: bedrockAccessRole,
|
|
454
|
-
timeout: Duration.seconds(30)
|
|
455
|
-
});
|
|
456
|
-
this.summarizeAiUrl = new lambda.FunctionUrl(scope, "SummarizeAiFunctionUrl", {
|
|
457
|
-
function: summarizeAi,
|
|
458
|
-
authType: lambda.FunctionUrlAuthType.NONE,
|
|
459
|
-
cors: {
|
|
460
|
-
allowedOrigins: ["*"]
|
|
461
|
-
}
|
|
462
|
-
});
|
|
463
|
-
new Output(scope, "AiVanityAskApiUrl", {
|
|
464
|
-
value: this.askAiUrl.url
|
|
465
|
-
});
|
|
466
|
-
new Output(scope, "AiVanitySummarizeApiUrl", {
|
|
467
|
-
value: this.summarizeAiUrl.url
|
|
468
|
-
});
|
|
469
|
-
new Output(scope, "AiAskApiUrl", {
|
|
470
|
-
value: `https://${props.domain}/ai/ask`
|
|
471
|
-
});
|
|
472
|
-
new Output(scope, "AiSummarizeApiUrl", {
|
|
473
|
-
value: `https://${props.domain}/ai/summary`
|
|
474
|
-
});
|
|
475
|
-
}
|
|
476
|
-
}
|
|
477
|
-
|
|
478
|
-
// src/cloud/cdn.ts
|
|
479
|
-
import {Duration as Duration2, Fn, CfnOutput as Output2, aws_cloudfront as cloudfront, aws_cloudfront_origins as origins, aws_route53 as route53, aws_route53_targets as targets} from "aws-cdk-lib";
|
|
480
|
-
import {config as config6} from "@stacksjs/config";
|
|
481
|
-
import {hasFiles} from "@stacksjs/storage";
|
|
482
|
-
import {path as p2} from "@stacksjs/path";
|
|
483
|
-
import {env as env2} from "@stacksjs/env";
|
|
484
|
-
import * as kinesis from "aws-cdk-lib/aws-kinesis";
|
|
485
|
-
|
|
486
|
-
class CdnStack {
|
|
487
|
-
distribution;
|
|
488
|
-
originAccessIdentity;
|
|
489
|
-
cdnCachePolicy;
|
|
490
|
-
apiCachePolicy;
|
|
491
|
-
vanityUrl;
|
|
492
|
-
realtimeLogConfig;
|
|
493
|
-
props;
|
|
494
|
-
constructor(scope, props) {
|
|
495
|
-
this.props = props;
|
|
496
|
-
this.originAccessIdentity = new cloudfront.OriginAccessIdentity(scope, "OAI");
|
|
497
|
-
this.cdnCachePolicy = new cloudfront.CachePolicy(scope, "CdnCachePolicy", {
|
|
498
|
-
comment: "Stacks CDN Cache Policy",
|
|
499
|
-
cachePolicyName: `${props.slug}-${props.appEnv}-cdn-cache-policy`,
|
|
500
|
-
minTtl: config6.cloud.cdn?.minTtl ? Duration2.seconds(config6.cloud.cdn.minTtl) : undefined,
|
|
501
|
-
defaultTtl: config6.cloud.cdn?.defaultTtl ? Duration2.seconds(config6.cloud.cdn.defaultTtl) : undefined,
|
|
502
|
-
maxTtl: config6.cloud.cdn?.maxTtl ? Duration2.seconds(config6.cloud.cdn.maxTtl) : undefined,
|
|
503
|
-
cookieBehavior: this.getCookieBehavior(config6.cloud.cdn?.cookieBehavior)
|
|
504
|
-
});
|
|
505
|
-
const logStream = new kinesis.Stream(scope, "StacksCdnRealtimeLogStream", {
|
|
506
|
-
streamName: "StacksCdnRealtimeLogStream",
|
|
507
|
-
retentionPeriod: Duration2.days(1),
|
|
508
|
-
shardCount: 1,
|
|
509
|
-
encryption: kinesis.StreamEncryption.UNENCRYPTED
|
|
510
|
-
});
|
|
511
|
-
this.realtimeLogConfig = new cloudfront.RealtimeLogConfig(scope, "StacksRealTimeLogConfig", {
|
|
512
|
-
endPoints: [
|
|
513
|
-
cloudfront.Endpoint.fromKinesisStream(logStream)
|
|
514
|
-
],
|
|
515
|
-
fields: [
|
|
516
|
-
"timestamp",
|
|
517
|
-
"c-ip",
|
|
518
|
-
"cs-method",
|
|
519
|
-
"cs-uri-stem",
|
|
520
|
-
"cs-uri-query",
|
|
521
|
-
"cs-referer",
|
|
522
|
-
"cs-user-agent",
|
|
523
|
-
"sc-status"
|
|
524
|
-
],
|
|
525
|
-
samplingRate: 100
|
|
526
|
-
});
|
|
527
|
-
this.distribution = new cloudfront.Distribution(scope, "Cdn", {
|
|
528
|
-
domainNames: [props.domain],
|
|
529
|
-
defaultRootObject: "index.html",
|
|
530
|
-
comment: `CDN for ${config6.app.url}`,
|
|
531
|
-
certificate: props.certificate,
|
|
532
|
-
enableLogging: true,
|
|
533
|
-
logBucket: props.logBucket,
|
|
534
|
-
httpVersion: cloudfront.HttpVersion.HTTP2_AND_3,
|
|
535
|
-
priceClass: cloudfront.PriceClass.PRICE_CLASS_ALL,
|
|
536
|
-
enabled: true,
|
|
537
|
-
minimumProtocolVersion: cloudfront.SecurityPolicyProtocol.TLS_V1_2_2021,
|
|
538
|
-
webAclId: props.firewall.attrArn,
|
|
539
|
-
enableIpv6: true,
|
|
540
|
-
defaultBehavior: {
|
|
541
|
-
origin: new origins.S3Origin(props.publicBucket, {
|
|
542
|
-
originAccessIdentity: this.originAccessIdentity
|
|
543
|
-
}),
|
|
544
|
-
edgeLambdas: [
|
|
545
|
-
{
|
|
546
|
-
eventType: cloudfront.LambdaEdgeEventType.ORIGIN_REQUEST,
|
|
547
|
-
functionVersion: props.originRequestFunction.currentVersion
|
|
548
|
-
}
|
|
549
|
-
],
|
|
550
|
-
compress: config6.cloud.cdn?.compress,
|
|
551
|
-
allowedMethods: this.allowedMethods(),
|
|
552
|
-
cachedMethods: this.cachedMethods(),
|
|
553
|
-
viewerProtocolPolicy: cloudfront.ViewerProtocolPolicy.REDIRECT_TO_HTTPS,
|
|
554
|
-
cachePolicy: this.cdnCachePolicy,
|
|
555
|
-
realtimeLogConfig: this.realtimeLogConfig
|
|
556
|
-
},
|
|
557
|
-
additionalBehaviors: this.additionalBehaviors(scope, props),
|
|
558
|
-
errorResponses: [
|
|
559
|
-
{
|
|
560
|
-
httpStatus: 403,
|
|
561
|
-
responsePagePath: "/index.html",
|
|
562
|
-
responseHttpStatus: 200,
|
|
563
|
-
ttl: Duration2.seconds(0)
|
|
564
|
-
}
|
|
565
|
-
]
|
|
566
|
-
});
|
|
567
|
-
new route53.ARecord(scope, "AliasRecord", {
|
|
568
|
-
recordName: props.domain,
|
|
569
|
-
zone: props.zone,
|
|
570
|
-
target: route53.RecordTarget.fromAlias(new targets.CloudFrontTarget(this.distribution))
|
|
571
|
-
});
|
|
572
|
-
new Output2(scope, "DistributionId", {
|
|
573
|
-
value: this.distribution.distributionId
|
|
574
|
-
});
|
|
575
|
-
new Output2(scope, "AppUrl", {
|
|
576
|
-
value: `https://${props.domain}`,
|
|
577
|
-
description: "The URL of the deployed application"
|
|
578
|
-
});
|
|
579
|
-
this.vanityUrl = `https://${this.distribution.domainName}`;
|
|
580
|
-
new Output2(scope, "AppVanityUrl", {
|
|
581
|
-
value: this.vanityUrl,
|
|
582
|
-
description: "The vanity URL of the deployed application"
|
|
583
|
-
});
|
|
584
|
-
}
|
|
585
|
-
getCookieBehavior(behavior) {
|
|
586
|
-
switch (behavior) {
|
|
587
|
-
case "all":
|
|
588
|
-
return cloudfront.CacheCookieBehavior.all();
|
|
589
|
-
case "none":
|
|
590
|
-
return cloudfront.CacheCookieBehavior.none();
|
|
591
|
-
case "allowList":
|
|
592
|
-
return cloudfront.CacheCookieBehavior.allowList(...config6.cloud.cdn?.allowList.cookies || []);
|
|
593
|
-
default:
|
|
594
|
-
return;
|
|
595
|
-
}
|
|
596
|
-
}
|
|
597
|
-
allowedMethods() {
|
|
598
|
-
switch (config6.cloud.cdn?.allowedMethods) {
|
|
599
|
-
case "ALL":
|
|
600
|
-
return cloudfront.AllowedMethods.ALLOW_ALL;
|
|
601
|
-
case "GET_HEAD":
|
|
602
|
-
return cloudfront.AllowedMethods.ALLOW_GET_HEAD;
|
|
603
|
-
case "GET_HEAD_OPTIONS":
|
|
604
|
-
return cloudfront.AllowedMethods.ALLOW_GET_HEAD_OPTIONS;
|
|
605
|
-
default:
|
|
606
|
-
return cloudfront.AllowedMethods.ALLOW_ALL;
|
|
607
|
-
}
|
|
608
|
-
}
|
|
609
|
-
cachedMethods() {
|
|
610
|
-
switch (config6.cloud.cdn?.cachedMethods) {
|
|
611
|
-
case "GET_HEAD":
|
|
612
|
-
return cloudfront.CachedMethods.CACHE_GET_HEAD;
|
|
613
|
-
case "GET_HEAD_OPTIONS":
|
|
614
|
-
return cloudfront.CachedMethods.CACHE_GET_HEAD_OPTIONS;
|
|
615
|
-
default:
|
|
616
|
-
return cloudfront.CachedMethods.CACHE_GET_HEAD;
|
|
617
|
-
}
|
|
618
|
-
}
|
|
619
|
-
allowedMethodsFromString(methods) {
|
|
620
|
-
if (!methods)
|
|
621
|
-
return cloudfront.AllowedMethods.ALLOW_ALL;
|
|
622
|
-
switch (methods) {
|
|
623
|
-
case "ALL":
|
|
624
|
-
return cloudfront.AllowedMethods.ALLOW_ALL;
|
|
625
|
-
case "GET_HEAD":
|
|
626
|
-
return cloudfront.AllowedMethods.ALLOW_GET_HEAD;
|
|
627
|
-
case "GET_HEAD_OPTIONS":
|
|
628
|
-
return cloudfront.AllowedMethods.ALLOW_GET_HEAD_OPTIONS;
|
|
629
|
-
default:
|
|
630
|
-
return cloudfront.AllowedMethods.ALLOW_ALL;
|
|
631
|
-
}
|
|
632
|
-
}
|
|
633
|
-
cachedMethodsFromString(methods) {
|
|
634
|
-
if (!methods)
|
|
635
|
-
return cloudfront.CachedMethods.CACHE_GET_HEAD;
|
|
636
|
-
switch (methods) {
|
|
637
|
-
case "GET_HEAD":
|
|
638
|
-
return cloudfront.CachedMethods.CACHE_GET_HEAD;
|
|
639
|
-
case "GET_HEAD_OPTIONS":
|
|
640
|
-
return cloudfront.CachedMethods.CACHE_GET_HEAD_OPTIONS;
|
|
641
|
-
default:
|
|
642
|
-
return cloudfront.CachedMethods.CACHE_GET_HEAD;
|
|
643
|
-
}
|
|
644
|
-
}
|
|
645
|
-
shouldDeployApi() {
|
|
646
|
-
return config6.cloud.api?.deploy;
|
|
647
|
-
}
|
|
648
|
-
apiBehaviorOptions(scope, props) {
|
|
649
|
-
const hostname = `api.${props.domain}`;
|
|
650
|
-
const origin = () => {
|
|
651
|
-
return new origins.HttpOrigin(hostname, {
|
|
652
|
-
originPath: "/",
|
|
653
|
-
protocolPolicy: cloudfront.OriginProtocolPolicy.HTTPS_ONLY
|
|
654
|
-
});
|
|
655
|
-
};
|
|
656
|
-
return {
|
|
657
|
-
"/api": {
|
|
658
|
-
origin: origin(),
|
|
659
|
-
compress: true,
|
|
660
|
-
allowedMethods: cloudfront.AllowedMethods.ALLOW_ALL,
|
|
661
|
-
cachedMethods: cloudfront.CachedMethods.CACHE_GET_HEAD_OPTIONS,
|
|
662
|
-
cachePolicy: this.setApiCachePolicy(scope),
|
|
663
|
-
viewerProtocolPolicy: cloudfront.ViewerProtocolPolicy.REDIRECT_TO_HTTPS,
|
|
664
|
-
realtimeLogConfig: this.realtimeLogConfig
|
|
665
|
-
},
|
|
666
|
-
"/api/*": {
|
|
667
|
-
origin: origin(),
|
|
668
|
-
compress: true,
|
|
669
|
-
allowedMethods: cloudfront.AllowedMethods.ALLOW_ALL,
|
|
670
|
-
cachedMethods: cloudfront.CachedMethods.CACHE_GET_HEAD_OPTIONS,
|
|
671
|
-
cachePolicy: this.apiCachePolicy,
|
|
672
|
-
viewerProtocolPolicy: cloudfront.ViewerProtocolPolicy.REDIRECT_TO_HTTPS,
|
|
673
|
-
realtimeLogConfig: this.realtimeLogConfig
|
|
674
|
-
}
|
|
675
|
-
};
|
|
676
|
-
}
|
|
677
|
-
docsBehaviorOptions(props) {
|
|
678
|
-
return {
|
|
679
|
-
"/docs": {
|
|
680
|
-
origin: new origins.S3Origin(props.publicBucket, {
|
|
681
|
-
originAccessIdentity: this.originAccessIdentity,
|
|
682
|
-
originPath: "/docs"
|
|
683
|
-
}),
|
|
684
|
-
compress: true,
|
|
685
|
-
allowedMethods: this.allowedMethodsFromString(config6.cloud.cdn?.allowedMethods),
|
|
686
|
-
cachedMethods: this.cachedMethodsFromString(config6.cloud.cdn?.cachedMethods),
|
|
687
|
-
viewerProtocolPolicy: cloudfront.ViewerProtocolPolicy.REDIRECT_TO_HTTPS,
|
|
688
|
-
cachePolicy: cloudfront.CachePolicy.CACHING_OPTIMIZED,
|
|
689
|
-
realtimeLogConfig: this.realtimeLogConfig
|
|
690
|
-
},
|
|
691
|
-
"/docs/*": {
|
|
692
|
-
origin: new origins.S3Origin(props.publicBucket, {
|
|
693
|
-
originAccessIdentity: this.originAccessIdentity,
|
|
694
|
-
originPath: "/docs"
|
|
695
|
-
}),
|
|
696
|
-
compress: true,
|
|
697
|
-
allowedMethods: this.allowedMethodsFromString(config6.cloud.cdn?.allowedMethods),
|
|
698
|
-
cachedMethods: this.cachedMethodsFromString(config6.cloud.cdn?.cachedMethods),
|
|
699
|
-
viewerProtocolPolicy: cloudfront.ViewerProtocolPolicy.REDIRECT_TO_HTTPS,
|
|
700
|
-
cachePolicy: cloudfront.CachePolicy.CACHING_OPTIMIZED,
|
|
701
|
-
realtimeLogConfig: this.realtimeLogConfig
|
|
702
|
-
}
|
|
703
|
-
};
|
|
704
|
-
}
|
|
705
|
-
aiBehaviorOptions(scope, props) {
|
|
706
|
-
const hostname = Fn.select(2, Fn.split("/", props.askAiUrl.url));
|
|
707
|
-
const summaryHostname = Fn.select(2, Fn.split("/", props.summarizeAiUrl.url));
|
|
708
|
-
const aiCachePolicy = new cloudfront.CachePolicy(scope, "AiCachePolicy", {
|
|
709
|
-
comment: "Stacks AI Cache Policy",
|
|
710
|
-
cachePolicyName: `${this.props.slug}-${this.props.appEnv}-ai-cache-policy`,
|
|
711
|
-
defaultTtl: Duration2.seconds(0),
|
|
712
|
-
cookieBehavior: cloudfront.CacheCookieBehavior.none(),
|
|
713
|
-
headerBehavior: cloudfront.CacheHeaderBehavior.allowList("Accept", "x-api-key", "Authorization", "Content-Type"),
|
|
714
|
-
queryStringBehavior: cloudfront.CacheQueryStringBehavior.all()
|
|
715
|
-
});
|
|
716
|
-
return {
|
|
717
|
-
"/ai/ask": {
|
|
718
|
-
origin: new origins.HttpOrigin(hostname, {
|
|
719
|
-
originPath: "/ai",
|
|
720
|
-
protocolPolicy: cloudfront.OriginProtocolPolicy.HTTPS_ONLY
|
|
721
|
-
}),
|
|
722
|
-
compress: false,
|
|
723
|
-
allowedMethods: cloudfront.AllowedMethods.ALLOW_ALL,
|
|
724
|
-
viewerProtocolPolicy: cloudfront.ViewerProtocolPolicy.REDIRECT_TO_HTTPS,
|
|
725
|
-
cachePolicy: aiCachePolicy,
|
|
726
|
-
realtimeLogConfig: this.realtimeLogConfig
|
|
727
|
-
},
|
|
728
|
-
"/ai/summary": {
|
|
729
|
-
origin: new origins.HttpOrigin(summaryHostname, {
|
|
730
|
-
originPath: "/ai",
|
|
731
|
-
protocolPolicy: cloudfront.OriginProtocolPolicy.HTTPS_ONLY
|
|
732
|
-
}),
|
|
733
|
-
compress: false,
|
|
734
|
-
allowedMethods: cloudfront.AllowedMethods.ALLOW_ALL,
|
|
735
|
-
viewerProtocolPolicy: cloudfront.ViewerProtocolPolicy.REDIRECT_TO_HTTPS,
|
|
736
|
-
cachePolicy: aiCachePolicy,
|
|
737
|
-
realtimeLogConfig: this.realtimeLogConfig
|
|
738
|
-
}
|
|
739
|
-
};
|
|
740
|
-
}
|
|
741
|
-
cliSetupBehaviorOptions(scope, props) {
|
|
742
|
-
const hostname = Fn.select(2, Fn.split("/", props.cliSetupUrl.url));
|
|
743
|
-
return {
|
|
744
|
-
"/install": {
|
|
745
|
-
origin: new origins.HttpOrigin(hostname, {
|
|
746
|
-
originPath: "/cli-setup",
|
|
747
|
-
protocolPolicy: cloudfront.OriginProtocolPolicy.HTTPS_ONLY
|
|
748
|
-
}),
|
|
749
|
-
compress: false,
|
|
750
|
-
allowedMethods: cloudfront.AllowedMethods.ALLOW_ALL,
|
|
751
|
-
viewerProtocolPolicy: cloudfront.ViewerProtocolPolicy.REDIRECT_TO_HTTPS,
|
|
752
|
-
cachePolicy: new cloudfront.CachePolicy(scope, "CliSetupCachePolicy", {
|
|
753
|
-
comment: "Stacks CLI Setup Cache Policy",
|
|
754
|
-
cachePolicyName: `${this.props.slug}-${this.props.appEnv}-cli-setup-cache-policy`,
|
|
755
|
-
defaultTtl: Duration2.seconds(0),
|
|
756
|
-
cookieBehavior: cloudfront.CacheCookieBehavior.none(),
|
|
757
|
-
headerBehavior: cloudfront.CacheHeaderBehavior.none(),
|
|
758
|
-
queryStringBehavior: cloudfront.CacheQueryStringBehavior.none()
|
|
759
|
-
}),
|
|
760
|
-
realtimeLogConfig: this.realtimeLogConfig
|
|
761
|
-
}
|
|
762
|
-
};
|
|
763
|
-
}
|
|
764
|
-
shouldDeployAiEndpoints() {
|
|
765
|
-
return config6.cloud.ai;
|
|
766
|
-
}
|
|
767
|
-
shouldDeployCliSetup() {
|
|
768
|
-
return config6.cloud.cli;
|
|
769
|
-
}
|
|
770
|
-
shouldDeployDocs() {
|
|
771
|
-
return hasFiles(p2.projectPath("docs"));
|
|
772
|
-
}
|
|
773
|
-
additionalBehaviors(scope, props) {
|
|
774
|
-
let behaviorOptions = {};
|
|
775
|
-
if (this.shouldDeployApi()) {
|
|
776
|
-
const keysToRemove = ["_HANDLER", "_X_AMZN_TRACE_ID", "AWS_REGION", "AWS_EXECUTION_ENV", "AWS_LAMBDA_FUNCTION_NAME", "AWS_LAMBDA_FUNCTION_MEMORY_SIZE", "AWS_LAMBDA_FUNCTION_VERSION", "AWS_LAMBDA_INITIALIZATION_TYPE", "AWS_LAMBDA_LOG_GROUP_NAME", "AWS_LAMBDA_LOG_STREAM_NAME", "AWS_ACCESS_KEY", "AWS_ACCESS_KEY_ID", "AWS_SECRET_ACCESS_KEY", "AWS_SESSION_TOKEN", "AWS_LAMBDA_RUNTIME_API", "LAMBDA_TASK_ROOT", "LAMBDA_RUNTIME_DIR", "_"];
|
|
777
|
-
keysToRemove.forEach((key) => delete env2[key]);
|
|
778
|
-
behaviorOptions = this.apiBehaviorOptions(scope, props);
|
|
779
|
-
}
|
|
780
|
-
if (this.shouldDeployDocs() && !config6.app.docMode) {
|
|
781
|
-
behaviorOptions = {
|
|
782
|
-
...this.docsBehaviorOptions(props),
|
|
783
|
-
...behaviorOptions
|
|
784
|
-
};
|
|
785
|
-
}
|
|
786
|
-
if (this.shouldDeployAiEndpoints()) {
|
|
787
|
-
behaviorOptions = {
|
|
788
|
-
...this.aiBehaviorOptions(scope, props),
|
|
789
|
-
...behaviorOptions
|
|
790
|
-
};
|
|
791
|
-
}
|
|
792
|
-
if (this.shouldDeployCliSetup()) {
|
|
793
|
-
behaviorOptions = {
|
|
794
|
-
...this.cliSetupBehaviorOptions(scope, props),
|
|
795
|
-
...behaviorOptions
|
|
796
|
-
};
|
|
797
|
-
}
|
|
798
|
-
return behaviorOptions;
|
|
799
|
-
}
|
|
800
|
-
setApiCachePolicy(scope) {
|
|
801
|
-
if (this.apiCachePolicy)
|
|
802
|
-
return this.apiCachePolicy;
|
|
803
|
-
this.apiCachePolicy = new cloudfront.CachePolicy(scope, "ApiCachePolicy", {
|
|
804
|
-
comment: "Stacks API Cache Policy",
|
|
805
|
-
cachePolicyName: `${this.props.slug}-${this.props.appEnv}-api-cache-policy`,
|
|
806
|
-
defaultTtl: Duration2.seconds(0),
|
|
807
|
-
cookieBehavior: cloudfront.CacheCookieBehavior.none(),
|
|
808
|
-
headerBehavior: cloudfront.CacheHeaderBehavior.allowList("Accept", "x-api-key", "Authorization", "Content-Type"),
|
|
809
|
-
queryStringBehavior: cloudfront.CacheQueryStringBehavior.none()
|
|
810
|
-
});
|
|
811
|
-
return this.apiCachePolicy;
|
|
812
|
-
}
|
|
813
|
-
}
|
|
814
|
-
|
|
815
|
-
// src/cloud/cli.ts
|
|
816
|
-
import {Duration as Duration3, CfnOutput as Output3, aws_lambda as lambda2} from "aws-cdk-lib";
|
|
817
|
-
|
|
818
|
-
class CliStack {
|
|
819
|
-
cliSetupUrl;
|
|
820
|
-
constructor(scope, props) {
|
|
821
|
-
const cliSetupFunc = new lambda2.Function(scope, "CliSetupFunction", {
|
|
822
|
-
functionName: `${props.slug}-${props.appEnv}-cli-setup`,
|
|
823
|
-
description: "Lambda function that triggers setup script for a Stacks project",
|
|
824
|
-
runtime: lambda2.Runtime.NODEJS_20_X,
|
|
825
|
-
handler: "index.handler",
|
|
826
|
-
code: lambda2.Code.fromAsset("../core/cloud/src/cloud/lambda/cli-setup"),
|
|
827
|
-
timeout: Duration3.seconds(30)
|
|
828
|
-
});
|
|
829
|
-
this.cliSetupUrl = new lambda2.FunctionUrl(scope, "CliSetupFunctionUrl", {
|
|
830
|
-
function: cliSetupFunc,
|
|
831
|
-
authType: lambda2.FunctionUrlAuthType.NONE,
|
|
832
|
-
cors: {
|
|
833
|
-
allowedOrigins: ["*"]
|
|
834
|
-
}
|
|
835
|
-
});
|
|
836
|
-
new Output3(scope, "CliSetupVanityUrl", {
|
|
837
|
-
value: `${this.cliSetupUrl.url}cli-setup`
|
|
838
|
-
});
|
|
839
|
-
new Output3(scope, "CliSetupUrl", {
|
|
840
|
-
value: `https://${props.domain}/install`,
|
|
841
|
-
description: "URL to trigger the CLI setup function"
|
|
842
|
-
});
|
|
843
|
-
}
|
|
844
|
-
}
|
|
845
|
-
|
|
846
|
-
// src/cloud/dns.ts
|
|
847
|
-
import {RemovalPolicy, aws_route53 as route532, aws_s3 as s3, aws_route53_targets as targets2} from "aws-cdk-lib";
|
|
848
|
-
|
|
849
|
-
class DnsStack {
|
|
850
|
-
zone;
|
|
851
|
-
constructor(scope, props) {
|
|
852
|
-
this.zone = route532.PublicHostedZone.fromLookup(scope, "AppUrlHostedZone", {
|
|
853
|
-
domainName: props.domain
|
|
854
|
-
});
|
|
855
|
-
const wwwBucket = new s3.Bucket(scope, "WwwBucket", {
|
|
856
|
-
bucketName: `www.${props.domain}`,
|
|
857
|
-
websiteRedirect: {
|
|
858
|
-
hostName: props.domain,
|
|
859
|
-
protocol: s3.RedirectProtocol.HTTPS
|
|
860
|
-
},
|
|
861
|
-
removalPolicy: RemovalPolicy.DESTROY,
|
|
862
|
-
autoDeleteObjects: true
|
|
863
|
-
});
|
|
864
|
-
new route532.ARecord(scope, "WwwAliasRecord", {
|
|
865
|
-
recordName: `www.${props.domain}`,
|
|
866
|
-
zone: this.zone,
|
|
867
|
-
target: route532.RecordTarget.fromAlias(new targets2.BucketWebsiteTarget(wwwBucket))
|
|
868
|
-
});
|
|
869
|
-
new route532.ARecord(scope, "StoreAliasRecord", {
|
|
870
|
-
recordName: `store.${props.domain}`,
|
|
871
|
-
zone: this.zone,
|
|
872
|
-
target: route532.RecordTarget.fromIpAddresses("137.66.37.136")
|
|
873
|
-
});
|
|
874
|
-
}
|
|
875
|
-
}
|
|
876
|
-
|
|
877
|
-
// src/cloud/docs.ts
|
|
878
|
-
import {AssetHashType, CfnOutput as Output4, RemovalPolicy as RemovalPolicy2, aws_lambda as lambda3} from "aws-cdk-lib";
|
|
879
|
-
import {config as config8} from "@stacksjs/config";
|
|
880
|
-
import {path as p3} from "@stacksjs/path";
|
|
881
|
-
import {storage as storage3} from "@stacksjs/storage";
|
|
882
|
-
import {originRequestFunctionHash} from "@stacksjs/utils";
|
|
883
|
-
|
|
884
|
-
class DocsStack {
|
|
885
|
-
originRequestFunction;
|
|
886
|
-
constructor(scope, props) {
|
|
887
|
-
const docsPrefix = config8.app.docMode ? "" : config8.docs.base;
|
|
888
|
-
this.originRequestFunction = new lambda3.Function(scope, "OriginRequestFunction", {
|
|
889
|
-
functionName: `${props.slug}-${props.appEnv}-origin-request-${props.timestamp}`,
|
|
890
|
-
description: "The Stacks Origin Request function that prettifies URLs",
|
|
891
|
-
runtime: lambda3.Runtime.NODEJS_18_X,
|
|
892
|
-
handler: "dist/origin-request.handler",
|
|
893
|
-
code: lambda3.Code.fromAsset(p3.frameworkCloudPath("dist.zip"), {
|
|
894
|
-
assetHash: originRequestFunctionHash(),
|
|
895
|
-
assetHashType: AssetHashType.CUSTOM
|
|
896
|
-
})
|
|
897
|
-
});
|
|
898
|
-
const cfnOriginRequestFunction = this.originRequestFunction.node.defaultChild;
|
|
899
|
-
cfnOriginRequestFunction.applyRemovalPolicy(RemovalPolicy2.RETAIN);
|
|
900
|
-
if (!config8.app.docMode && storage3.hasFiles(p3.projectPath("docs"))) {
|
|
901
|
-
new Output4(scope, "DocsUrl", {
|
|
902
|
-
value: `https://${props.domain}/${docsPrefix}`,
|
|
903
|
-
description: "The URL of the deployed documentation"
|
|
904
|
-
});
|
|
905
|
-
}
|
|
906
|
-
}
|
|
907
|
-
}
|
|
908
|
-
|
|
909
|
-
// src/cloud/storage.ts
|
|
910
|
-
import {RemovalPolicy as RemovalPolicy3, Tags, aws_backup as backup, aws_iam as iam2, aws_s3 as s32} from "aws-cdk-lib";
|
|
911
|
-
|
|
912
|
-
class StorageStack {
|
|
913
|
-
publicBucket;
|
|
914
|
-
privateBucket;
|
|
915
|
-
logBucket;
|
|
916
|
-
bucketPrefix;
|
|
917
|
-
vault;
|
|
918
|
-
backupPlan;
|
|
919
|
-
backupRole;
|
|
920
|
-
constructor(scope, props) {
|
|
921
|
-
this.bucketPrefix = `${props.slug}-${props.appEnv}`;
|
|
922
|
-
this.publicBucket = new s32.Bucket(scope, "PublicBucket", {
|
|
923
|
-
bucketName: `${this.bucketPrefix}-public-${props.timestamp}`,
|
|
924
|
-
versioned: true,
|
|
925
|
-
autoDeleteObjects: true,
|
|
926
|
-
removalPolicy: RemovalPolicy3.DESTROY,
|
|
927
|
-
encryption: s32.BucketEncryption.S3_MANAGED
|
|
928
|
-
});
|
|
929
|
-
Tags.of(this.publicBucket).add("daily-backup", "true");
|
|
930
|
-
this.privateBucket = new s32.Bucket(scope, "PrivateBucket", {
|
|
931
|
-
bucketName: `${this.bucketPrefix}-private-${props.timestamp}`,
|
|
932
|
-
versioned: true,
|
|
933
|
-
removalPolicy: RemovalPolicy3.DESTROY,
|
|
934
|
-
autoDeleteObjects: true,
|
|
935
|
-
encryption: s32.BucketEncryption.S3_MANAGED,
|
|
936
|
-
enforceSSL: true,
|
|
937
|
-
publicReadAccess: false,
|
|
938
|
-
blockPublicAccess: {
|
|
939
|
-
blockPublicAcls: true,
|
|
940
|
-
blockPublicPolicy: true,
|
|
941
|
-
ignorePublicAcls: true,
|
|
942
|
-
restrictPublicBuckets: true
|
|
943
|
-
}
|
|
944
|
-
});
|
|
945
|
-
Tags.of(this.privateBucket).add("daily-backup", "true");
|
|
946
|
-
this.logBucket = new s32.Bucket(scope, "LogsBucket", {
|
|
947
|
-
bucketName: `${this.bucketPrefix}-logs-${props.timestamp}`,
|
|
948
|
-
removalPolicy: RemovalPolicy3.RETAIN,
|
|
949
|
-
blockPublicAccess: new s32.BlockPublicAccess({
|
|
950
|
-
blockPublicAcls: false,
|
|
951
|
-
ignorePublicAcls: true,
|
|
952
|
-
blockPublicPolicy: true,
|
|
953
|
-
restrictPublicBuckets: true
|
|
954
|
-
}),
|
|
955
|
-
objectOwnership: s32.ObjectOwnership.BUCKET_OWNER_PREFERRED
|
|
956
|
-
});
|
|
957
|
-
Tags.of(this.logBucket).add("daily-backup", "true");
|
|
958
|
-
this.backupRole = this.createBackupRole(scope);
|
|
959
|
-
this.vault = new backup.BackupVault(scope, "BackupVault", {
|
|
960
|
-
backupVaultName: `${props.slug}-${props.appEnv}-daily-backup-vault`,
|
|
961
|
-
encryptionKey: props.kmsKey,
|
|
962
|
-
removalPolicy: RemovalPolicy3.DESTROY
|
|
963
|
-
});
|
|
964
|
-
this.backupPlan = backup.BackupPlan.daily35DayRetention(scope, "BackupPlan", this.vault);
|
|
965
|
-
this.backupPlan.addSelection("Selection", {
|
|
966
|
-
role: this.backupRole,
|
|
967
|
-
resources: [backup.BackupResource.fromTag("daily-backup", "true")]
|
|
968
|
-
});
|
|
969
|
-
}
|
|
970
|
-
createBackupRole(scope) {
|
|
971
|
-
const backupRole = new iam2.Role(scope, "BackupRole", {
|
|
972
|
-
assumedBy: new iam2.ServicePrincipal("backup.amazonaws.com")
|
|
973
|
-
});
|
|
974
|
-
backupRole.addToPolicy(new iam2.PolicyStatement({
|
|
975
|
-
actions: [
|
|
976
|
-
"s3:GetInventoryConfiguration",
|
|
977
|
-
"s3:PutInventoryConfiguration",
|
|
978
|
-
"s3:ListBucketVersions",
|
|
979
|
-
"s3:ListBucket",
|
|
980
|
-
"s3:GetBucketVersioning",
|
|
981
|
-
"s3:GetBucketNotification",
|
|
982
|
-
"s3:PutBucketNotification",
|
|
983
|
-
"s3:GetBucketLocation",
|
|
984
|
-
"s3:GetBucketTagging"
|
|
985
|
-
],
|
|
986
|
-
resources: ["arn:aws:s3:::*"],
|
|
987
|
-
sid: "S3BucketBackupPermissions"
|
|
988
|
-
}));
|
|
989
|
-
backupRole.addToPolicy(new iam2.PolicyStatement({
|
|
990
|
-
actions: [
|
|
991
|
-
"s3:GetObjectAcl",
|
|
992
|
-
"s3:GetObject",
|
|
993
|
-
"s3:GetObjectVersionTagging",
|
|
994
|
-
"s3:GetObjectVersionAcl",
|
|
995
|
-
"s3:GetObjectTagging",
|
|
996
|
-
"s3:GetObjectVersion"
|
|
997
|
-
],
|
|
998
|
-
resources: ["arn:aws:s3:::*/*"],
|
|
999
|
-
sid: "S3ObjectBackupPermissions"
|
|
1000
|
-
}));
|
|
1001
|
-
backupRole.addToPolicy(new iam2.PolicyStatement({
|
|
1002
|
-
actions: ["s3:ListAllMyBuckets"],
|
|
1003
|
-
resources: ["*"],
|
|
1004
|
-
sid: "S3GlobalPermissions"
|
|
1005
|
-
}));
|
|
1006
|
-
backupRole.addToPolicy(new iam2.PolicyStatement({
|
|
1007
|
-
actions: ["kms:Decrypt", "kms:DescribeKey"],
|
|
1008
|
-
resources: ["*"],
|
|
1009
|
-
sid: "KMSBackupPermissions",
|
|
1010
|
-
conditions: {
|
|
1011
|
-
StringLike: {
|
|
1012
|
-
"kms:ViaService": "s3.*.amazonaws.com"
|
|
1013
|
-
}
|
|
1014
|
-
}
|
|
1015
|
-
}));
|
|
1016
|
-
backupRole.addToPolicy(new iam2.PolicyStatement({
|
|
1017
|
-
actions: [
|
|
1018
|
-
"events:DescribeRule",
|
|
1019
|
-
"events:EnableRule",
|
|
1020
|
-
"events:PutRule",
|
|
1021
|
-
"events:DeleteRule",
|
|
1022
|
-
"events:PutTargets",
|
|
1023
|
-
"events:RemoveTargets",
|
|
1024
|
-
"events:ListTargetsByRule",
|
|
1025
|
-
"events:DisableRule"
|
|
1026
|
-
],
|
|
1027
|
-
resources: ["arn:aws:events:*:*:rule/AwsBackupManagedRule*"],
|
|
1028
|
-
sid: "EventsPermissions"
|
|
1029
|
-
}));
|
|
1030
|
-
backupRole.addToPolicy(new iam2.PolicyStatement({
|
|
1031
|
-
actions: ["cloudwatch:GetMetricData", "events:ListRules"],
|
|
1032
|
-
resources: ["*"],
|
|
1033
|
-
sid: "EventsMetricsGlobalPermissions"
|
|
1034
|
-
}));
|
|
1035
|
-
return backupRole;
|
|
1036
|
-
}
|
|
1037
|
-
}
|
|
1038
|
-
|
|
1039
|
-
// src/cloud/security.ts
|
|
1040
|
-
import {config as config10} from "@stacksjs/config";
|
|
1041
|
-
import {Duration as Duration4, RemovalPolicy as RemovalPolicy4, Tags as Tags2, aws_certificatemanager as acm, aws_kms as kms, aws_wafv2 as wafv2} from "aws-cdk-lib";
|
|
1042
|
-
|
|
1043
|
-
class SecurityStack {
|
|
1044
|
-
firewall;
|
|
1045
|
-
kmsKey;
|
|
1046
|
-
certificate;
|
|
1047
|
-
constructor(scope, props) {
|
|
1048
|
-
const firewallOptions = config10.cloud.firewall;
|
|
1049
|
-
if (!firewallOptions)
|
|
1050
|
-
throw new Error("No firewall options found in config");
|
|
1051
|
-
const options = {
|
|
1052
|
-
defaultAction: { allow: {} },
|
|
1053
|
-
scope: "CLOUDFRONT",
|
|
1054
|
-
visibilityConfig: {
|
|
1055
|
-
sampledRequestsEnabled: true,
|
|
1056
|
-
cloudWatchMetricsEnabled: true,
|
|
1057
|
-
metricName: "firewallMetric"
|
|
1058
|
-
},
|
|
1059
|
-
rules: this.getFirewallRules()
|
|
1060
|
-
};
|
|
1061
|
-
this.firewall = new wafv2.CfnWebACL(scope, "StacksWebFirewall", options);
|
|
1062
|
-
Tags2.of(this.firewall).add("Name", "waf-cloudfront", { priority: 300 });
|
|
1063
|
-
Tags2.of(this.firewall).add("Purpose", "CloudFront", { priority: 300 });
|
|
1064
|
-
Tags2.of(this.firewall).add("CreatedBy", "CloudFormation", { priority: 300 });
|
|
1065
|
-
this.kmsKey = new kms.Key(scope, "EncryptionKey", {
|
|
1066
|
-
alias: "stacks-encryption-key",
|
|
1067
|
-
description: "KMS key for Stacks Cloud",
|
|
1068
|
-
enableKeyRotation: true,
|
|
1069
|
-
removalPolicy: RemovalPolicy4.DESTROY,
|
|
1070
|
-
pendingWindow: Duration4.days(30)
|
|
1071
|
-
});
|
|
1072
|
-
this.certificate = new acm.Certificate(scope, "Certificate", {
|
|
1073
|
-
domainName: props.domain,
|
|
1074
|
-
validation: acm.CertificateValidation.fromDns(props.zone),
|
|
1075
|
-
subjectAlternativeNames: [`www.${props.domain}`, `api.${props.domain}`]
|
|
1076
|
-
});
|
|
1077
|
-
}
|
|
1078
|
-
getFirewallRules() {
|
|
1079
|
-
const rules = [];
|
|
1080
|
-
const priorities = [];
|
|
1081
|
-
if (config10.security.firewall?.countryCodes?.length) {
|
|
1082
|
-
priorities.push(1);
|
|
1083
|
-
rules.push({
|
|
1084
|
-
name: "CountryRule",
|
|
1085
|
-
priority: priorities.length,
|
|
1086
|
-
statement: {
|
|
1087
|
-
geoMatchStatement: {
|
|
1088
|
-
countryCodes: config10.security.firewall.countryCodes
|
|
1089
|
-
}
|
|
1090
|
-
},
|
|
1091
|
-
action: {
|
|
1092
|
-
block: {}
|
|
1093
|
-
},
|
|
1094
|
-
visibilityConfig: {
|
|
1095
|
-
sampledRequestsEnabled: true,
|
|
1096
|
-
cloudWatchMetricsEnabled: true,
|
|
1097
|
-
metricName: "CountryRule"
|
|
1098
|
-
}
|
|
1099
|
-
});
|
|
1100
|
-
}
|
|
1101
|
-
if (config10.security.firewall?.ipAddresses?.length) {
|
|
1102
|
-
const ipSet = new wafv2.CfnIPSet(this, "IpSet", {
|
|
1103
|
-
name: "IpSet",
|
|
1104
|
-
description: "IP Set",
|
|
1105
|
-
scope: "CLOUDFRONT",
|
|
1106
|
-
addresses: config10.security.firewall.ipAddresses,
|
|
1107
|
-
ipAddressVersion: "IPV4"
|
|
1108
|
-
});
|
|
1109
|
-
priorities.push(1);
|
|
1110
|
-
rules.push({
|
|
1111
|
-
name: "IpAddressRule",
|
|
1112
|
-
priority: priorities.length,
|
|
1113
|
-
statement: {
|
|
1114
|
-
ipSetReferenceStatement: {
|
|
1115
|
-
arn: ipSet.attrArn
|
|
1116
|
-
}
|
|
1117
|
-
},
|
|
1118
|
-
action: {
|
|
1119
|
-
block: {}
|
|
1120
|
-
},
|
|
1121
|
-
visibilityConfig: {
|
|
1122
|
-
sampledRequestsEnabled: true,
|
|
1123
|
-
cloudWatchMetricsEnabled: true,
|
|
1124
|
-
metricName: "IpAddressRule"
|
|
1125
|
-
}
|
|
1126
|
-
});
|
|
1127
|
-
}
|
|
1128
|
-
if (config10.security.firewall?.httpHeaders?.length) {
|
|
1129
|
-
config10.security.firewall.httpHeaders.forEach((header, index) => {
|
|
1130
|
-
priorities.push(1);
|
|
1131
|
-
rules.push({
|
|
1132
|
-
name: `HttpHeaderRule${index}`,
|
|
1133
|
-
priority: priorities.length,
|
|
1134
|
-
statement: {
|
|
1135
|
-
byteMatchStatement: {
|
|
1136
|
-
fieldToMatch: {
|
|
1137
|
-
singleHeader: {
|
|
1138
|
-
name: header
|
|
1139
|
-
}
|
|
1140
|
-
},
|
|
1141
|
-
positionalConstraint: "EXACTLY",
|
|
1142
|
-
searchString: "true",
|
|
1143
|
-
textTransformations: [
|
|
1144
|
-
{
|
|
1145
|
-
priority: index,
|
|
1146
|
-
type: "NONE"
|
|
1147
|
-
}
|
|
1148
|
-
]
|
|
1149
|
-
}
|
|
1150
|
-
},
|
|
1151
|
-
action: {
|
|
1152
|
-
block: {}
|
|
1153
|
-
},
|
|
1154
|
-
visibilityConfig: {
|
|
1155
|
-
sampledRequestsEnabled: true,
|
|
1156
|
-
cloudWatchMetricsEnabled: true,
|
|
1157
|
-
metricName: `HttpHeaderRule${index}`
|
|
1158
|
-
}
|
|
1159
|
-
});
|
|
1160
|
-
});
|
|
1161
|
-
}
|
|
1162
|
-
return rules;
|
|
1163
|
-
}
|
|
1164
|
-
}
|
|
1165
|
-
|
|
1166
|
-
// src/cloud/deployment.ts
|
|
1167
|
-
import {AssetHashType as AssetHashType2, aws_s3_deployment as s3deploy} from "aws-cdk-lib";
|
|
1168
|
-
import {config as config12} from "@stacksjs/config";
|
|
1169
|
-
import {websiteSourceHash} from "@stacksjs/utils";
|
|
1170
|
-
|
|
1171
|
-
class DeploymentStack {
|
|
1172
|
-
privateSource;
|
|
1173
|
-
docsSource;
|
|
1174
|
-
websiteSource;
|
|
1175
|
-
constructor(scope, props) {
|
|
1176
|
-
this.privateSource = "../../private";
|
|
1177
|
-
this.docsSource = "../docs/dist/";
|
|
1178
|
-
this.websiteSource = config12.app.docMode === true ? this.docsSource : "../views/dist/";
|
|
1179
|
-
new s3deploy.BucketDeployment(scope, "Website", {
|
|
1180
|
-
sources: [s3deploy.Source.asset(this.websiteSource, {
|
|
1181
|
-
assetHash: websiteSourceHash,
|
|
1182
|
-
assetHashType: AssetHashType2.CUSTOM
|
|
1183
|
-
})],
|
|
1184
|
-
destinationBucket: props.publicBucket,
|
|
1185
|
-
distribution: props.cdn,
|
|
1186
|
-
distributionPaths: ["/*"]
|
|
1187
|
-
});
|
|
1188
|
-
new s3deploy.BucketDeployment(scope, "PrivateFiles", {
|
|
1189
|
-
sources: [s3deploy.Source.asset(this.privateSource)],
|
|
1190
|
-
destinationBucket: props.privateBucket
|
|
1191
|
-
});
|
|
1192
|
-
}
|
|
1193
|
-
}
|
|
1194
|
-
|
|
1195
|
-
// src/cloud/jump-box.ts
|
|
1196
|
-
import {CfnOutput as Output5, aws_ec2 as ec2, aws_iam as iam3} from "aws-cdk-lib";
|
|
1197
|
-
|
|
1198
|
-
class JumpBoxStack {
|
|
1199
|
-
jumpBox;
|
|
1200
|
-
constructor(scope, props) {
|
|
1201
|
-
const role = new iam3.Role(scope, "JumpBoxInstanceRole", {
|
|
1202
|
-
assumedBy: new iam3.ServicePrincipal("ec2.amazonaws.com"),
|
|
1203
|
-
managedPolicies: [
|
|
1204
|
-
iam3.ManagedPolicy.fromAwsManagedPolicyName("AmazonSSMManagedInstanceCore"),
|
|
1205
|
-
iam3.ManagedPolicy.fromAwsManagedPolicyName("CloudWatchAgentServerPolicy")
|
|
1206
|
-
]
|
|
1207
|
-
});
|
|
1208
|
-
this.jumpBox = new ec2.Instance(scope, "JumpBox", {
|
|
1209
|
-
vpc: props.vpc,
|
|
1210
|
-
instanceType: ec2.InstanceType.of(ec2.InstanceClass.T2, ec2.InstanceSize.MICRO),
|
|
1211
|
-
machineImage: new ec2.AmazonLinuxImage,
|
|
1212
|
-
role,
|
|
1213
|
-
userData: ec2.UserData.custom(`
|
|
1214
|
-
#!/bin/bash
|
|
1215
|
-
yum update -y
|
|
1216
|
-
yum install -y amazon-efs-utils
|
|
1217
|
-
yum install -y git
|
|
1218
|
-
yum install -y https://s3.us-east-1.amazonaws.com/amazon-ssm-us-east-1/latest/linux_amd64/amazon-ssm-agent.rpm
|
|
1219
|
-
mkdir /mnt/efs
|
|
1220
|
-
mount -t efs ${props.fileSystem.fileSystemId}:/ /mnt/efs
|
|
1221
|
-
git clone https://github.com/stacksjs/stacks.git /mnt/efs
|
|
1222
|
-
`)
|
|
1223
|
-
});
|
|
1224
|
-
new Output5(scope, "JumpBoxInstanceId", {
|
|
1225
|
-
value: this.jumpBox.instanceId,
|
|
1226
|
-
description: "The ID of the EC2 instance that can be used to SSH into the Stacks Cloud."
|
|
1227
|
-
});
|
|
1228
|
-
}
|
|
1229
|
-
}
|
|
1230
|
-
|
|
1231
|
-
// src/cloud/file-system.ts
|
|
1232
|
-
import {RemovalPolicy as RemovalPolicy5, aws_efs as efs} from "aws-cdk-lib";
|
|
1233
|
-
|
|
1234
|
-
class FileSystemStack {
|
|
1235
|
-
fileSystem;
|
|
1236
|
-
accessPoint;
|
|
1237
|
-
constructor(scope, props) {
|
|
1238
|
-
this.fileSystem = new efs.FileSystem(scope, "FileSystem", {
|
|
1239
|
-
fileSystemName: `${props.slug}-${props.appEnv}-efs`,
|
|
1240
|
-
vpc: props.vpc,
|
|
1241
|
-
removalPolicy: RemovalPolicy5.DESTROY,
|
|
1242
|
-
lifecyclePolicy: efs.LifecyclePolicy.AFTER_7_DAYS,
|
|
1243
|
-
performanceMode: efs.PerformanceMode.GENERAL_PURPOSE,
|
|
1244
|
-
throughputMode: efs.ThroughputMode.BURSTING,
|
|
1245
|
-
enableAutomaticBackups: true,
|
|
1246
|
-
encrypted: true
|
|
1247
|
-
});
|
|
1248
|
-
this.accessPoint = new efs.AccessPoint(scope, "FileSystemAccessPoint", {
|
|
1249
|
-
fileSystem: this.fileSystem,
|
|
1250
|
-
path: "/",
|
|
1251
|
-
posixUser: {
|
|
1252
|
-
uid: "1000",
|
|
1253
|
-
gid: "1000"
|
|
1254
|
-
}
|
|
1255
|
-
});
|
|
1256
|
-
}
|
|
1257
|
-
}
|
|
1258
|
-
|
|
1259
|
-
// src/cloud/network.ts
|
|
1260
|
-
import {aws_ec2 as ec22} from "aws-cdk-lib";
|
|
1261
|
-
|
|
1262
|
-
class NetworkStack {
|
|
1263
|
-
vpc;
|
|
1264
|
-
constructor(scope, props) {
|
|
1265
|
-
this.vpc = new ec22.Vpc(scope, "Network", {
|
|
1266
|
-
vpcName: `${props.slug}-${props.appEnv}-vpc`,
|
|
1267
|
-
ipAddresses: ec22.IpAddresses.cidr("10.0.0.0/16"),
|
|
1268
|
-
maxAzs: 3,
|
|
1269
|
-
natGateways: 0,
|
|
1270
|
-
subnetConfiguration: [
|
|
1271
|
-
{
|
|
1272
|
-
name: "public-subnet-1",
|
|
1273
|
-
subnetType: ec22.SubnetType.PUBLIC,
|
|
1274
|
-
cidrMask: 24
|
|
1275
|
-
},
|
|
1276
|
-
{
|
|
1277
|
-
name: "private-subnet-1",
|
|
1278
|
-
subnetType: ec22.SubnetType.PRIVATE_ISOLATED,
|
|
1279
|
-
cidrMask: 28
|
|
1280
|
-
}
|
|
1281
|
-
]
|
|
1282
|
-
});
|
|
1283
|
-
}
|
|
1284
|
-
}
|
|
1285
|
-
|
|
1286
|
-
// src/cloud/redirects.ts
|
|
1287
|
-
import {config as config14} from "@stacksjs/config";
|
|
1288
|
-
import {RemovalPolicy as RemovalPolicy6, aws_route53 as route533, aws_s3 as s33} from "aws-cdk-lib";
|
|
1289
|
-
|
|
1290
|
-
class RedirectsStack {
|
|
1291
|
-
redirectZones = [];
|
|
1292
|
-
constructor(scope, props) {
|
|
1293
|
-
config14.dns.redirects?.forEach((redirect) => {
|
|
1294
|
-
const slug2 = redirect.split(".").map((part, index) => index === 0 ? part : part.charAt(0).toUpperCase() + part.slice(1)).join("");
|
|
1295
|
-
const hostedZone = route533.HostedZone.fromLookup(scope, "HostedZone", { domainName: redirect });
|
|
1296
|
-
const redirectBucket = new s33.Bucket(scope, `RedirectBucket${slug2}`, {
|
|
1297
|
-
bucketName: `${redirect}-redirect`,
|
|
1298
|
-
websiteRedirect: {
|
|
1299
|
-
hostName: props.domain,
|
|
1300
|
-
protocol: s33.RedirectProtocol.HTTPS
|
|
1301
|
-
},
|
|
1302
|
-
removalPolicy: RemovalPolicy6.DESTROY,
|
|
1303
|
-
autoDeleteObjects: true
|
|
1304
|
-
});
|
|
1305
|
-
new route533.CnameRecord(scope, `RedirectRecord${slug2}`, {
|
|
1306
|
-
zone: hostedZone,
|
|
1307
|
-
recordName: "redirect",
|
|
1308
|
-
domainName: redirectBucket.bucketWebsiteDomainName
|
|
1309
|
-
});
|
|
1310
|
-
});
|
|
1311
|
-
config14.dns.redirects?.forEach((redirect) => {
|
|
1312
|
-
const slug2 = redirect.split(".").map((part, index) => index === 0 ? part : part.charAt(0).toUpperCase() + part.slice(1)).join("");
|
|
1313
|
-
const hostedZone = route533.HostedZone.fromLookup(scope, `RedirectHostedZone${slug2}`, { domainName: redirect });
|
|
1314
|
-
this.redirectZones.push(hostedZone);
|
|
1315
|
-
});
|
|
1316
|
-
}
|
|
1317
|
-
}
|
|
1318
|
-
|
|
1319
|
-
// src/cloud/email.ts
|
|
1320
|
-
import {Duration as Duration5, RemovalPolicy as RemovalPolicy7, Stack, Tags as Tags3, aws_iam as iam4, aws_lambda as lambda4, aws_route53 as route534, aws_s3 as s34, aws_s3_notifications as s3n, aws_ses as ses} from "aws-cdk-lib";
|
|
1321
|
-
import {config as config16} from "@stacksjs/config";
|
|
1322
|
-
|
|
1323
|
-
class EmailStack {
|
|
1324
|
-
emailBucket;
|
|
1325
|
-
constructor(scope, props) {
|
|
1326
|
-
const bucketPrefix = `${props.slug}-${props.appEnv}`;
|
|
1327
|
-
this.emailBucket = new s34.Bucket(scope, "EmailBucket", {
|
|
1328
|
-
bucketName: `${bucketPrefix}-email-${props.timestamp}`,
|
|
1329
|
-
versioned: true,
|
|
1330
|
-
removalPolicy: RemovalPolicy7.DESTROY,
|
|
1331
|
-
autoDeleteObjects: true,
|
|
1332
|
-
encryption: s34.BucketEncryption.S3_MANAGED,
|
|
1333
|
-
lifecycleRules: [
|
|
1334
|
-
{
|
|
1335
|
-
id: "24h",
|
|
1336
|
-
enabled: true,
|
|
1337
|
-
expiration: Duration5.days(1),
|
|
1338
|
-
noncurrentVersionExpiration: Duration5.days(1),
|
|
1339
|
-
prefix: "today/"
|
|
1340
|
-
},
|
|
1341
|
-
{
|
|
1342
|
-
id: "Intelligent transition for Inbox",
|
|
1343
|
-
enabled: true,
|
|
1344
|
-
prefix: "inbox/",
|
|
1345
|
-
transitions: [
|
|
1346
|
-
{
|
|
1347
|
-
storageClass: s34.StorageClass.INTELLIGENT_TIERING,
|
|
1348
|
-
transitionAfter: Duration5.days(0)
|
|
1349
|
-
}
|
|
1350
|
-
]
|
|
1351
|
-
},
|
|
1352
|
-
{
|
|
1353
|
-
id: "Intelligent transition for Sent",
|
|
1354
|
-
enabled: true,
|
|
1355
|
-
prefix: "sent/",
|
|
1356
|
-
transitions: [
|
|
1357
|
-
{
|
|
1358
|
-
storageClass: s34.StorageClass.INTELLIGENT_TIERING,
|
|
1359
|
-
transitionAfter: Duration5.days(0)
|
|
1360
|
-
}
|
|
1361
|
-
]
|
|
1362
|
-
}
|
|
1363
|
-
]
|
|
1364
|
-
});
|
|
1365
|
-
Tags3.of(this.emailBucket).add("daily-backup", "true");
|
|
1366
|
-
const sesPrincipal = new iam4.ServicePrincipal("ses.amazonaws.com");
|
|
1367
|
-
const ruleSetName = `${props.slug}-${props.appEnv}-email-receipt-rule-set`;
|
|
1368
|
-
const receiptRuleName = `${props.slug}-${props.appEnv}-email-receipt-rule`;
|
|
1369
|
-
const ruleSet = new ses.CfnReceiptRuleSet(scope, "SESReceiptRuleSet", {
|
|
1370
|
-
ruleSetName
|
|
1371
|
-
});
|
|
1372
|
-
this.emailBucket.addToResourcePolicy(new iam4.PolicyStatement({
|
|
1373
|
-
sid: "AllowSESPuts",
|
|
1374
|
-
effect: iam4.Effect.ALLOW,
|
|
1375
|
-
principals: [sesPrincipal],
|
|
1376
|
-
actions: [
|
|
1377
|
-
"s3:PutObject"
|
|
1378
|
-
],
|
|
1379
|
-
resources: [
|
|
1380
|
-
`${this.emailBucket.bucketArn}/*`
|
|
1381
|
-
],
|
|
1382
|
-
conditions: {
|
|
1383
|
-
StringEquals: {
|
|
1384
|
-
"aws:SourceAccount": Stack.of(scope).account
|
|
1385
|
-
},
|
|
1386
|
-
ArnLike: {
|
|
1387
|
-
"aws:SourceArn": `arn:aws:ses:${Stack.of(scope).region}:${Stack.of(scope).account}:receipt-rule-set/${ruleSetName}:receipt-rule/${receiptRuleName}`
|
|
1388
|
-
}
|
|
1389
|
-
}
|
|
1390
|
-
}));
|
|
1391
|
-
const receiptRule = new ses.CfnReceiptRule(scope, "SESReceiptRule", {
|
|
1392
|
-
ruleSetName: ruleSet.ref,
|
|
1393
|
-
rule: {
|
|
1394
|
-
name: receiptRuleName,
|
|
1395
|
-
enabled: true,
|
|
1396
|
-
actions: [
|
|
1397
|
-
{
|
|
1398
|
-
s3Action: {
|
|
1399
|
-
bucketName: this.emailBucket.bucketName,
|
|
1400
|
-
objectKeyPrefix: "tmp/email_in/"
|
|
1401
|
-
}
|
|
1402
|
-
}
|
|
1403
|
-
],
|
|
1404
|
-
recipients: config16.email.mailboxes || [],
|
|
1405
|
-
scanEnabled: config16.email.server?.scan || true,
|
|
1406
|
-
tlsPolicy: "Require"
|
|
1407
|
-
}
|
|
1408
|
-
});
|
|
1409
|
-
receiptRule.node.addDependency(this.emailBucket);
|
|
1410
|
-
const iamGroup = new iam4.Group(scope, "IAMGroup", {
|
|
1411
|
-
groupName: `${props.slug}-${props.appEnv}-email-management-s3-group`
|
|
1412
|
-
});
|
|
1413
|
-
const listBucketsPolicyStatement = new iam4.PolicyStatement({
|
|
1414
|
-
effect: iam4.Effect.ALLOW,
|
|
1415
|
-
actions: ["s3:ListAllMyBuckets"],
|
|
1416
|
-
resources: ["*"]
|
|
1417
|
-
});
|
|
1418
|
-
const policyStatement = new iam4.PolicyStatement({
|
|
1419
|
-
effect: iam4.Effect.ALLOW,
|
|
1420
|
-
actions: [
|
|
1421
|
-
"s3:ListBucket",
|
|
1422
|
-
"s3:GetObject",
|
|
1423
|
-
"s3:PutObject",
|
|
1424
|
-
"s3:DeleteObject",
|
|
1425
|
-
"s3:GetObjectAcl",
|
|
1426
|
-
"s3:GetObjectVersionAcl",
|
|
1427
|
-
"s3:PutObjectAcl",
|
|
1428
|
-
"s3:PutObjectVersionAcl"
|
|
1429
|
-
],
|
|
1430
|
-
resources: [
|
|
1431
|
-
this.emailBucket.bucketArn,
|
|
1432
|
-
`${this.emailBucket.bucketArn}/*`
|
|
1433
|
-
]
|
|
1434
|
-
});
|
|
1435
|
-
const policy = new iam4.Policy(scope, "EmailAccessPolicy", {
|
|
1436
|
-
policyName: `${props.slug}-${props.appEnv}-email-management-s3-policy`,
|
|
1437
|
-
statements: [policyStatement, listBucketsPolicyStatement]
|
|
1438
|
-
});
|
|
1439
|
-
iamGroup.attachInlinePolicy(policy);
|
|
1440
|
-
const sesIdentity = new ses.CfnEmailIdentity(scope, "DomainIdentity", {
|
|
1441
|
-
emailIdentity: props.domain,
|
|
1442
|
-
dkimSigningAttributes: {
|
|
1443
|
-
nextSigningKeyLength: "RSA_2048_BIT"
|
|
1444
|
-
},
|
|
1445
|
-
dkimAttributes: {
|
|
1446
|
-
signingEnabled: true
|
|
1447
|
-
},
|
|
1448
|
-
mailFromAttributes: {
|
|
1449
|
-
behaviorOnMxFailure: "USE_DEFAULT_VALUE",
|
|
1450
|
-
mailFromDomain: `mail.${props.domain}`
|
|
1451
|
-
},
|
|
1452
|
-
feedbackAttributes: {
|
|
1453
|
-
emailForwardingEnabled: true
|
|
1454
|
-
}
|
|
1455
|
-
});
|
|
1456
|
-
new route534.CfnRecordSet(scope, "DkimRecord1", {
|
|
1457
|
-
hostedZoneName: `${props.zone.zoneName}.`,
|
|
1458
|
-
name: sesIdentity.attrDkimDnsTokenName1,
|
|
1459
|
-
type: "CNAME",
|
|
1460
|
-
resourceRecords: [sesIdentity.attrDkimDnsTokenValue1],
|
|
1461
|
-
ttl: "1800"
|
|
1462
|
-
});
|
|
1463
|
-
new route534.CfnRecordSet(scope, "DkimRecord2", {
|
|
1464
|
-
hostedZoneName: `${props.zone.zoneName}.`,
|
|
1465
|
-
name: sesIdentity.attrDkimDnsTokenName2,
|
|
1466
|
-
type: "CNAME",
|
|
1467
|
-
resourceRecords: [sesIdentity.attrDkimDnsTokenValue2],
|
|
1468
|
-
ttl: "1800"
|
|
1469
|
-
});
|
|
1470
|
-
new route534.CfnRecordSet(scope, "DkimRecord3", {
|
|
1471
|
-
hostedZoneName: `${props.zone.zoneName}.`,
|
|
1472
|
-
name: sesIdentity.attrDkimDnsTokenName3,
|
|
1473
|
-
type: "CNAME",
|
|
1474
|
-
resourceRecords: [sesIdentity.attrDkimDnsTokenValue3],
|
|
1475
|
-
ttl: "1800"
|
|
1476
|
-
});
|
|
1477
|
-
new route534.MxRecord(scope, "MxRecord", {
|
|
1478
|
-
zone: props.zone,
|
|
1479
|
-
recordName: "mail",
|
|
1480
|
-
values: [{
|
|
1481
|
-
priority: 10,
|
|
1482
|
-
hostName: "feedback-smtp.us-east-1.amazonses.com"
|
|
1483
|
-
}]
|
|
1484
|
-
});
|
|
1485
|
-
new route534.TxtRecord(scope, "TxtSpfRecord", {
|
|
1486
|
-
zone: props.zone,
|
|
1487
|
-
recordName: "mail",
|
|
1488
|
-
values: ["v=spf1 include:amazonses.com ~all"]
|
|
1489
|
-
});
|
|
1490
|
-
new route534.TxtRecord(scope, "TxtDmarcRecord", {
|
|
1491
|
-
zone: props.zone,
|
|
1492
|
-
recordName: "_dmarc",
|
|
1493
|
-
values: [`v=DMARC1;p=quarantine;pct=25;rua=mailto:dmarcreports@${props.domain}`]
|
|
1494
|
-
});
|
|
1495
|
-
const lambdaEmailOutboundRole = new iam4.Role(scope, "LambdaEmailOutboundRole", {
|
|
1496
|
-
roleName: `${props.slug}-${props.appEnv}-email-outbound`,
|
|
1497
|
-
assumedBy: new iam4.ServicePrincipal("lambda.amazonaws.com"),
|
|
1498
|
-
managedPolicies: [
|
|
1499
|
-
iam4.ManagedPolicy.fromAwsManagedPolicyName("service-role/AWSLambdaBasicExecutionRole")
|
|
1500
|
-
]
|
|
1501
|
-
});
|
|
1502
|
-
const lambdaEmailOutbound = new lambda4.Function(scope, "LambdaEmailOutbound", {
|
|
1503
|
-
functionName: `${props.slug}-${props.appEnv}-email-outbound`,
|
|
1504
|
-
description: "Take the JSON and convert it in to an raw email.",
|
|
1505
|
-
code: lambda4.Code.fromInline("exports.handler = async (event) => {return true;};"),
|
|
1506
|
-
handler: "index.handler",
|
|
1507
|
-
memorySize: 256,
|
|
1508
|
-
runtime: lambda4.Runtime.NODEJS_18_X,
|
|
1509
|
-
timeout: Duration5.seconds(60),
|
|
1510
|
-
environment: {
|
|
1511
|
-
BUCKET: this.emailBucket.bucketName
|
|
1512
|
-
},
|
|
1513
|
-
role: lambdaEmailOutboundRole
|
|
1514
|
-
});
|
|
1515
|
-
lambdaEmailOutboundRole.addToPolicy(policyStatement);
|
|
1516
|
-
const sesPolicyStatement = new iam4.PolicyStatement({
|
|
1517
|
-
effect: iam4.Effect.ALLOW,
|
|
1518
|
-
actions: ["ses:SendRawEmail"],
|
|
1519
|
-
resources: ["*"]
|
|
1520
|
-
});
|
|
1521
|
-
lambdaEmailOutboundRole.addToPolicy(sesPolicyStatement);
|
|
1522
|
-
const lambdaEmailInboundRole = new iam4.Role(scope, "LambdaEmailInboundRole", {
|
|
1523
|
-
roleName: `${props.slug}-${props.appEnv}-email-inbound`,
|
|
1524
|
-
assumedBy: new iam4.ServicePrincipal("lambda.amazonaws.com"),
|
|
1525
|
-
managedPolicies: [
|
|
1526
|
-
iam4.ManagedPolicy.fromAwsManagedPolicyName("service-role/AWSLambdaBasicExecutionRole")
|
|
1527
|
-
]
|
|
1528
|
-
});
|
|
1529
|
-
const lambdaEmailInbound = new lambda4.Function(scope, "LambdaEmailInbound", {
|
|
1530
|
-
functionName: `${props.slug}-${props.appEnv}-email-inbound`,
|
|
1531
|
-
description: "This Lambda organizes all the incoming emails based on the From and To field.",
|
|
1532
|
-
code: lambda4.Code.fromInline("exports.handler = async (event) => {return true;};"),
|
|
1533
|
-
handler: "index.handler",
|
|
1534
|
-
memorySize: 256,
|
|
1535
|
-
role: lambdaEmailInboundRole,
|
|
1536
|
-
runtime: lambda4.Runtime.NODEJS_18_X,
|
|
1537
|
-
timeout: Duration5.seconds(60),
|
|
1538
|
-
environment: {
|
|
1539
|
-
BUCKET: this.emailBucket.bucketName
|
|
1540
|
-
}
|
|
1541
|
-
});
|
|
1542
|
-
new lambda4.CfnPermission(scope, "S3InboundPermission", {
|
|
1543
|
-
action: "lambda:InvokeFunction",
|
|
1544
|
-
functionName: lambdaEmailInbound.functionName,
|
|
1545
|
-
principal: "s3.amazonaws.com"
|
|
1546
|
-
});
|
|
1547
|
-
const inboundS3PolicyStatement = new iam4.PolicyStatement({
|
|
1548
|
-
effect: iam4.Effect.ALLOW,
|
|
1549
|
-
actions: ["s3:*"],
|
|
1550
|
-
resources: [
|
|
1551
|
-
this.emailBucket.bucketArn,
|
|
1552
|
-
`${this.emailBucket.bucketArn}/*`
|
|
1553
|
-
]
|
|
1554
|
-
});
|
|
1555
|
-
lambdaEmailInboundRole.addToPolicy(inboundS3PolicyStatement);
|
|
1556
|
-
const sesInboundPolicyStatement = new iam4.PolicyStatement({
|
|
1557
|
-
effect: iam4.Effect.ALLOW,
|
|
1558
|
-
actions: ["ses:ListIdentities"],
|
|
1559
|
-
resources: ["*"]
|
|
1560
|
-
});
|
|
1561
|
-
lambdaEmailInboundRole.addToPolicy(sesInboundPolicyStatement);
|
|
1562
|
-
const lambdaEmailConverterRole = new iam4.Role(scope, "LambdaEmailConverterRole", {
|
|
1563
|
-
roleName: `${props.slug}-${props.appEnv}-email-converter`,
|
|
1564
|
-
assumedBy: new iam4.ServicePrincipal("lambda.amazonaws.com"),
|
|
1565
|
-
managedPolicies: [
|
|
1566
|
-
iam4.ManagedPolicy.fromAwsManagedPolicyName("service-role/AWSLambdaBasicExecutionRole")
|
|
1567
|
-
]
|
|
1568
|
-
});
|
|
1569
|
-
const lambdaEmailConverter = new lambda4.Function(scope, "LambdaEmailConverter", {
|
|
1570
|
-
functionName: `${props.slug}-${props.appEnv}-email-converter`,
|
|
1571
|
-
description: "This Lambda converts raw emails files in to HTML and text.",
|
|
1572
|
-
code: lambda4.Code.fromInline('exports.handler = async (event) => {console.log("hello world email converter");return true;};'),
|
|
1573
|
-
handler: "index.handler",
|
|
1574
|
-
memorySize: 256,
|
|
1575
|
-
role: lambdaEmailConverterRole,
|
|
1576
|
-
runtime: lambda4.Runtime.NODEJS_18_X,
|
|
1577
|
-
timeout: Duration5.seconds(60),
|
|
1578
|
-
environment: {
|
|
1579
|
-
BUCKET: this.emailBucket.bucketName
|
|
1580
|
-
}
|
|
1581
|
-
});
|
|
1582
|
-
const converterS3PolicyStatement = new iam4.PolicyStatement({
|
|
1583
|
-
effect: iam4.Effect.ALLOW,
|
|
1584
|
-
actions: ["s3:*"],
|
|
1585
|
-
resources: [
|
|
1586
|
-
this.emailBucket.bucketArn,
|
|
1587
|
-
`${this.emailBucket.bucketArn}/*`
|
|
1588
|
-
]
|
|
1589
|
-
});
|
|
1590
|
-
new lambda4.CfnPermission(scope, "S3ConverterPermission", {
|
|
1591
|
-
action: "lambda:InvokeFunction",
|
|
1592
|
-
functionName: lambdaEmailConverter.functionName,
|
|
1593
|
-
principal: "s3.amazonaws.com"
|
|
1594
|
-
});
|
|
1595
|
-
lambdaEmailConverterRole.addToPolicy(converterS3PolicyStatement);
|
|
1596
|
-
this.emailBucket.addEventNotification(s34.EventType.OBJECT_CREATED_PUT, new s3n.LambdaDestination(lambdaEmailInbound), { prefix: "tmp/email_in/" });
|
|
1597
|
-
this.emailBucket.addEventNotification(s34.EventType.OBJECT_CREATED_PUT, new s3n.LambdaDestination(lambdaEmailOutbound), { prefix: "tmp/email_out/json/" });
|
|
1598
|
-
this.emailBucket.addEventNotification(s34.EventType.OBJECT_CREATED_COPY, new s3n.LambdaDestination(lambdaEmailConverter), { prefix: "sent/" });
|
|
1599
|
-
this.emailBucket.addEventNotification(s34.EventType.OBJECT_CREATED_COPY, new s3n.LambdaDestination(lambdaEmailConverter), { prefix: "inbox/" });
|
|
1600
|
-
this.emailBucket.addEventNotification(s34.EventType.OBJECT_CREATED_COPY, new s3n.LambdaDestination(lambdaEmailConverter), { prefix: "today/" });
|
|
1601
|
-
}
|
|
1602
|
-
}
|
|
1603
|
-
|
|
1604
|
-
// src/cloud/permissions.ts
|
|
1605
|
-
import {SecretValue, aws_iam as iam5} from "aws-cdk-lib";
|
|
1606
|
-
import {config as config18} from "@stacksjs/config";
|
|
1607
|
-
import {string} from "@stacksjs/strings";
|
|
1608
|
-
import {env as env4} from "@stacksjs/env";
|
|
1609
|
-
|
|
1610
|
-
class PermissionsStack {
|
|
1611
|
-
constructor(scope) {
|
|
1612
|
-
const teamName = config18.team.name;
|
|
1613
|
-
const users = config18.team.members;
|
|
1614
|
-
const password = env4.AWS_DEFAULT_PASSWORD || string.random();
|
|
1615
|
-
for (const name in users) {
|
|
1616
|
-
const id = `User${string.pascalCase(teamName)}${string.pascalCase(name)}`;
|
|
1617
|
-
const userName = string.slug(`${teamName}-${name}`);
|
|
1618
|
-
const user = new iam5.User(scope, id, {
|
|
1619
|
-
userName,
|
|
1620
|
-
password: SecretValue.unsafePlainText(password),
|
|
1621
|
-
passwordResetRequired: true
|
|
1622
|
-
});
|
|
1623
|
-
user.addManagedPolicy(iam5.ManagedPolicy.fromAwsManagedPolicyName("AdministratorAccess"));
|
|
1624
|
-
}
|
|
1625
|
-
}
|
|
1626
|
-
}
|
|
1627
|
-
|
|
1628
|
-
// src/cloud/compute.ts
|
|
1629
|
-
import {Duration as Duration6, CfnOutput as Output6, RemovalPolicy as RemovalPolicy8, aws_ec2 as ec23, aws_ecs as ecs, aws_route53 as route535, aws_route53_targets as route53Targets, aws_secretsmanager as secretsmanager} from "aws-cdk-lib";
|
|
1630
|
-
import {path as p4} from "@stacksjs/path";
|
|
1631
|
-
import {env as env6} from "@stacksjs/env";
|
|
1632
|
-
import {LogGroup} from "aws-cdk-lib/aws-logs";
|
|
1633
|
-
import * as elbv2 from "aws-cdk-lib/aws-elasticloadbalancingv2";
|
|
1634
|
-
|
|
1635
|
-
class ComputeStack {
|
|
1636
|
-
lb;
|
|
1637
|
-
cluster;
|
|
1638
|
-
taskDefinition;
|
|
1639
|
-
constructor(scope, props) {
|
|
1640
|
-
const vpc = props.vpc;
|
|
1641
|
-
const fileSystem = props.fileSystem;
|
|
1642
|
-
if (!fileSystem)
|
|
1643
|
-
throw new Error("The file system is missing. Please make sure it was created properly.");
|
|
1644
|
-
this.cluster = new ecs.Cluster(scope, "StacksCluster", {
|
|
1645
|
-
clusterName: `${props.slug}-${props.appEnv}-web-server-cluster`,
|
|
1646
|
-
vpc
|
|
1647
|
-
});
|
|
1648
|
-
this.taskDefinition = new ecs.FargateTaskDefinition(scope, "TaskDefinition", {
|
|
1649
|
-
family: `${props.appName}-${props.appEnv}-api`,
|
|
1650
|
-
memoryLimitMiB: 512,
|
|
1651
|
-
cpu: 256,
|
|
1652
|
-
runtimePlatform: {
|
|
1653
|
-
cpuArchitecture: ecs.CpuArchitecture.ARM64
|
|
1654
|
-
}
|
|
1655
|
-
});
|
|
1656
|
-
const container = this.taskDefinition.addContainer("WebServerContainer", {
|
|
1657
|
-
containerName: `${props.appName}-${props.appEnv}-api`,
|
|
1658
|
-
image: ecs.ContainerImage.fromAsset(p4.frameworkPath("server")),
|
|
1659
|
-
logging: new ecs.AwsLogDriver({
|
|
1660
|
-
streamPrefix: `${props.appName}-${props.appEnv}-web-server-logs`,
|
|
1661
|
-
logGroup: new LogGroup(scope, "StacksApiLogs", {
|
|
1662
|
-
logGroupName: "/aws/ecs/stacks-api",
|
|
1663
|
-
removalPolicy: RemovalPolicy8.DESTROY
|
|
1664
|
-
})
|
|
1665
|
-
}),
|
|
1666
|
-
healthCheck: {
|
|
1667
|
-
command: ["CMD-SHELL", "curl -f http://localhost:3000/api/health || exit 1"],
|
|
1668
|
-
interval: Duration6.seconds(10),
|
|
1669
|
-
timeout: Duration6.seconds(5),
|
|
1670
|
-
retries: 3,
|
|
1671
|
-
startPeriod: Duration6.seconds(10)
|
|
1672
|
-
}
|
|
1673
|
-
});
|
|
1674
|
-
container.addPortMappings({
|
|
1675
|
-
containerPort: 3000,
|
|
1676
|
-
hostPort: 3000
|
|
1677
|
-
});
|
|
1678
|
-
const serviceSecurityGroup = new ec23.SecurityGroup(scope, "ServiceSecurityGroup", {
|
|
1679
|
-
securityGroupName: `${props.appName}-${props.appEnv}-api-service-sg`,
|
|
1680
|
-
vpc,
|
|
1681
|
-
description: "Stacks Security Group for API Service"
|
|
1682
|
-
});
|
|
1683
|
-
const publicLoadBalancerSG = new ec23.SecurityGroup(scope, "PublicLoadBalancerSG", {
|
|
1684
|
-
securityGroupName: `${props.appName}-${props.appEnv}-public-load-balancer-sg`,
|
|
1685
|
-
vpc,
|
|
1686
|
-
description: "Access to the public facing load balancer"
|
|
1687
|
-
});
|
|
1688
|
-
serviceSecurityGroup.addIngressRule(publicLoadBalancerSG, ec23.Port.allTraffic(), "Ingress from the public ALB");
|
|
1689
|
-
this.lb = new elbv2.ApplicationLoadBalancer(scope, "ApplicationLoadBalancer", {
|
|
1690
|
-
http2Enabled: true,
|
|
1691
|
-
loadBalancerName: `${props.appName}-${props.appEnv}-alb`,
|
|
1692
|
-
vpc,
|
|
1693
|
-
vpcSubnets: {
|
|
1694
|
-
subnets: vpc.selectSubnets({
|
|
1695
|
-
subnetType: ec23.SubnetType.PUBLIC,
|
|
1696
|
-
onePerAz: true
|
|
1697
|
-
}).subnets
|
|
1698
|
-
},
|
|
1699
|
-
internetFacing: true,
|
|
1700
|
-
idleTimeout: Duration6.seconds(30),
|
|
1701
|
-
securityGroup: publicLoadBalancerSG
|
|
1702
|
-
});
|
|
1703
|
-
new route535.ARecord(scope, "ApiDomainAliasRecord", {
|
|
1704
|
-
zone: props.zone,
|
|
1705
|
-
recordName: "api",
|
|
1706
|
-
target: route535.RecordTarget.fromAlias(new route53Targets.LoadBalancerTarget(this.lb))
|
|
1707
|
-
});
|
|
1708
|
-
const serviceTargetGroup = new elbv2.ApplicationTargetGroup(scope, "ServiceTargetGroup", {
|
|
1709
|
-
targetGroupName: `${props.appName}-${props.appEnv}-api-tg`,
|
|
1710
|
-
vpc,
|
|
1711
|
-
targetType: elbv2.TargetType.IP,
|
|
1712
|
-
protocol: elbv2.ApplicationProtocol.HTTP,
|
|
1713
|
-
port: 3000,
|
|
1714
|
-
healthCheck: {
|
|
1715
|
-
interval: Duration6.seconds(6),
|
|
1716
|
-
path: "/api/health",
|
|
1717
|
-
protocol: elbv2.Protocol.HTTP,
|
|
1718
|
-
timeout: Duration6.seconds(5),
|
|
1719
|
-
healthyThresholdCount: 2,
|
|
1720
|
-
unhealthyThresholdCount: 10
|
|
1721
|
-
}
|
|
1722
|
-
});
|
|
1723
|
-
const service = new ecs.FargateService(scope, "StacksApiService", {
|
|
1724
|
-
serviceName: `${props.appName}-${props.appEnv}-api-service`,
|
|
1725
|
-
cluster: this.cluster,
|
|
1726
|
-
taskDefinition: this.taskDefinition,
|
|
1727
|
-
desiredCount: 1,
|
|
1728
|
-
assignPublicIp: true,
|
|
1729
|
-
maxHealthyPercent: 200,
|
|
1730
|
-
vpcSubnets: vpc.selectSubnets({
|
|
1731
|
-
subnetType: ec23.SubnetType.PUBLIC,
|
|
1732
|
-
onePerAz: true
|
|
1733
|
-
}),
|
|
1734
|
-
minHealthyPercent: 75,
|
|
1735
|
-
securityGroups: [serviceSecurityGroup]
|
|
1736
|
-
});
|
|
1737
|
-
service.attachToApplicationTargetGroup(serviceTargetGroup);
|
|
1738
|
-
publicLoadBalancerSG.addIngressRule(ec23.Peer.anyIpv4(), ec23.Port.allTraffic());
|
|
1739
|
-
this.lb.addListener("HttpsListener", {
|
|
1740
|
-
port: 443,
|
|
1741
|
-
certificates: [props.certificate],
|
|
1742
|
-
defaultAction: elbv2.ListenerAction.forward([serviceTargetGroup])
|
|
1743
|
-
});
|
|
1744
|
-
this.lb.addListener("HttpListener", {
|
|
1745
|
-
port: 80,
|
|
1746
|
-
defaultAction: elbv2.ListenerAction.forward([serviceTargetGroup])
|
|
1747
|
-
});
|
|
1748
|
-
props.fileSystem.connections.allowFromAnyIpv4(ec23.Port.tcp(2049));
|
|
1749
|
-
const volumeName = `${props.slug}-${props.appEnv}-efs`;
|
|
1750
|
-
this.taskDefinition.addVolume({
|
|
1751
|
-
name: volumeName,
|
|
1752
|
-
efsVolumeConfiguration: {
|
|
1753
|
-
fileSystemId: props.fileSystem.fileSystemId
|
|
1754
|
-
}
|
|
1755
|
-
});
|
|
1756
|
-
container.addMountPoints({
|
|
1757
|
-
sourceVolume: volumeName,
|
|
1758
|
-
containerPath: "/mnt/efs",
|
|
1759
|
-
readOnly: false
|
|
1760
|
-
});
|
|
1761
|
-
const scaling = service.autoScaleTaskCount({ maxCapacity: 2 });
|
|
1762
|
-
scaling.scaleOnCpuUtilization("CpuScaling", {
|
|
1763
|
-
targetUtilizationPercent: 50,
|
|
1764
|
-
scaleInCooldown: Duration6.seconds(60),
|
|
1765
|
-
scaleOutCooldown: Duration6.seconds(60)
|
|
1766
|
-
});
|
|
1767
|
-
scaling.scaleOnMemoryUtilization("MemoryScaling", {
|
|
1768
|
-
targetUtilizationPercent: 60,
|
|
1769
|
-
scaleInCooldown: Duration6.seconds(60),
|
|
1770
|
-
scaleOutCooldown: Duration6.seconds(60)
|
|
1771
|
-
});
|
|
1772
|
-
const keysToRemove = ["_HANDLER", "_X_AMZN_TRACE_ID", "AWS_REGION", "AWS_EXECUTION_ENV", "AWS_LAMBDA_FUNCTION_NAME", "AWS_LAMBDA_FUNCTION_MEMORY_SIZE", "AWS_LAMBDA_FUNCTION_VERSION", "AWS_LAMBDA_INITIALIZATION_TYPE", "AWS_LAMBDA_LOG_GROUP_NAME", "AWS_LAMBDA_LOG_STREAM_NAME", "AWS_ACCESS_KEY", "AWS_ACCESS_KEY_ID", "AWS_SECRET_ACCESS_KEY", "AWS_SESSION_TOKEN", "AWS_LAMBDA_RUNTIME_API", "LAMBDA_TASK_ROOT", "LAMBDA_RUNTIME_DIR", "_"];
|
|
1773
|
-
keysToRemove.forEach((key) => delete env6[key]);
|
|
1774
|
-
const secrets = new secretsmanager.Secret(scope, "StacksSecrets", {
|
|
1775
|
-
secretName: `${props.slug}-${props.appEnv}-secrets`,
|
|
1776
|
-
description: "Secrets for the Stacks application",
|
|
1777
|
-
generateSecretString: {
|
|
1778
|
-
secretStringTemplate: JSON.stringify(env6),
|
|
1779
|
-
generateStringKey: Object.keys(env6).join(",").length.toString()
|
|
1780
|
-
}
|
|
1781
|
-
});
|
|
1782
|
-
secrets.grantRead(service.taskDefinition.executionRole);
|
|
1783
|
-
container.addEnvironment("SECRETS_ARN", secrets.secretArn);
|
|
1784
|
-
const apiPrefix = "api";
|
|
1785
|
-
new Output6(scope, "ApiUrl", {
|
|
1786
|
-
value: `https://${props.domain}/${apiPrefix}`,
|
|
1787
|
-
description: "The URL of the deployed application"
|
|
1788
|
-
});
|
|
1789
|
-
new Output6(scope, "ApiVanityUrl", {
|
|
1790
|
-
value: `http://${this.lb.loadBalancerDnsName}`,
|
|
1791
|
-
description: "The Vanity URL / DNS name of the load balancer"
|
|
1792
|
-
});
|
|
1793
|
-
}
|
|
1794
|
-
}
|
|
1795
|
-
|
|
1796
|
-
// src/cloud/queue.ts
|
|
1797
|
-
import {aws_ec2 as ec24} from "aws-cdk-lib";
|
|
1798
|
-
import {pascalCase, slug as slug2} from "@stacksjs/strings";
|
|
1799
|
-
import {fs} from "@stacksjs/storage";
|
|
1800
|
-
import {path as path6} from "@stacksjs/path";
|
|
1801
|
-
import {Rule, Schedule} from "aws-cdk-lib/aws-events";
|
|
1802
|
-
import {EcsTask} from "aws-cdk-lib/aws-events-targets";
|
|
1803
|
-
|
|
1804
|
-
class QueueStack {
|
|
1805
|
-
scope;
|
|
1806
|
-
props;
|
|
1807
|
-
constructor(scope, props) {
|
|
1808
|
-
this.scope = scope;
|
|
1809
|
-
this.props = props;
|
|
1810
|
-
}
|
|
1811
|
-
async init() {
|
|
1812
|
-
const jobsDir = path6.jobsPath();
|
|
1813
|
-
const actionsDir = path6.appPath("Actions");
|
|
1814
|
-
const jobFiles = await fs.readdir(jobsDir);
|
|
1815
|
-
const actionFiles = await fs.readdir(actionsDir);
|
|
1816
|
-
const jobs = [];
|
|
1817
|
-
for (const file of jobFiles) {
|
|
1818
|
-
if (!file.endsWith(".ts"))
|
|
1819
|
-
continue;
|
|
1820
|
-
const jobPath = path6.jobsPath(file);
|
|
1821
|
-
const job = await this.loadModule(jobPath);
|
|
1822
|
-
this.createQueueRule(job, file);
|
|
1823
|
-
jobs.push(job);
|
|
1824
|
-
}
|
|
1825
|
-
for (const file of actionFiles) {
|
|
1826
|
-
if (!file.endsWith(".ts"))
|
|
1827
|
-
continue;
|
|
1828
|
-
const actionPath = path6.appPath(`Actions/${file}`);
|
|
1829
|
-
const action = await this.loadModule(actionPath);
|
|
1830
|
-
this.createQueueRule(action, file);
|
|
1831
|
-
jobs.push(action);
|
|
1832
|
-
}
|
|
1833
|
-
}
|
|
1834
|
-
cronScheduleFromRate(rate) {
|
|
1835
|
-
const parts = rate.split(" ");
|
|
1836
|
-
return {
|
|
1837
|
-
minute: parts[0],
|
|
1838
|
-
hour: parts[1],
|
|
1839
|
-
month: parts[2],
|
|
1840
|
-
weekDay: parts[3],
|
|
1841
|
-
year: parts[4]
|
|
1842
|
-
};
|
|
1843
|
-
}
|
|
1844
|
-
async loadModule(filePath) {
|
|
1845
|
-
const jobModule = await import(filePath);
|
|
1846
|
-
return jobModule;
|
|
1847
|
-
}
|
|
1848
|
-
createQueueRule(module, file) {
|
|
1849
|
-
const rate = module.default?.rate;
|
|
1850
|
-
if (!rate || module.default?.enabled === false)
|
|
1851
|
-
return;
|
|
1852
|
-
const schedule = Schedule.cron(this.cronScheduleFromRate(rate));
|
|
1853
|
-
const id = `QueueRule${pascalCase(file.replace(".ts", ""))}`;
|
|
1854
|
-
const rule = new Rule(this.scope, id, {
|
|
1855
|
-
ruleName: `${this.props.appName}-${this.props.appEnv}-queue-rule-${slug2(file.replace(".ts", ""))}`,
|
|
1856
|
-
schedule
|
|
1857
|
-
});
|
|
1858
|
-
rule.addTarget(new EcsTask({
|
|
1859
|
-
cluster: this.props.cluster,
|
|
1860
|
-
taskDefinition: this.props.taskDefinition,
|
|
1861
|
-
containerOverrides: [
|
|
1862
|
-
{
|
|
1863
|
-
containerName: `${this.props.appName}-${this.props.appEnv}-api`,
|
|
1864
|
-
environment: [
|
|
1865
|
-
{
|
|
1866
|
-
name: "QUEUE_WORKER",
|
|
1867
|
-
value: "true"
|
|
1868
|
-
},
|
|
1869
|
-
{
|
|
1870
|
-
name: "JOB",
|
|
1871
|
-
value: file
|
|
1872
|
-
},
|
|
1873
|
-
{
|
|
1874
|
-
name: "JOB_BACKOFF_FACTOR",
|
|
1875
|
-
value: module.default?.backoffFactor
|
|
1876
|
-
},
|
|
1877
|
-
{
|
|
1878
|
-
name: "JOB_RETRIES",
|
|
1879
|
-
value: module.default?.tries
|
|
1880
|
-
},
|
|
1881
|
-
{
|
|
1882
|
-
name: "JOB_INITIAL_DELAY",
|
|
1883
|
-
value: module.default?.initialDelay
|
|
1884
|
-
},
|
|
1885
|
-
{
|
|
1886
|
-
name: "JOB_JITTER",
|
|
1887
|
-
value: module.default?.jitter
|
|
1888
|
-
}
|
|
1889
|
-
]
|
|
1890
|
-
}
|
|
1891
|
-
],
|
|
1892
|
-
retryAttempts: 1,
|
|
1893
|
-
subnetSelection: {
|
|
1894
|
-
subnetType: ec24.SubnetType.PUBLIC
|
|
1895
|
-
}
|
|
1896
|
-
}));
|
|
1897
|
-
}
|
|
1898
|
-
}
|
|
1899
|
-
|
|
1900
|
-
// src/cloud/index.ts
|
|
1901
|
-
class Cloud extends Stack2 {
|
|
1902
|
-
dns;
|
|
1903
|
-
security;
|
|
1904
|
-
storage;
|
|
1905
|
-
network;
|
|
1906
|
-
fileSystem;
|
|
1907
|
-
jumpBox;
|
|
1908
|
-
docs;
|
|
1909
|
-
email;
|
|
1910
|
-
redirects;
|
|
1911
|
-
permissions;
|
|
1912
|
-
ai;
|
|
1913
|
-
cli;
|
|
1914
|
-
api;
|
|
1915
|
-
cdn;
|
|
1916
|
-
queue;
|
|
1917
|
-
deployment;
|
|
1918
|
-
scope;
|
|
1919
|
-
props;
|
|
1920
|
-
constructor(scope, id, props) {
|
|
1921
|
-
super(scope, id, props);
|
|
1922
|
-
this.scope = scope;
|
|
1923
|
-
this.props = props;
|
|
1924
|
-
this.dns = new DnsStack(this, props);
|
|
1925
|
-
this.security = new SecurityStack(this, {
|
|
1926
|
-
...props,
|
|
1927
|
-
zone: this.dns.zone
|
|
1928
|
-
});
|
|
1929
|
-
this.storage = new StorageStack(this, {
|
|
1930
|
-
...props,
|
|
1931
|
-
kmsKey: this.security.kmsKey
|
|
1932
|
-
});
|
|
1933
|
-
this.network = new NetworkStack(this, props);
|
|
1934
|
-
this.fileSystem = new FileSystemStack(this, {
|
|
1935
|
-
...props,
|
|
1936
|
-
vpc: this.network.vpc
|
|
1937
|
-
});
|
|
1938
|
-
this.jumpBox = new JumpBoxStack(this, {
|
|
1939
|
-
...props,
|
|
1940
|
-
vpc: this.network.vpc,
|
|
1941
|
-
fileSystem: this.fileSystem.fileSystem
|
|
1942
|
-
});
|
|
1943
|
-
this.docs = new DocsStack(this, props);
|
|
1944
|
-
this.email = new EmailStack(this, {
|
|
1945
|
-
...props,
|
|
1946
|
-
zone: this.dns.zone
|
|
1947
|
-
});
|
|
1948
|
-
this.redirects = new RedirectsStack(this, props);
|
|
1949
|
-
this.permissions = new PermissionsStack(this);
|
|
1950
|
-
this.ai = new AiStack(this, props);
|
|
1951
|
-
this.cli = new CliStack(this, props);
|
|
1952
|
-
}
|
|
1953
|
-
async init() {
|
|
1954
|
-
if (config20.cloud.api?.deploy) {
|
|
1955
|
-
const props = this.props;
|
|
1956
|
-
this.api = new ComputeStack(this, {
|
|
1957
|
-
...props,
|
|
1958
|
-
vpc: this.network.vpc,
|
|
1959
|
-
fileSystem: this.fileSystem.fileSystem,
|
|
1960
|
-
zone: this.dns.zone,
|
|
1961
|
-
certificate: this.security.certificate
|
|
1962
|
-
});
|
|
1963
|
-
this.queue = new QueueStack(this, {
|
|
1964
|
-
...props,
|
|
1965
|
-
cluster: this.api.cluster,
|
|
1966
|
-
taskDefinition: this.api.taskDefinition
|
|
1967
|
-
});
|
|
1968
|
-
await this.queue.init();
|
|
1969
|
-
this.cdn = new CdnStack(this, {
|
|
1970
|
-
...props,
|
|
1971
|
-
publicBucket: this.storage.publicBucket,
|
|
1972
|
-
logBucket: this.storage.logBucket,
|
|
1973
|
-
certificate: this.security.certificate,
|
|
1974
|
-
firewall: this.security.firewall,
|
|
1975
|
-
originRequestFunction: this.docs.originRequestFunction,
|
|
1976
|
-
zone: this.dns.zone,
|
|
1977
|
-
cliSetupUrl: this.cli.cliSetupUrl,
|
|
1978
|
-
askAiUrl: this.ai.askAiUrl,
|
|
1979
|
-
summarizeAiUrl: this.ai.summarizeAiUrl,
|
|
1980
|
-
lb: this.api?.lb
|
|
1981
|
-
});
|
|
1982
|
-
this.deployment = new DeploymentStack(this, {
|
|
1983
|
-
...props,
|
|
1984
|
-
publicBucket: this.storage.publicBucket,
|
|
1985
|
-
privateBucket: this.storage.privateBucket,
|
|
1986
|
-
cdn: this.cdn.distribution
|
|
1987
|
-
});
|
|
1988
|
-
}
|
|
1989
|
-
}
|
|
1990
|
-
}
|
|
1991
|
-
export {
|
|
1992
|
-
purchaseDomain,
|
|
1993
|
-
isFirstDeployment,
|
|
1994
|
-
isFailedState,
|
|
1995
|
-
hasBeenDeployed,
|
|
1996
|
-
getSecurityGroupId,
|
|
1997
|
-
getSecurityGroupFromInstanceId,
|
|
1998
|
-
getOrCreateTimestamp,
|
|
1999
|
-
getJumpBoxSecurityGroupName,
|
|
2000
|
-
getJumpBoxInstanceProfileName,
|
|
2001
|
-
getJumpBoxInstanceId,
|
|
2002
|
-
deleteStacksFunctions,
|
|
2003
|
-
deleteStacksBuckets,
|
|
2004
|
-
deleteParameterStore,
|
|
2005
|
-
deleteLogGroups,
|
|
2006
|
-
deleteJumpBox,
|
|
2007
|
-
deleteIamUsers,
|
|
2008
|
-
deleteEc2Instance,
|
|
2009
|
-
deleteCdkRemnants,
|
|
2010
|
-
addJumpBox,
|
|
2011
|
-
InstanceType,
|
|
2012
|
-
Cloud
|
|
2013
|
-
};
|