cdk-turso 0.0.1 → 0.0.3
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 +2 -2
- package/AGENTS.md +120 -18
- package/lib/handler/index.js +588 -24
- package/lib/turso-database.js +3 -2
- package/package.json +2 -1
package/.jsii
CHANGED
|
@@ -3129,6 +3129,6 @@
|
|
|
3129
3129
|
"symbolId": "src/turso-database:TursoDatabaseSeed"
|
|
3130
3130
|
}
|
|
3131
3131
|
},
|
|
3132
|
-
"version": "0.0.
|
|
3133
|
-
"fingerprint": "
|
|
3132
|
+
"version": "0.0.3",
|
|
3133
|
+
"fingerprint": "2JbcEWhNjajcTuFaNl+79TwukC95w10mlbSw0EwU9+Y="
|
|
3134
3134
|
}
|
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/lib/handler/index.js
CHANGED
|
@@ -1,8 +1,13 @@
|
|
|
1
1
|
"use strict";
|
|
2
|
+
var __create = Object.create;
|
|
2
3
|
var __defProp = Object.defineProperty;
|
|
3
4
|
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
4
5
|
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
6
|
+
var __getProtoOf = Object.getPrototypeOf;
|
|
5
7
|
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
8
|
+
var __commonJS = (cb, mod) => function __require() {
|
|
9
|
+
return mod || (0, cb[__getOwnPropNames(cb)[0]])((mod = { exports: {} }).exports, mod), mod.exports;
|
|
10
|
+
};
|
|
6
11
|
var __export = (target, all) => {
|
|
7
12
|
for (var name in all)
|
|
8
13
|
__defProp(target, name, { get: all[name], enumerable: true });
|
|
@@ -15,8 +20,562 @@ var __copyProps = (to, from, except, desc) => {
|
|
|
15
20
|
}
|
|
16
21
|
return to;
|
|
17
22
|
};
|
|
23
|
+
var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
|
|
24
|
+
// If the importer is in node compatibility mode or this is not an ESM
|
|
25
|
+
// file that has been converted to a CommonJS file using a Babel-
|
|
26
|
+
// compatible transform (i.e. "__esModule" has not been set), then set
|
|
27
|
+
// "default" to the CommonJS "module.exports" for node compatibility.
|
|
28
|
+
isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
|
|
29
|
+
mod
|
|
30
|
+
));
|
|
18
31
|
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
19
32
|
|
|
33
|
+
// node_modules/exponential-backoff/dist/options.js
|
|
34
|
+
var require_options = __commonJS({
|
|
35
|
+
"node_modules/exponential-backoff/dist/options.js"(exports2) {
|
|
36
|
+
"use strict";
|
|
37
|
+
var __assign = exports2 && exports2.__assign || function() {
|
|
38
|
+
__assign = Object.assign || function(t) {
|
|
39
|
+
for (var s, i = 1, n = arguments.length; i < n; i++) {
|
|
40
|
+
s = arguments[i];
|
|
41
|
+
for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p))
|
|
42
|
+
t[p] = s[p];
|
|
43
|
+
}
|
|
44
|
+
return t;
|
|
45
|
+
};
|
|
46
|
+
return __assign.apply(this, arguments);
|
|
47
|
+
};
|
|
48
|
+
Object.defineProperty(exports2, "__esModule", { value: true });
|
|
49
|
+
var defaultOptions = {
|
|
50
|
+
delayFirstAttempt: false,
|
|
51
|
+
jitter: "none",
|
|
52
|
+
maxDelay: Infinity,
|
|
53
|
+
numOfAttempts: 10,
|
|
54
|
+
retry: function() {
|
|
55
|
+
return true;
|
|
56
|
+
},
|
|
57
|
+
startingDelay: 100,
|
|
58
|
+
timeMultiple: 2
|
|
59
|
+
};
|
|
60
|
+
function getSanitizedOptions(options) {
|
|
61
|
+
var sanitized = __assign(__assign({}, defaultOptions), options);
|
|
62
|
+
if (sanitized.numOfAttempts < 1) {
|
|
63
|
+
sanitized.numOfAttempts = 1;
|
|
64
|
+
}
|
|
65
|
+
return sanitized;
|
|
66
|
+
}
|
|
67
|
+
exports2.getSanitizedOptions = getSanitizedOptions;
|
|
68
|
+
}
|
|
69
|
+
});
|
|
70
|
+
|
|
71
|
+
// node_modules/exponential-backoff/dist/jitter/full/full.jitter.js
|
|
72
|
+
var require_full_jitter = __commonJS({
|
|
73
|
+
"node_modules/exponential-backoff/dist/jitter/full/full.jitter.js"(exports2) {
|
|
74
|
+
"use strict";
|
|
75
|
+
Object.defineProperty(exports2, "__esModule", { value: true });
|
|
76
|
+
function fullJitter(delay) {
|
|
77
|
+
var jitteredDelay = Math.random() * delay;
|
|
78
|
+
return Math.round(jitteredDelay);
|
|
79
|
+
}
|
|
80
|
+
exports2.fullJitter = fullJitter;
|
|
81
|
+
}
|
|
82
|
+
});
|
|
83
|
+
|
|
84
|
+
// node_modules/exponential-backoff/dist/jitter/no/no.jitter.js
|
|
85
|
+
var require_no_jitter = __commonJS({
|
|
86
|
+
"node_modules/exponential-backoff/dist/jitter/no/no.jitter.js"(exports2) {
|
|
87
|
+
"use strict";
|
|
88
|
+
Object.defineProperty(exports2, "__esModule", { value: true });
|
|
89
|
+
function noJitter(delay) {
|
|
90
|
+
return delay;
|
|
91
|
+
}
|
|
92
|
+
exports2.noJitter = noJitter;
|
|
93
|
+
}
|
|
94
|
+
});
|
|
95
|
+
|
|
96
|
+
// node_modules/exponential-backoff/dist/jitter/jitter.factory.js
|
|
97
|
+
var require_jitter_factory = __commonJS({
|
|
98
|
+
"node_modules/exponential-backoff/dist/jitter/jitter.factory.js"(exports2) {
|
|
99
|
+
"use strict";
|
|
100
|
+
Object.defineProperty(exports2, "__esModule", { value: true });
|
|
101
|
+
var full_jitter_1 = require_full_jitter();
|
|
102
|
+
var no_jitter_1 = require_no_jitter();
|
|
103
|
+
function JitterFactory(options) {
|
|
104
|
+
switch (options.jitter) {
|
|
105
|
+
case "full":
|
|
106
|
+
return full_jitter_1.fullJitter;
|
|
107
|
+
case "none":
|
|
108
|
+
default:
|
|
109
|
+
return no_jitter_1.noJitter;
|
|
110
|
+
}
|
|
111
|
+
}
|
|
112
|
+
exports2.JitterFactory = JitterFactory;
|
|
113
|
+
}
|
|
114
|
+
});
|
|
115
|
+
|
|
116
|
+
// node_modules/exponential-backoff/dist/delay/delay.base.js
|
|
117
|
+
var require_delay_base = __commonJS({
|
|
118
|
+
"node_modules/exponential-backoff/dist/delay/delay.base.js"(exports2) {
|
|
119
|
+
"use strict";
|
|
120
|
+
Object.defineProperty(exports2, "__esModule", { value: true });
|
|
121
|
+
var jitter_factory_1 = require_jitter_factory();
|
|
122
|
+
var Delay = (
|
|
123
|
+
/** @class */
|
|
124
|
+
(function() {
|
|
125
|
+
function Delay2(options) {
|
|
126
|
+
this.options = options;
|
|
127
|
+
this.attempt = 0;
|
|
128
|
+
}
|
|
129
|
+
Delay2.prototype.apply = function() {
|
|
130
|
+
var _this = this;
|
|
131
|
+
return new Promise(function(resolve) {
|
|
132
|
+
return setTimeout(resolve, _this.jitteredDelay);
|
|
133
|
+
});
|
|
134
|
+
};
|
|
135
|
+
Delay2.prototype.setAttemptNumber = function(attempt) {
|
|
136
|
+
this.attempt = attempt;
|
|
137
|
+
};
|
|
138
|
+
Object.defineProperty(Delay2.prototype, "jitteredDelay", {
|
|
139
|
+
get: function() {
|
|
140
|
+
var jitter = jitter_factory_1.JitterFactory(this.options);
|
|
141
|
+
return jitter(this.delay);
|
|
142
|
+
},
|
|
143
|
+
enumerable: true,
|
|
144
|
+
configurable: true
|
|
145
|
+
});
|
|
146
|
+
Object.defineProperty(Delay2.prototype, "delay", {
|
|
147
|
+
get: function() {
|
|
148
|
+
var constant = this.options.startingDelay;
|
|
149
|
+
var base = this.options.timeMultiple;
|
|
150
|
+
var power = this.numOfDelayedAttempts;
|
|
151
|
+
var delay = constant * Math.pow(base, power);
|
|
152
|
+
return Math.min(delay, this.options.maxDelay);
|
|
153
|
+
},
|
|
154
|
+
enumerable: true,
|
|
155
|
+
configurable: true
|
|
156
|
+
});
|
|
157
|
+
Object.defineProperty(Delay2.prototype, "numOfDelayedAttempts", {
|
|
158
|
+
get: function() {
|
|
159
|
+
return this.attempt;
|
|
160
|
+
},
|
|
161
|
+
enumerable: true,
|
|
162
|
+
configurable: true
|
|
163
|
+
});
|
|
164
|
+
return Delay2;
|
|
165
|
+
})()
|
|
166
|
+
);
|
|
167
|
+
exports2.Delay = Delay;
|
|
168
|
+
}
|
|
169
|
+
});
|
|
170
|
+
|
|
171
|
+
// node_modules/exponential-backoff/dist/delay/skip-first/skip-first.delay.js
|
|
172
|
+
var require_skip_first_delay = __commonJS({
|
|
173
|
+
"node_modules/exponential-backoff/dist/delay/skip-first/skip-first.delay.js"(exports2) {
|
|
174
|
+
"use strict";
|
|
175
|
+
var __extends = exports2 && exports2.__extends || /* @__PURE__ */ (function() {
|
|
176
|
+
var extendStatics = function(d, b) {
|
|
177
|
+
extendStatics = Object.setPrototypeOf || { __proto__: [] } instanceof Array && function(d2, b2) {
|
|
178
|
+
d2.__proto__ = b2;
|
|
179
|
+
} || function(d2, b2) {
|
|
180
|
+
for (var p in b2) if (b2.hasOwnProperty(p)) d2[p] = b2[p];
|
|
181
|
+
};
|
|
182
|
+
return extendStatics(d, b);
|
|
183
|
+
};
|
|
184
|
+
return function(d, b) {
|
|
185
|
+
extendStatics(d, b);
|
|
186
|
+
function __() {
|
|
187
|
+
this.constructor = d;
|
|
188
|
+
}
|
|
189
|
+
d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
|
|
190
|
+
};
|
|
191
|
+
})();
|
|
192
|
+
var __awaiter = exports2 && exports2.__awaiter || function(thisArg, _arguments, P, generator) {
|
|
193
|
+
function adopt(value) {
|
|
194
|
+
return value instanceof P ? value : new P(function(resolve) {
|
|
195
|
+
resolve(value);
|
|
196
|
+
});
|
|
197
|
+
}
|
|
198
|
+
return new (P || (P = Promise))(function(resolve, reject) {
|
|
199
|
+
function fulfilled(value) {
|
|
200
|
+
try {
|
|
201
|
+
step(generator.next(value));
|
|
202
|
+
} catch (e) {
|
|
203
|
+
reject(e);
|
|
204
|
+
}
|
|
205
|
+
}
|
|
206
|
+
function rejected(value) {
|
|
207
|
+
try {
|
|
208
|
+
step(generator["throw"](value));
|
|
209
|
+
} catch (e) {
|
|
210
|
+
reject(e);
|
|
211
|
+
}
|
|
212
|
+
}
|
|
213
|
+
function step(result) {
|
|
214
|
+
result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected);
|
|
215
|
+
}
|
|
216
|
+
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
|
217
|
+
});
|
|
218
|
+
};
|
|
219
|
+
var __generator = exports2 && exports2.__generator || function(thisArg, body) {
|
|
220
|
+
var _ = { label: 0, sent: function() {
|
|
221
|
+
if (t[0] & 1) throw t[1];
|
|
222
|
+
return t[1];
|
|
223
|
+
}, trys: [], ops: [] }, f, y, t, g;
|
|
224
|
+
return g = { next: verb(0), "throw": verb(1), "return": verb(2) }, typeof Symbol === "function" && (g[Symbol.iterator] = function() {
|
|
225
|
+
return this;
|
|
226
|
+
}), g;
|
|
227
|
+
function verb(n) {
|
|
228
|
+
return function(v) {
|
|
229
|
+
return step([n, v]);
|
|
230
|
+
};
|
|
231
|
+
}
|
|
232
|
+
function step(op) {
|
|
233
|
+
if (f) throw new TypeError("Generator is already executing.");
|
|
234
|
+
while (_) try {
|
|
235
|
+
if (f = 1, y && (t = op[0] & 2 ? y["return"] : op[0] ? y["throw"] || ((t = y["return"]) && t.call(y), 0) : y.next) && !(t = t.call(y, op[1])).done) return t;
|
|
236
|
+
if (y = 0, t) op = [op[0] & 2, t.value];
|
|
237
|
+
switch (op[0]) {
|
|
238
|
+
case 0:
|
|
239
|
+
case 1:
|
|
240
|
+
t = op;
|
|
241
|
+
break;
|
|
242
|
+
case 4:
|
|
243
|
+
_.label++;
|
|
244
|
+
return { value: op[1], done: false };
|
|
245
|
+
case 5:
|
|
246
|
+
_.label++;
|
|
247
|
+
y = op[1];
|
|
248
|
+
op = [0];
|
|
249
|
+
continue;
|
|
250
|
+
case 7:
|
|
251
|
+
op = _.ops.pop();
|
|
252
|
+
_.trys.pop();
|
|
253
|
+
continue;
|
|
254
|
+
default:
|
|
255
|
+
if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) {
|
|
256
|
+
_ = 0;
|
|
257
|
+
continue;
|
|
258
|
+
}
|
|
259
|
+
if (op[0] === 3 && (!t || op[1] > t[0] && op[1] < t[3])) {
|
|
260
|
+
_.label = op[1];
|
|
261
|
+
break;
|
|
262
|
+
}
|
|
263
|
+
if (op[0] === 6 && _.label < t[1]) {
|
|
264
|
+
_.label = t[1];
|
|
265
|
+
t = op;
|
|
266
|
+
break;
|
|
267
|
+
}
|
|
268
|
+
if (t && _.label < t[2]) {
|
|
269
|
+
_.label = t[2];
|
|
270
|
+
_.ops.push(op);
|
|
271
|
+
break;
|
|
272
|
+
}
|
|
273
|
+
if (t[2]) _.ops.pop();
|
|
274
|
+
_.trys.pop();
|
|
275
|
+
continue;
|
|
276
|
+
}
|
|
277
|
+
op = body.call(thisArg, _);
|
|
278
|
+
} catch (e) {
|
|
279
|
+
op = [6, e];
|
|
280
|
+
y = 0;
|
|
281
|
+
} finally {
|
|
282
|
+
f = t = 0;
|
|
283
|
+
}
|
|
284
|
+
if (op[0] & 5) throw op[1];
|
|
285
|
+
return { value: op[0] ? op[1] : void 0, done: true };
|
|
286
|
+
}
|
|
287
|
+
};
|
|
288
|
+
Object.defineProperty(exports2, "__esModule", { value: true });
|
|
289
|
+
var delay_base_1 = require_delay_base();
|
|
290
|
+
var SkipFirstDelay = (
|
|
291
|
+
/** @class */
|
|
292
|
+
(function(_super) {
|
|
293
|
+
__extends(SkipFirstDelay2, _super);
|
|
294
|
+
function SkipFirstDelay2() {
|
|
295
|
+
return _super !== null && _super.apply(this, arguments) || this;
|
|
296
|
+
}
|
|
297
|
+
SkipFirstDelay2.prototype.apply = function() {
|
|
298
|
+
return __awaiter(this, void 0, void 0, function() {
|
|
299
|
+
return __generator(this, function(_a) {
|
|
300
|
+
return [2, this.isFirstAttempt ? true : _super.prototype.apply.call(this)];
|
|
301
|
+
});
|
|
302
|
+
});
|
|
303
|
+
};
|
|
304
|
+
Object.defineProperty(SkipFirstDelay2.prototype, "isFirstAttempt", {
|
|
305
|
+
get: function() {
|
|
306
|
+
return this.attempt === 0;
|
|
307
|
+
},
|
|
308
|
+
enumerable: true,
|
|
309
|
+
configurable: true
|
|
310
|
+
});
|
|
311
|
+
Object.defineProperty(SkipFirstDelay2.prototype, "numOfDelayedAttempts", {
|
|
312
|
+
get: function() {
|
|
313
|
+
return this.attempt - 1;
|
|
314
|
+
},
|
|
315
|
+
enumerable: true,
|
|
316
|
+
configurable: true
|
|
317
|
+
});
|
|
318
|
+
return SkipFirstDelay2;
|
|
319
|
+
})(delay_base_1.Delay)
|
|
320
|
+
);
|
|
321
|
+
exports2.SkipFirstDelay = SkipFirstDelay;
|
|
322
|
+
}
|
|
323
|
+
});
|
|
324
|
+
|
|
325
|
+
// node_modules/exponential-backoff/dist/delay/always/always.delay.js
|
|
326
|
+
var require_always_delay = __commonJS({
|
|
327
|
+
"node_modules/exponential-backoff/dist/delay/always/always.delay.js"(exports2) {
|
|
328
|
+
"use strict";
|
|
329
|
+
var __extends = exports2 && exports2.__extends || /* @__PURE__ */ (function() {
|
|
330
|
+
var extendStatics = function(d, b) {
|
|
331
|
+
extendStatics = Object.setPrototypeOf || { __proto__: [] } instanceof Array && function(d2, b2) {
|
|
332
|
+
d2.__proto__ = b2;
|
|
333
|
+
} || function(d2, b2) {
|
|
334
|
+
for (var p in b2) if (b2.hasOwnProperty(p)) d2[p] = b2[p];
|
|
335
|
+
};
|
|
336
|
+
return extendStatics(d, b);
|
|
337
|
+
};
|
|
338
|
+
return function(d, b) {
|
|
339
|
+
extendStatics(d, b);
|
|
340
|
+
function __() {
|
|
341
|
+
this.constructor = d;
|
|
342
|
+
}
|
|
343
|
+
d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
|
|
344
|
+
};
|
|
345
|
+
})();
|
|
346
|
+
Object.defineProperty(exports2, "__esModule", { value: true });
|
|
347
|
+
var delay_base_1 = require_delay_base();
|
|
348
|
+
var AlwaysDelay = (
|
|
349
|
+
/** @class */
|
|
350
|
+
(function(_super) {
|
|
351
|
+
__extends(AlwaysDelay2, _super);
|
|
352
|
+
function AlwaysDelay2() {
|
|
353
|
+
return _super !== null && _super.apply(this, arguments) || this;
|
|
354
|
+
}
|
|
355
|
+
return AlwaysDelay2;
|
|
356
|
+
})(delay_base_1.Delay)
|
|
357
|
+
);
|
|
358
|
+
exports2.AlwaysDelay = AlwaysDelay;
|
|
359
|
+
}
|
|
360
|
+
});
|
|
361
|
+
|
|
362
|
+
// node_modules/exponential-backoff/dist/delay/delay.factory.js
|
|
363
|
+
var require_delay_factory = __commonJS({
|
|
364
|
+
"node_modules/exponential-backoff/dist/delay/delay.factory.js"(exports2) {
|
|
365
|
+
"use strict";
|
|
366
|
+
Object.defineProperty(exports2, "__esModule", { value: true });
|
|
367
|
+
var skip_first_delay_1 = require_skip_first_delay();
|
|
368
|
+
var always_delay_1 = require_always_delay();
|
|
369
|
+
function DelayFactory(options, attempt) {
|
|
370
|
+
var delay = initDelayClass(options);
|
|
371
|
+
delay.setAttemptNumber(attempt);
|
|
372
|
+
return delay;
|
|
373
|
+
}
|
|
374
|
+
exports2.DelayFactory = DelayFactory;
|
|
375
|
+
function initDelayClass(options) {
|
|
376
|
+
if (!options.delayFirstAttempt) {
|
|
377
|
+
return new skip_first_delay_1.SkipFirstDelay(options);
|
|
378
|
+
}
|
|
379
|
+
return new always_delay_1.AlwaysDelay(options);
|
|
380
|
+
}
|
|
381
|
+
}
|
|
382
|
+
});
|
|
383
|
+
|
|
384
|
+
// node_modules/exponential-backoff/dist/backoff.js
|
|
385
|
+
var require_backoff = __commonJS({
|
|
386
|
+
"node_modules/exponential-backoff/dist/backoff.js"(exports2) {
|
|
387
|
+
"use strict";
|
|
388
|
+
var __awaiter = exports2 && exports2.__awaiter || function(thisArg, _arguments, P, generator) {
|
|
389
|
+
function adopt(value) {
|
|
390
|
+
return value instanceof P ? value : new P(function(resolve) {
|
|
391
|
+
resolve(value);
|
|
392
|
+
});
|
|
393
|
+
}
|
|
394
|
+
return new (P || (P = Promise))(function(resolve, reject) {
|
|
395
|
+
function fulfilled(value) {
|
|
396
|
+
try {
|
|
397
|
+
step(generator.next(value));
|
|
398
|
+
} catch (e) {
|
|
399
|
+
reject(e);
|
|
400
|
+
}
|
|
401
|
+
}
|
|
402
|
+
function rejected(value) {
|
|
403
|
+
try {
|
|
404
|
+
step(generator["throw"](value));
|
|
405
|
+
} catch (e) {
|
|
406
|
+
reject(e);
|
|
407
|
+
}
|
|
408
|
+
}
|
|
409
|
+
function step(result) {
|
|
410
|
+
result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected);
|
|
411
|
+
}
|
|
412
|
+
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
|
413
|
+
});
|
|
414
|
+
};
|
|
415
|
+
var __generator = exports2 && exports2.__generator || function(thisArg, body) {
|
|
416
|
+
var _ = { label: 0, sent: function() {
|
|
417
|
+
if (t[0] & 1) throw t[1];
|
|
418
|
+
return t[1];
|
|
419
|
+
}, trys: [], ops: [] }, f, y, t, g;
|
|
420
|
+
return g = { next: verb(0), "throw": verb(1), "return": verb(2) }, typeof Symbol === "function" && (g[Symbol.iterator] = function() {
|
|
421
|
+
return this;
|
|
422
|
+
}), g;
|
|
423
|
+
function verb(n) {
|
|
424
|
+
return function(v) {
|
|
425
|
+
return step([n, v]);
|
|
426
|
+
};
|
|
427
|
+
}
|
|
428
|
+
function step(op) {
|
|
429
|
+
if (f) throw new TypeError("Generator is already executing.");
|
|
430
|
+
while (_) try {
|
|
431
|
+
if (f = 1, y && (t = op[0] & 2 ? y["return"] : op[0] ? y["throw"] || ((t = y["return"]) && t.call(y), 0) : y.next) && !(t = t.call(y, op[1])).done) return t;
|
|
432
|
+
if (y = 0, t) op = [op[0] & 2, t.value];
|
|
433
|
+
switch (op[0]) {
|
|
434
|
+
case 0:
|
|
435
|
+
case 1:
|
|
436
|
+
t = op;
|
|
437
|
+
break;
|
|
438
|
+
case 4:
|
|
439
|
+
_.label++;
|
|
440
|
+
return { value: op[1], done: false };
|
|
441
|
+
case 5:
|
|
442
|
+
_.label++;
|
|
443
|
+
y = op[1];
|
|
444
|
+
op = [0];
|
|
445
|
+
continue;
|
|
446
|
+
case 7:
|
|
447
|
+
op = _.ops.pop();
|
|
448
|
+
_.trys.pop();
|
|
449
|
+
continue;
|
|
450
|
+
default:
|
|
451
|
+
if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) {
|
|
452
|
+
_ = 0;
|
|
453
|
+
continue;
|
|
454
|
+
}
|
|
455
|
+
if (op[0] === 3 && (!t || op[1] > t[0] && op[1] < t[3])) {
|
|
456
|
+
_.label = op[1];
|
|
457
|
+
break;
|
|
458
|
+
}
|
|
459
|
+
if (op[0] === 6 && _.label < t[1]) {
|
|
460
|
+
_.label = t[1];
|
|
461
|
+
t = op;
|
|
462
|
+
break;
|
|
463
|
+
}
|
|
464
|
+
if (t && _.label < t[2]) {
|
|
465
|
+
_.label = t[2];
|
|
466
|
+
_.ops.push(op);
|
|
467
|
+
break;
|
|
468
|
+
}
|
|
469
|
+
if (t[2]) _.ops.pop();
|
|
470
|
+
_.trys.pop();
|
|
471
|
+
continue;
|
|
472
|
+
}
|
|
473
|
+
op = body.call(thisArg, _);
|
|
474
|
+
} catch (e) {
|
|
475
|
+
op = [6, e];
|
|
476
|
+
y = 0;
|
|
477
|
+
} finally {
|
|
478
|
+
f = t = 0;
|
|
479
|
+
}
|
|
480
|
+
if (op[0] & 5) throw op[1];
|
|
481
|
+
return { value: op[0] ? op[1] : void 0, done: true };
|
|
482
|
+
}
|
|
483
|
+
};
|
|
484
|
+
Object.defineProperty(exports2, "__esModule", { value: true });
|
|
485
|
+
var options_1 = require_options();
|
|
486
|
+
var delay_factory_1 = require_delay_factory();
|
|
487
|
+
function backOff2(request, options) {
|
|
488
|
+
if (options === void 0) {
|
|
489
|
+
options = {};
|
|
490
|
+
}
|
|
491
|
+
return __awaiter(this, void 0, void 0, function() {
|
|
492
|
+
var sanitizedOptions, backOff3;
|
|
493
|
+
return __generator(this, function(_a) {
|
|
494
|
+
switch (_a.label) {
|
|
495
|
+
case 0:
|
|
496
|
+
sanitizedOptions = options_1.getSanitizedOptions(options);
|
|
497
|
+
backOff3 = new BackOff(request, sanitizedOptions);
|
|
498
|
+
return [4, backOff3.execute()];
|
|
499
|
+
case 1:
|
|
500
|
+
return [2, _a.sent()];
|
|
501
|
+
}
|
|
502
|
+
});
|
|
503
|
+
});
|
|
504
|
+
}
|
|
505
|
+
exports2.backOff = backOff2;
|
|
506
|
+
var BackOff = (
|
|
507
|
+
/** @class */
|
|
508
|
+
(function() {
|
|
509
|
+
function BackOff2(request, options) {
|
|
510
|
+
this.request = request;
|
|
511
|
+
this.options = options;
|
|
512
|
+
this.attemptNumber = 0;
|
|
513
|
+
}
|
|
514
|
+
BackOff2.prototype.execute = function() {
|
|
515
|
+
return __awaiter(this, void 0, void 0, function() {
|
|
516
|
+
var e_1, shouldRetry;
|
|
517
|
+
return __generator(this, function(_a) {
|
|
518
|
+
switch (_a.label) {
|
|
519
|
+
case 0:
|
|
520
|
+
if (!!this.attemptLimitReached) return [3, 7];
|
|
521
|
+
_a.label = 1;
|
|
522
|
+
case 1:
|
|
523
|
+
_a.trys.push([1, 4, , 6]);
|
|
524
|
+
return [4, this.applyDelay()];
|
|
525
|
+
case 2:
|
|
526
|
+
_a.sent();
|
|
527
|
+
return [4, this.request()];
|
|
528
|
+
case 3:
|
|
529
|
+
return [2, _a.sent()];
|
|
530
|
+
case 4:
|
|
531
|
+
e_1 = _a.sent();
|
|
532
|
+
this.attemptNumber++;
|
|
533
|
+
return [4, this.options.retry(e_1, this.attemptNumber)];
|
|
534
|
+
case 5:
|
|
535
|
+
shouldRetry = _a.sent();
|
|
536
|
+
if (!shouldRetry || this.attemptLimitReached) {
|
|
537
|
+
throw e_1;
|
|
538
|
+
}
|
|
539
|
+
return [3, 6];
|
|
540
|
+
case 6:
|
|
541
|
+
return [3, 0];
|
|
542
|
+
case 7:
|
|
543
|
+
throw new Error("Something went wrong.");
|
|
544
|
+
}
|
|
545
|
+
});
|
|
546
|
+
});
|
|
547
|
+
};
|
|
548
|
+
Object.defineProperty(BackOff2.prototype, "attemptLimitReached", {
|
|
549
|
+
get: function() {
|
|
550
|
+
return this.attemptNumber >= this.options.numOfAttempts;
|
|
551
|
+
},
|
|
552
|
+
enumerable: true,
|
|
553
|
+
configurable: true
|
|
554
|
+
});
|
|
555
|
+
BackOff2.prototype.applyDelay = function() {
|
|
556
|
+
return __awaiter(this, void 0, void 0, function() {
|
|
557
|
+
var delay;
|
|
558
|
+
return __generator(this, function(_a) {
|
|
559
|
+
switch (_a.label) {
|
|
560
|
+
case 0:
|
|
561
|
+
delay = delay_factory_1.DelayFactory(this.options, this.attemptNumber);
|
|
562
|
+
return [4, delay.apply()];
|
|
563
|
+
case 1:
|
|
564
|
+
_a.sent();
|
|
565
|
+
return [
|
|
566
|
+
2
|
|
567
|
+
/*return*/
|
|
568
|
+
];
|
|
569
|
+
}
|
|
570
|
+
});
|
|
571
|
+
});
|
|
572
|
+
};
|
|
573
|
+
return BackOff2;
|
|
574
|
+
})()
|
|
575
|
+
);
|
|
576
|
+
}
|
|
577
|
+
});
|
|
578
|
+
|
|
20
579
|
// src/handler/index.ts
|
|
21
580
|
var index_exports = {};
|
|
22
581
|
__export(index_exports, {
|
|
@@ -24,7 +583,24 @@ __export(index_exports, {
|
|
|
24
583
|
});
|
|
25
584
|
module.exports = __toCommonJS(index_exports);
|
|
26
585
|
var import_client_ssm = require("@aws-sdk/client-ssm");
|
|
586
|
+
var import_exponential_backoff = __toESM(require_backoff());
|
|
27
587
|
var ssmClient = new import_client_ssm.SSMClient({});
|
|
588
|
+
var retryOptions = {
|
|
589
|
+
startingDelay: 5e3,
|
|
590
|
+
timeMultiple: 3,
|
|
591
|
+
numOfAttempts: 4,
|
|
592
|
+
jitter: "none"
|
|
593
|
+
};
|
|
594
|
+
async function fetchWithRetry(url, options, errorMessage, allow404) {
|
|
595
|
+
return (0, import_exponential_backoff.backOff)(async () => {
|
|
596
|
+
const response = await fetch(url, options);
|
|
597
|
+
if (!response.ok && !(allow404 && response.status === 404)) {
|
|
598
|
+
const errorText = await response.text();
|
|
599
|
+
throw new Error(`${errorMessage}: ${response.status} ${errorText}`);
|
|
600
|
+
}
|
|
601
|
+
return response;
|
|
602
|
+
}, retryOptions);
|
|
603
|
+
}
|
|
28
604
|
async function getApiToken(parameterName) {
|
|
29
605
|
const command = new import_client_ssm.GetParameterCommand({
|
|
30
606
|
Name: parameterName,
|
|
@@ -67,7 +643,7 @@ async function handler(event) {
|
|
|
67
643
|
if (ResourceProperties.Encryption) {
|
|
68
644
|
body.encryption = ResourceProperties.Encryption;
|
|
69
645
|
}
|
|
70
|
-
const response = await
|
|
646
|
+
const response = await fetchWithRetry(
|
|
71
647
|
`${baseUrl}/organizations/${orgSlug}/databases`,
|
|
72
648
|
{
|
|
73
649
|
method: "POST",
|
|
@@ -76,14 +652,10 @@ async function handler(event) {
|
|
|
76
652
|
"Content-Type": "application/json"
|
|
77
653
|
},
|
|
78
654
|
body: JSON.stringify(body)
|
|
79
|
-
}
|
|
655
|
+
},
|
|
656
|
+
"Failed to create database",
|
|
657
|
+
false
|
|
80
658
|
);
|
|
81
|
-
if (!response.ok) {
|
|
82
|
-
const errorText = await response.text();
|
|
83
|
-
throw new Error(
|
|
84
|
-
`Failed to create database: ${response.status} ${errorText}`
|
|
85
|
-
);
|
|
86
|
-
}
|
|
87
659
|
const data = await response.json();
|
|
88
660
|
return {
|
|
89
661
|
PhysicalResourceId: dbName,
|
|
@@ -102,7 +674,7 @@ async function handler(event) {
|
|
|
102
674
|
name: newDbName,
|
|
103
675
|
group: ResourceProperties.Group
|
|
104
676
|
};
|
|
105
|
-
const response = await
|
|
677
|
+
const response = await fetchWithRetry(
|
|
106
678
|
`${baseUrl}/organizations/${orgSlug}/databases`,
|
|
107
679
|
{
|
|
108
680
|
method: "POST",
|
|
@@ -111,14 +683,10 @@ async function handler(event) {
|
|
|
111
683
|
"Content-Type": "application/json"
|
|
112
684
|
},
|
|
113
685
|
body: JSON.stringify(body)
|
|
114
|
-
}
|
|
686
|
+
},
|
|
687
|
+
"Failed to create database",
|
|
688
|
+
false
|
|
115
689
|
);
|
|
116
|
-
if (!response.ok) {
|
|
117
|
-
const errorText = await response.text();
|
|
118
|
-
throw new Error(
|
|
119
|
-
`Failed to create database: ${response.status} ${errorText}`
|
|
120
|
-
);
|
|
121
|
-
}
|
|
122
690
|
const data = await response.json();
|
|
123
691
|
return {
|
|
124
692
|
PhysicalResourceId: newDbName,
|
|
@@ -141,21 +709,17 @@ async function handler(event) {
|
|
|
141
709
|
return { PhysicalResourceId };
|
|
142
710
|
}
|
|
143
711
|
const dbNameToDelete = encodeURIComponent(PhysicalResourceId);
|
|
144
|
-
|
|
712
|
+
await fetchWithRetry(
|
|
145
713
|
`${baseUrl}/organizations/${orgSlug}/databases/${dbNameToDelete}`,
|
|
146
714
|
{
|
|
147
715
|
method: "DELETE",
|
|
148
716
|
headers: {
|
|
149
717
|
Authorization: `Bearer ${apiToken}`
|
|
150
718
|
}
|
|
151
|
-
}
|
|
719
|
+
},
|
|
720
|
+
"Failed to delete database",
|
|
721
|
+
true
|
|
152
722
|
);
|
|
153
|
-
if (!response.ok && response.status !== 404) {
|
|
154
|
-
const errorText = await response.text();
|
|
155
|
-
throw new Error(
|
|
156
|
-
`Failed to delete database: ${response.status} ${errorText}`
|
|
157
|
-
);
|
|
158
|
-
}
|
|
159
723
|
return { PhysicalResourceId };
|
|
160
724
|
}
|
|
161
725
|
throw new Error(`Unknown request type: ${RequestType}`);
|
package/lib/turso-database.js
CHANGED
|
@@ -21,6 +21,7 @@ class TursoDatabase extends constructs_1.Construct {
|
|
|
21
21
|
runtime: new aws_lambda_1.Runtime("nodejs24.x", aws_lambda_1.RuntimeFamily.NODEJS),
|
|
22
22
|
handler: "index.handler",
|
|
23
23
|
code: aws_lambda_1.Code.fromAsset(path.join(__dirname, "handler")),
|
|
24
|
+
timeout: aws_cdk_lib_1.Duration.minutes(3),
|
|
24
25
|
environment: {
|
|
25
26
|
TURSO_API_TOKEN_PARAMETER_NAME: props.apiToken.parameterName,
|
|
26
27
|
},
|
|
@@ -54,5 +55,5 @@ class TursoDatabase extends constructs_1.Construct {
|
|
|
54
55
|
}
|
|
55
56
|
exports.TursoDatabase = TursoDatabase;
|
|
56
57
|
_a = JSII_RTTI_SYMBOL_1;
|
|
57
|
-
TursoDatabase[_a] = { fqn: "cdk-turso.TursoDatabase", version: "0.0.
|
|
58
|
-
//# sourceMappingURL=data:application/json;base64,
|
|
58
|
+
TursoDatabase[_a] = { fqn: "cdk-turso.TursoDatabase", version: "0.0.3" };
|
|
59
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidHVyc28tZGF0YWJhc2UuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi9zcmMvdHVyc28tZGF0YWJhc2UudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6Ijs7Ozs7QUFBQSw2Q0FBc0Q7QUFDdEQsdURBQStFO0FBRS9FLG1FQUF1RDtBQUN2RCwyQ0FBc0M7QUFDdEMsNkJBQTRCO0FBdUI1QixNQUFhLGFBQWMsU0FBUSxzQkFBUztJQVMxQyxZQUFZLEtBQWdCLEVBQUUsRUFBVSxFQUFFLEtBQXlCO1FBQ2pFLEtBQUssQ0FBQyxLQUFLLEVBQUUsRUFBRSxDQUFDLENBQUE7UUFFaEIsSUFBSSxDQUFDLGNBQWMsQ0FBQyxJQUFJLENBQUMsS0FBSyxDQUFDLFlBQVksQ0FBQyxFQUFFLENBQUM7WUFDN0MsTUFBTSxJQUFJLEtBQUssQ0FDYix1RUFBdUUsQ0FDeEUsQ0FBQTtRQUNILENBQUM7UUFDRCxJQUFJLEtBQUssQ0FBQyxZQUFZLENBQUMsTUFBTSxHQUFHLEVBQUUsRUFBRSxDQUFDO1lBQ25DLE1BQU0sSUFBSSxLQUFLLENBQUMsNENBQTRDLENBQUMsQ0FBQTtRQUMvRCxDQUFDO1FBRUQsTUFBTSxPQUFPLEdBQUcsSUFBSSxxQkFBUSxDQUFDLElBQUksRUFBRSxTQUFTLEVBQUU7WUFDNUMsT0FBTyxFQUFFLElBQUksb0JBQU8sQ0FBQyxZQUFZLEVBQUUsMEJBQWEsQ0FBQyxNQUFNLENBQUM7WUFDeEQsT0FBTyxFQUFFLGVBQWU7WUFDeEIsSUFBSSxFQUFFLGlCQUFJLENBQUMsU0FBUyxDQUFDLElBQUksQ0FBQyxJQUFJLENBQUMsU0FBUyxFQUFFLFNBQVMsQ0FBQyxDQUFDO1lBQ3JELE9BQU8sRUFBRSxzQkFBUSxDQUFDLE9BQU8sQ0FBQyxDQUFDLENBQUM7WUFDNUIsV0FBVyxFQUFFO2dCQUNYLDhCQUE4QixFQUFFLEtBQUssQ0FBQyxRQUFRLENBQUMsYUFBYTthQUM3RDtTQUNGLENBQUMsQ0FBQTtRQUVGLEtBQUssQ0FBQyxRQUFRLENBQUMsU0FBUyxDQUFDLE9BQU8sQ0FBQyxDQUFBO1FBRWpDLE1BQU0sUUFBUSxHQUFHLElBQUksMkJBQVEsQ0FBQyxJQUFJLEVBQUUsVUFBVSxFQUFFO1lBQzlDLGNBQWMsRUFBRSxPQUFPO1NBQ3hCLENBQUMsQ0FBQTtRQUVGLE1BQU0sYUFBYSxHQUE0QjtZQUM3QyxZQUFZLEVBQUUsS0FBSyxDQUFDLFlBQVk7WUFDaEMsS0FBSyxFQUFFLEtBQUssQ0FBQyxLQUFLO1lBQ2xCLGdCQUFnQixFQUFFLEtBQUssQ0FBQyxnQkFBZ0I7U0FDekMsQ0FBQTtRQUVELElBQUksS0FBSyxDQUFDLFNBQVMsRUFBRSxDQUFDO1lBQ3BCLGFBQWEsQ0FBQyxTQUFTLEdBQUcsS0FBSyxDQUFDLFNBQVMsQ0FBQTtRQUMzQyxDQUFDO1FBQ0QsSUFBSSxLQUFLLENBQUMsSUFBSSxFQUFFLENBQUM7WUFDZixhQUFhLENBQUMsSUFBSSxHQUFHLEtBQUssQ0FBQyxJQUFJLENBQUE7UUFDakMsQ0FBQztRQUNELElBQUksS0FBSyxDQUFDLFVBQVUsRUFBRSxDQUFDO1lBQ3JCLGFBQWEsQ0FBQyxVQUFVLEdBQUcsS0FBSyxDQUFDLFVBQVUsQ0FBQTtRQUM3QyxDQUFDO1FBRUQsTUFBTSxFQUFFLEdBQUcsSUFBSSw0QkFBYyxDQUFDLElBQUksRUFBRSxnQkFBZ0IsRUFBRTtZQUNwRCxZQUFZLEVBQUUsUUFBUSxDQUFDLFlBQVk7WUFDbkMsVUFBVSxFQUFFLGFBQWE7U0FDMUIsQ0FBQyxDQUFBO1FBRUYsSUFBSSxDQUFDLElBQUksR0FBRyxFQUFFLENBQUMsWUFBWSxDQUFDLE1BQU0sQ0FBQyxDQUFBO1FBQ25DLElBQUksQ0FBQyxRQUFRLEdBQUcsRUFBRSxDQUFDLFlBQVksQ0FBQyxVQUFVLENBQUMsQ0FBQTtRQUMzQyxJQUFJLENBQUMsWUFBWSxHQUFHLEVBQUUsQ0FBQyxZQUFZLENBQUMsTUFBTSxDQUFDLENBQUE7SUFDN0MsQ0FBQzs7QUE3REgsc0NBOERDIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHsgQ3VzdG9tUmVzb3VyY2UsIER1cmF0aW9uIH0gZnJvbSBcImF3cy1jZGstbGliXCJcbmltcG9ydCB7IENvZGUsIEZ1bmN0aW9uLCBSdW50aW1lLCBSdW50aW1lRmFtaWx5IH0gZnJvbSBcImF3cy1jZGstbGliL2F3cy1sYW1iZGFcIlxuaW1wb3J0IHR5cGUgeyBJUGFyYW1ldGVyIH0gZnJvbSBcImF3cy1jZGstbGliL2F3cy1zc21cIlxuaW1wb3J0IHsgUHJvdmlkZXIgfSBmcm9tIFwiYXdzLWNkay1saWIvY3VzdG9tLXJlc291cmNlc1wiXG5pbXBvcnQgeyBDb25zdHJ1Y3QgfSBmcm9tIFwiY29uc3RydWN0c1wiXG5pbXBvcnQgKiBhcyBwYXRoIGZyb20gXCJwYXRoXCJcblxuZXhwb3J0IGludGVyZmFjZSBUdXJzb0RhdGFiYXNlU2VlZCB7XG4gIHJlYWRvbmx5IHR5cGU6IHN0cmluZ1xuICByZWFkb25seSBuYW1lOiBzdHJpbmdcbiAgcmVhZG9ubHkgdGltZXN0YW1wPzogc3RyaW5nXG59XG5cbmV4cG9ydCBpbnRlcmZhY2UgVHVyc29EYXRhYmFzZUVuY3J5cHRpb24ge1xuICByZWFkb25seSBlbmNyeXB0aW9uS2V5OiBzdHJpbmdcbiAgcmVhZG9ubHkgZW5jcnlwdGlvbkNpcGhlcjogc3RyaW5nXG59XG5cbmV4cG9ydCBpbnRlcmZhY2UgVHVyc29EYXRhYmFzZVByb3BzIHtcbiAgcmVhZG9ubHkgZGF0YWJhc2VOYW1lOiBzdHJpbmdcbiAgcmVhZG9ubHkgZ3JvdXA6IHN0cmluZ1xuICByZWFkb25seSBvcmdhbml6YXRpb25TbHVnOiBzdHJpbmdcbiAgcmVhZG9ubHkgYXBpVG9rZW46IElQYXJhbWV0ZXJcbiAgcmVhZG9ubHkgc2l6ZUxpbWl0Pzogc3RyaW5nXG4gIHJlYWRvbmx5IHNlZWQ/OiBUdXJzb0RhdGFiYXNlU2VlZFxuICByZWFkb25seSBlbmNyeXB0aW9uPzogVHVyc29EYXRhYmFzZUVuY3J5cHRpb25cbn1cblxuZXhwb3J0IGNsYXNzIFR1cnNvRGF0YWJhc2UgZXh0ZW5kcyBDb25zdHJ1Y3Qge1xuICBwdWJsaWMgcmVhZG9ubHkgZGJJZDogc3RyaW5nXG4gIC8qKlxuICAgKiBETlMgaG9zdG5hbWUgZm9yIHRoZSBkYXRhYmFzZSAoZS5nLiwgYG15LWRiLW15LW9yZy50dXJzby5pb2ApLlxuICAgKiBVc2Ugd2l0aCBsaWJTUUwgb3IgSFRUUCBjb25uZWN0aW9ucy5cbiAgICovXG4gIHB1YmxpYyByZWFkb25seSBob3N0bmFtZTogc3RyaW5nXG4gIHB1YmxpYyByZWFkb25seSBkYXRhYmFzZU5hbWU6IHN0cmluZ1xuXG4gIGNvbnN0cnVjdG9yKHNjb3BlOiBDb25zdHJ1Y3QsIGlkOiBzdHJpbmcsIHByb3BzOiBUdXJzb0RhdGFiYXNlUHJvcHMpIHtcbiAgICBzdXBlcihzY29wZSwgaWQpXG5cbiAgICBpZiAoIS9eW2EtejAtOS1dKyQvLnRlc3QocHJvcHMuZGF0YWJhc2VOYW1lKSkge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKFxuICAgICAgICBcImRhdGFiYXNlTmFtZSBtdXN0IGNvbnRhaW4gb25seSBsb3dlcmNhc2UgbGV0dGVycywgbnVtYmVycywgYW5kIGRhc2hlc1wiLFxuICAgICAgKVxuICAgIH1cbiAgICBpZiAocHJvcHMuZGF0YWJhc2VOYW1lLmxlbmd0aCA+IDY0KSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoXCJkYXRhYmFzZU5hbWUgbXVzdCBiZSBhdCBtb3N0IDY0IGNoYXJhY3RlcnNcIilcbiAgICB9XG5cbiAgICBjb25zdCBoYW5kbGVyID0gbmV3IEZ1bmN0aW9uKHRoaXMsIFwiSGFuZGxlclwiLCB7XG4gICAgICBydW50aW1lOiBuZXcgUnVudGltZShcIm5vZGVqczI0LnhcIiwgUnVudGltZUZhbWlseS5OT0RFSlMpLFxuICAgICAgaGFuZGxlcjogXCJpbmRleC5oYW5kbGVyXCIsXG4gICAgICBjb2RlOiBDb2RlLmZyb21Bc3NldChwYXRoLmpvaW4oX19kaXJuYW1lLCBcImhhbmRsZXJcIikpLFxuICAgICAgdGltZW91dDogRHVyYXRpb24ubWludXRlcygzKSxcbiAgICAgIGVudmlyb25tZW50OiB7XG4gICAgICAgIFRVUlNPX0FQSV9UT0tFTl9QQVJBTUVURVJfTkFNRTogcHJvcHMuYXBpVG9rZW4ucGFyYW1ldGVyTmFtZSxcbiAgICAgIH0sXG4gICAgfSlcblxuICAgIHByb3BzLmFwaVRva2VuLmdyYW50UmVhZChoYW5kbGVyKVxuXG4gICAgY29uc3QgcHJvdmlkZXIgPSBuZXcgUHJvdmlkZXIodGhpcywgXCJQcm92aWRlclwiLCB7XG4gICAgICBvbkV2ZW50SGFuZGxlcjogaGFuZGxlcixcbiAgICB9KVxuXG4gICAgY29uc3QgcmVzb3VyY2VQcm9wczogUmVjb3JkPHN0cmluZywgdW5rbm93bj4gPSB7XG4gICAgICBEYXRhYmFzZU5hbWU6IHByb3BzLmRhdGFiYXNlTmFtZSxcbiAgICAgIEdyb3VwOiBwcm9wcy5ncm91cCxcbiAgICAgIE9yZ2FuaXphdGlvblNsdWc6IHByb3BzLm9yZ2FuaXphdGlvblNsdWcsXG4gICAgfVxuXG4gICAgaWYgKHByb3BzLnNpemVMaW1pdCkge1xuICAgICAgcmVzb3VyY2VQcm9wcy5TaXplTGltaXQgPSBwcm9wcy5zaXplTGltaXRcbiAgICB9XG4gICAgaWYgKHByb3BzLnNlZWQpIHtcbiAgICAgIHJlc291cmNlUHJvcHMuU2VlZCA9IHByb3BzLnNlZWRcbiAgICB9XG4gICAgaWYgKHByb3BzLmVuY3J5cHRpb24pIHtcbiAgICAgIHJlc291cmNlUHJvcHMuRW5jcnlwdGlvbiA9IHByb3BzLmVuY3J5cHRpb25cbiAgICB9XG5cbiAgICBjb25zdCBjciA9IG5ldyBDdXN0b21SZXNvdXJjZSh0aGlzLCBcIkN1c3RvbVJlc291cmNlXCIsIHtcbiAgICAgIHNlcnZpY2VUb2tlbjogcHJvdmlkZXIuc2VydmljZVRva2VuLFxuICAgICAgcHJvcGVydGllczogcmVzb3VyY2VQcm9wcyxcbiAgICB9KVxuXG4gICAgdGhpcy5kYklkID0gY3IuZ2V0QXR0U3RyaW5nKFwiRGJJZFwiKVxuICAgIHRoaXMuaG9zdG5hbWUgPSBjci5nZXRBdHRTdHJpbmcoXCJIb3N0bmFtZVwiKVxuICAgIHRoaXMuZGF0YWJhc2VOYW1lID0gY3IuZ2V0QXR0U3RyaW5nKFwiTmFtZVwiKVxuICB9XG59XG4iXX0=
|
package/package.json
CHANGED
|
@@ -42,6 +42,7 @@
|
|
|
42
42
|
"commit-and-tag-version": "^12",
|
|
43
43
|
"constructs": "10.0.5",
|
|
44
44
|
"esbuild": "^0.27.3",
|
|
45
|
+
"exponential-backoff": "^3.1.3",
|
|
45
46
|
"husky": "^9.1.7",
|
|
46
47
|
"jest": "^30.2.0",
|
|
47
48
|
"jest-junit": "^16",
|
|
@@ -67,7 +68,7 @@
|
|
|
67
68
|
"publishConfig": {
|
|
68
69
|
"access": "public"
|
|
69
70
|
},
|
|
70
|
-
"version": "0.0.
|
|
71
|
+
"version": "0.0.3",
|
|
71
72
|
"jest": {
|
|
72
73
|
"coverageProvider": "v8",
|
|
73
74
|
"testMatch": [
|