@aws-blocks/core 0.1.0
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/LICENSE +174 -0
- package/dist/api.d.ts +147 -0
- package/dist/api.d.ts.map +1 -0
- package/dist/api.js +10 -0
- package/dist/api.test.d.ts +2 -0
- package/dist/api.test.d.ts.map +1 -0
- package/dist/api.test.js +19 -0
- package/dist/bb-utils.d.ts +11 -0
- package/dist/bb-utils.d.ts.map +1 -0
- package/dist/bb-utils.js +12 -0
- package/dist/builtin-routes.d.ts +6 -0
- package/dist/builtin-routes.d.ts.map +1 -0
- package/dist/builtin-routes.js +57 -0
- package/dist/cdk/__fixtures__/factory-backend.d.ts +3 -0
- package/dist/cdk/__fixtures__/factory-backend.d.ts.map +1 -0
- package/dist/cdk/__fixtures__/factory-backend.js +6 -0
- package/dist/cdk/__fixtures__/fullid-construct-backend.d.ts +2 -0
- package/dist/cdk/__fixtures__/fullid-construct-backend.d.ts.map +1 -0
- package/dist/cdk/__fixtures__/fullid-construct-backend.js +37 -0
- package/dist/cdk/__fixtures__/handler.d.ts +5 -0
- package/dist/cdk/__fixtures__/handler.d.ts.map +1 -0
- package/dist/cdk/__fixtures__/handler.js +3 -0
- package/dist/cdk/__fixtures__/side-effect-backend.d.ts +2 -0
- package/dist/cdk/__fixtures__/side-effect-backend.d.ts.map +1 -0
- package/dist/cdk/__fixtures__/side-effect-backend.js +5 -0
- package/dist/cdk/blocks-backend.d.ts +68 -0
- package/dist/cdk/blocks-backend.d.ts.map +1 -0
- package/dist/cdk/blocks-backend.js +214 -0
- package/dist/cdk/blocks-backend.test.d.ts +2 -0
- package/dist/cdk/blocks-backend.test.d.ts.map +1 -0
- package/dist/cdk/blocks-backend.test.js +151 -0
- package/dist/cdk/blocks-stack.test.d.ts +2 -0
- package/dist/cdk/blocks-stack.test.d.ts.map +1 -0
- package/dist/cdk/blocks-stack.test.js +78 -0
- package/dist/cdk/config-registry.d.ts +26 -0
- package/dist/cdk/config-registry.d.ts.map +1 -0
- package/dist/cdk/config-registry.js +80 -0
- package/dist/cdk/index.d.ts +35 -0
- package/dist/cdk/index.d.ts.map +1 -0
- package/dist/cdk/index.js +90 -0
- package/dist/cdk/mixins.d.ts +28 -0
- package/dist/cdk/mixins.d.ts.map +1 -0
- package/dist/cdk/mixins.js +37 -0
- package/dist/cdk/mixins.test.d.ts +2 -0
- package/dist/cdk/mixins.test.d.ts.map +1 -0
- package/dist/cdk/mixins.test.js +108 -0
- package/dist/cdk/node-version.d.ts +14 -0
- package/dist/cdk/node-version.d.ts.map +1 -0
- package/dist/cdk/node-version.js +15 -0
- package/dist/cdk/stack-metadata.d.ts +12 -0
- package/dist/cdk/stack-metadata.d.ts.map +1 -0
- package/dist/cdk/stack-metadata.js +22 -0
- package/dist/cdk/stack-metadata.test.d.ts +2 -0
- package/dist/cdk/stack-metadata.test.d.ts.map +1 -0
- package/dist/cdk/stack-metadata.test.js +56 -0
- package/dist/cdk/synth-guard.d.ts +14 -0
- package/dist/cdk/synth-guard.d.ts.map +1 -0
- package/dist/cdk/synth-guard.js +20 -0
- package/dist/cdk/synth-guard.test.d.ts +2 -0
- package/dist/cdk/synth-guard.test.d.ts.map +1 -0
- package/dist/cdk/synth-guard.test.js +15 -0
- package/dist/client/index.d.ts +97 -0
- package/dist/client/index.d.ts.map +1 -0
- package/dist/client/index.js +238 -0
- package/dist/client/index.test.d.ts +2 -0
- package/dist/client/index.test.d.ts.map +1 -0
- package/dist/client/index.test.js +113 -0
- package/dist/common/config.d.ts +45 -0
- package/dist/common/config.d.ts.map +1 -0
- package/dist/common/config.js +154 -0
- package/dist/common/config.test.d.ts +2 -0
- package/dist/common/config.test.d.ts.map +1 -0
- package/dist/common/config.test.js +173 -0
- package/dist/common/constants.d.ts +11 -0
- package/dist/common/constants.d.ts.map +1 -0
- package/dist/common/constants.js +12 -0
- package/dist/common/crypto.d.ts +6 -0
- package/dist/common/crypto.d.ts.map +1 -0
- package/dist/common/crypto.js +14 -0
- package/dist/common/index.d.ts +220 -0
- package/dist/common/index.d.ts.map +1 -0
- package/dist/common/index.js +180 -0
- package/dist/common/index.test.d.ts +2 -0
- package/dist/common/index.test.d.ts.map +1 -0
- package/dist/common/index.test.js +195 -0
- package/dist/common/mock-data.d.ts +40 -0
- package/dist/common/mock-data.d.ts.map +1 -0
- package/dist/common/mock-data.js +39 -0
- package/dist/common/official-bb-names.generated.d.ts +7 -0
- package/dist/common/official-bb-names.generated.d.ts.map +1 -0
- package/dist/common/official-bb-names.generated.js +28 -0
- package/dist/common/sdk-registry.d.ts +136 -0
- package/dist/common/sdk-registry.d.ts.map +1 -0
- package/dist/common/sdk-registry.js +125 -0
- package/dist/constants.d.ts +27 -0
- package/dist/constants.d.ts.map +1 -0
- package/dist/constants.js +28 -0
- package/dist/cors.d.ts +39 -0
- package/dist/cors.d.ts.map +1 -0
- package/dist/cors.js +85 -0
- package/dist/cors.test.d.ts +2 -0
- package/dist/cors.test.d.ts.map +1 -0
- package/dist/cors.test.js +241 -0
- package/dist/db-naming.d.ts +21 -0
- package/dist/db-naming.d.ts.map +1 -0
- package/dist/db-naming.js +38 -0
- package/dist/db-naming.test.d.ts +2 -0
- package/dist/db-naming.test.d.ts.map +1 -0
- package/dist/db-naming.test.js +29 -0
- package/dist/errors.d.ts +67 -0
- package/dist/errors.d.ts.map +1 -0
- package/dist/errors.js +69 -0
- package/dist/hosting.d.ts +258 -0
- package/dist/hosting.d.ts.map +1 -0
- package/dist/hosting.js +340 -0
- package/dist/hosting.test.d.ts +2 -0
- package/dist/hosting.test.d.ts.map +1 -0
- package/dist/hosting.test.js +1077 -0
- package/dist/index.cdk.d.ts +13 -0
- package/dist/index.cdk.d.ts.map +1 -0
- package/dist/index.cdk.js +13 -0
- package/dist/index.d.ts +9 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +10 -0
- package/dist/lambda-handler.d.ts +131 -0
- package/dist/lambda-handler.d.ts.map +1 -0
- package/dist/lambda-handler.js +610 -0
- package/dist/lambda-handler.test.d.ts +2 -0
- package/dist/lambda-handler.test.d.ts.map +1 -0
- package/dist/lambda-handler.test.js +835 -0
- package/dist/pipeline/index.d.ts +4 -0
- package/dist/pipeline/index.d.ts.map +1 -0
- package/dist/pipeline/index.js +3 -0
- package/dist/pipeline/pipeline-construct.d.ts +130 -0
- package/dist/pipeline/pipeline-construct.d.ts.map +1 -0
- package/dist/pipeline/pipeline-construct.js +484 -0
- package/dist/pipeline/pipeline.test.d.ts +2 -0
- package/dist/pipeline/pipeline.test.d.ts.map +1 -0
- package/dist/pipeline/pipeline.test.js +1231 -0
- package/dist/pipeline/types.d.ts +351 -0
- package/dist/pipeline/types.d.ts.map +1 -0
- package/dist/pipeline/types.js +3 -0
- package/dist/raw-route.cdk.d.ts +47 -0
- package/dist/raw-route.cdk.d.ts.map +1 -0
- package/dist/raw-route.cdk.js +51 -0
- package/dist/raw-route.d.ts +119 -0
- package/dist/raw-route.d.ts.map +1 -0
- package/dist/raw-route.js +239 -0
- package/dist/raw-route.mock.d.ts +47 -0
- package/dist/raw-route.mock.d.ts.map +1 -0
- package/dist/raw-route.mock.js +51 -0
- package/dist/raw-route.test.d.ts +2 -0
- package/dist/raw-route.test.d.ts.map +1 -0
- package/dist/raw-route.test.js +597 -0
- package/dist/redact.d.ts +51 -0
- package/dist/redact.d.ts.map +1 -0
- package/dist/redact.js +134 -0
- package/dist/redact.test.d.ts +2 -0
- package/dist/redact.test.d.ts.map +1 -0
- package/dist/redact.test.js +199 -0
- package/dist/rpc.d.ts +54 -0
- package/dist/rpc.d.ts.map +1 -0
- package/dist/rpc.js +127 -0
- package/dist/rpc.test.d.ts +2 -0
- package/dist/rpc.test.d.ts.map +1 -0
- package/dist/rpc.test.js +60 -0
- package/dist/scripts/cdk-telemetry-env.d.ts +13 -0
- package/dist/scripts/cdk-telemetry-env.d.ts.map +1 -0
- package/dist/scripts/cdk-telemetry-env.js +21 -0
- package/dist/scripts/cdk-telemetry-env.test.d.ts +2 -0
- package/dist/scripts/cdk-telemetry-env.test.d.ts.map +1 -0
- package/dist/scripts/cdk-telemetry-env.test.js +56 -0
- package/dist/scripts/cleanup.d.ts +3 -0
- package/dist/scripts/cleanup.d.ts.map +1 -0
- package/dist/scripts/cleanup.js +35 -0
- package/dist/scripts/console.d.ts +6 -0
- package/dist/scripts/console.d.ts.map +1 -0
- package/dist/scripts/console.js +25 -0
- package/dist/scripts/deploy.d.ts +6 -0
- package/dist/scripts/deploy.d.ts.map +1 -0
- package/dist/scripts/deploy.js +82 -0
- package/dist/scripts/destroy.d.ts +6 -0
- package/dist/scripts/destroy.d.ts.map +1 -0
- package/dist/scripts/destroy.js +30 -0
- package/dist/scripts/dev-server-cors.test.d.ts +2 -0
- package/dist/scripts/dev-server-cors.test.d.ts.map +1 -0
- package/dist/scripts/dev-server-cors.test.js +23 -0
- package/dist/scripts/dev-server-telemetry.test.d.ts +2 -0
- package/dist/scripts/dev-server-telemetry.test.d.ts.map +1 -0
- package/dist/scripts/dev-server-telemetry.test.js +113 -0
- package/dist/scripts/dev-server.d.ts +21 -0
- package/dist/scripts/dev-server.d.ts.map +1 -0
- package/dist/scripts/dev-server.js +456 -0
- package/dist/scripts/ensure-secrets.d.ts +31 -0
- package/dist/scripts/ensure-secrets.d.ts.map +1 -0
- package/dist/scripts/ensure-secrets.js +100 -0
- package/dist/scripts/ensure-secrets.test.d.ts +2 -0
- package/dist/scripts/ensure-secrets.test.d.ts.map +1 -0
- package/dist/scripts/ensure-secrets.test.js +44 -0
- package/dist/scripts/external-migrations-step.d.ts +62 -0
- package/dist/scripts/external-migrations-step.d.ts.map +1 -0
- package/dist/scripts/external-migrations-step.js +243 -0
- package/dist/scripts/external-migrations-step.test.d.ts +2 -0
- package/dist/scripts/external-migrations-step.test.d.ts.map +1 -0
- package/dist/scripts/external-migrations-step.test.js +47 -0
- package/dist/scripts/extract-ts-types.d.ts +65 -0
- package/dist/scripts/extract-ts-types.d.ts.map +1 -0
- package/dist/scripts/extract-ts-types.js +664 -0
- package/dist/scripts/extract-ts-types.test.d.ts +2 -0
- package/dist/scripts/extract-ts-types.test.d.ts.map +1 -0
- package/dist/scripts/extract-ts-types.test.js +497 -0
- package/dist/scripts/generate-client-worker.d.ts +2 -0
- package/dist/scripts/generate-client-worker.d.ts.map +1 -0
- package/dist/scripts/generate-client-worker.js +13 -0
- package/dist/scripts/generate-client.d.ts +14 -0
- package/dist/scripts/generate-client.d.ts.map +1 -0
- package/dist/scripts/generate-client.js +73 -0
- package/dist/scripts/generate-client.test.d.ts +2 -0
- package/dist/scripts/generate-client.test.d.ts.map +1 -0
- package/dist/scripts/generate-client.test.js +48 -0
- package/dist/scripts/generate-spec-cli.d.ts +3 -0
- package/dist/scripts/generate-spec-cli.d.ts.map +1 -0
- package/dist/scripts/generate-spec-cli.js +77 -0
- package/dist/scripts/generate-spec-cli.test.d.ts +14 -0
- package/dist/scripts/generate-spec-cli.test.d.ts.map +1 -0
- package/dist/scripts/generate-spec-cli.test.js +90 -0
- package/dist/scripts/generate-spec.d.ts +61 -0
- package/dist/scripts/generate-spec.d.ts.map +1 -0
- package/dist/scripts/generate-spec.js +746 -0
- package/dist/scripts/generate-spec.test.d.ts +12 -0
- package/dist/scripts/generate-spec.test.d.ts.map +1 -0
- package/dist/scripts/generate-spec.test.js +88 -0
- package/dist/scripts/index.d.ts +12 -0
- package/dist/scripts/index.d.ts.map +1 -0
- package/dist/scripts/index.js +13 -0
- package/dist/scripts/sandbox.d.ts +11 -0
- package/dist/scripts/sandbox.d.ts.map +1 -0
- package/dist/scripts/sandbox.js +200 -0
- package/dist/scripts/telemetry-cli.d.ts +3 -0
- package/dist/scripts/telemetry-cli.d.ts.map +1 -0
- package/dist/scripts/telemetry-cli.js +8 -0
- package/dist/scripts/telemetry.d.ts +17 -0
- package/dist/scripts/telemetry.d.ts.map +1 -0
- package/dist/scripts/telemetry.js +150 -0
- package/dist/scripts/telemetry.test.d.ts +2 -0
- package/dist/scripts/telemetry.test.d.ts.map +1 -0
- package/dist/scripts/telemetry.test.js +203 -0
- package/dist/scripts/validate-spec.d.ts +22 -0
- package/dist/scripts/validate-spec.d.ts.map +1 -0
- package/dist/scripts/validate-spec.js +159 -0
- package/dist/server/index.d.ts +3 -0
- package/dist/server/index.d.ts.map +1 -0
- package/dist/server/index.js +3 -0
- package/dist/server/withAuth.d.ts +142 -0
- package/dist/server/withAuth.d.ts.map +1 -0
- package/dist/server/withAuth.js +261 -0
- package/dist/server/withAuth.test.d.ts +2 -0
- package/dist/server/withAuth.test.d.ts.map +1 -0
- package/dist/server/withAuth.test.js +278 -0
- package/dist/telemetry/client.d.ts +59 -0
- package/dist/telemetry/client.d.ts.map +1 -0
- package/dist/telemetry/client.js +215 -0
- package/dist/telemetry/config-writer.d.ts +16 -0
- package/dist/telemetry/config-writer.d.ts.map +1 -0
- package/dist/telemetry/config-writer.js +36 -0
- package/dist/telemetry/consent-commands.test.d.ts +2 -0
- package/dist/telemetry/consent-commands.test.d.ts.map +1 -0
- package/dist/telemetry/consent-commands.test.js +161 -0
- package/dist/telemetry/consent.d.ts +60 -0
- package/dist/telemetry/consent.d.ts.map +1 -0
- package/dist/telemetry/consent.js +122 -0
- package/dist/telemetry/environment.d.ts +33 -0
- package/dist/telemetry/environment.d.ts.map +1 -0
- package/dist/telemetry/environment.js +87 -0
- package/dist/telemetry/identifiers.d.ts +20 -0
- package/dist/telemetry/identifiers.d.ts.map +1 -0
- package/dist/telemetry/identifiers.js +86 -0
- package/dist/telemetry/index.d.ts +6 -0
- package/dist/telemetry/index.d.ts.map +1 -0
- package/dist/telemetry/index.js +4 -0
- package/dist/telemetry/telemetry.test.d.ts +2 -0
- package/dist/telemetry/telemetry.test.d.ts.map +1 -0
- package/dist/telemetry/telemetry.test.js +1131 -0
- package/dist/telemetry/trackCommand.d.ts +32 -0
- package/dist/telemetry/trackCommand.d.ts.map +1 -0
- package/dist/telemetry/trackCommand.js +102 -0
- package/dist/telemetry/types.d.ts +92 -0
- package/dist/telemetry/types.d.ts.map +1 -0
- package/dist/telemetry/types.js +1 -0
- package/dist/types.d.ts +24 -0
- package/dist/types.d.ts.map +1 -0
- package/dist/types.js +3 -0
- package/dist/version.d.ts +2 -0
- package/dist/version.d.ts.map +1 -0
- package/dist/version.js +2 -0
- package/package.json +83 -0
- package/src/api.test.ts +25 -0
- package/src/api.ts +163 -0
- package/src/bb-utils.ts +13 -0
- package/src/builtin-routes.ts +62 -0
- package/src/cdk/__fixtures__/factory-backend.ts +8 -0
- package/src/cdk/__fixtures__/fullid-construct-backend.ts +42 -0
- package/src/cdk/__fixtures__/handler.ts +4 -0
- package/src/cdk/__fixtures__/side-effect-backend.ts +7 -0
- package/src/cdk/blocks-backend.test.ts +207 -0
- package/src/cdk/blocks-backend.ts +249 -0
- package/src/cdk/blocks-stack.test.ts +106 -0
- package/src/cdk/config-registry.ts +106 -0
- package/src/cdk/index.ts +115 -0
- package/src/cdk/mixins.test.ts +129 -0
- package/src/cdk/mixins.ts +41 -0
- package/src/cdk/node-version.ts +17 -0
- package/src/cdk/stack-metadata.test.ts +71 -0
- package/src/cdk/stack-metadata.ts +29 -0
- package/src/cdk/synth-guard.test.ts +21 -0
- package/src/cdk/synth-guard.ts +23 -0
- package/src/client/index.test.ts +118 -0
- package/src/client/index.ts +320 -0
- package/src/common/config.test.ts +236 -0
- package/src/common/config.ts +169 -0
- package/src/common/constants.ts +15 -0
- package/src/common/crypto.ts +15 -0
- package/src/common/index.test.ts +242 -0
- package/src/common/index.ts +335 -0
- package/src/common/mock-data.ts +52 -0
- package/src/common/official-bb-names.generated.ts +29 -0
- package/src/common/sdk-registry.ts +150 -0
- package/src/constants.ts +31 -0
- package/src/cors.test.ts +279 -0
- package/src/cors.ts +91 -0
- package/src/db-naming.test.ts +48 -0
- package/src/db-naming.ts +41 -0
- package/src/errors.ts +72 -0
- package/src/hosting.test.ts +1431 -0
- package/src/hosting.ts +626 -0
- package/src/index.cdk.ts +45 -0
- package/src/index.ts +22 -0
- package/src/lambda-handler.test.ts +1005 -0
- package/src/lambda-handler.ts +706 -0
- package/src/pipeline/index.ts +12 -0
- package/src/pipeline/pipeline-construct.ts +662 -0
- package/src/pipeline/pipeline.test.ts +1565 -0
- package/src/pipeline/types.ts +384 -0
- package/src/raw-route.cdk.ts +56 -0
- package/src/raw-route.mock.ts +56 -0
- package/src/raw-route.test.ts +819 -0
- package/src/raw-route.ts +316 -0
- package/src/redact.test.ts +222 -0
- package/src/redact.ts +143 -0
- package/src/rpc.test.ts +73 -0
- package/src/rpc.ts +174 -0
- package/src/scripts/cdk-telemetry-env.test.ts +75 -0
- package/src/scripts/cdk-telemetry-env.ts +23 -0
- package/src/scripts/cleanup.ts +39 -0
- package/src/scripts/console.ts +34 -0
- package/src/scripts/deploy.ts +106 -0
- package/src/scripts/destroy.ts +42 -0
- package/src/scripts/dev-server-cors.test.ts +28 -0
- package/src/scripts/dev-server-telemetry.test.ts +127 -0
- package/src/scripts/dev-server.ts +515 -0
- package/src/scripts/ensure-secrets.test.ts +50 -0
- package/src/scripts/ensure-secrets.ts +113 -0
- package/src/scripts/external-migrations-step.test.ts +64 -0
- package/src/scripts/external-migrations-step.ts +269 -0
- package/src/scripts/extract-ts-types.test.ts +516 -0
- package/src/scripts/extract-ts-types.ts +773 -0
- package/src/scripts/generate-client-worker.ts +15 -0
- package/src/scripts/generate-client.test.ts +69 -0
- package/src/scripts/generate-client.ts +86 -0
- package/src/scripts/generate-spec-cli.test.ts +106 -0
- package/src/scripts/generate-spec-cli.ts +92 -0
- package/src/scripts/generate-spec.test.ts +99 -0
- package/src/scripts/generate-spec.ts +833 -0
- package/src/scripts/index.ts +21 -0
- package/src/scripts/sandbox.ts +230 -0
- package/src/scripts/telemetry-cli.ts +10 -0
- package/src/scripts/telemetry.test.ts +239 -0
- package/src/scripts/telemetry.ts +173 -0
- package/src/scripts/validate-spec.ts +199 -0
- package/src/server/index.ts +5 -0
- package/src/server/withAuth.test.ts +348 -0
- package/src/server/withAuth.ts +323 -0
- package/src/telemetry/client.ts +226 -0
- package/src/telemetry/config-writer.ts +52 -0
- package/src/telemetry/consent-commands.test.ts +196 -0
- package/src/telemetry/consent.ts +154 -0
- package/src/telemetry/environment.ts +100 -0
- package/src/telemetry/identifiers.ts +94 -0
- package/src/telemetry/index.ts +11 -0
- package/src/telemetry/telemetry.test.ts +1343 -0
- package/src/telemetry/trackCommand.ts +110 -0
- package/src/telemetry/types.ts +92 -0
- package/src/types.ts +33 -0
- package/src/version.ts +2 -0
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
import type { CommandName, TrackCommandOptions } from './types.js';
|
|
2
|
+
/**
|
|
3
|
+
* Classify a caught error into a telemetry-safe error code.
|
|
4
|
+
* Only inspects the error message for known patterns — never transmits raw messages.
|
|
5
|
+
*/
|
|
6
|
+
export declare function classifyError(error: unknown): {
|
|
7
|
+
code: string;
|
|
8
|
+
phase: string;
|
|
9
|
+
};
|
|
10
|
+
/**
|
|
11
|
+
* Wrap a CLI command function with telemetry tracking.
|
|
12
|
+
*
|
|
13
|
+
* Measures wall-clock duration, classifies errors, and sends a single telemetry event
|
|
14
|
+
* after the command completes (success or failure). The telemetry send is fire-and-forget
|
|
15
|
+
* and bounded by a 5s timeout — it will never delay the command or affect its exit code.
|
|
16
|
+
*
|
|
17
|
+
* If telemetry is disabled (via env var or config), the function is executed directly
|
|
18
|
+
* with zero overhead.
|
|
19
|
+
*
|
|
20
|
+
* @param commandName - The command being tracked
|
|
21
|
+
* @param fn - The async function to execute
|
|
22
|
+
* @param options - Optional metadata (template, framework, etc.)
|
|
23
|
+
*
|
|
24
|
+
* @example
|
|
25
|
+
* ```ts
|
|
26
|
+
* await trackCommand('sandbox', async () => {
|
|
27
|
+
* await startSandbox({ backendPath: '...' });
|
|
28
|
+
* });
|
|
29
|
+
* ```
|
|
30
|
+
*/
|
|
31
|
+
export declare function trackCommand(commandName: CommandName, fn: () => Promise<void>, options?: TrackCommandOptions): Promise<void>;
|
|
32
|
+
//# sourceMappingURL=trackCommand.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"trackCommand.d.ts","sourceRoot":"","sources":["../../src/telemetry/trackCommand.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,WAAW,EAAgB,mBAAmB,EAAE,MAAM,YAAY,CAAC;AAIjF;;;GAGG;AACH,wBAAgB,aAAa,CAAC,KAAK,EAAE,OAAO,GAAG;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,KAAK,EAAE,MAAM,CAAA;CAAE,CAuC7E;AAED;;;;;;;;;;;;;;;;;;;;GAoBG;AACH,wBAAsB,YAAY,CAChC,WAAW,EAAE,WAAW,EACxB,EAAE,EAAE,MAAM,OAAO,CAAC,IAAI,CAAC,EACvB,OAAO,CAAC,EAAE,mBAAmB,GAC5B,OAAO,CAAC,IAAI,CAAC,CAmCf"}
|
|
@@ -0,0 +1,102 @@
|
|
|
1
|
+
import { isTelemetryEnabled } from './consent.js';
|
|
2
|
+
import { buildAndSendEvent } from './client.js';
|
|
3
|
+
/**
|
|
4
|
+
* Classify a caught error into a telemetry-safe error code.
|
|
5
|
+
* Only inspects the error message for known patterns — never transmits raw messages.
|
|
6
|
+
*/
|
|
7
|
+
export function classifyError(error) {
|
|
8
|
+
if (!(error instanceof Error))
|
|
9
|
+
return { code: 'UNKNOWN', phase: 'unknown' };
|
|
10
|
+
const msg = error.message.toLowerCase();
|
|
11
|
+
if (msg.includes('eaddrinuse') || (msg.includes('port') && msg.includes('in use'))) {
|
|
12
|
+
return { code: 'PORT_IN_USE', phase: 'startup' };
|
|
13
|
+
}
|
|
14
|
+
if (msg.includes('access denied') || msg.includes('not authorized') || msg.includes('forbidden')) {
|
|
15
|
+
return { code: 'PERMISSION_DENIED', phase: 'auth' };
|
|
16
|
+
}
|
|
17
|
+
if (msg.includes('credentials') || msg.includes('no credentials') || msg.includes('security token')) {
|
|
18
|
+
return { code: 'CREDENTIALS_FAILED', phase: 'auth' };
|
|
19
|
+
}
|
|
20
|
+
if (msg.includes('cdk synth') || msg.includes('synthesis')) {
|
|
21
|
+
return { code: 'CDK_SYNTH_FAILED', phase: 'synth' };
|
|
22
|
+
}
|
|
23
|
+
if (msg.includes('cdk deploy') || msg.includes('deployment failed')) {
|
|
24
|
+
return { code: 'CDK_DEPLOY_FAILED', phase: 'deploy' };
|
|
25
|
+
}
|
|
26
|
+
if (msg.includes('cdk destroy') || msg.includes('destroy failed')) {
|
|
27
|
+
return { code: 'CDK_DESTROY_FAILED', phase: 'destroy' };
|
|
28
|
+
}
|
|
29
|
+
if (msg.includes('npm install') || msg.includes('npm err')) {
|
|
30
|
+
return { code: 'NPM_INSTALL_FAILED', phase: 'install' };
|
|
31
|
+
}
|
|
32
|
+
if (msg.includes('codegen') || msg.includes('generate client')) {
|
|
33
|
+
return { code: 'CODEGEN_FAILED', phase: 'codegen' };
|
|
34
|
+
}
|
|
35
|
+
if (msg.includes('vite') || msg.includes('next build') || msg.includes('frontend build')) {
|
|
36
|
+
return { code: 'FRONTEND_BUILD_FAILED', phase: 'build' };
|
|
37
|
+
}
|
|
38
|
+
if (msg.includes('template') && msg.includes('copy')) {
|
|
39
|
+
return { code: 'TEMPLATE_COPY_FAILED', phase: 'init' };
|
|
40
|
+
}
|
|
41
|
+
if (msg.includes('argument') || msg.includes('parse')) {
|
|
42
|
+
return { code: 'ARG_PARSE_FAILED', phase: 'init' };
|
|
43
|
+
}
|
|
44
|
+
return { code: 'UNKNOWN', phase: 'unknown' };
|
|
45
|
+
}
|
|
46
|
+
/**
|
|
47
|
+
* Wrap a CLI command function with telemetry tracking.
|
|
48
|
+
*
|
|
49
|
+
* Measures wall-clock duration, classifies errors, and sends a single telemetry event
|
|
50
|
+
* after the command completes (success or failure). The telemetry send is fire-and-forget
|
|
51
|
+
* and bounded by a 5s timeout — it will never delay the command or affect its exit code.
|
|
52
|
+
*
|
|
53
|
+
* If telemetry is disabled (via env var or config), the function is executed directly
|
|
54
|
+
* with zero overhead.
|
|
55
|
+
*
|
|
56
|
+
* @param commandName - The command being tracked
|
|
57
|
+
* @param fn - The async function to execute
|
|
58
|
+
* @param options - Optional metadata (template, framework, etc.)
|
|
59
|
+
*
|
|
60
|
+
* @example
|
|
61
|
+
* ```ts
|
|
62
|
+
* await trackCommand('sandbox', async () => {
|
|
63
|
+
* await startSandbox({ backendPath: '...' });
|
|
64
|
+
* });
|
|
65
|
+
* ```
|
|
66
|
+
*/
|
|
67
|
+
export async function trackCommand(commandName, fn, options) {
|
|
68
|
+
if (!isTelemetryEnabled()) {
|
|
69
|
+
return fn();
|
|
70
|
+
}
|
|
71
|
+
const startTime = Date.now();
|
|
72
|
+
let state = 'SUCCESS';
|
|
73
|
+
let errorInfo;
|
|
74
|
+
try {
|
|
75
|
+
await fn();
|
|
76
|
+
}
|
|
77
|
+
catch (error) {
|
|
78
|
+
state = 'FAIL';
|
|
79
|
+
errorInfo = classifyError(error);
|
|
80
|
+
throw error;
|
|
81
|
+
}
|
|
82
|
+
finally {
|
|
83
|
+
const duration = Date.now() - startTime;
|
|
84
|
+
buildAndSendEvent({
|
|
85
|
+
command: commandName,
|
|
86
|
+
state,
|
|
87
|
+
duration,
|
|
88
|
+
...(errorInfo && { error: errorInfo }),
|
|
89
|
+
...(options && {
|
|
90
|
+
product: {
|
|
91
|
+
...(options.cdkVersion && { cdkVersion: options.cdkVersion }),
|
|
92
|
+
...(options.framework && { framework: options.framework }),
|
|
93
|
+
...(options.template && { template: options.template }),
|
|
94
|
+
...(options.templateVersion && { templateVersion: options.templateVersion }),
|
|
95
|
+
},
|
|
96
|
+
}),
|
|
97
|
+
...(options?.blocksCount !== undefined && {
|
|
98
|
+
counters: { blocksCount: options.blocksCount },
|
|
99
|
+
}),
|
|
100
|
+
});
|
|
101
|
+
}
|
|
102
|
+
}
|
|
@@ -0,0 +1,92 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Command names tracked by the Blocks CLI telemetry system.
|
|
3
|
+
*/
|
|
4
|
+
export type CommandName = 'create-blocks-app' | 'dev' | 'sandbox' | 'sandbox:destroy' | 'deploy' | 'destroy' | 'cleanup' | 'console' | 'vendorize';
|
|
5
|
+
/**
|
|
6
|
+
* Terminal state of a command execution.
|
|
7
|
+
*/
|
|
8
|
+
export type CommandState = 'SUCCESS' | 'FAIL' | 'ABORTED';
|
|
9
|
+
/**
|
|
10
|
+
* The telemetry event payload sent to the endpoint.
|
|
11
|
+
*
|
|
12
|
+
* Matches the server schema exactly (additionalProperties: false).
|
|
13
|
+
* All fields are anonymized — no PII, no customer content, no account IDs.
|
|
14
|
+
*/
|
|
15
|
+
export interface BlocksTelemetryEvent {
|
|
16
|
+
telemetryVersion: string;
|
|
17
|
+
identifiers: {
|
|
18
|
+
installationId: string;
|
|
19
|
+
projectId: string;
|
|
20
|
+
eventId: string;
|
|
21
|
+
timestamp: string;
|
|
22
|
+
};
|
|
23
|
+
event: {
|
|
24
|
+
command: CommandName;
|
|
25
|
+
state: CommandState;
|
|
26
|
+
duration: number;
|
|
27
|
+
error?: {
|
|
28
|
+
code: string;
|
|
29
|
+
phase: string;
|
|
30
|
+
};
|
|
31
|
+
};
|
|
32
|
+
environment: {
|
|
33
|
+
os: 'linux' | 'darwin' | 'win32';
|
|
34
|
+
nodeVersion: string;
|
|
35
|
+
ci: boolean;
|
|
36
|
+
packageManager?: string;
|
|
37
|
+
agent?: string;
|
|
38
|
+
};
|
|
39
|
+
product?: {
|
|
40
|
+
blocksVersion: string;
|
|
41
|
+
cdkVersion?: string;
|
|
42
|
+
framework?: 'nextjs' | 'spa' | 'static';
|
|
43
|
+
template?: {
|
|
44
|
+
name: string;
|
|
45
|
+
version?: string;
|
|
46
|
+
};
|
|
47
|
+
buildingBlocks?: Array<{
|
|
48
|
+
name: string;
|
|
49
|
+
version: string;
|
|
50
|
+
}>;
|
|
51
|
+
};
|
|
52
|
+
counters?: {
|
|
53
|
+
blocksCount: number;
|
|
54
|
+
customBuildingBlocks?: number;
|
|
55
|
+
};
|
|
56
|
+
}
|
|
57
|
+
/**
|
|
58
|
+
* Options for the `trackCommand` utility.
|
|
59
|
+
*/
|
|
60
|
+
export interface TrackCommandOptions {
|
|
61
|
+
template?: string;
|
|
62
|
+
templateVersion?: string;
|
|
63
|
+
framework?: 'nextjs' | 'spa' | 'static';
|
|
64
|
+
cdkVersion?: string;
|
|
65
|
+
blocksCount?: number;
|
|
66
|
+
}
|
|
67
|
+
/**
|
|
68
|
+
* Options accepted by `buildAndSendEvent()`.
|
|
69
|
+
*
|
|
70
|
+
* Callers provide minimal metadata; the function resolves identifiers,
|
|
71
|
+
* environment, and consent internally.
|
|
72
|
+
*/
|
|
73
|
+
export interface BuildAndSendEventOptions {
|
|
74
|
+
command: CommandName;
|
|
75
|
+
state: CommandState;
|
|
76
|
+
duration: number;
|
|
77
|
+
error?: {
|
|
78
|
+
code: string;
|
|
79
|
+
phase: string;
|
|
80
|
+
};
|
|
81
|
+
product?: {
|
|
82
|
+
cdkVersion?: string;
|
|
83
|
+
framework?: 'nextjs' | 'spa' | 'static';
|
|
84
|
+
template?: string;
|
|
85
|
+
templateVersion?: string;
|
|
86
|
+
};
|
|
87
|
+
counters?: {
|
|
88
|
+
blocksCount: number;
|
|
89
|
+
customBuildingBlocks?: number;
|
|
90
|
+
};
|
|
91
|
+
}
|
|
92
|
+
//# sourceMappingURL=types.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/telemetry/types.ts"],"names":[],"mappings":"AAAA;;GAEG;AACH,MAAM,MAAM,WAAW,GACnB,mBAAmB,GACnB,KAAK,GACL,SAAS,GACT,iBAAiB,GACjB,QAAQ,GACR,SAAS,GACT,SAAS,GACT,SAAS,GACT,WAAW,CAAC;AAEhB;;GAEG;AACH,MAAM,MAAM,YAAY,GAAG,SAAS,GAAG,MAAM,GAAG,SAAS,CAAC;AAE1D;;;;;GAKG;AACH,MAAM,WAAW,oBAAoB;IACnC,gBAAgB,EAAE,MAAM,CAAC;IACzB,WAAW,EAAE;QACX,cAAc,EAAE,MAAM,CAAC;QACvB,SAAS,EAAE,MAAM,CAAC;QAClB,OAAO,EAAE,MAAM,CAAC;QAChB,SAAS,EAAE,MAAM,CAAC;KACnB,CAAC;IACF,KAAK,EAAE;QACL,OAAO,EAAE,WAAW,CAAC;QACrB,KAAK,EAAE,YAAY,CAAC;QACpB,QAAQ,EAAE,MAAM,CAAC;QACjB,KAAK,CAAC,EAAE;YACN,IAAI,EAAE,MAAM,CAAC;YACb,KAAK,EAAE,MAAM,CAAC;SACf,CAAC;KACH,CAAC;IACF,WAAW,EAAE;QACX,EAAE,EAAE,OAAO,GAAG,QAAQ,GAAG,OAAO,CAAC;QACjC,WAAW,EAAE,MAAM,CAAC;QACpB,EAAE,EAAE,OAAO,CAAC;QACZ,cAAc,CAAC,EAAE,MAAM,CAAC;QACxB,KAAK,CAAC,EAAE,MAAM,CAAC;KAChB,CAAC;IACF,OAAO,CAAC,EAAE;QACR,aAAa,EAAE,MAAM,CAAC;QACtB,UAAU,CAAC,EAAE,MAAM,CAAC;QACpB,SAAS,CAAC,EAAE,QAAQ,GAAG,KAAK,GAAG,QAAQ,CAAC;QACxC,QAAQ,CAAC,EAAE;YAAE,IAAI,EAAE,MAAM,CAAC;YAAC,OAAO,CAAC,EAAE,MAAM,CAAA;SAAE,CAAC;QAC9C,cAAc,CAAC,EAAE,KAAK,CAAC;YAAE,IAAI,EAAE,MAAM,CAAC;YAAC,OAAO,EAAE,MAAM,CAAA;SAAE,CAAC,CAAC;KAC3D,CAAC;IACF,QAAQ,CAAC,EAAE;QACT,WAAW,EAAE,MAAM,CAAC;QACpB,oBAAoB,CAAC,EAAE,MAAM,CAAC;KAC/B,CAAC;CACH;AAED;;GAEG;AACH,MAAM,WAAW,mBAAmB;IAClC,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB,SAAS,CAAC,EAAE,QAAQ,GAAG,KAAK,GAAG,QAAQ,CAAC;IACxC,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,WAAW,CAAC,EAAE,MAAM,CAAC;CACtB;AAED;;;;;GAKG;AACH,MAAM,WAAW,wBAAwB;IACvC,OAAO,EAAE,WAAW,CAAC;IACrB,KAAK,EAAE,YAAY,CAAC;IACpB,QAAQ,EAAE,MAAM,CAAC;IACjB,KAAK,CAAC,EAAE;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,KAAK,EAAE,MAAM,CAAA;KAAE,CAAC;IACxC,OAAO,CAAC,EAAE;QACR,UAAU,CAAC,EAAE,MAAM,CAAC;QACpB,SAAS,CAAC,EAAE,QAAQ,GAAG,KAAK,GAAG,QAAQ,CAAC;QACxC,QAAQ,CAAC,EAAE,MAAM,CAAC;QAClB,eAAe,CAAC,EAAE,MAAM,CAAC;KAC1B,CAAC;IACF,QAAQ,CAAC,EAAE;QAAE,WAAW,EAAE,MAAM,CAAC;QAAC,oBAAoB,CAAC,EAAE,MAAM,CAAA;KAAE,CAAC;CACnE"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
package/dist/types.d.ts
ADDED
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
import type { Construct } from 'constructs';
|
|
2
|
+
/**
|
|
3
|
+
* Infrastructure layer function signature.
|
|
4
|
+
* Exported from `infra.ts` in a Building Block.
|
|
5
|
+
*/
|
|
6
|
+
export type MaterializeFn<TOptions = any> = (scope: Construct, name: string, options: TOptions) => void | Record<string, any>;
|
|
7
|
+
/**
|
|
8
|
+
* Building Block metadata discovered by Blocks.
|
|
9
|
+
*/
|
|
10
|
+
export interface BuildingBlockMetadata {
|
|
11
|
+
name: string;
|
|
12
|
+
runtimePath?: string;
|
|
13
|
+
infraPath?: string;
|
|
14
|
+
mockPath?: string;
|
|
15
|
+
clientHookPath?: string;
|
|
16
|
+
}
|
|
17
|
+
/**
|
|
18
|
+
* Client-side protocol extension hook.
|
|
19
|
+
*/
|
|
20
|
+
export interface ClientSideAPIHook {
|
|
21
|
+
onResponse?(response: Response): Promise<void>;
|
|
22
|
+
onRequest?(request: Request): Promise<void>;
|
|
23
|
+
}
|
|
24
|
+
//# sourceMappingURL=types.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,YAAY,CAAC;AAE5C;;;GAGG;AACH,MAAM,MAAM,aAAa,CAAC,QAAQ,GAAG,GAAG,IAAI,CAC1C,KAAK,EAAE,SAAS,EAChB,IAAI,EAAE,MAAM,EACZ,OAAO,EAAE,QAAQ,KACd,IAAI,GAAG,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC;AAEhC;;GAEG;AACH,MAAM,WAAW,qBAAqB;IACpC,IAAI,EAAE,MAAM,CAAC;IACb,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,cAAc,CAAC,EAAE,MAAM,CAAC;CACzB;AAED;;GAEG;AACH,MAAM,WAAW,iBAAiB;IAChC,UAAU,CAAC,CAAC,QAAQ,EAAE,QAAQ,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IAC/C,SAAS,CAAC,CAAC,OAAO,EAAE,OAAO,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;CAC7C"}
|
package/dist/types.js
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"version.d.ts","sourceRoot":"","sources":["../src/version.ts"],"names":[],"mappings":"AACA,eAAO,MAAM,YAAY,UAAU,CAAC"}
|
package/dist/version.js
ADDED
package/package.json
ADDED
|
@@ -0,0 +1,83 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@aws-blocks/core",
|
|
3
|
+
"version": "0.1.0",
|
|
4
|
+
"author": "Amazon Web Services",
|
|
5
|
+
"license": "Apache-2.0",
|
|
6
|
+
"type": "module",
|
|
7
|
+
"sideEffects": [
|
|
8
|
+
"./dist/server/withAuth.js"
|
|
9
|
+
],
|
|
10
|
+
"files": [
|
|
11
|
+
"dist",
|
|
12
|
+
"README.md",
|
|
13
|
+
"src",
|
|
14
|
+
"LICENSE"
|
|
15
|
+
],
|
|
16
|
+
"exports": {
|
|
17
|
+
".": {
|
|
18
|
+
"browser": "./dist/client/index.js",
|
|
19
|
+
"cdk": "./dist/index.cdk.js",
|
|
20
|
+
"default": "./dist/index.js"
|
|
21
|
+
},
|
|
22
|
+
"./cdk": {
|
|
23
|
+
"types": "./dist/index.cdk.js",
|
|
24
|
+
"default": "./dist/index.cdk.js"
|
|
25
|
+
},
|
|
26
|
+
"./client": "./dist/client/index.js",
|
|
27
|
+
"./lambda-handler": "./dist/lambda-handler.js",
|
|
28
|
+
"./bb-utils": {
|
|
29
|
+
"types": "./dist/bb-utils.d.ts",
|
|
30
|
+
"default": "./dist/bb-utils.js"
|
|
31
|
+
},
|
|
32
|
+
"./version": {
|
|
33
|
+
"types": "./dist/version.d.ts",
|
|
34
|
+
"default": "./dist/version.js"
|
|
35
|
+
},
|
|
36
|
+
"./server": {
|
|
37
|
+
"types": "./dist/server/index.d.ts",
|
|
38
|
+
"import": "./dist/server/index.js",
|
|
39
|
+
"require": "./dist/server/index.js"
|
|
40
|
+
},
|
|
41
|
+
"./scripts": "./dist/scripts/index.js",
|
|
42
|
+
"./db-naming": {
|
|
43
|
+
"types": "./dist/db-naming.d.ts",
|
|
44
|
+
"default": "./dist/db-naming.js"
|
|
45
|
+
}
|
|
46
|
+
},
|
|
47
|
+
"scripts": {
|
|
48
|
+
"prebuild": "node ../../scripts/generate-version.mjs --core && node ../../scripts/generate-bb-names.mjs",
|
|
49
|
+
"build": "tsc --build",
|
|
50
|
+
"test": "node --test dist/*.test.js dist/**/*.test.js",
|
|
51
|
+
"dev": "tsc --build --watch"
|
|
52
|
+
},
|
|
53
|
+
"bin": {
|
|
54
|
+
"blocks-generate-spec": "./dist/scripts/generate-spec-cli.js",
|
|
55
|
+
"blocks-telemetry": "./dist/scripts/telemetry-cli.js"
|
|
56
|
+
},
|
|
57
|
+
"devDependencies": {
|
|
58
|
+
"@types/http-proxy": "^1.17.16",
|
|
59
|
+
"@types/node": "^20.0.0",
|
|
60
|
+
"typescript": "^5.3.0",
|
|
61
|
+
"unctx": "^2.0.0"
|
|
62
|
+
},
|
|
63
|
+
"dependencies": {
|
|
64
|
+
"@aws-blocks/hosting": "*",
|
|
65
|
+
"@aws-sdk/client-s3": "^3.700.0",
|
|
66
|
+
"@aws-sdk/client-ssm": "^3.700.0",
|
|
67
|
+
"http-proxy": "^1.18.1"
|
|
68
|
+
},
|
|
69
|
+
"peerDependencies": {
|
|
70
|
+
"aws-cdk-lib": "^2.257.0",
|
|
71
|
+
"constructs": "^10.6.0",
|
|
72
|
+
"next": ">=13.0.0",
|
|
73
|
+
"unctx": ">=2.0.0"
|
|
74
|
+
},
|
|
75
|
+
"peerDependenciesMeta": {
|
|
76
|
+
"next": {
|
|
77
|
+
"optional": true
|
|
78
|
+
},
|
|
79
|
+
"unctx": {
|
|
80
|
+
"optional": true
|
|
81
|
+
}
|
|
82
|
+
}
|
|
83
|
+
}
|
package/src/api.test.ts
ADDED
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
// Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
|
|
2
|
+
// SPDX-License-Identifier: Apache-2.0
|
|
3
|
+
|
|
4
|
+
import { test } from 'node:test';
|
|
5
|
+
import assert from 'node:assert';
|
|
6
|
+
import { ApiNamespace, API_NAMESPACE_MARKER } from './api.js';
|
|
7
|
+
import { Scope } from './common/index.js';
|
|
8
|
+
|
|
9
|
+
const scope = new Scope('test');
|
|
10
|
+
|
|
11
|
+
test('ApiNamespace stores name via marker symbol', () => {
|
|
12
|
+
const api1 = new ApiNamespace(scope, 'myapi', (ctx) => ({
|
|
13
|
+
test: () => 'hello'
|
|
14
|
+
}));
|
|
15
|
+
|
|
16
|
+
assert.strictEqual((api1 as any)[API_NAMESPACE_MARKER], 'myapi');
|
|
17
|
+
});
|
|
18
|
+
|
|
19
|
+
test('Different ApiNamespace names should not collide', () => {
|
|
20
|
+
const api1 = new ApiNamespace(scope, 'api1', (ctx) => ({ test: () => 'a' }));
|
|
21
|
+
const api2 = new ApiNamespace(scope, 'api2', (ctx) => ({ test: () => 'b' }));
|
|
22
|
+
|
|
23
|
+
assert.strictEqual((api1 as any)[API_NAMESPACE_MARKER], 'api1');
|
|
24
|
+
assert.strictEqual((api2 as any)[API_NAMESPACE_MARKER], 'api2');
|
|
25
|
+
});
|
package/src/api.ts
ADDED
|
@@ -0,0 +1,163 @@
|
|
|
1
|
+
// Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
|
|
2
|
+
// SPDX-License-Identifier: Apache-2.0
|
|
3
|
+
|
|
4
|
+
export type BlocksContext = {
|
|
5
|
+
request: {
|
|
6
|
+
headers: Headers;
|
|
7
|
+
body: ReadableStream<Uint8Array> | null;
|
|
8
|
+
json: () => Promise<any>;
|
|
9
|
+
text: () => Promise<string>;
|
|
10
|
+
/**
|
|
11
|
+
* Absolute URL of the incoming request. Built from the request's `host`
|
|
12
|
+
* header plus the path + query string. Useful for RawRoute handlers
|
|
13
|
+
* that need query-string parsing or must echo the request URL back
|
|
14
|
+
* (e.g., building OIDC redirect URIs).
|
|
15
|
+
*
|
|
16
|
+
* In dev: derived from `req.url` and `req.headers.host`.
|
|
17
|
+
* In AWS: derived from `event.path`, `event.queryStringParameters`,
|
|
18
|
+
* and `event.headers.host`. May include a trusted `x-forwarded-proto`
|
|
19
|
+
* to pick http vs https.
|
|
20
|
+
*/
|
|
21
|
+
url: URL;
|
|
22
|
+
/**
|
|
23
|
+
* Path parameters extracted from RawRoute patterns.
|
|
24
|
+
* Example: route `/users/{id}` with request `/users/123` → `{ id: '123' }`.
|
|
25
|
+
*
|
|
26
|
+
* Only populated for RawRoute handlers. Always `{}` for RPC API methods.
|
|
27
|
+
*/
|
|
28
|
+
params: Record<string, string>;
|
|
29
|
+
/**
|
|
30
|
+
* Abort signal tied to the HTTP deadline guard.
|
|
31
|
+
*
|
|
32
|
+
* Fires when the Lambda is about to return a 504 timeout response.
|
|
33
|
+
* Pass this to `fetch()`, AWS SDK calls, or any cancellable I/O so
|
|
34
|
+
* in-flight work is cancelled rather than continuing to run (and bill)
|
|
35
|
+
* after the client has already received a timeout.
|
|
36
|
+
*
|
|
37
|
+
* `undefined` in local dev or when no deadline is configured.
|
|
38
|
+
*/
|
|
39
|
+
signal?: AbortSignal;
|
|
40
|
+
};
|
|
41
|
+
response: {
|
|
42
|
+
headers: Headers;
|
|
43
|
+
status: number;
|
|
44
|
+
send: (body: any) => void;
|
|
45
|
+
};
|
|
46
|
+
};
|
|
47
|
+
|
|
48
|
+
export type ApiHandler<T extends Record<string, (...args: any[]) => any>> = (context: BlocksContext) => T;
|
|
49
|
+
|
|
50
|
+
// Map all methods to return Promises
|
|
51
|
+
type AsyncAPI<T extends Record<string, (...args: any[]) => any>> = {
|
|
52
|
+
[K in keyof T]: T[K] extends (...args: infer Args) => infer R
|
|
53
|
+
? (...args: Args) => Promise<Awaited<R>>
|
|
54
|
+
: never;
|
|
55
|
+
};
|
|
56
|
+
|
|
57
|
+
/** Marker symbol to identify ApiNamespace instances during discovery. */
|
|
58
|
+
export const API_NAMESPACE_MARKER = Symbol.for('blocks:ApiNamespace');
|
|
59
|
+
|
|
60
|
+
import type { ScopeParent } from './common/index.js';
|
|
61
|
+
|
|
62
|
+
/**
|
|
63
|
+
* Define a type-safe API namespace that works seamlessly between frontend and backend.
|
|
64
|
+
*
|
|
65
|
+
* ## Usage
|
|
66
|
+
*
|
|
67
|
+
* Define your API in the backend (`aws-blocks/index.ts`):
|
|
68
|
+
*
|
|
69
|
+
* ```typescript
|
|
70
|
+
* const scope = new Scope('my-app');
|
|
71
|
+
*
|
|
72
|
+
* export const api = new ApiNamespace(scope, 'api', (context) => ({
|
|
73
|
+
* async greet(name: string) {
|
|
74
|
+
* return { message: `Hello, ${name}!` };
|
|
75
|
+
* },
|
|
76
|
+
*
|
|
77
|
+
* async deleteAccount(id: string) {
|
|
78
|
+
* // Gated: throws 401 if the caller has no valid session.
|
|
79
|
+
* await auth.requireAuth(context);
|
|
80
|
+
* return db.users.delete(id);
|
|
81
|
+
* }
|
|
82
|
+
* }));
|
|
83
|
+
* ```
|
|
84
|
+
*
|
|
85
|
+
* Import and call from the frontend with full type safety:
|
|
86
|
+
*
|
|
87
|
+
* ```typescript
|
|
88
|
+
* import { api } from 'aws-blocks';
|
|
89
|
+
*
|
|
90
|
+
* const result = await api.greet('World'); // Fully typed
|
|
91
|
+
* ```
|
|
92
|
+
*
|
|
93
|
+
* ## Authentication — every method is a public endpoint
|
|
94
|
+
*
|
|
95
|
+
* Each method becomes a public, internet-reachable RPC endpoint with **no
|
|
96
|
+
* authentication by default**. Gating is opt-in per method by calling an auth
|
|
97
|
+
* Building Block at the top of the handler:
|
|
98
|
+
*
|
|
99
|
+
* ```typescript
|
|
100
|
+
* export const api = new ApiNamespace(scope, 'api', (context) => ({
|
|
101
|
+
* // No requireAuth call → callable by anyone.
|
|
102
|
+
* async listPublicPosts() {
|
|
103
|
+
* return db.posts.findPublished();
|
|
104
|
+
* },
|
|
105
|
+
*
|
|
106
|
+
* async createPost(input: NewPost) {
|
|
107
|
+
* const user = await auth.requireAuth(context);
|
|
108
|
+
* return db.posts.create({ ...input, authorId: user.userId });
|
|
109
|
+
* },
|
|
110
|
+
*
|
|
111
|
+
* async deletePost(id: string) {
|
|
112
|
+
* await auth.requireRole(context, 'admins');
|
|
113
|
+
* return db.posts.delete(id);
|
|
114
|
+
* },
|
|
115
|
+
* }));
|
|
116
|
+
* ```
|
|
117
|
+
*
|
|
118
|
+
* The local mock applies no auth either, so an ungated method passes every
|
|
119
|
+
* local check and still ships callable by anyone. See your auth block's README
|
|
120
|
+
* (e.g. `@aws-blocks/bb-auth-cognito`) for `requireAuth` / `requireRole`.
|
|
121
|
+
*
|
|
122
|
+
* ## Context
|
|
123
|
+
*
|
|
124
|
+
* The `context` parameter provides access to:
|
|
125
|
+
* - `context.request.headers` - Incoming request headers
|
|
126
|
+
* - `context.request.json()` - Parse request body as JSON
|
|
127
|
+
* - `context.response.headers` - Set response headers (e.g., cookies)
|
|
128
|
+
* - `context.response.status` - Set HTTP status code
|
|
129
|
+
*
|
|
130
|
+
* ## Local vs Deployed
|
|
131
|
+
*
|
|
132
|
+
* - **Local**: APIs run in-process. Calls are direct function invocations.
|
|
133
|
+
* - **Deployed**: APIs run in Lambda. Calls go through API Gateway over HTTPS.
|
|
134
|
+
*
|
|
135
|
+
* The same code works in both environments without changes.
|
|
136
|
+
*
|
|
137
|
+
* ## Scaling Characteristics (AWS)
|
|
138
|
+
*
|
|
139
|
+
* - Serverless: Auto-scales from 0 to thousands of concurrent requests
|
|
140
|
+
* - Cold starts: ~100-500ms for first request after idle period
|
|
141
|
+
* - Warm requests: Single-digit millisecond overhead
|
|
142
|
+
* - Cost: Pay per request (free tier: 1M requests/month)
|
|
143
|
+
*
|
|
144
|
+
* ## Best Practices
|
|
145
|
+
*
|
|
146
|
+
* - No auth by default — gate methods with `requireAuth`/`requireRole` (see above)
|
|
147
|
+
* - Keep API methods focused and single-purpose
|
|
148
|
+
* - Use async/await for all I/O operations
|
|
149
|
+
* - Return serializable data (JSON-compatible types)
|
|
150
|
+
* - Handle errors explicitly - they'll be sent to the client
|
|
151
|
+
* - Use Building Blocks (KVStore, DistributedTable) for state
|
|
152
|
+
*/
|
|
153
|
+
export interface ApiNamespaceConstructor {
|
|
154
|
+
new <T extends Record<string, (...args: any[]) => any>>(scope: ScopeParent, name: string, handler: ApiHandler<T>): AsyncAPI<T>;
|
|
155
|
+
}
|
|
156
|
+
|
|
157
|
+
export const ApiNamespace: ApiNamespaceConstructor = class ApiNamespace {
|
|
158
|
+
constructor(scope: ScopeParent, name: string, handler: any) {
|
|
159
|
+
handler[API_NAMESPACE_MARKER] = name;
|
|
160
|
+
return handler;
|
|
161
|
+
}
|
|
162
|
+
} as any;
|
|
163
|
+
|
package/src/bb-utils.ts
ADDED
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
// Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
|
|
2
|
+
// SPDX-License-Identifier: Apache-2.0
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* Utilities for Building Block authors.
|
|
6
|
+
*
|
|
7
|
+
* Used by standard BBs and available to customers writing custom Building Blocks.
|
|
8
|
+
* Not part of the main '.' export — import from '@aws-blocks/core/bb-utils'.
|
|
9
|
+
*/
|
|
10
|
+
export { getMockDataDir } from './common/mock-data.js';
|
|
11
|
+
export { API_NAMESPACE_MARKER } from './api.js';
|
|
12
|
+
export { EventSourceMapping } from './lambda-handler.js';
|
|
13
|
+
export { constantTimeEquals } from './common/crypto.js';
|
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
// Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
|
|
2
|
+
// SPDX-License-Identifier: Apache-2.0
|
|
3
|
+
|
|
4
|
+
import { getRegisteredRoutes, registerRoute } from './raw-route.js';
|
|
5
|
+
import { exec } from 'node:child_process';
|
|
6
|
+
import { join } from 'node:path';
|
|
7
|
+
import type { BlocksContext } from './api.js';
|
|
8
|
+
|
|
9
|
+
function openInEditor(filePath: string): void {
|
|
10
|
+
const platform = process.platform;
|
|
11
|
+
const cmd = platform === 'darwin' ? 'open' : platform === 'win32' ? 'start ""' : 'xdg-open';
|
|
12
|
+
exec(`${cmd} "${filePath}"`);
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
/**
|
|
16
|
+
* Register built-in /aws-blocks/resources and /aws-blocks/settings routes.
|
|
17
|
+
* Skips if already registered (safe to call from both CDK and dev server).
|
|
18
|
+
*/
|
|
19
|
+
export function registerBuiltinRoutes(): void {
|
|
20
|
+
const routes: Array<{ method: 'GET' | 'POST'; path: string; handler: (ctx: BlocksContext) => Promise<void> }> = [
|
|
21
|
+
{
|
|
22
|
+
method: 'GET',
|
|
23
|
+
path: '/aws-blocks/resources',
|
|
24
|
+
handler: async (ctx: BlocksContext) => {
|
|
25
|
+
const url = process.env.BB_RESOURCES_GROUP_URL;
|
|
26
|
+
if (!url) {
|
|
27
|
+
ctx.response.status = 200;
|
|
28
|
+
ctx.response.headers.set('Content-Type', 'text/html');
|
|
29
|
+
ctx.response.send(`<!DOCTYPE html><html><head><title>Resources</title><style>body{font-family:system-ui,sans-serif;max-width:640px;margin:4rem auto;padding:0 1rem;color:#1a1a1a}h1{font-size:1.5rem}p{line-height:1.6}code{background:#f3f4f6;padding:2px 6px;border-radius:4px;font-size:0.9em}</style></head><body><h1>Resources</h1><p>Locally, each Building Block persists data to <code>.bb-data/</code> in your project root. Tables, buckets, queues, and other state live under <code>.bb-data/{id}/</code>.</p><p>For deployed apps, this page automatically redirects to the Resources group in the AWS console.</p></body></html>`);
|
|
30
|
+
return;
|
|
31
|
+
}
|
|
32
|
+
ctx.response.status = 302;
|
|
33
|
+
ctx.response.headers.set('Location', url);
|
|
34
|
+
ctx.response.send('');
|
|
35
|
+
},
|
|
36
|
+
},
|
|
37
|
+
{
|
|
38
|
+
method: 'GET',
|
|
39
|
+
path: '/aws-blocks/settings',
|
|
40
|
+
handler: async (ctx: BlocksContext) => {
|
|
41
|
+
const url = process.env.BB_SETTINGS_GROUP_URL;
|
|
42
|
+
if (!url) {
|
|
43
|
+
const settingsPath = join(process.cwd(), '.bb-data', 'settings.json');
|
|
44
|
+
openInEditor(settingsPath);
|
|
45
|
+
ctx.response.status = 200;
|
|
46
|
+
ctx.response.headers.set('Content-Type', 'text/html');
|
|
47
|
+
ctx.response.send(`<!DOCTYPE html><html><head><title>Settings</title><style>body{font-family:system-ui,sans-serif;max-width:640px;margin:4rem auto;padding:0 1rem;color:#1a1a1a}h1{font-size:1.5rem}p{line-height:1.6}code{background:#f3f4f6;padding:2px 6px;border-radius:4px;font-size:0.9em}a{color:#0066cc}</style></head><body><h1>Settings</h1><p>Opening <code>.bb-data/settings.json</code> in your default editor.</p><p>All AppSetting values are stored as <code>{ "fullId": value }</code> entries. Edit and save -- changes take effect on the next <code>get()</code> call.</p><p>File location: <code>${settingsPath}</code></p></body></html>`);
|
|
48
|
+
return;
|
|
49
|
+
}
|
|
50
|
+
ctx.response.status = 302;
|
|
51
|
+
ctx.response.headers.set('Location', url);
|
|
52
|
+
ctx.response.send('');
|
|
53
|
+
},
|
|
54
|
+
},
|
|
55
|
+
];
|
|
56
|
+
|
|
57
|
+
for (const route of routes) {
|
|
58
|
+
if (!getRegisteredRoutes().some(r => r.method === route.method && r.path === route.path)) {
|
|
59
|
+
registerRoute(route);
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
}
|