cdk-turso 0.2.0 → 0.3.1
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 +1480 -146
- package/AGENTS.md +7 -4
- package/API.md +254 -32
- package/README.md +38 -16
- package/lib/handler/index.d.ts +4 -21
- package/lib/handler/index.js +107 -20
- package/lib/index.d.ts +1 -0
- package/lib/index.js +4 -2
- package/lib/turso-auth-token.d.ts +8 -3
- package/lib/turso-auth-token.js +7 -22
- package/lib/turso-database.d.ts +2 -4
- package/lib/turso-database.js +4 -21
- package/lib/turso-provider.d.ts +34 -0
- package/lib/turso-provider.js +40 -0
- package/package.json +7 -7
- package/lib/handler-auth-token/index.d.ts +0 -15
- package/lib/handler-auth-token/index.js +0 -708
package/lib/handler/index.js
CHANGED
|
@@ -591,7 +591,7 @@ var retryOptions = {
|
|
|
591
591
|
numOfAttempts: 4,
|
|
592
592
|
jitter: "none"
|
|
593
593
|
};
|
|
594
|
-
async function fetchWithRetry(url, options, errorMessage, allow404) {
|
|
594
|
+
async function fetchWithRetry(url, options, errorMessage, allow404 = false) {
|
|
595
595
|
return (0, import_exponential_backoff.backOff)(async () => {
|
|
596
596
|
const response = await fetch(url, options);
|
|
597
597
|
if (!response.ok && !(allow404 && response.status === 404)) {
|
|
@@ -612,20 +612,8 @@ async function getApiToken(parameterName) {
|
|
|
612
612
|
}
|
|
613
613
|
return response.Parameter.Value;
|
|
614
614
|
}
|
|
615
|
-
async function
|
|
616
|
-
const {
|
|
617
|
-
RequestType,
|
|
618
|
-
PhysicalResourceId,
|
|
619
|
-
ResourceProperties,
|
|
620
|
-
OldResourceProperties
|
|
621
|
-
} = event;
|
|
622
|
-
const parameterName = process.env.TURSO_API_TOKEN_PARAMETER_NAME;
|
|
623
|
-
if (!parameterName) {
|
|
624
|
-
throw new Error(
|
|
625
|
-
"TURSO_API_TOKEN_PARAMETER_NAME environment variable not set"
|
|
626
|
-
);
|
|
627
|
-
}
|
|
628
|
-
const apiToken = await getApiToken(parameterName);
|
|
615
|
+
async function handleDatabase(event, apiToken) {
|
|
616
|
+
const { RequestType, PhysicalResourceId, ResourceProperties } = event;
|
|
629
617
|
const orgSlug = encodeURIComponent(ResourceProperties.OrganizationSlug);
|
|
630
618
|
const baseUrl = "https://api.turso.tech/v1";
|
|
631
619
|
if (RequestType === "Create") {
|
|
@@ -653,8 +641,7 @@ async function handler(event) {
|
|
|
653
641
|
},
|
|
654
642
|
body: JSON.stringify(body)
|
|
655
643
|
},
|
|
656
|
-
"Failed to create database"
|
|
657
|
-
false
|
|
644
|
+
"Failed to create database"
|
|
658
645
|
);
|
|
659
646
|
const data = await response.json();
|
|
660
647
|
return {
|
|
@@ -667,7 +654,7 @@ async function handler(event) {
|
|
|
667
654
|
};
|
|
668
655
|
}
|
|
669
656
|
if (RequestType === "Update") {
|
|
670
|
-
const oldDbName = OldResourceProperties?.DatabaseName;
|
|
657
|
+
const oldDbName = event.OldResourceProperties?.DatabaseName;
|
|
671
658
|
const newDbName = ResourceProperties.DatabaseName;
|
|
672
659
|
if (oldDbName && oldDbName !== newDbName) {
|
|
673
660
|
const body = {
|
|
@@ -684,8 +671,7 @@ async function handler(event) {
|
|
|
684
671
|
},
|
|
685
672
|
body: JSON.stringify(body)
|
|
686
673
|
},
|
|
687
|
-
"Failed to create database"
|
|
688
|
-
false
|
|
674
|
+
"Failed to create database"
|
|
689
675
|
);
|
|
690
676
|
const data = await response.json();
|
|
691
677
|
return {
|
|
@@ -724,6 +710,107 @@ async function handler(event) {
|
|
|
724
710
|
}
|
|
725
711
|
throw new Error(`Unknown request type: ${RequestType}`);
|
|
726
712
|
}
|
|
713
|
+
async function createToken(baseUrl, orgSlug, dbName, apiToken, expiration, authorization) {
|
|
714
|
+
const params = new URLSearchParams();
|
|
715
|
+
params.set("expiration", expiration);
|
|
716
|
+
params.set("authorization", authorization);
|
|
717
|
+
const response = await fetchWithRetry(
|
|
718
|
+
`${baseUrl}/organizations/${orgSlug}/databases/${dbName}/auth/tokens?${params.toString()}`,
|
|
719
|
+
{
|
|
720
|
+
method: "POST",
|
|
721
|
+
headers: {
|
|
722
|
+
Authorization: `Bearer ${apiToken}`
|
|
723
|
+
}
|
|
724
|
+
},
|
|
725
|
+
"Failed to create auth token"
|
|
726
|
+
);
|
|
727
|
+
const data = await response.json();
|
|
728
|
+
return data.jwt;
|
|
729
|
+
}
|
|
730
|
+
async function storeToken(parameterName, token) {
|
|
731
|
+
const command = new import_client_ssm.PutParameterCommand({
|
|
732
|
+
Name: parameterName,
|
|
733
|
+
Value: token,
|
|
734
|
+
Type: "SecureString",
|
|
735
|
+
Overwrite: true
|
|
736
|
+
});
|
|
737
|
+
await ssmClient.send(command);
|
|
738
|
+
}
|
|
739
|
+
async function deleteParameter(parameterName) {
|
|
740
|
+
try {
|
|
741
|
+
const command = new import_client_ssm.DeleteParameterCommand({
|
|
742
|
+
Name: parameterName
|
|
743
|
+
});
|
|
744
|
+
await ssmClient.send(command);
|
|
745
|
+
} catch (error) {
|
|
746
|
+
if (error instanceof Error && error.name === "ParameterNotFound") {
|
|
747
|
+
return;
|
|
748
|
+
}
|
|
749
|
+
throw error;
|
|
750
|
+
}
|
|
751
|
+
}
|
|
752
|
+
async function handleAuthToken(event, apiToken) {
|
|
753
|
+
const { RequestType, PhysicalResourceId, ResourceProperties } = event;
|
|
754
|
+
const orgSlug = encodeURIComponent(ResourceProperties.OrganizationSlug);
|
|
755
|
+
const dbName = encodeURIComponent(ResourceProperties.DatabaseName);
|
|
756
|
+
const baseUrl = "https://api.turso.tech/v1";
|
|
757
|
+
const parameterName = ResourceProperties.ParameterName;
|
|
758
|
+
const expiration = ResourceProperties.Expiration || "never";
|
|
759
|
+
const authorization = ResourceProperties.Authorization || "full-access";
|
|
760
|
+
if (RequestType === "Create") {
|
|
761
|
+
const jwt = await createToken(
|
|
762
|
+
baseUrl,
|
|
763
|
+
orgSlug,
|
|
764
|
+
dbName,
|
|
765
|
+
apiToken,
|
|
766
|
+
expiration,
|
|
767
|
+
authorization
|
|
768
|
+
);
|
|
769
|
+
await storeToken(parameterName, jwt);
|
|
770
|
+
return { PhysicalResourceId: parameterName };
|
|
771
|
+
}
|
|
772
|
+
if (RequestType === "Update") {
|
|
773
|
+
const jwt = await createToken(
|
|
774
|
+
baseUrl,
|
|
775
|
+
orgSlug,
|
|
776
|
+
dbName,
|
|
777
|
+
apiToken,
|
|
778
|
+
expiration,
|
|
779
|
+
authorization
|
|
780
|
+
);
|
|
781
|
+
await storeToken(parameterName, jwt);
|
|
782
|
+
return { PhysicalResourceId: parameterName };
|
|
783
|
+
}
|
|
784
|
+
if (RequestType === "Delete") {
|
|
785
|
+
if (!PhysicalResourceId) {
|
|
786
|
+
return { PhysicalResourceId: "unknown" };
|
|
787
|
+
}
|
|
788
|
+
if (PhysicalResourceId === "unknown" || PhysicalResourceId.startsWith("failed-")) {
|
|
789
|
+
return { PhysicalResourceId };
|
|
790
|
+
}
|
|
791
|
+
await deleteParameter(PhysicalResourceId);
|
|
792
|
+
return { PhysicalResourceId };
|
|
793
|
+
}
|
|
794
|
+
throw new Error(`Unknown request type: ${RequestType}`);
|
|
795
|
+
}
|
|
796
|
+
async function handler(event) {
|
|
797
|
+
const parameterName = process.env.TURSO_API_TOKEN_PARAMETER_NAME;
|
|
798
|
+
if (!parameterName) {
|
|
799
|
+
throw new Error(
|
|
800
|
+
"TURSO_API_TOKEN_PARAMETER_NAME environment variable not set"
|
|
801
|
+
);
|
|
802
|
+
}
|
|
803
|
+
const apiToken = await getApiToken(parameterName);
|
|
804
|
+
const resourceType = event.ResourceProperties.ResourceType;
|
|
805
|
+
switch (resourceType) {
|
|
806
|
+
case "Database":
|
|
807
|
+
return handleDatabase(event, apiToken);
|
|
808
|
+
case "AuthToken":
|
|
809
|
+
return handleAuthToken(event, apiToken);
|
|
810
|
+
default:
|
|
811
|
+
throw new Error(`Unknown resource type: ${resourceType}`);
|
|
812
|
+
}
|
|
813
|
+
}
|
|
727
814
|
// Annotate the CommonJS export names for ESM import in node:
|
|
728
815
|
0 && (module.exports = {
|
|
729
816
|
handler
|
package/lib/index.d.ts
CHANGED
package/lib/index.js
CHANGED
|
@@ -1,8 +1,10 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.TursoDatabase = exports.TursoAuthToken = void 0;
|
|
3
|
+
exports.TursoProvider = exports.TursoDatabase = exports.TursoAuthToken = void 0;
|
|
4
4
|
var turso_auth_token_1 = require("./turso-auth-token");
|
|
5
5
|
Object.defineProperty(exports, "TursoAuthToken", { enumerable: true, get: function () { return turso_auth_token_1.TursoAuthToken; } });
|
|
6
6
|
var turso_database_1 = require("./turso-database");
|
|
7
7
|
Object.defineProperty(exports, "TursoDatabase", { enumerable: true, get: function () { return turso_database_1.TursoDatabase; } });
|
|
8
|
-
|
|
8
|
+
var turso_provider_1 = require("./turso-provider");
|
|
9
|
+
Object.defineProperty(exports, "TursoProvider", { enumerable: true, get: function () { return turso_provider_1.TursoProvider; } });
|
|
10
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiaW5kZXguanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi9zcmMvaW5kZXgudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6Ijs7O0FBQUEsdURBQXdFO0FBQS9ELGtIQUFBLGNBQWMsT0FBQTtBQUN2QixtREFLeUI7QUFKdkIsK0dBQUEsYUFBYSxPQUFBO0FBS2YsbURBQW9FO0FBQTNELCtHQUFBLGFBQWEsT0FBQSIsInNvdXJjZXNDb250ZW50IjpbImV4cG9ydCB7IFR1cnNvQXV0aFRva2VuLCBUdXJzb0F1dGhUb2tlblByb3BzIH0gZnJvbSBcIi4vdHVyc28tYXV0aC10b2tlblwiXG5leHBvcnQge1xuICBUdXJzb0RhdGFiYXNlLFxuICBUdXJzb0RhdGFiYXNlRW5jcnlwdGlvbixcbiAgVHVyc29EYXRhYmFzZVByb3BzLFxuICBUdXJzb0RhdGFiYXNlU2VlZCxcbn0gZnJvbSBcIi4vdHVyc28tZGF0YWJhc2VcIlxuZXhwb3J0IHsgVHVyc29Qcm92aWRlciwgVHVyc29Qcm92aWRlclByb3BzIH0gZnJvbSBcIi4vdHVyc28tcHJvdmlkZXJcIlxuIl19
|
|
@@ -1,10 +1,15 @@
|
|
|
1
1
|
import { Construct } from "constructs";
|
|
2
|
-
import type {
|
|
2
|
+
import type { TursoProvider } from "./turso-provider";
|
|
3
3
|
export interface TursoAuthTokenProps {
|
|
4
|
+
readonly provider: TursoProvider;
|
|
4
5
|
/**
|
|
5
|
-
* The Turso database to create an auth token for.
|
|
6
|
+
* The name of the Turso database to create an auth token for.
|
|
6
7
|
*/
|
|
7
|
-
readonly
|
|
8
|
+
readonly databaseName: string;
|
|
9
|
+
/**
|
|
10
|
+
* The Turso organization slug that owns the database.
|
|
11
|
+
*/
|
|
12
|
+
readonly organizationSlug: string;
|
|
8
13
|
/**
|
|
9
14
|
* The SSM parameter name where the generated JWT will be stored
|
|
10
15
|
* as a SecureString.
|
package/lib/turso-auth-token.js
CHANGED
|
@@ -5,10 +5,7 @@ exports.TursoAuthToken = void 0;
|
|
|
5
5
|
const JSII_RTTI_SYMBOL_1 = Symbol.for("jsii.rtti");
|
|
6
6
|
const aws_cdk_lib_1 = require("aws-cdk-lib");
|
|
7
7
|
const aws_iam_1 = require("aws-cdk-lib/aws-iam");
|
|
8
|
-
const aws_lambda_1 = require("aws-cdk-lib/aws-lambda");
|
|
9
|
-
const custom_resources_1 = require("aws-cdk-lib/custom-resources");
|
|
10
8
|
const constructs_1 = require("constructs");
|
|
11
|
-
const path = require("path");
|
|
12
9
|
class TursoAuthToken extends constructs_1.Construct {
|
|
13
10
|
constructor(scope, id, props) {
|
|
14
11
|
super(scope, id);
|
|
@@ -17,16 +14,6 @@ class TursoAuthToken extends constructs_1.Construct {
|
|
|
17
14
|
props.authorization !== "read-only") {
|
|
18
15
|
throw new Error('authorization must be "full-access" or "read-only"');
|
|
19
16
|
}
|
|
20
|
-
const handler = new aws_lambda_1.Function(this, "Handler", {
|
|
21
|
-
runtime: new aws_lambda_1.Runtime("nodejs24.x", aws_lambda_1.RuntimeFamily.NODEJS),
|
|
22
|
-
handler: "index.handler",
|
|
23
|
-
code: aws_lambda_1.Code.fromAsset(path.join(__dirname, "handler-auth-token")),
|
|
24
|
-
timeout: aws_cdk_lib_1.Duration.minutes(3),
|
|
25
|
-
environment: {
|
|
26
|
-
TURSO_API_TOKEN_PARAMETER_NAME: props.database.apiToken.parameterName,
|
|
27
|
-
},
|
|
28
|
-
});
|
|
29
|
-
props.database.apiToken.grantRead(handler);
|
|
30
17
|
const parameterArn = aws_cdk_lib_1.Stack.of(this).formatArn({
|
|
31
18
|
service: "ssm",
|
|
32
19
|
resource: "parameter",
|
|
@@ -34,17 +21,15 @@ class TursoAuthToken extends constructs_1.Construct {
|
|
|
34
21
|
? props.parameterName.slice(1)
|
|
35
22
|
: props.parameterName,
|
|
36
23
|
});
|
|
37
|
-
handler.addToRolePolicy(new aws_iam_1.PolicyStatement({
|
|
24
|
+
props.provider.handler.addToRolePolicy(new aws_iam_1.PolicyStatement({
|
|
38
25
|
effect: aws_iam_1.Effect.ALLOW,
|
|
39
26
|
actions: ["ssm:PutParameter", "ssm:DeleteParameter"],
|
|
40
27
|
resources: [parameterArn],
|
|
41
28
|
}));
|
|
42
|
-
const provider = new custom_resources_1.Provider(this, "Provider", {
|
|
43
|
-
onEventHandler: handler,
|
|
44
|
-
});
|
|
45
29
|
const resourceProps = {
|
|
46
|
-
|
|
47
|
-
|
|
30
|
+
ResourceType: "AuthToken",
|
|
31
|
+
DatabaseName: props.databaseName,
|
|
32
|
+
OrganizationSlug: props.organizationSlug,
|
|
48
33
|
ParameterName: props.parameterName,
|
|
49
34
|
};
|
|
50
35
|
if (props.expiration) {
|
|
@@ -54,7 +39,7 @@ class TursoAuthToken extends constructs_1.Construct {
|
|
|
54
39
|
resourceProps.Authorization = props.authorization;
|
|
55
40
|
}
|
|
56
41
|
new aws_cdk_lib_1.CustomResource(this, "TursoAuthToken", {
|
|
57
|
-
serviceToken: provider.serviceToken,
|
|
42
|
+
serviceToken: props.provider.serviceToken,
|
|
58
43
|
properties: resourceProps,
|
|
59
44
|
});
|
|
60
45
|
this.parameterName = props.parameterName;
|
|
@@ -62,5 +47,5 @@ class TursoAuthToken extends constructs_1.Construct {
|
|
|
62
47
|
}
|
|
63
48
|
exports.TursoAuthToken = TursoAuthToken;
|
|
64
49
|
_a = JSII_RTTI_SYMBOL_1;
|
|
65
|
-
TursoAuthToken[_a] = { fqn: "cdk-turso.TursoAuthToken", version: "0.
|
|
66
|
-
//# sourceMappingURL=data:application/json;base64,
|
|
50
|
+
TursoAuthToken[_a] = { fqn: "cdk-turso.TursoAuthToken", version: "0.3.1" };
|
|
51
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidHVyc28tYXV0aC10b2tlbi5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uL3NyYy90dXJzby1hdXRoLXRva2VuLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7Ozs7O0FBQUEsNkNBQW1EO0FBQ25ELGlEQUE2RDtBQUM3RCwyQ0FBc0M7QUFxQ3RDLE1BQWEsY0FBZSxTQUFRLHNCQUFTO0lBTTNDLFlBQVksS0FBZ0IsRUFBRSxFQUFVLEVBQUUsS0FBMEI7UUFDbEUsS0FBSyxDQUFDLEtBQUssRUFBRSxFQUFFLENBQUMsQ0FBQTtRQUVoQixJQUNFLEtBQUssQ0FBQyxhQUFhO1lBQ25CLEtBQUssQ0FBQyxhQUFhLEtBQUssYUFBYTtZQUNyQyxLQUFLLENBQUMsYUFBYSxLQUFLLFdBQVcsRUFDbkMsQ0FBQztZQUNELE1BQU0sSUFBSSxLQUFLLENBQUMsb0RBQW9ELENBQUMsQ0FBQTtRQUN2RSxDQUFDO1FBRUQsTUFBTSxZQUFZLEdBQUcsbUJBQUssQ0FBQyxFQUFFLENBQUMsSUFBSSxDQUFDLENBQUMsU0FBUyxDQUFDO1lBQzVDLE9BQU8sRUFBRSxLQUFLO1lBQ2QsUUFBUSxFQUFFLFdBQVc7WUFDckIsWUFBWSxFQUFFLEtBQUssQ0FBQyxhQUFhLENBQUMsVUFBVSxDQUFDLEdBQUcsQ0FBQztnQkFDL0MsQ0FBQyxDQUFDLEtBQUssQ0FBQyxhQUFhLENBQUMsS0FBSyxDQUFDLENBQUMsQ0FBQztnQkFDOUIsQ0FBQyxDQUFDLEtBQUssQ0FBQyxhQUFhO1NBQ3hCLENBQUMsQ0FBQTtRQUVGLEtBQUssQ0FBQyxRQUFRLENBQUMsT0FBTyxDQUFDLGVBQWUsQ0FDcEMsSUFBSSx5QkFBZSxDQUFDO1lBQ2xCLE1BQU0sRUFBRSxnQkFBTSxDQUFDLEtBQUs7WUFDcEIsT0FBTyxFQUFFLENBQUMsa0JBQWtCLEVBQUUscUJBQXFCLENBQUM7WUFDcEQsU0FBUyxFQUFFLENBQUMsWUFBWSxDQUFDO1NBQzFCLENBQUMsQ0FDSCxDQUFBO1FBRUQsTUFBTSxhQUFhLEdBQTRCO1lBQzdDLFlBQVksRUFBRSxXQUFXO1lBQ3pCLFlBQVksRUFBRSxLQUFLLENBQUMsWUFBWTtZQUNoQyxnQkFBZ0IsRUFBRSxLQUFLLENBQUMsZ0JBQWdCO1lBQ3hDLGFBQWEsRUFBRSxLQUFLLENBQUMsYUFBYTtTQUNuQyxDQUFBO1FBRUQsSUFBSSxLQUFLLENBQUMsVUFBVSxFQUFFLENBQUM7WUFDckIsYUFBYSxDQUFDLFVBQVUsR0FBRyxLQUFLLENBQUMsVUFBVSxDQUFBO1FBQzdDLENBQUM7UUFDRCxJQUFJLEtBQUssQ0FBQyxhQUFhLEVBQUUsQ0FBQztZQUN4QixhQUFhLENBQUMsYUFBYSxHQUFHLEtBQUssQ0FBQyxhQUFhLENBQUE7UUFDbkQsQ0FBQztRQUVELElBQUksNEJBQWMsQ0FBQyxJQUFJLEVBQUUsZ0JBQWdCLEVBQUU7WUFDekMsWUFBWSxFQUFFLEtBQUssQ0FBQyxRQUFRLENBQUMsWUFBWTtZQUN6QyxVQUFVLEVBQUUsYUFBYTtTQUMxQixDQUFDLENBQUE7UUFFRixJQUFJLENBQUMsYUFBYSxHQUFHLEtBQUssQ0FBQyxhQUFhLENBQUE7SUFDMUMsQ0FBQzs7QUFyREgsd0NBc0RDIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHsgQ3VzdG9tUmVzb3VyY2UsIFN0YWNrIH0gZnJvbSBcImF3cy1jZGstbGliXCJcbmltcG9ydCB7IEVmZmVjdCwgUG9saWN5U3RhdGVtZW50IH0gZnJvbSBcImF3cy1jZGstbGliL2F3cy1pYW1cIlxuaW1wb3J0IHsgQ29uc3RydWN0IH0gZnJvbSBcImNvbnN0cnVjdHNcIlxuaW1wb3J0IHR5cGUgeyBUdXJzb1Byb3ZpZGVyIH0gZnJvbSBcIi4vdHVyc28tcHJvdmlkZXJcIlxuXG5leHBvcnQgaW50ZXJmYWNlIFR1cnNvQXV0aFRva2VuUHJvcHMge1xuICByZWFkb25seSBwcm92aWRlcjogVHVyc29Qcm92aWRlclxuXG4gIC8qKlxuICAgKiBUaGUgbmFtZSBvZiB0aGUgVHVyc28gZGF0YWJhc2UgdG8gY3JlYXRlIGFuIGF1dGggdG9rZW4gZm9yLlxuICAgKi9cbiAgcmVhZG9ubHkgZGF0YWJhc2VOYW1lOiBzdHJpbmdcblxuICAvKipcbiAgICogVGhlIFR1cnNvIG9yZ2FuaXphdGlvbiBzbHVnIHRoYXQgb3ducyB0aGUgZGF0YWJhc2UuXG4gICAqL1xuICByZWFkb25seSBvcmdhbml6YXRpb25TbHVnOiBzdHJpbmdcblxuICAvKipcbiAgICogVGhlIFNTTSBwYXJhbWV0ZXIgbmFtZSB3aGVyZSB0aGUgZ2VuZXJhdGVkIEpXVCB3aWxsIGJlIHN0b3JlZFxuICAgKiBhcyBhIFNlY3VyZVN0cmluZy5cbiAgICovXG4gIHJlYWRvbmx5IHBhcmFtZXRlck5hbWU6IHN0cmluZ1xuXG4gIC8qKlxuICAgKiBFeHBpcmF0aW9uIHRpbWUgZm9yIHRoZSB0b2tlbiAoZS5nLiwgYFwiMndcImAsIGBcIjFkMzBtXCJgKS5cbiAgICpcbiAgICogQGRlZmF1bHQgXCJuZXZlclwiXG4gICAqL1xuICByZWFkb25seSBleHBpcmF0aW9uPzogc3RyaW5nXG5cbiAgLyoqXG4gICAqIEF1dGhvcml6YXRpb24gbGV2ZWwgZm9yIHRoZSB0b2tlbi5cbiAgICpcbiAgICogQGRlZmF1bHQgXCJmdWxsLWFjY2Vzc1wiXG4gICAqL1xuICByZWFkb25seSBhdXRob3JpemF0aW9uPzogc3RyaW5nXG59XG5cbmV4cG9ydCBjbGFzcyBUdXJzb0F1dGhUb2tlbiBleHRlbmRzIENvbnN0cnVjdCB7XG4gIC8qKlxuICAgKiBUaGUgU1NNIHBhcmFtZXRlciBuYW1lIHdoZXJlIHRoZSBhdXRoIHRva2VuIGlzIHN0b3JlZC5cbiAgICovXG4gIHB1YmxpYyByZWFkb25seSBwYXJhbWV0ZXJOYW1lOiBzdHJpbmdcblxuICBjb25zdHJ1Y3RvcihzY29wZTogQ29uc3RydWN0LCBpZDogc3RyaW5nLCBwcm9wczogVHVyc29BdXRoVG9rZW5Qcm9wcykge1xuICAgIHN1cGVyKHNjb3BlLCBpZClcblxuICAgIGlmIChcbiAgICAgIHByb3BzLmF1dGhvcml6YXRpb24gJiZcbiAgICAgIHByb3BzLmF1dGhvcml6YXRpb24gIT09IFwiZnVsbC1hY2Nlc3NcIiAmJlxuICAgICAgcHJvcHMuYXV0aG9yaXphdGlvbiAhPT0gXCJyZWFkLW9ubHlcIlxuICAgICkge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKCdhdXRob3JpemF0aW9uIG11c3QgYmUgXCJmdWxsLWFjY2Vzc1wiIG9yIFwicmVhZC1vbmx5XCInKVxuICAgIH1cblxuICAgIGNvbnN0IHBhcmFtZXRlckFybiA9IFN0YWNrLm9mKHRoaXMpLmZvcm1hdEFybih7XG4gICAgICBzZXJ2aWNlOiBcInNzbVwiLFxuICAgICAgcmVzb3VyY2U6IFwicGFyYW1ldGVyXCIsXG4gICAgICByZXNvdXJjZU5hbWU6IHByb3BzLnBhcmFtZXRlck5hbWUuc3RhcnRzV2l0aChcIi9cIilcbiAgICAgICAgPyBwcm9wcy5wYXJhbWV0ZXJOYW1lLnNsaWNlKDEpXG4gICAgICAgIDogcHJvcHMucGFyYW1ldGVyTmFtZSxcbiAgICB9KVxuXG4gICAgcHJvcHMucHJvdmlkZXIuaGFuZGxlci5hZGRUb1JvbGVQb2xpY3koXG4gICAgICBuZXcgUG9saWN5U3RhdGVtZW50KHtcbiAgICAgICAgZWZmZWN0OiBFZmZlY3QuQUxMT1csXG4gICAgICAgIGFjdGlvbnM6IFtcInNzbTpQdXRQYXJhbWV0ZXJcIiwgXCJzc206RGVsZXRlUGFyYW1ldGVyXCJdLFxuICAgICAgICByZXNvdXJjZXM6IFtwYXJhbWV0ZXJBcm5dLFxuICAgICAgfSksXG4gICAgKVxuXG4gICAgY29uc3QgcmVzb3VyY2VQcm9wczogUmVjb3JkPHN0cmluZywgdW5rbm93bj4gPSB7XG4gICAgICBSZXNvdXJjZVR5cGU6IFwiQXV0aFRva2VuXCIsXG4gICAgICBEYXRhYmFzZU5hbWU6IHByb3BzLmRhdGFiYXNlTmFtZSxcbiAgICAgIE9yZ2FuaXphdGlvblNsdWc6IHByb3BzLm9yZ2FuaXphdGlvblNsdWcsXG4gICAgICBQYXJhbWV0ZXJOYW1lOiBwcm9wcy5wYXJhbWV0ZXJOYW1lLFxuICAgIH1cblxuICAgIGlmIChwcm9wcy5leHBpcmF0aW9uKSB7XG4gICAgICByZXNvdXJjZVByb3BzLkV4cGlyYXRpb24gPSBwcm9wcy5leHBpcmF0aW9uXG4gICAgfVxuICAgIGlmIChwcm9wcy5hdXRob3JpemF0aW9uKSB7XG4gICAgICByZXNvdXJjZVByb3BzLkF1dGhvcml6YXRpb24gPSBwcm9wcy5hdXRob3JpemF0aW9uXG4gICAgfVxuXG4gICAgbmV3IEN1c3RvbVJlc291cmNlKHRoaXMsIFwiVHVyc29BdXRoVG9rZW5cIiwge1xuICAgICAgc2VydmljZVRva2VuOiBwcm9wcy5wcm92aWRlci5zZXJ2aWNlVG9rZW4sXG4gICAgICBwcm9wZXJ0aWVzOiByZXNvdXJjZVByb3BzLFxuICAgIH0pXG5cbiAgICB0aGlzLnBhcmFtZXRlck5hbWUgPSBwcm9wcy5wYXJhbWV0ZXJOYW1lXG4gIH1cbn1cbiJdfQ==
|
package/lib/turso-database.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import type { IParameter } from "aws-cdk-lib/aws-ssm";
|
|
2
1
|
import { Construct } from "constructs";
|
|
2
|
+
import type { TursoProvider } from "./turso-provider";
|
|
3
3
|
export interface TursoDatabaseSeed {
|
|
4
4
|
readonly type: string;
|
|
5
5
|
readonly name: string;
|
|
@@ -10,10 +10,10 @@ export interface TursoDatabaseEncryption {
|
|
|
10
10
|
readonly encryptionCipher: string;
|
|
11
11
|
}
|
|
12
12
|
export interface TursoDatabaseProps {
|
|
13
|
+
readonly provider: TursoProvider;
|
|
13
14
|
readonly databaseName: string;
|
|
14
15
|
readonly group: string;
|
|
15
16
|
readonly organizationSlug: string;
|
|
16
|
-
readonly apiToken: IParameter;
|
|
17
17
|
readonly sizeLimit?: string;
|
|
18
18
|
readonly seed?: TursoDatabaseSeed;
|
|
19
19
|
readonly encryption?: TursoDatabaseEncryption;
|
|
@@ -26,7 +26,5 @@ export declare class TursoDatabase extends Construct {
|
|
|
26
26
|
*/
|
|
27
27
|
readonly hostname: string;
|
|
28
28
|
readonly databaseName: string;
|
|
29
|
-
readonly organizationSlug: string;
|
|
30
|
-
readonly apiToken: IParameter;
|
|
31
29
|
constructor(scope: Construct, id: string, props: TursoDatabaseProps);
|
|
32
30
|
}
|
package/lib/turso-database.js
CHANGED
|
@@ -4,35 +4,18 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
4
4
|
exports.TursoDatabase = void 0;
|
|
5
5
|
const JSII_RTTI_SYMBOL_1 = Symbol.for("jsii.rtti");
|
|
6
6
|
const aws_cdk_lib_1 = require("aws-cdk-lib");
|
|
7
|
-
const aws_lambda_1 = require("aws-cdk-lib/aws-lambda");
|
|
8
|
-
const custom_resources_1 = require("aws-cdk-lib/custom-resources");
|
|
9
7
|
const constructs_1 = require("constructs");
|
|
10
|
-
const path = require("path");
|
|
11
8
|
class TursoDatabase extends constructs_1.Construct {
|
|
12
9
|
constructor(scope, id, props) {
|
|
13
10
|
super(scope, id);
|
|
14
|
-
this.organizationSlug = props.organizationSlug;
|
|
15
|
-
this.apiToken = props.apiToken;
|
|
16
11
|
if (!/^[a-z0-9-]+$/.test(props.databaseName)) {
|
|
17
12
|
throw new Error("databaseName must contain only lowercase letters, numbers, and dashes");
|
|
18
13
|
}
|
|
19
14
|
if (props.databaseName.length > 64) {
|
|
20
15
|
throw new Error("databaseName must be at most 64 characters");
|
|
21
16
|
}
|
|
22
|
-
const handler = new aws_lambda_1.Function(this, "Handler", {
|
|
23
|
-
runtime: new aws_lambda_1.Runtime("nodejs24.x", aws_lambda_1.RuntimeFamily.NODEJS),
|
|
24
|
-
handler: "index.handler",
|
|
25
|
-
code: aws_lambda_1.Code.fromAsset(path.join(__dirname, "handler")),
|
|
26
|
-
timeout: aws_cdk_lib_1.Duration.minutes(3),
|
|
27
|
-
environment: {
|
|
28
|
-
TURSO_API_TOKEN_PARAMETER_NAME: props.apiToken.parameterName,
|
|
29
|
-
},
|
|
30
|
-
});
|
|
31
|
-
props.apiToken.grantRead(handler);
|
|
32
|
-
const provider = new custom_resources_1.Provider(this, "Provider", {
|
|
33
|
-
onEventHandler: handler,
|
|
34
|
-
});
|
|
35
17
|
const resourceProps = {
|
|
18
|
+
ResourceType: "Database",
|
|
36
19
|
DatabaseName: props.databaseName,
|
|
37
20
|
Group: props.group,
|
|
38
21
|
OrganizationSlug: props.organizationSlug,
|
|
@@ -47,7 +30,7 @@ class TursoDatabase extends constructs_1.Construct {
|
|
|
47
30
|
resourceProps.Encryption = props.encryption;
|
|
48
31
|
}
|
|
49
32
|
const cr = new aws_cdk_lib_1.CustomResource(this, "TursoDb", {
|
|
50
|
-
serviceToken: provider.serviceToken,
|
|
33
|
+
serviceToken: props.provider.serviceToken,
|
|
51
34
|
properties: resourceProps,
|
|
52
35
|
});
|
|
53
36
|
this.dbId = cr.getAttString("DbId");
|
|
@@ -57,5 +40,5 @@ class TursoDatabase extends constructs_1.Construct {
|
|
|
57
40
|
}
|
|
58
41
|
exports.TursoDatabase = TursoDatabase;
|
|
59
42
|
_a = JSII_RTTI_SYMBOL_1;
|
|
60
|
-
TursoDatabase[_a] = { fqn: "cdk-turso.TursoDatabase", version: "0.
|
|
61
|
-
//# sourceMappingURL=data:application/json;base64,
|
|
43
|
+
TursoDatabase[_a] = { fqn: "cdk-turso.TursoDatabase", version: "0.3.1" };
|
|
44
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidHVyc28tZGF0YWJhc2UuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi9zcmMvdHVyc28tZGF0YWJhc2UudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6Ijs7Ozs7QUFBQSw2Q0FBNEM7QUFDNUMsMkNBQXNDO0FBd0J0QyxNQUFhLGFBQWMsU0FBUSxzQkFBUztJQVMxQyxZQUFZLEtBQWdCLEVBQUUsRUFBVSxFQUFFLEtBQXlCO1FBQ2pFLEtBQUssQ0FBQyxLQUFLLEVBQUUsRUFBRSxDQUFDLENBQUE7UUFFaEIsSUFBSSxDQUFDLGNBQWMsQ0FBQyxJQUFJLENBQUMsS0FBSyxDQUFDLFlBQVksQ0FBQyxFQUFFLENBQUM7WUFDN0MsTUFBTSxJQUFJLEtBQUssQ0FDYix1RUFBdUUsQ0FDeEUsQ0FBQTtRQUNILENBQUM7UUFDRCxJQUFJLEtBQUssQ0FBQyxZQUFZLENBQUMsTUFBTSxHQUFHLEVBQUUsRUFBRSxDQUFDO1lBQ25DLE1BQU0sSUFBSSxLQUFLLENBQUMsNENBQTRDLENBQUMsQ0FBQTtRQUMvRCxDQUFDO1FBRUQsTUFBTSxhQUFhLEdBQTRCO1lBQzdDLFlBQVksRUFBRSxVQUFVO1lBQ3hCLFlBQVksRUFBRSxLQUFLLENBQUMsWUFBWTtZQUNoQyxLQUFLLEVBQUUsS0FBSyxDQUFDLEtBQUs7WUFDbEIsZ0JBQWdCLEVBQUUsS0FBSyxDQUFDLGdCQUFnQjtTQUN6QyxDQUFBO1FBRUQsSUFBSSxLQUFLLENBQUMsU0FBUyxFQUFFLENBQUM7WUFDcEIsYUFBYSxDQUFDLFNBQVMsR0FBRyxLQUFLLENBQUMsU0FBUyxDQUFBO1FBQzNDLENBQUM7UUFDRCxJQUFJLEtBQUssQ0FBQyxJQUFJLEVBQUUsQ0FBQztZQUNmLGFBQWEsQ0FBQyxJQUFJLEdBQUcsS0FBSyxDQUFDLElBQUksQ0FBQTtRQUNqQyxDQUFDO1FBQ0QsSUFBSSxLQUFLLENBQUMsVUFBVSxFQUFFLENBQUM7WUFDckIsYUFBYSxDQUFDLFVBQVUsR0FBRyxLQUFLLENBQUMsVUFBVSxDQUFBO1FBQzdDLENBQUM7UUFFRCxNQUFNLEVBQUUsR0FBRyxJQUFJLDRCQUFjLENBQUMsSUFBSSxFQUFFLFNBQVMsRUFBRTtZQUM3QyxZQUFZLEVBQUUsS0FBSyxDQUFDLFFBQVEsQ0FBQyxZQUFZO1lBQ3pDLFVBQVUsRUFBRSxhQUFhO1NBQzFCLENBQUMsQ0FBQTtRQUVGLElBQUksQ0FBQyxJQUFJLEdBQUcsRUFBRSxDQUFDLFlBQVksQ0FBQyxNQUFNLENBQUMsQ0FBQTtRQUNuQyxJQUFJLENBQUMsUUFBUSxHQUFHLEVBQUUsQ0FBQyxZQUFZLENBQUMsVUFBVSxDQUFDLENBQUE7UUFDM0MsSUFBSSxDQUFDLFlBQVksR0FBRyxFQUFFLENBQUMsWUFBWSxDQUFDLE1BQU0sQ0FBQyxDQUFBO0lBQzdDLENBQUM7O0FBOUNILHNDQStDQyIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7IEN1c3RvbVJlc291cmNlIH0gZnJvbSBcImF3cy1jZGstbGliXCJcbmltcG9ydCB7IENvbnN0cnVjdCB9IGZyb20gXCJjb25zdHJ1Y3RzXCJcbmltcG9ydCB0eXBlIHsgVHVyc29Qcm92aWRlciB9IGZyb20gXCIuL3R1cnNvLXByb3ZpZGVyXCJcblxuZXhwb3J0IGludGVyZmFjZSBUdXJzb0RhdGFiYXNlU2VlZCB7XG4gIHJlYWRvbmx5IHR5cGU6IHN0cmluZ1xuICByZWFkb25seSBuYW1lOiBzdHJpbmdcbiAgcmVhZG9ubHkgdGltZXN0YW1wPzogc3RyaW5nXG59XG5cbmV4cG9ydCBpbnRlcmZhY2UgVHVyc29EYXRhYmFzZUVuY3J5cHRpb24ge1xuICByZWFkb25seSBlbmNyeXB0aW9uS2V5OiBzdHJpbmdcbiAgcmVhZG9ubHkgZW5jcnlwdGlvbkNpcGhlcjogc3RyaW5nXG59XG5cbmV4cG9ydCBpbnRlcmZhY2UgVHVyc29EYXRhYmFzZVByb3BzIHtcbiAgcmVhZG9ubHkgcHJvdmlkZXI6IFR1cnNvUHJvdmlkZXJcbiAgcmVhZG9ubHkgZGF0YWJhc2VOYW1lOiBzdHJpbmdcbiAgcmVhZG9ubHkgZ3JvdXA6IHN0cmluZ1xuICByZWFkb25seSBvcmdhbml6YXRpb25TbHVnOiBzdHJpbmdcbiAgcmVhZG9ubHkgc2l6ZUxpbWl0Pzogc3RyaW5nXG4gIHJlYWRvbmx5IHNlZWQ/OiBUdXJzb0RhdGFiYXNlU2VlZFxuICByZWFkb25seSBlbmNyeXB0aW9uPzogVHVyc29EYXRhYmFzZUVuY3J5cHRpb25cbn1cblxuZXhwb3J0IGNsYXNzIFR1cnNvRGF0YWJhc2UgZXh0ZW5kcyBDb25zdHJ1Y3Qge1xuICBwdWJsaWMgcmVhZG9ubHkgZGJJZDogc3RyaW5nXG4gIC8qKlxuICAgKiBETlMgaG9zdG5hbWUgZm9yIHRoZSBkYXRhYmFzZSAoZS5nLiwgYG15LWRiLW15LW9yZy50dXJzby5pb2ApLlxuICAgKiBVc2Ugd2l0aCBsaWJTUUwgb3IgSFRUUCBjb25uZWN0aW9ucy5cbiAgICovXG4gIHB1YmxpYyByZWFkb25seSBob3N0bmFtZTogc3RyaW5nXG4gIHB1YmxpYyByZWFkb25seSBkYXRhYmFzZU5hbWU6IHN0cmluZ1xuXG4gIGNvbnN0cnVjdG9yKHNjb3BlOiBDb25zdHJ1Y3QsIGlkOiBzdHJpbmcsIHByb3BzOiBUdXJzb0RhdGFiYXNlUHJvcHMpIHtcbiAgICBzdXBlcihzY29wZSwgaWQpXG5cbiAgICBpZiAoIS9eW2EtejAtOS1dKyQvLnRlc3QocHJvcHMuZGF0YWJhc2VOYW1lKSkge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKFxuICAgICAgICBcImRhdGFiYXNlTmFtZSBtdXN0IGNvbnRhaW4gb25seSBsb3dlcmNhc2UgbGV0dGVycywgbnVtYmVycywgYW5kIGRhc2hlc1wiLFxuICAgICAgKVxuICAgIH1cbiAgICBpZiAocHJvcHMuZGF0YWJhc2VOYW1lLmxlbmd0aCA+IDY0KSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoXCJkYXRhYmFzZU5hbWUgbXVzdCBiZSBhdCBtb3N0IDY0IGNoYXJhY3RlcnNcIilcbiAgICB9XG5cbiAgICBjb25zdCByZXNvdXJjZVByb3BzOiBSZWNvcmQ8c3RyaW5nLCB1bmtub3duPiA9IHtcbiAgICAgIFJlc291cmNlVHlwZTogXCJEYXRhYmFzZVwiLFxuICAgICAgRGF0YWJhc2VOYW1lOiBwcm9wcy5kYXRhYmFzZU5hbWUsXG4gICAgICBHcm91cDogcHJvcHMuZ3JvdXAsXG4gICAgICBPcmdhbml6YXRpb25TbHVnOiBwcm9wcy5vcmdhbml6YXRpb25TbHVnLFxuICAgIH1cblxuICAgIGlmIChwcm9wcy5zaXplTGltaXQpIHtcbiAgICAgIHJlc291cmNlUHJvcHMuU2l6ZUxpbWl0ID0gcHJvcHMuc2l6ZUxpbWl0XG4gICAgfVxuICAgIGlmIChwcm9wcy5zZWVkKSB7XG4gICAgICByZXNvdXJjZVByb3BzLlNlZWQgPSBwcm9wcy5zZWVkXG4gICAgfVxuICAgIGlmIChwcm9wcy5lbmNyeXB0aW9uKSB7XG4gICAgICByZXNvdXJjZVByb3BzLkVuY3J5cHRpb24gPSBwcm9wcy5lbmNyeXB0aW9uXG4gICAgfVxuXG4gICAgY29uc3QgY3IgPSBuZXcgQ3VzdG9tUmVzb3VyY2UodGhpcywgXCJUdXJzb0RiXCIsIHtcbiAgICAgIHNlcnZpY2VUb2tlbjogcHJvcHMucHJvdmlkZXIuc2VydmljZVRva2VuLFxuICAgICAgcHJvcGVydGllczogcmVzb3VyY2VQcm9wcyxcbiAgICB9KVxuXG4gICAgdGhpcy5kYklkID0gY3IuZ2V0QXR0U3RyaW5nKFwiRGJJZFwiKVxuICAgIHRoaXMuaG9zdG5hbWUgPSBjci5nZXRBdHRTdHJpbmcoXCJIb3N0bmFtZVwiKVxuICAgIHRoaXMuZGF0YWJhc2VOYW1lID0gY3IuZ2V0QXR0U3RyaW5nKFwiTmFtZVwiKVxuICB9XG59XG4iXX0=
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
import { Function } from "aws-cdk-lib/aws-lambda";
|
|
2
|
+
import type { ILogGroup } from "aws-cdk-lib/aws-logs";
|
|
3
|
+
import type { IParameter } from "aws-cdk-lib/aws-ssm";
|
|
4
|
+
import { Construct } from "constructs";
|
|
5
|
+
export interface TursoProviderProps {
|
|
6
|
+
/**
|
|
7
|
+
* SSM parameter that holds the Turso platform API token
|
|
8
|
+
* (stored as SecureString).
|
|
9
|
+
*/
|
|
10
|
+
readonly apiToken: IParameter;
|
|
11
|
+
/**
|
|
12
|
+
* Optional log group for the Lambda function.
|
|
13
|
+
* If not provided, a log group will be automatically created.
|
|
14
|
+
*/
|
|
15
|
+
readonly logGroup?: ILogGroup;
|
|
16
|
+
}
|
|
17
|
+
/**
|
|
18
|
+
* Shared Lambda + CloudFormation custom-resource provider for all
|
|
19
|
+
* Turso resources. Create one per stack and pass it to every
|
|
20
|
+
* `TursoDatabase`, `TursoAuthToken`, etc.
|
|
21
|
+
*/
|
|
22
|
+
export declare class TursoProvider extends Construct {
|
|
23
|
+
/**
|
|
24
|
+
* The Lambda function backing all Turso custom resources.
|
|
25
|
+
* Use this to attach additional IAM permissions when a resource
|
|
26
|
+
* type needs them (e.g. `ssm:PutParameter` for auth-token storage).
|
|
27
|
+
*/
|
|
28
|
+
readonly handler: Function;
|
|
29
|
+
/**
|
|
30
|
+
* The CDK custom-resource provider service token.
|
|
31
|
+
*/
|
|
32
|
+
readonly serviceToken: string;
|
|
33
|
+
constructor(scope: Construct, id: string, props: TursoProviderProps);
|
|
34
|
+
}
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var _a;
|
|
3
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
4
|
+
exports.TursoProvider = void 0;
|
|
5
|
+
const JSII_RTTI_SYMBOL_1 = Symbol.for("jsii.rtti");
|
|
6
|
+
const aws_cdk_lib_1 = require("aws-cdk-lib");
|
|
7
|
+
const aws_lambda_1 = require("aws-cdk-lib/aws-lambda");
|
|
8
|
+
const custom_resources_1 = require("aws-cdk-lib/custom-resources");
|
|
9
|
+
const constructs_1 = require("constructs");
|
|
10
|
+
const path = require("path");
|
|
11
|
+
/**
|
|
12
|
+
* Shared Lambda + CloudFormation custom-resource provider for all
|
|
13
|
+
* Turso resources. Create one per stack and pass it to every
|
|
14
|
+
* `TursoDatabase`, `TursoAuthToken`, etc.
|
|
15
|
+
*/
|
|
16
|
+
class TursoProvider extends constructs_1.Construct {
|
|
17
|
+
constructor(scope, id, props) {
|
|
18
|
+
super(scope, id);
|
|
19
|
+
this.handler = new aws_lambda_1.Function(this, "Handler", {
|
|
20
|
+
runtime: new aws_lambda_1.Runtime("nodejs24.x", aws_lambda_1.RuntimeFamily.NODEJS),
|
|
21
|
+
handler: "index.handler",
|
|
22
|
+
code: aws_lambda_1.Code.fromAsset(path.join(__dirname, "handler")),
|
|
23
|
+
timeout: aws_cdk_lib_1.Duration.minutes(3),
|
|
24
|
+
logGroup: props.logGroup,
|
|
25
|
+
environment: {
|
|
26
|
+
TURSO_API_TOKEN_PARAMETER_NAME: props.apiToken.parameterName,
|
|
27
|
+
},
|
|
28
|
+
});
|
|
29
|
+
props.apiToken.grantRead(this.handler);
|
|
30
|
+
const provider = new custom_resources_1.Provider(this, "Provider", {
|
|
31
|
+
onEventHandler: this.handler,
|
|
32
|
+
logGroup: props.logGroup,
|
|
33
|
+
});
|
|
34
|
+
this.serviceToken = provider.serviceToken;
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
exports.TursoProvider = TursoProvider;
|
|
38
|
+
_a = JSII_RTTI_SYMBOL_1;
|
|
39
|
+
TursoProvider[_a] = { fqn: "cdk-turso.TursoProvider", version: "0.3.1" };
|
|
40
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidHVyc28tcHJvdmlkZXIuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi9zcmMvdHVyc28tcHJvdmlkZXIudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6Ijs7Ozs7QUFBQSw2Q0FBc0M7QUFDdEMsdURBQStFO0FBRy9FLG1FQUF1RDtBQUN2RCwyQ0FBc0M7QUFDdEMsNkJBQTRCO0FBZ0I1Qjs7OztHQUlHO0FBQ0gsTUFBYSxhQUFjLFNBQVEsc0JBQVM7SUFhMUMsWUFBWSxLQUFnQixFQUFFLEVBQVUsRUFBRSxLQUF5QjtRQUNqRSxLQUFLLENBQUMsS0FBSyxFQUFFLEVBQUUsQ0FBQyxDQUFBO1FBRWhCLElBQUksQ0FBQyxPQUFPLEdBQUcsSUFBSSxxQkFBUSxDQUFDLElBQUksRUFBRSxTQUFTLEVBQUU7WUFDM0MsT0FBTyxFQUFFLElBQUksb0JBQU8sQ0FBQyxZQUFZLEVBQUUsMEJBQWEsQ0FBQyxNQUFNLENBQUM7WUFDeEQsT0FBTyxFQUFFLGVBQWU7WUFDeEIsSUFBSSxFQUFFLGlCQUFJLENBQUMsU0FBUyxDQUFDLElBQUksQ0FBQyxJQUFJLENBQUMsU0FBUyxFQUFFLFNBQVMsQ0FBQyxDQUFDO1lBQ3JELE9BQU8sRUFBRSxzQkFBUSxDQUFDLE9BQU8sQ0FBQyxDQUFDLENBQUM7WUFDNUIsUUFBUSxFQUFFLEtBQUssQ0FBQyxRQUFRO1lBQ3hCLFdBQVcsRUFBRTtnQkFDWCw4QkFBOEIsRUFBRSxLQUFLLENBQUMsUUFBUSxDQUFDLGFBQWE7YUFDN0Q7U0FDRixDQUFDLENBQUE7UUFFRixLQUFLLENBQUMsUUFBUSxDQUFDLFNBQVMsQ0FBQyxJQUFJLENBQUMsT0FBTyxDQUFDLENBQUE7UUFFdEMsTUFBTSxRQUFRLEdBQUcsSUFBSSwyQkFBUSxDQUFDLElBQUksRUFBRSxVQUFVLEVBQUU7WUFDOUMsY0FBYyxFQUFFLElBQUksQ0FBQyxPQUFPO1lBQzVCLFFBQVEsRUFBRSxLQUFLLENBQUMsUUFBUTtTQUN6QixDQUFDLENBQUE7UUFFRixJQUFJLENBQUMsWUFBWSxHQUFHLFFBQVEsQ0FBQyxZQUFZLENBQUE7SUFDM0MsQ0FBQzs7QUFuQ0gsc0NBb0NDIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHsgRHVyYXRpb24gfSBmcm9tIFwiYXdzLWNkay1saWJcIlxuaW1wb3J0IHsgQ29kZSwgRnVuY3Rpb24sIFJ1bnRpbWUsIFJ1bnRpbWVGYW1pbHkgfSBmcm9tIFwiYXdzLWNkay1saWIvYXdzLWxhbWJkYVwiXG5pbXBvcnQgdHlwZSB7IElMb2dHcm91cCB9IGZyb20gXCJhd3MtY2RrLWxpYi9hd3MtbG9nc1wiXG5pbXBvcnQgdHlwZSB7IElQYXJhbWV0ZXIgfSBmcm9tIFwiYXdzLWNkay1saWIvYXdzLXNzbVwiXG5pbXBvcnQgeyBQcm92aWRlciB9IGZyb20gXCJhd3MtY2RrLWxpYi9jdXN0b20tcmVzb3VyY2VzXCJcbmltcG9ydCB7IENvbnN0cnVjdCB9IGZyb20gXCJjb25zdHJ1Y3RzXCJcbmltcG9ydCAqIGFzIHBhdGggZnJvbSBcInBhdGhcIlxuXG5leHBvcnQgaW50ZXJmYWNlIFR1cnNvUHJvdmlkZXJQcm9wcyB7XG4gIC8qKlxuICAgKiBTU00gcGFyYW1ldGVyIHRoYXQgaG9sZHMgdGhlIFR1cnNvIHBsYXRmb3JtIEFQSSB0b2tlblxuICAgKiAoc3RvcmVkIGFzIFNlY3VyZVN0cmluZykuXG4gICAqL1xuICByZWFkb25seSBhcGlUb2tlbjogSVBhcmFtZXRlclxuXG4gIC8qKlxuICAgKiBPcHRpb25hbCBsb2cgZ3JvdXAgZm9yIHRoZSBMYW1iZGEgZnVuY3Rpb24uXG4gICAqIElmIG5vdCBwcm92aWRlZCwgYSBsb2cgZ3JvdXAgd2lsbCBiZSBhdXRvbWF0aWNhbGx5IGNyZWF0ZWQuXG4gICAqL1xuICByZWFkb25seSBsb2dHcm91cD86IElMb2dHcm91cFxufVxuXG4vKipcbiAqIFNoYXJlZCBMYW1iZGEgKyBDbG91ZEZvcm1hdGlvbiBjdXN0b20tcmVzb3VyY2UgcHJvdmlkZXIgZm9yIGFsbFxuICogVHVyc28gcmVzb3VyY2VzLiAgQ3JlYXRlIG9uZSBwZXIgc3RhY2sgYW5kIHBhc3MgaXQgdG8gZXZlcnlcbiAqIGBUdXJzb0RhdGFiYXNlYCwgYFR1cnNvQXV0aFRva2VuYCwgZXRjLlxuICovXG5leHBvcnQgY2xhc3MgVHVyc29Qcm92aWRlciBleHRlbmRzIENvbnN0cnVjdCB7XG4gIC8qKlxuICAgKiBUaGUgTGFtYmRhIGZ1bmN0aW9uIGJhY2tpbmcgYWxsIFR1cnNvIGN1c3RvbSByZXNvdXJjZXMuXG4gICAqIFVzZSB0aGlzIHRvIGF0dGFjaCBhZGRpdGlvbmFsIElBTSBwZXJtaXNzaW9ucyB3aGVuIGEgcmVzb3VyY2VcbiAgICogdHlwZSBuZWVkcyB0aGVtIChlLmcuIGBzc206UHV0UGFyYW1ldGVyYCBmb3IgYXV0aC10b2tlbiBzdG9yYWdlKS5cbiAgICovXG4gIHB1YmxpYyByZWFkb25seSBoYW5kbGVyOiBGdW5jdGlvblxuXG4gIC8qKlxuICAgKiBUaGUgQ0RLIGN1c3RvbS1yZXNvdXJjZSBwcm92aWRlciBzZXJ2aWNlIHRva2VuLlxuICAgKi9cbiAgcHVibGljIHJlYWRvbmx5IHNlcnZpY2VUb2tlbjogc3RyaW5nXG5cbiAgY29uc3RydWN0b3Ioc2NvcGU6IENvbnN0cnVjdCwgaWQ6IHN0cmluZywgcHJvcHM6IFR1cnNvUHJvdmlkZXJQcm9wcykge1xuICAgIHN1cGVyKHNjb3BlLCBpZClcblxuICAgIHRoaXMuaGFuZGxlciA9IG5ldyBGdW5jdGlvbih0aGlzLCBcIkhhbmRsZXJcIiwge1xuICAgICAgcnVudGltZTogbmV3IFJ1bnRpbWUoXCJub2RlanMyNC54XCIsIFJ1bnRpbWVGYW1pbHkuTk9ERUpTKSxcbiAgICAgIGhhbmRsZXI6IFwiaW5kZXguaGFuZGxlclwiLFxuICAgICAgY29kZTogQ29kZS5mcm9tQXNzZXQocGF0aC5qb2luKF9fZGlybmFtZSwgXCJoYW5kbGVyXCIpKSxcbiAgICAgIHRpbWVvdXQ6IER1cmF0aW9uLm1pbnV0ZXMoMyksXG4gICAgICBsb2dHcm91cDogcHJvcHMubG9nR3JvdXAsXG4gICAgICBlbnZpcm9ubWVudDoge1xuICAgICAgICBUVVJTT19BUElfVE9LRU5fUEFSQU1FVEVSX05BTUU6IHByb3BzLmFwaVRva2VuLnBhcmFtZXRlck5hbWUsXG4gICAgICB9LFxuICAgIH0pXG5cbiAgICBwcm9wcy5hcGlUb2tlbi5ncmFudFJlYWQodGhpcy5oYW5kbGVyKVxuXG4gICAgY29uc3QgcHJvdmlkZXIgPSBuZXcgUHJvdmlkZXIodGhpcywgXCJQcm92aWRlclwiLCB7XG4gICAgICBvbkV2ZW50SGFuZGxlcjogdGhpcy5oYW5kbGVyLFxuICAgICAgbG9nR3JvdXA6IHByb3BzLmxvZ0dyb3VwLFxuICAgIH0pXG5cbiAgICB0aGlzLnNlcnZpY2VUb2tlbiA9IHByb3ZpZGVyLnNlcnZpY2VUb2tlblxuICB9XG59XG4iXX0=
|
package/package.json
CHANGED
|
@@ -34,13 +34,13 @@
|
|
|
34
34
|
"organization": false
|
|
35
35
|
},
|
|
36
36
|
"devDependencies": {
|
|
37
|
-
"@aws-sdk/client-ssm": "^3.
|
|
37
|
+
"@aws-sdk/client-ssm": "^3.993.0",
|
|
38
38
|
"@biomejs/biome": "^2",
|
|
39
39
|
"@types/jest": "^30.0.0",
|
|
40
|
-
"@types/node": "^25.
|
|
41
|
-
"aws-cdk-lib": "2.
|
|
40
|
+
"@types/node": "^25.3.0",
|
|
41
|
+
"aws-cdk-lib": "2.201.0",
|
|
42
42
|
"commit-and-tag-version": "^12",
|
|
43
|
-
"constructs": "10.0
|
|
43
|
+
"constructs": "10.3.0",
|
|
44
44
|
"esbuild": "^0.27.3",
|
|
45
45
|
"exponential-backoff": "^3.1.3",
|
|
46
46
|
"husky": "^9.1.7",
|
|
@@ -57,8 +57,8 @@
|
|
|
57
57
|
"typescript": "^5.9.3"
|
|
58
58
|
},
|
|
59
59
|
"peerDependencies": {
|
|
60
|
-
"aws-cdk-lib": "^2.
|
|
61
|
-
"constructs": "^10.0
|
|
60
|
+
"aws-cdk-lib": "^2.201.0",
|
|
61
|
+
"constructs": "^10.3.0"
|
|
62
62
|
},
|
|
63
63
|
"keywords": [
|
|
64
64
|
"cdk"
|
|
@@ -68,7 +68,7 @@
|
|
|
68
68
|
"publishConfig": {
|
|
69
69
|
"access": "public"
|
|
70
70
|
},
|
|
71
|
-
"version": "0.
|
|
71
|
+
"version": "0.3.1",
|
|
72
72
|
"jest": {
|
|
73
73
|
"coverageProvider": "v8",
|
|
74
74
|
"testMatch": [
|
|
@@ -1,15 +0,0 @@
|
|
|
1
|
-
export interface CloudFormationCustomResourceEvent {
|
|
2
|
-
RequestType: "Create" | "Update" | "Delete";
|
|
3
|
-
PhysicalResourceId?: string;
|
|
4
|
-
ResourceProperties: {
|
|
5
|
-
ServiceToken: string;
|
|
6
|
-
DatabaseName: string;
|
|
7
|
-
OrganizationSlug: string;
|
|
8
|
-
ParameterName: string;
|
|
9
|
-
Expiration?: string;
|
|
10
|
-
Authorization?: string;
|
|
11
|
-
};
|
|
12
|
-
}
|
|
13
|
-
export declare function handler(event: CloudFormationCustomResourceEvent): Promise<{
|
|
14
|
-
PhysicalResourceId: string;
|
|
15
|
-
}>;
|