cdk-turso 0.0.2 → 0.0.4
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/.jsii +178 -4
- package/AGENTS.md +120 -18
- package/API.md +205 -0
- package/README.md +35 -0
- package/lib/handler/index.js +588 -24
- package/lib/handler-auth-token/index.d.ts +15 -0
- package/lib/handler-auth-token/index.js +708 -0
- package/lib/index.d.ts +1 -0
- package/lib/index.js +4 -2
- package/lib/turso-auth-token.d.ts +32 -0
- package/lib/turso-auth-token.js +66 -0
- package/lib/turso-database.d.ts +2 -0
- package/lib/turso-database.js +4 -2
- package/package.json +2 -1
package/.jsii
CHANGED
|
@@ -2791,7 +2791,7 @@
|
|
|
2791
2791
|
},
|
|
2792
2792
|
"name": "cdk-turso",
|
|
2793
2793
|
"readme": {
|
|
2794
|
-
"markdown": "# CDK Turso\n\nCDK construct to create a [Turso cloud](https://docs.turso.tech/turso-cloud) database.\n\n## Installation\n\n```bash\nnpm install cdk-turso\n```\n\n## Usage\n\n```typescript\nimport { Stack } from 'aws-cdk-lib';\nimport { StringParameter } from 'aws-cdk-lib/aws-ssm';\nimport { TursoDatabase } from 'cdk-turso';\n\nconst stack = new Stack();\n\n// SSM Parameter containing your Turso API token\nconst apiToken = new StringParameter(stack, 'TursoApiToken', {\n parameterName: '/turso/api-token',\n stringValue: 'your-api-token',\n});\n\nconst database = new TursoDatabase(stack, 'Database', {\n databaseName: 'my-database',\n group: 'group-name',\n organizationSlug: 'my-org',\n apiToken,\n});\n\n// Use the database attributes\ndatabase.dbId; // Database ID\ndatabase.hostname; // Database hostname\ndatabase.databaseName; // Database name\n```\n\n## API\n\n### TursoDatabaseProps\n\n| Prop | Type | Required | Description |\n|------|------|----------|-------------|\n| `databaseName` | `string` | Yes | Database name (lowercase, numbers, dashes only, max 64 chars) |\n| `group` | `string` | Yes | Turso group name (must already exist) |\n| `organizationSlug` | `string` | Yes | Organization slug |\n| `apiToken` | `ssm.IParameter` | Yes | SSM Parameter containing the Turso API token |\n| `sizeLimit` | `string` | No | Size limit (e.g., '256mb') |\n| `seed` | `TursoDatabaseSeed` | No | Database seed configuration |\n| `encryption` | `TursoDatabaseEncryption` | No | Encryption configuration |\n\n### TursoDatabaseSeed\n\n```typescript\ninterface TursoDatabaseSeed {\n readonly type: string; // Seed type (e.g., 'schema')\n readonly name: string; // Seed name\n readonly timestamp?: string; // Optional timestamp\n}\n```\n\n### TursoDatabaseEncryption\n\n```typescript\ninterface TursoDatabaseEncryption {\n readonly encryptionKey: string; // KMS key ARN\n readonly encryptionCipher: string; // Cipher type (e.g., 'AES')\n}\n```\n\n### TursoDatabase\n\n| Attribute | Type | Description |\n|-----------|------|-------------|\n| `dbId` | `string` | Turso database ID |\n| `hostname` | `string` | DNS hostname (e.g., `my-db-my-org.turso.io`) for libSQL/HTTP connections |\n| `databaseName` | `string` | Database name |\n\n## Requirements\n\n- Node.js 24.x runtime for the Lambda handler\n- The Lambda handler requires the AWS SDK for JavaScript v3 (pre-installed in Lambda runtime)\n"
|
|
2794
|
+
"markdown": "# CDK Turso\n\nCDK construct to create a [Turso cloud](https://docs.turso.tech/turso-cloud) database.\n\n## Installation\n\n```bash\nnpm install cdk-turso\n```\n\n## Usage\n\n```typescript\nimport { Stack } from 'aws-cdk-lib';\nimport { StringParameter } from 'aws-cdk-lib/aws-ssm';\nimport { TursoDatabase } from 'cdk-turso';\n\nconst stack = new Stack();\n\n// SSM Parameter containing your Turso API token\nconst apiToken = new StringParameter(stack, 'TursoApiToken', {\n parameterName: '/turso/api-token',\n stringValue: 'your-api-token',\n});\n\nconst database = new TursoDatabase(stack, 'Database', {\n databaseName: 'my-database',\n group: 'group-name',\n organizationSlug: 'my-org',\n apiToken,\n});\n\n// Use the database attributes\ndatabase.dbId; // Database ID\ndatabase.hostname; // Database hostname\ndatabase.databaseName; // Database name\n```\n\n### Auth Token\n\nGenerate a database auth token and store it as a SecureString in SSM Parameter Store:\n\n```typescript\nimport { TursoAuthToken } from 'cdk-turso';\n\nconst authToken = new TursoAuthToken(stack, 'AuthToken', {\n database,\n parameterName: '/turso/db-token',\n expiration: '2w', // optional, default: 'never'\n authorization: 'read-only', // optional, default: 'full-access'\n});\n\n// The SSM parameter name where the JWT is stored\nauthToken.parameterName;\n```\n\n## API\n\n### TursoDatabaseProps\n\n| Prop | Type | Required | Description |\n|------|------|----------|-------------|\n| `databaseName` | `string` | Yes | Database name (lowercase, numbers, dashes only, max 64 chars) |\n| `group` | `string` | Yes | Turso group name (must already exist) |\n| `organizationSlug` | `string` | Yes | Organization slug |\n| `apiToken` | `ssm.IParameter` | Yes | SSM Parameter containing the Turso API token |\n| `sizeLimit` | `string` | No | Size limit (e.g., '256mb') |\n| `seed` | `TursoDatabaseSeed` | No | Database seed configuration |\n| `encryption` | `TursoDatabaseEncryption` | No | Encryption configuration |\n\n### TursoDatabaseSeed\n\n```typescript\ninterface TursoDatabaseSeed {\n readonly type: string; // Seed type (e.g., 'schema')\n readonly name: string; // Seed name\n readonly timestamp?: string; // Optional timestamp\n}\n```\n\n### TursoDatabaseEncryption\n\n```typescript\ninterface TursoDatabaseEncryption {\n readonly encryptionKey: string; // KMS key ARN\n readonly encryptionCipher: string; // Cipher type (e.g., 'AES')\n}\n```\n\n### TursoDatabase\n\n| Attribute | Type | Description |\n|-----------|------|-------------|\n| `dbId` | `string` | Turso database ID |\n| `hostname` | `string` | DNS hostname (e.g., `my-db-my-org.turso.io`) for libSQL/HTTP connections |\n| `databaseName` | `string` | Database name |\n| `organizationSlug` | `string` | Organization slug |\n| `apiToken` | `ssm.IParameter` | SSM Parameter containing the Turso API token |\n\n### TursoAuthTokenProps\n\n| Prop | Type | Required | Description |\n|------|------|----------|-------------|\n| `database` | `TursoDatabase` | Yes | The Turso database to create an auth token for |\n| `parameterName` | `string` | Yes | SSM parameter name where the generated JWT will be stored as a SecureString |\n| `expiration` | `string` | No | Token expiry (e.g., `'2w'`, `'1d30m'`). Default: `'never'` |\n| `authorization` | `string` | No | `'full-access'` or `'read-only'`. Default: `'full-access'` |\n\n### TursoAuthToken\n\n| Attribute | Type | Description |\n|-----------|------|-------------|\n| `parameterName` | `string` | The SSM parameter name where the auth token is stored |\n\n## Requirements\n\n- Node.js 24.x runtime for the Lambda handler\n- The Lambda handler requires the AWS SDK for JavaScript v3 (pre-installed in Lambda runtime)\n"
|
|
2795
2795
|
},
|
|
2796
2796
|
"repository": {
|
|
2797
2797
|
"type": "git",
|
|
@@ -2804,6 +2804,152 @@
|
|
|
2804
2804
|
}
|
|
2805
2805
|
},
|
|
2806
2806
|
"types": {
|
|
2807
|
+
"cdk-turso.TursoAuthToken": {
|
|
2808
|
+
"assembly": "cdk-turso",
|
|
2809
|
+
"base": "constructs.Construct",
|
|
2810
|
+
"docs": {
|
|
2811
|
+
"stability": "stable"
|
|
2812
|
+
},
|
|
2813
|
+
"fqn": "cdk-turso.TursoAuthToken",
|
|
2814
|
+
"initializer": {
|
|
2815
|
+
"docs": {
|
|
2816
|
+
"stability": "stable"
|
|
2817
|
+
},
|
|
2818
|
+
"locationInModule": {
|
|
2819
|
+
"filename": "src/turso-auth-token.ts",
|
|
2820
|
+
"line": 42
|
|
2821
|
+
},
|
|
2822
|
+
"parameters": [
|
|
2823
|
+
{
|
|
2824
|
+
"name": "scope",
|
|
2825
|
+
"type": {
|
|
2826
|
+
"fqn": "constructs.Construct"
|
|
2827
|
+
}
|
|
2828
|
+
},
|
|
2829
|
+
{
|
|
2830
|
+
"name": "id",
|
|
2831
|
+
"type": {
|
|
2832
|
+
"primitive": "string"
|
|
2833
|
+
}
|
|
2834
|
+
},
|
|
2835
|
+
{
|
|
2836
|
+
"name": "props",
|
|
2837
|
+
"type": {
|
|
2838
|
+
"fqn": "cdk-turso.TursoAuthTokenProps"
|
|
2839
|
+
}
|
|
2840
|
+
}
|
|
2841
|
+
]
|
|
2842
|
+
},
|
|
2843
|
+
"kind": "class",
|
|
2844
|
+
"locationInModule": {
|
|
2845
|
+
"filename": "src/turso-auth-token.ts",
|
|
2846
|
+
"line": 36
|
|
2847
|
+
},
|
|
2848
|
+
"name": "TursoAuthToken",
|
|
2849
|
+
"properties": [
|
|
2850
|
+
{
|
|
2851
|
+
"docs": {
|
|
2852
|
+
"stability": "stable",
|
|
2853
|
+
"summary": "The SSM parameter name where the auth token is stored."
|
|
2854
|
+
},
|
|
2855
|
+
"immutable": true,
|
|
2856
|
+
"locationInModule": {
|
|
2857
|
+
"filename": "src/turso-auth-token.ts",
|
|
2858
|
+
"line": 40
|
|
2859
|
+
},
|
|
2860
|
+
"name": "parameterName",
|
|
2861
|
+
"type": {
|
|
2862
|
+
"primitive": "string"
|
|
2863
|
+
}
|
|
2864
|
+
}
|
|
2865
|
+
],
|
|
2866
|
+
"symbolId": "src/turso-auth-token:TursoAuthToken"
|
|
2867
|
+
},
|
|
2868
|
+
"cdk-turso.TursoAuthTokenProps": {
|
|
2869
|
+
"assembly": "cdk-turso",
|
|
2870
|
+
"datatype": true,
|
|
2871
|
+
"docs": {
|
|
2872
|
+
"stability": "stable"
|
|
2873
|
+
},
|
|
2874
|
+
"fqn": "cdk-turso.TursoAuthTokenProps",
|
|
2875
|
+
"kind": "interface",
|
|
2876
|
+
"locationInModule": {
|
|
2877
|
+
"filename": "src/turso-auth-token.ts",
|
|
2878
|
+
"line": 9
|
|
2879
|
+
},
|
|
2880
|
+
"name": "TursoAuthTokenProps",
|
|
2881
|
+
"properties": [
|
|
2882
|
+
{
|
|
2883
|
+
"abstract": true,
|
|
2884
|
+
"docs": {
|
|
2885
|
+
"stability": "stable",
|
|
2886
|
+
"summary": "The Turso database to create an auth token for."
|
|
2887
|
+
},
|
|
2888
|
+
"immutable": true,
|
|
2889
|
+
"locationInModule": {
|
|
2890
|
+
"filename": "src/turso-auth-token.ts",
|
|
2891
|
+
"line": 13
|
|
2892
|
+
},
|
|
2893
|
+
"name": "database",
|
|
2894
|
+
"type": {
|
|
2895
|
+
"fqn": "cdk-turso.TursoDatabase"
|
|
2896
|
+
}
|
|
2897
|
+
},
|
|
2898
|
+
{
|
|
2899
|
+
"abstract": true,
|
|
2900
|
+
"docs": {
|
|
2901
|
+
"stability": "stable",
|
|
2902
|
+
"summary": "The SSM parameter name where the generated JWT will be stored as a SecureString."
|
|
2903
|
+
},
|
|
2904
|
+
"immutable": true,
|
|
2905
|
+
"locationInModule": {
|
|
2906
|
+
"filename": "src/turso-auth-token.ts",
|
|
2907
|
+
"line": 19
|
|
2908
|
+
},
|
|
2909
|
+
"name": "parameterName",
|
|
2910
|
+
"type": {
|
|
2911
|
+
"primitive": "string"
|
|
2912
|
+
}
|
|
2913
|
+
},
|
|
2914
|
+
{
|
|
2915
|
+
"abstract": true,
|
|
2916
|
+
"docs": {
|
|
2917
|
+
"default": "\"full-access\"",
|
|
2918
|
+
"stability": "stable",
|
|
2919
|
+
"summary": "Authorization level for the token."
|
|
2920
|
+
},
|
|
2921
|
+
"immutable": true,
|
|
2922
|
+
"locationInModule": {
|
|
2923
|
+
"filename": "src/turso-auth-token.ts",
|
|
2924
|
+
"line": 33
|
|
2925
|
+
},
|
|
2926
|
+
"name": "authorization",
|
|
2927
|
+
"optional": true,
|
|
2928
|
+
"type": {
|
|
2929
|
+
"primitive": "string"
|
|
2930
|
+
}
|
|
2931
|
+
},
|
|
2932
|
+
{
|
|
2933
|
+
"abstract": true,
|
|
2934
|
+
"docs": {
|
|
2935
|
+
"default": "\"never\"",
|
|
2936
|
+
"stability": "stable",
|
|
2937
|
+
"summary": "Expiration time for the token (e.g., `\"2w\"`, `\"1d30m\"`)."
|
|
2938
|
+
},
|
|
2939
|
+
"immutable": true,
|
|
2940
|
+
"locationInModule": {
|
|
2941
|
+
"filename": "src/turso-auth-token.ts",
|
|
2942
|
+
"line": 26
|
|
2943
|
+
},
|
|
2944
|
+
"name": "expiration",
|
|
2945
|
+
"optional": true,
|
|
2946
|
+
"type": {
|
|
2947
|
+
"primitive": "string"
|
|
2948
|
+
}
|
|
2949
|
+
}
|
|
2950
|
+
],
|
|
2951
|
+
"symbolId": "src/turso-auth-token:TursoAuthTokenProps"
|
|
2952
|
+
},
|
|
2807
2953
|
"cdk-turso.TursoDatabase": {
|
|
2808
2954
|
"assembly": "cdk-turso",
|
|
2809
2955
|
"base": "constructs.Construct",
|
|
@@ -2817,7 +2963,7 @@
|
|
|
2817
2963
|
},
|
|
2818
2964
|
"locationInModule": {
|
|
2819
2965
|
"filename": "src/turso-database.ts",
|
|
2820
|
-
"line":
|
|
2966
|
+
"line": 40
|
|
2821
2967
|
},
|
|
2822
2968
|
"parameters": [
|
|
2823
2969
|
{
|
|
@@ -2847,6 +2993,20 @@
|
|
|
2847
2993
|
},
|
|
2848
2994
|
"name": "TursoDatabase",
|
|
2849
2995
|
"properties": [
|
|
2996
|
+
{
|
|
2997
|
+
"docs": {
|
|
2998
|
+
"stability": "stable"
|
|
2999
|
+
},
|
|
3000
|
+
"immutable": true,
|
|
3001
|
+
"locationInModule": {
|
|
3002
|
+
"filename": "src/turso-database.ts",
|
|
3003
|
+
"line": 38
|
|
3004
|
+
},
|
|
3005
|
+
"name": "apiToken",
|
|
3006
|
+
"type": {
|
|
3007
|
+
"fqn": "aws-cdk-lib.aws_ssm.IParameter"
|
|
3008
|
+
}
|
|
3009
|
+
},
|
|
2850
3010
|
{
|
|
2851
3011
|
"docs": {
|
|
2852
3012
|
"stability": "stable"
|
|
@@ -2889,6 +3049,20 @@
|
|
|
2889
3049
|
"type": {
|
|
2890
3050
|
"primitive": "string"
|
|
2891
3051
|
}
|
|
3052
|
+
},
|
|
3053
|
+
{
|
|
3054
|
+
"docs": {
|
|
3055
|
+
"stability": "stable"
|
|
3056
|
+
},
|
|
3057
|
+
"immutable": true,
|
|
3058
|
+
"locationInModule": {
|
|
3059
|
+
"filename": "src/turso-database.ts",
|
|
3060
|
+
"line": 37
|
|
3061
|
+
},
|
|
3062
|
+
"name": "organizationSlug",
|
|
3063
|
+
"type": {
|
|
3064
|
+
"primitive": "string"
|
|
3065
|
+
}
|
|
2892
3066
|
}
|
|
2893
3067
|
],
|
|
2894
3068
|
"symbolId": "src/turso-database:TursoDatabase"
|
|
@@ -3129,6 +3303,6 @@
|
|
|
3129
3303
|
"symbolId": "src/turso-database:TursoDatabaseSeed"
|
|
3130
3304
|
}
|
|
3131
3305
|
},
|
|
3132
|
-
"version": "0.0.
|
|
3133
|
-
"fingerprint": "
|
|
3306
|
+
"version": "0.0.4",
|
|
3307
|
+
"fingerprint": "USxC5s0tkERUA9DB2YybfbXUXWF2FsLi8ae2BIX8WFQ="
|
|
3134
3308
|
}
|
package/AGENTS.md
CHANGED
|
@@ -1,41 +1,143 @@
|
|
|
1
|
-
#
|
|
1
|
+
# AGENTS.md
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
Guidance for AI coding agents working in this repository.
|
|
4
4
|
|
|
5
5
|
## Project Overview
|
|
6
6
|
|
|
7
|
-
CDK construct library for provisioning Turso cloud databases. Built with projen's `AwsCdkConstructLibrary` template, using JSII for
|
|
7
|
+
CDK construct library for provisioning Turso cloud databases. Built with projen's `AwsCdkConstructLibrary` template, using JSII for multi-language support. Source must remain JSII-compatible.
|
|
8
8
|
|
|
9
9
|
## Commands
|
|
10
10
|
|
|
11
11
|
```bash
|
|
12
12
|
npm run build # Full pipeline: compile → test → package
|
|
13
|
-
npm run compile # jsii compiler (TypeScript → JS + .d.ts)
|
|
14
|
-
npm run test # Jest (with coverage) +
|
|
13
|
+
npm run compile # jsii compiler (TypeScript → JS + .d.ts) + esbuild handler bundle
|
|
14
|
+
npm run test # Jest (with coverage) + Biome lint
|
|
15
15
|
npm run test:watch # Jest in watch mode
|
|
16
|
-
npm run eslint # ESLint with --fix on src/, test/, projenrc/
|
|
17
16
|
npm run watch # jsii in watch mode (for development)
|
|
17
|
+
npx projen biome # Run Biome formatter + linter with --fix
|
|
18
18
|
npx projen # Regenerate project files from .projenrc.ts
|
|
19
19
|
```
|
|
20
20
|
|
|
21
|
-
Run a single test file:
|
|
21
|
+
Run a single test file:
|
|
22
|
+
```bash
|
|
23
|
+
npx jest --passWithNoTests test/handler.test.ts
|
|
24
|
+
```
|
|
22
25
|
|
|
23
26
|
## Projen: Critical Rule
|
|
24
27
|
|
|
25
|
-
Most
|
|
28
|
+
Most config files are **generated by projen** and must NOT be edited directly. This includes `package.json`, `biome.jsonc`, `tsconfig.json`, `tsconfig.dev.json`, GitHub workflows, `.mergify.yml`, and anything marked `~~ Generated by projen`. To change project configuration, edit `.projenrc.ts` and run `npx projen`.
|
|
26
29
|
|
|
27
30
|
## Architecture
|
|
28
31
|
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
-
|
|
32
|
+
```
|
|
33
|
+
src/
|
|
34
|
+
index.ts # Barrel exports — all public symbols re-exported here
|
|
35
|
+
turso-database.ts # Main CDK construct
|
|
36
|
+
handler/index.ts # Lambda handler for CloudFormation custom resource (bundled via esbuild)
|
|
37
|
+
test/
|
|
38
|
+
turso-database.test.ts # Construct unit tests (CDK assertions)
|
|
39
|
+
handler.test.ts # Handler unit tests (Jest mocks)
|
|
40
|
+
lib/ # Compiled output (generated, gitignored)
|
|
41
|
+
dist/ # Distribution packages (generated, gitignored)
|
|
42
|
+
```
|
|
43
|
+
|
|
33
44
|
- Peer dependencies: `aws-cdk-lib` (^2.1.0), `constructs` (^10.0.5)
|
|
45
|
+
- Handler bundled separately: `esbuild src/handler/index.ts --bundle --platform=node --target=node24 --outfile=lib/handler/index.js --external:@aws-sdk/*`
|
|
46
|
+
- Pre-commit hook (husky): runs `npx projen biome && npx projen build`
|
|
47
|
+
|
|
48
|
+
## Code Style (enforced by Biome)
|
|
49
|
+
|
|
50
|
+
Biome is the sole linter and formatter. ESLint is disabled.
|
|
51
|
+
|
|
52
|
+
### Formatting
|
|
53
|
+
- **2-space** indentation (spaces, not tabs)
|
|
54
|
+
- **80-char** max line width
|
|
55
|
+
- **Double quotes** for strings: `"hello"` not `'hello'`
|
|
56
|
+
- **Semicolons as needed** — omit them; Biome inserts only where syntactically required
|
|
57
|
+
- **Trailing commas** on all multi-line constructs (arrays, objects, parameters)
|
|
58
|
+
- **Arrow parentheses**: always, even for single parameter `(x) => x`
|
|
59
|
+
- **Bracket spacing**: `{ a }` not `{a}`
|
|
60
|
+
|
|
61
|
+
### Linting Rules
|
|
62
|
+
- `noUnusedImports`: error
|
|
63
|
+
- `noUnusedVariables`: error
|
|
64
|
+
- `noConfusingVoidType`: error
|
|
65
|
+
- `noNonNullAssertion`: allowed in `**/*.test.ts` only
|
|
66
|
+
- `useNodejsImportProtocol`: off — use `"path"` not `"node:path"`
|
|
67
|
+
|
|
68
|
+
## Import Conventions
|
|
69
|
+
|
|
70
|
+
### Ordering
|
|
71
|
+
1. AWS CDK / framework imports (`aws-cdk-lib`, `aws-cdk-lib/*`, `constructs`)
|
|
72
|
+
2. External packages (`@aws-sdk/client-ssm`)
|
|
73
|
+
3. Node.js builtins (`import * as path from "path"`)
|
|
74
|
+
4. Relative imports (`"./turso-database"`, `"../src"`)
|
|
75
|
+
|
|
76
|
+
### Style
|
|
77
|
+
- **Named imports** with destructuring: `import { CustomResource, Duration } from "aws-cdk-lib"`
|
|
78
|
+
- **Namespace imports** for Node builtins: `import * as path from "path"`
|
|
79
|
+
- **`type` keyword** for type-only imports: `import type { IParameter } from "aws-cdk-lib/aws-ssm"`
|
|
80
|
+
- **Inline `type`** in mixed imports: `import { type SomeType, someValue } from "..."`
|
|
81
|
+
- Use deep CDK imports: `aws-cdk-lib/aws-lambda`, `aws-cdk-lib/aws-ssm`, `aws-cdk-lib/custom-resources`
|
|
82
|
+
- Barrel exports in `src/index.ts` are **alphabetically sorted**
|
|
83
|
+
|
|
84
|
+
## Naming Conventions
|
|
85
|
+
|
|
86
|
+
| Category | Convention | Example |
|
|
87
|
+
|---|---|---|
|
|
88
|
+
| Source files | kebab-case `.ts` | `turso-database.ts` |
|
|
89
|
+
| Test files | `{source-name}.test.ts` | `handler.test.ts` |
|
|
90
|
+
| Classes | PascalCase | `TursoDatabase` |
|
|
91
|
+
| Props interfaces | `{ClassName}Props` | `TursoDatabaseProps` |
|
|
92
|
+
| Sub-config interfaces | `{ClassName}{Feature}` | `TursoDatabaseEncryption` |
|
|
93
|
+
| Interface properties | `readonly`, camelCase | `readonly databaseName: string` |
|
|
94
|
+
| Public class properties | `public readonly`, camelCase | `public readonly dbId: string` |
|
|
95
|
+
| Functions | camelCase | `handler`, `getApiToken` |
|
|
96
|
+
| CDK resource IDs | PascalCase string | `"Handler"`, `"Provider"` |
|
|
97
|
+
| CF resource properties | PascalCase string | `"DatabaseName"`, `"Group"` |
|
|
98
|
+
| Environment variables | SCREAMING_SNAKE_CASE | `TURSO_API_TOKEN_PARAMETER_NAME` |
|
|
99
|
+
|
|
100
|
+
## TypeScript
|
|
101
|
+
|
|
102
|
+
- `strict: true` — all strict checks enabled (`noImplicitAny`, `strictNullChecks`, `strictPropertyInitialization`, etc.)
|
|
103
|
+
- `noUnusedLocals: true`, `noUnusedParameters: true`, `noImplicitReturns: true`
|
|
104
|
+
- `noFallthroughCasesInSwitch: true`
|
|
105
|
+
- Target: `ES2020`, Module: `CommonJS`
|
|
106
|
+
|
|
107
|
+
## CDK Construct Patterns
|
|
108
|
+
|
|
109
|
+
- Extend `Construct` from `constructs`, not from `aws-cdk-lib`
|
|
110
|
+
- Constructor signature: `constructor(scope: Construct, id: string, props: XxxProps)`
|
|
111
|
+
- Call `super(scope, id)` first
|
|
112
|
+
- Validate inputs in constructor with `throw new Error(...)` for bad values
|
|
113
|
+
- Custom resource pattern: Lambda Function → Provider → CustomResource
|
|
114
|
+
- Expose outputs as `public readonly` properties via `cr.getAttString("AttrName")`
|
|
115
|
+
|
|
116
|
+
## Error Handling
|
|
117
|
+
|
|
118
|
+
- **Constructor validation**: throw `new Error(...)` with clear messages for invalid props (regex checks, length limits)
|
|
119
|
+
- **Handler errors**: include HTTP status and response text: `throw new Error(\`Failed to create: ${response.status} ${errorText}\`)`
|
|
120
|
+
- **Environment checks**: throw early if required env vars are missing
|
|
121
|
+
- **Idempotent deletes**: tolerate 404 on delete operations
|
|
122
|
+
- **Graceful handling**: skip delete for unknown/failed physical resource IDs
|
|
123
|
+
|
|
124
|
+
## Testing Patterns
|
|
125
|
+
|
|
126
|
+
- Use `describe("ClassName", () => { ... })` as outer wrapper
|
|
127
|
+
- Use **`test()`** (not `it()`) for individual cases
|
|
128
|
+
- Test names are descriptive sentences: `"creates custom resource with correct properties"`
|
|
34
129
|
|
|
35
|
-
|
|
130
|
+
### Construct Tests
|
|
131
|
+
- Helper function `createStack()` at top of describe block for shared setup
|
|
132
|
+
- CDK assertions: `Template.fromStack(stack)`, `template.hasResource()`, `template.hasResourceProperties()`
|
|
133
|
+
- Partial matching: `Match.arrayWith([...])`, `Match.objectLike({...})`
|
|
134
|
+
- Validation tests: `expect(() => { ... }).toThrow("exact message")`
|
|
135
|
+
- Import constructs from barrel: `import { TursoDatabase } from "../src"`
|
|
36
136
|
|
|
37
|
-
|
|
38
|
-
-
|
|
39
|
-
-
|
|
40
|
-
-
|
|
41
|
-
-
|
|
137
|
+
### Handler Tests
|
|
138
|
+
- `jest.mock()` at file top level, before imports
|
|
139
|
+
- Mock `global.fetch` per test: `global.fetch = jest.fn()`
|
|
140
|
+
- `beforeEach`: clear mocks, set env vars, configure default mock responses
|
|
141
|
+
- `afterEach`: clean up env vars
|
|
142
|
+
- Async error assertions: `await expect(handler(...)).rejects.toThrow("message")`
|
|
143
|
+
- Argument checking: `expect(mockFetch).toHaveBeenCalledWith(url, expect.objectContaining({...}))`
|
package/API.md
CHANGED
|
@@ -2,6 +2,118 @@
|
|
|
2
2
|
|
|
3
3
|
## Constructs <a name="Constructs" id="Constructs"></a>
|
|
4
4
|
|
|
5
|
+
### TursoAuthToken <a name="TursoAuthToken" id="cdk-turso.TursoAuthToken"></a>
|
|
6
|
+
|
|
7
|
+
#### Initializers <a name="Initializers" id="cdk-turso.TursoAuthToken.Initializer"></a>
|
|
8
|
+
|
|
9
|
+
```typescript
|
|
10
|
+
import { TursoAuthToken } from 'cdk-turso'
|
|
11
|
+
|
|
12
|
+
new TursoAuthToken(scope: Construct, id: string, props: TursoAuthTokenProps)
|
|
13
|
+
```
|
|
14
|
+
|
|
15
|
+
| **Name** | **Type** | **Description** |
|
|
16
|
+
| --- | --- | --- |
|
|
17
|
+
| <code><a href="#cdk-turso.TursoAuthToken.Initializer.parameter.scope">scope</a></code> | <code>constructs.Construct</code> | *No description.* |
|
|
18
|
+
| <code><a href="#cdk-turso.TursoAuthToken.Initializer.parameter.id">id</a></code> | <code>string</code> | *No description.* |
|
|
19
|
+
| <code><a href="#cdk-turso.TursoAuthToken.Initializer.parameter.props">props</a></code> | <code><a href="#cdk-turso.TursoAuthTokenProps">TursoAuthTokenProps</a></code> | *No description.* |
|
|
20
|
+
|
|
21
|
+
---
|
|
22
|
+
|
|
23
|
+
##### `scope`<sup>Required</sup> <a name="scope" id="cdk-turso.TursoAuthToken.Initializer.parameter.scope"></a>
|
|
24
|
+
|
|
25
|
+
- *Type:* constructs.Construct
|
|
26
|
+
|
|
27
|
+
---
|
|
28
|
+
|
|
29
|
+
##### `id`<sup>Required</sup> <a name="id" id="cdk-turso.TursoAuthToken.Initializer.parameter.id"></a>
|
|
30
|
+
|
|
31
|
+
- *Type:* string
|
|
32
|
+
|
|
33
|
+
---
|
|
34
|
+
|
|
35
|
+
##### `props`<sup>Required</sup> <a name="props" id="cdk-turso.TursoAuthToken.Initializer.parameter.props"></a>
|
|
36
|
+
|
|
37
|
+
- *Type:* <a href="#cdk-turso.TursoAuthTokenProps">TursoAuthTokenProps</a>
|
|
38
|
+
|
|
39
|
+
---
|
|
40
|
+
|
|
41
|
+
#### Methods <a name="Methods" id="Methods"></a>
|
|
42
|
+
|
|
43
|
+
| **Name** | **Description** |
|
|
44
|
+
| --- | --- |
|
|
45
|
+
| <code><a href="#cdk-turso.TursoAuthToken.toString">toString</a></code> | Returns a string representation of this construct. |
|
|
46
|
+
|
|
47
|
+
---
|
|
48
|
+
|
|
49
|
+
##### `toString` <a name="toString" id="cdk-turso.TursoAuthToken.toString"></a>
|
|
50
|
+
|
|
51
|
+
```typescript
|
|
52
|
+
public toString(): string
|
|
53
|
+
```
|
|
54
|
+
|
|
55
|
+
Returns a string representation of this construct.
|
|
56
|
+
|
|
57
|
+
#### Static Functions <a name="Static Functions" id="Static Functions"></a>
|
|
58
|
+
|
|
59
|
+
| **Name** | **Description** |
|
|
60
|
+
| --- | --- |
|
|
61
|
+
| <code><a href="#cdk-turso.TursoAuthToken.isConstruct">isConstruct</a></code> | Checks if `x` is a construct. |
|
|
62
|
+
|
|
63
|
+
---
|
|
64
|
+
|
|
65
|
+
##### ~~`isConstruct`~~ <a name="isConstruct" id="cdk-turso.TursoAuthToken.isConstruct"></a>
|
|
66
|
+
|
|
67
|
+
```typescript
|
|
68
|
+
import { TursoAuthToken } from 'cdk-turso'
|
|
69
|
+
|
|
70
|
+
TursoAuthToken.isConstruct(x: any)
|
|
71
|
+
```
|
|
72
|
+
|
|
73
|
+
Checks if `x` is a construct.
|
|
74
|
+
|
|
75
|
+
###### `x`<sup>Required</sup> <a name="x" id="cdk-turso.TursoAuthToken.isConstruct.parameter.x"></a>
|
|
76
|
+
|
|
77
|
+
- *Type:* any
|
|
78
|
+
|
|
79
|
+
Any object.
|
|
80
|
+
|
|
81
|
+
---
|
|
82
|
+
|
|
83
|
+
#### Properties <a name="Properties" id="Properties"></a>
|
|
84
|
+
|
|
85
|
+
| **Name** | **Type** | **Description** |
|
|
86
|
+
| --- | --- | --- |
|
|
87
|
+
| <code><a href="#cdk-turso.TursoAuthToken.property.node">node</a></code> | <code>constructs.Node</code> | The tree node. |
|
|
88
|
+
| <code><a href="#cdk-turso.TursoAuthToken.property.parameterName">parameterName</a></code> | <code>string</code> | The SSM parameter name where the auth token is stored. |
|
|
89
|
+
|
|
90
|
+
---
|
|
91
|
+
|
|
92
|
+
##### `node`<sup>Required</sup> <a name="node" id="cdk-turso.TursoAuthToken.property.node"></a>
|
|
93
|
+
|
|
94
|
+
```typescript
|
|
95
|
+
public readonly node: Node;
|
|
96
|
+
```
|
|
97
|
+
|
|
98
|
+
- *Type:* constructs.Node
|
|
99
|
+
|
|
100
|
+
The tree node.
|
|
101
|
+
|
|
102
|
+
---
|
|
103
|
+
|
|
104
|
+
##### `parameterName`<sup>Required</sup> <a name="parameterName" id="cdk-turso.TursoAuthToken.property.parameterName"></a>
|
|
105
|
+
|
|
106
|
+
```typescript
|
|
107
|
+
public readonly parameterName: string;
|
|
108
|
+
```
|
|
109
|
+
|
|
110
|
+
- *Type:* string
|
|
111
|
+
|
|
112
|
+
The SSM parameter name where the auth token is stored.
|
|
113
|
+
|
|
114
|
+
---
|
|
115
|
+
|
|
116
|
+
|
|
5
117
|
### TursoDatabase <a name="TursoDatabase" id="cdk-turso.TursoDatabase"></a>
|
|
6
118
|
|
|
7
119
|
#### Initializers <a name="Initializers" id="cdk-turso.TursoDatabase.Initializer"></a>
|
|
@@ -85,9 +197,11 @@ Any object.
|
|
|
85
197
|
| **Name** | **Type** | **Description** |
|
|
86
198
|
| --- | --- | --- |
|
|
87
199
|
| <code><a href="#cdk-turso.TursoDatabase.property.node">node</a></code> | <code>constructs.Node</code> | The tree node. |
|
|
200
|
+
| <code><a href="#cdk-turso.TursoDatabase.property.apiToken">apiToken</a></code> | <code>aws-cdk-lib.aws_ssm.IParameter</code> | *No description.* |
|
|
88
201
|
| <code><a href="#cdk-turso.TursoDatabase.property.databaseName">databaseName</a></code> | <code>string</code> | *No description.* |
|
|
89
202
|
| <code><a href="#cdk-turso.TursoDatabase.property.dbId">dbId</a></code> | <code>string</code> | *No description.* |
|
|
90
203
|
| <code><a href="#cdk-turso.TursoDatabase.property.hostname">hostname</a></code> | <code>string</code> | DNS hostname for the database (e.g., `my-db-my-org.turso.io`). Use with libSQL or HTTP connections. |
|
|
204
|
+
| <code><a href="#cdk-turso.TursoDatabase.property.organizationSlug">organizationSlug</a></code> | <code>string</code> | *No description.* |
|
|
91
205
|
|
|
92
206
|
---
|
|
93
207
|
|
|
@@ -103,6 +217,16 @@ The tree node.
|
|
|
103
217
|
|
|
104
218
|
---
|
|
105
219
|
|
|
220
|
+
##### `apiToken`<sup>Required</sup> <a name="apiToken" id="cdk-turso.TursoDatabase.property.apiToken"></a>
|
|
221
|
+
|
|
222
|
+
```typescript
|
|
223
|
+
public readonly apiToken: IParameter;
|
|
224
|
+
```
|
|
225
|
+
|
|
226
|
+
- *Type:* aws-cdk-lib.aws_ssm.IParameter
|
|
227
|
+
|
|
228
|
+
---
|
|
229
|
+
|
|
106
230
|
##### `databaseName`<sup>Required</sup> <a name="databaseName" id="cdk-turso.TursoDatabase.property.databaseName"></a>
|
|
107
231
|
|
|
108
232
|
```typescript
|
|
@@ -135,9 +259,90 @@ DNS hostname for the database (e.g., `my-db-my-org.turso.io`). Use with libSQL o
|
|
|
135
259
|
|
|
136
260
|
---
|
|
137
261
|
|
|
262
|
+
##### `organizationSlug`<sup>Required</sup> <a name="organizationSlug" id="cdk-turso.TursoDatabase.property.organizationSlug"></a>
|
|
263
|
+
|
|
264
|
+
```typescript
|
|
265
|
+
public readonly organizationSlug: string;
|
|
266
|
+
```
|
|
267
|
+
|
|
268
|
+
- *Type:* string
|
|
269
|
+
|
|
270
|
+
---
|
|
271
|
+
|
|
138
272
|
|
|
139
273
|
## Structs <a name="Structs" id="Structs"></a>
|
|
140
274
|
|
|
275
|
+
### TursoAuthTokenProps <a name="TursoAuthTokenProps" id="cdk-turso.TursoAuthTokenProps"></a>
|
|
276
|
+
|
|
277
|
+
#### Initializer <a name="Initializer" id="cdk-turso.TursoAuthTokenProps.Initializer"></a>
|
|
278
|
+
|
|
279
|
+
```typescript
|
|
280
|
+
import { TursoAuthTokenProps } from 'cdk-turso'
|
|
281
|
+
|
|
282
|
+
const tursoAuthTokenProps: TursoAuthTokenProps = { ... }
|
|
283
|
+
```
|
|
284
|
+
|
|
285
|
+
#### Properties <a name="Properties" id="Properties"></a>
|
|
286
|
+
|
|
287
|
+
| **Name** | **Type** | **Description** |
|
|
288
|
+
| --- | --- | --- |
|
|
289
|
+
| <code><a href="#cdk-turso.TursoAuthTokenProps.property.database">database</a></code> | <code><a href="#cdk-turso.TursoDatabase">TursoDatabase</a></code> | The Turso database to create an auth token for. |
|
|
290
|
+
| <code><a href="#cdk-turso.TursoAuthTokenProps.property.parameterName">parameterName</a></code> | <code>string</code> | The SSM parameter name where the generated JWT will be stored as a SecureString. |
|
|
291
|
+
| <code><a href="#cdk-turso.TursoAuthTokenProps.property.authorization">authorization</a></code> | <code>string</code> | Authorization level for the token. |
|
|
292
|
+
| <code><a href="#cdk-turso.TursoAuthTokenProps.property.expiration">expiration</a></code> | <code>string</code> | Expiration time for the token (e.g., `"2w"`, `"1d30m"`). |
|
|
293
|
+
|
|
294
|
+
---
|
|
295
|
+
|
|
296
|
+
##### `database`<sup>Required</sup> <a name="database" id="cdk-turso.TursoAuthTokenProps.property.database"></a>
|
|
297
|
+
|
|
298
|
+
```typescript
|
|
299
|
+
public readonly database: TursoDatabase;
|
|
300
|
+
```
|
|
301
|
+
|
|
302
|
+
- *Type:* <a href="#cdk-turso.TursoDatabase">TursoDatabase</a>
|
|
303
|
+
|
|
304
|
+
The Turso database to create an auth token for.
|
|
305
|
+
|
|
306
|
+
---
|
|
307
|
+
|
|
308
|
+
##### `parameterName`<sup>Required</sup> <a name="parameterName" id="cdk-turso.TursoAuthTokenProps.property.parameterName"></a>
|
|
309
|
+
|
|
310
|
+
```typescript
|
|
311
|
+
public readonly parameterName: string;
|
|
312
|
+
```
|
|
313
|
+
|
|
314
|
+
- *Type:* string
|
|
315
|
+
|
|
316
|
+
The SSM parameter name where the generated JWT will be stored as a SecureString.
|
|
317
|
+
|
|
318
|
+
---
|
|
319
|
+
|
|
320
|
+
##### `authorization`<sup>Optional</sup> <a name="authorization" id="cdk-turso.TursoAuthTokenProps.property.authorization"></a>
|
|
321
|
+
|
|
322
|
+
```typescript
|
|
323
|
+
public readonly authorization: string;
|
|
324
|
+
```
|
|
325
|
+
|
|
326
|
+
- *Type:* string
|
|
327
|
+
- *Default:* "full-access"
|
|
328
|
+
|
|
329
|
+
Authorization level for the token.
|
|
330
|
+
|
|
331
|
+
---
|
|
332
|
+
|
|
333
|
+
##### `expiration`<sup>Optional</sup> <a name="expiration" id="cdk-turso.TursoAuthTokenProps.property.expiration"></a>
|
|
334
|
+
|
|
335
|
+
```typescript
|
|
336
|
+
public readonly expiration: string;
|
|
337
|
+
```
|
|
338
|
+
|
|
339
|
+
- *Type:* string
|
|
340
|
+
- *Default:* "never"
|
|
341
|
+
|
|
342
|
+
Expiration time for the token (e.g., `"2w"`, `"1d30m"`).
|
|
343
|
+
|
|
344
|
+
---
|
|
345
|
+
|
|
141
346
|
### TursoDatabaseEncryption <a name="TursoDatabaseEncryption" id="cdk-turso.TursoDatabaseEncryption"></a>
|
|
142
347
|
|
|
143
348
|
#### Initializer <a name="Initializer" id="cdk-turso.TursoDatabaseEncryption.Initializer"></a>
|
package/README.md
CHANGED
|
@@ -36,6 +36,24 @@ database.hostname; // Database hostname
|
|
|
36
36
|
database.databaseName; // Database name
|
|
37
37
|
```
|
|
38
38
|
|
|
39
|
+
### Auth Token
|
|
40
|
+
|
|
41
|
+
Generate a database auth token and store it as a SecureString in SSM Parameter Store:
|
|
42
|
+
|
|
43
|
+
```typescript
|
|
44
|
+
import { TursoAuthToken } from 'cdk-turso';
|
|
45
|
+
|
|
46
|
+
const authToken = new TursoAuthToken(stack, 'AuthToken', {
|
|
47
|
+
database,
|
|
48
|
+
parameterName: '/turso/db-token',
|
|
49
|
+
expiration: '2w', // optional, default: 'never'
|
|
50
|
+
authorization: 'read-only', // optional, default: 'full-access'
|
|
51
|
+
});
|
|
52
|
+
|
|
53
|
+
// The SSM parameter name where the JWT is stored
|
|
54
|
+
authToken.parameterName;
|
|
55
|
+
```
|
|
56
|
+
|
|
39
57
|
## API
|
|
40
58
|
|
|
41
59
|
### TursoDatabaseProps
|
|
@@ -76,6 +94,23 @@ interface TursoDatabaseEncryption {
|
|
|
76
94
|
| `dbId` | `string` | Turso database ID |
|
|
77
95
|
| `hostname` | `string` | DNS hostname (e.g., `my-db-my-org.turso.io`) for libSQL/HTTP connections |
|
|
78
96
|
| `databaseName` | `string` | Database name |
|
|
97
|
+
| `organizationSlug` | `string` | Organization slug |
|
|
98
|
+
| `apiToken` | `ssm.IParameter` | SSM Parameter containing the Turso API token |
|
|
99
|
+
|
|
100
|
+
### TursoAuthTokenProps
|
|
101
|
+
|
|
102
|
+
| Prop | Type | Required | Description |
|
|
103
|
+
|------|------|----------|-------------|
|
|
104
|
+
| `database` | `TursoDatabase` | Yes | The Turso database to create an auth token for |
|
|
105
|
+
| `parameterName` | `string` | Yes | SSM parameter name where the generated JWT will be stored as a SecureString |
|
|
106
|
+
| `expiration` | `string` | No | Token expiry (e.g., `'2w'`, `'1d30m'`). Default: `'never'` |
|
|
107
|
+
| `authorization` | `string` | No | `'full-access'` or `'read-only'`. Default: `'full-access'` |
|
|
108
|
+
|
|
109
|
+
### TursoAuthToken
|
|
110
|
+
|
|
111
|
+
| Attribute | Type | Description |
|
|
112
|
+
|-----------|------|-------------|
|
|
113
|
+
| `parameterName` | `string` | The SSM parameter name where the auth token is stored |
|
|
79
114
|
|
|
80
115
|
## Requirements
|
|
81
116
|
|