@chaim-tools/cdk-lib 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (39) hide show
  1. package/README.md +238 -0
  2. package/lib/binders/base-chaim-binder.d.ts +144 -0
  3. package/lib/binders/base-chaim-binder.js +532 -0
  4. package/lib/binders/chaim-dynamodb-binder.d.ts +95 -0
  5. package/lib/binders/chaim-dynamodb-binder.js +292 -0
  6. package/lib/config/chaim-endpoints.d.ts +47 -0
  7. package/lib/config/chaim-endpoints.js +51 -0
  8. package/lib/index.d.ts +15 -0
  9. package/lib/index.js +43 -0
  10. package/lib/lambda-handler/.test-temp/snapshot.json +1 -0
  11. package/lib/lambda-handler/handler.js +513 -0
  12. package/lib/lambda-handler/handler.test.ts +365 -0
  13. package/lib/lambda-handler/package-lock.json +1223 -0
  14. package/lib/lambda-handler/package.json +14 -0
  15. package/lib/services/ingestion-service.d.ts +50 -0
  16. package/lib/services/ingestion-service.js +81 -0
  17. package/lib/services/os-cache-paths.d.ts +52 -0
  18. package/lib/services/os-cache-paths.js +123 -0
  19. package/lib/services/schema-service.d.ts +11 -0
  20. package/lib/services/schema-service.js +67 -0
  21. package/lib/services/snapshot-cleanup.d.ts +78 -0
  22. package/lib/services/snapshot-cleanup.js +220 -0
  23. package/lib/types/base-binder-props.d.ts +32 -0
  24. package/lib/types/base-binder-props.js +17 -0
  25. package/lib/types/credentials.d.ts +57 -0
  26. package/lib/types/credentials.js +83 -0
  27. package/lib/types/data-store-metadata.d.ts +67 -0
  28. package/lib/types/data-store-metadata.js +4 -0
  29. package/lib/types/failure-mode.d.ts +16 -0
  30. package/lib/types/failure-mode.js +21 -0
  31. package/lib/types/ingest-contract.d.ts +110 -0
  32. package/lib/types/ingest-contract.js +12 -0
  33. package/lib/types/snapshot-cache-policy.d.ts +52 -0
  34. package/lib/types/snapshot-cache-policy.js +57 -0
  35. package/lib/types/snapshot-payload.d.ts +245 -0
  36. package/lib/types/snapshot-payload.js +3 -0
  37. package/lib/types/table-binding-config.d.ts +43 -0
  38. package/lib/types/table-binding-config.js +57 -0
  39. package/package.json +67 -0
@@ -0,0 +1,14 @@
1
+ {
2
+ "name": "chaim-lambda-handler",
3
+ "version": "1.0.0",
4
+ "description": "Lambda handler for Chaim CDK custom resource",
5
+ "main": "index.js",
6
+ "type": "commonjs",
7
+ "dependencies": {
8
+ "@types/node": "^20.0.0",
9
+ "@aws-sdk/client-secrets-manager": "^3.0.0"
10
+ },
11
+ "devDependencies": {
12
+ "typescript": "^5.0.0"
13
+ }
14
+ }
@@ -0,0 +1,50 @@
1
+ /**
2
+ * Chaim Ingestion Service
3
+ *
4
+ * Provides utilities for Chaim SaaS ingestion.
5
+ * The actual HTTP requests are made by the Lambda handler at runtime.
6
+ * This service provides compile-time types and configuration utilities.
7
+ */
8
+ import { CHAIM_ENDPOINTS } from '../config/chaim-endpoints';
9
+ /**
10
+ * Configuration for Chaim ingestion API.
11
+ */
12
+ export interface IngestionConfig {
13
+ /** Base URL for Chaim API */
14
+ readonly baseUrl: string;
15
+ /** Request timeout in milliseconds */
16
+ readonly timeoutMs: number;
17
+ /** Number of retry attempts */
18
+ readonly retryAttempts: number;
19
+ }
20
+ /**
21
+ * Default ingestion configuration.
22
+ */
23
+ export declare const DEFAULT_INGESTION_CONFIG: IngestionConfig;
24
+ /**
25
+ * Chaim ingestion API endpoints.
26
+ * Re-exported from centralized config for backwards compatibility.
27
+ */
28
+ export declare const INGESTION_ENDPOINTS: {
29
+ readonly PRESIGN: "/ingest/presign";
30
+ };
31
+ /**
32
+ * IngestionService provides utilities for Chaim SaaS ingestion.
33
+ *
34
+ * The actual HTTP requests are made by the Lambda handler at runtime.
35
+ * This service provides compile-time types and configuration.
36
+ */
37
+ export declare class IngestionService {
38
+ /**
39
+ * Get ingestion configuration from environment or defaults.
40
+ */
41
+ static getConfig(): IngestionConfig;
42
+ /**
43
+ * Build full URL for an ingestion endpoint.
44
+ */
45
+ static buildUrl(endpoint: keyof typeof CHAIM_ENDPOINTS, baseUrl?: string): string;
46
+ /**
47
+ * Compute HMAC-SHA256 signature for request body.
48
+ */
49
+ static computeSignature(body: string, secret: string): string;
50
+ }
@@ -0,0 +1,81 @@
1
+ "use strict";
2
+ /**
3
+ * Chaim Ingestion Service
4
+ *
5
+ * Provides utilities for Chaim SaaS ingestion.
6
+ * The actual HTTP requests are made by the Lambda handler at runtime.
7
+ * This service provides compile-time types and configuration utilities.
8
+ */
9
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ var desc = Object.getOwnPropertyDescriptor(m, k);
12
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
13
+ desc = { enumerable: true, get: function() { return m[k]; } };
14
+ }
15
+ Object.defineProperty(o, k2, desc);
16
+ }) : (function(o, m, k, k2) {
17
+ if (k2 === undefined) k2 = k;
18
+ o[k2] = m[k];
19
+ }));
20
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
21
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
22
+ }) : function(o, v) {
23
+ o["default"] = v;
24
+ });
25
+ var __importStar = (this && this.__importStar) || function (mod) {
26
+ if (mod && mod.__esModule) return mod;
27
+ var result = {};
28
+ if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
29
+ __setModuleDefault(result, mod);
30
+ return result;
31
+ };
32
+ Object.defineProperty(exports, "__esModule", { value: true });
33
+ exports.IngestionService = exports.INGESTION_ENDPOINTS = exports.DEFAULT_INGESTION_CONFIG = void 0;
34
+ const crypto = __importStar(require("crypto"));
35
+ const chaim_endpoints_1 = require("../config/chaim-endpoints");
36
+ /**
37
+ * Default ingestion configuration.
38
+ */
39
+ exports.DEFAULT_INGESTION_CONFIG = {
40
+ baseUrl: chaim_endpoints_1.DEFAULT_CHAIM_API_BASE_URL,
41
+ timeoutMs: chaim_endpoints_1.DEFAULT_REQUEST_TIMEOUT_MS,
42
+ retryAttempts: 3,
43
+ };
44
+ /**
45
+ * Chaim ingestion API endpoints.
46
+ * Re-exported from centralized config for backwards compatibility.
47
+ */
48
+ exports.INGESTION_ENDPOINTS = chaim_endpoints_1.CHAIM_ENDPOINTS;
49
+ /**
50
+ * IngestionService provides utilities for Chaim SaaS ingestion.
51
+ *
52
+ * The actual HTTP requests are made by the Lambda handler at runtime.
53
+ * This service provides compile-time types and configuration.
54
+ */
55
+ class IngestionService {
56
+ /**
57
+ * Get ingestion configuration from environment or defaults.
58
+ */
59
+ static getConfig() {
60
+ return {
61
+ baseUrl: process.env.CHAIM_API_BASE_URL || exports.DEFAULT_INGESTION_CONFIG.baseUrl,
62
+ timeoutMs: parseInt(process.env.CHAIM_API_TIMEOUT || String(exports.DEFAULT_INGESTION_CONFIG.timeoutMs), 10),
63
+ retryAttempts: parseInt(process.env.CHAIM_RETRY_ATTEMPTS || String(exports.DEFAULT_INGESTION_CONFIG.retryAttempts), 10),
64
+ };
65
+ }
66
+ /**
67
+ * Build full URL for an ingestion endpoint.
68
+ */
69
+ static buildUrl(endpoint, baseUrl) {
70
+ const base = baseUrl || exports.DEFAULT_INGESTION_CONFIG.baseUrl;
71
+ return base + chaim_endpoints_1.CHAIM_ENDPOINTS[endpoint];
72
+ }
73
+ /**
74
+ * Compute HMAC-SHA256 signature for request body.
75
+ */
76
+ static computeSignature(body, secret) {
77
+ return crypto.createHmac('sha256', secret).update(body).digest('hex');
78
+ }
79
+ }
80
+ exports.IngestionService = IngestionService;
81
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiaW5nZXN0aW9uLXNlcnZpY2UuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi9zcmMvc2VydmljZXMvaW5nZXN0aW9uLXNlcnZpY2UudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IjtBQUFBOzs7Ozs7R0FNRzs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7QUFFSCwrQ0FBaUM7QUFDakMsK0RBSW1DO0FBZ0JuQzs7R0FFRztBQUNVLFFBQUEsd0JBQXdCLEdBQW9CO0lBQ3ZELE9BQU8sRUFBRSw0Q0FBMEI7SUFDbkMsU0FBUyxFQUFFLDRDQUEwQjtJQUNyQyxhQUFhLEVBQUUsQ0FBQztDQUNqQixDQUFDO0FBRUY7OztHQUdHO0FBQ1UsUUFBQSxtQkFBbUIsR0FBRyxpQ0FBZSxDQUFDO0FBRW5EOzs7OztHQUtHO0FBQ0gsTUFBYSxnQkFBZ0I7SUFDM0I7O09BRUc7SUFDSCxNQUFNLENBQUMsU0FBUztRQUNkLE9BQU87WUFDTCxPQUFPLEVBQUUsT0FBTyxDQUFDLEdBQUcsQ0FBQyxrQkFBa0IsSUFBSSxnQ0FBd0IsQ0FBQyxPQUFPO1lBQzNFLFNBQVMsRUFBRSxRQUFRLENBQUMsT0FBTyxDQUFDLEdBQUcsQ0FBQyxpQkFBaUIsSUFBSSxNQUFNLENBQUMsZ0NBQXdCLENBQUMsU0FBUyxDQUFDLEVBQUUsRUFBRSxDQUFDO1lBQ3BHLGFBQWEsRUFBRSxRQUFRLENBQUMsT0FBTyxDQUFDLEdBQUcsQ0FBQyxvQkFBb0IsSUFBSSxNQUFNLENBQUMsZ0NBQXdCLENBQUMsYUFBYSxDQUFDLEVBQUUsRUFBRSxDQUFDO1NBQ2hILENBQUM7SUFDSixDQUFDO0lBRUQ7O09BRUc7SUFDSCxNQUFNLENBQUMsUUFBUSxDQUFDLFFBQXNDLEVBQUUsT0FBZ0I7UUFDdEUsTUFBTSxJQUFJLEdBQUcsT0FBTyxJQUFJLGdDQUF3QixDQUFDLE9BQU8sQ0FBQztRQUN6RCxPQUFPLElBQUksR0FBRyxpQ0FBZSxDQUFDLFFBQVEsQ0FBQyxDQUFDO0lBQzFDLENBQUM7SUFFRDs7T0FFRztJQUNILE1BQU0sQ0FBQyxnQkFBZ0IsQ0FBQyxJQUFZLEVBQUUsTUFBYztRQUNsRCxPQUFPLE1BQU0sQ0FBQyxVQUFVLENBQUMsUUFBUSxFQUFFLE1BQU0sQ0FBQyxDQUFDLE1BQU0sQ0FBQyxJQUFJLENBQUMsQ0FBQyxNQUFNLENBQUMsS0FBSyxDQUFDLENBQUM7SUFDeEUsQ0FBQztDQUNGO0FBMUJELDRDQTBCQyIsInNvdXJjZXNDb250ZW50IjpbIi8qKlxuICogQ2hhaW0gSW5nZXN0aW9uIFNlcnZpY2VcbiAqIFxuICogUHJvdmlkZXMgdXRpbGl0aWVzIGZvciBDaGFpbSBTYWFTIGluZ2VzdGlvbi5cbiAqIFRoZSBhY3R1YWwgSFRUUCByZXF1ZXN0cyBhcmUgbWFkZSBieSB0aGUgTGFtYmRhIGhhbmRsZXIgYXQgcnVudGltZS5cbiAqIFRoaXMgc2VydmljZSBwcm92aWRlcyBjb21waWxlLXRpbWUgdHlwZXMgYW5kIGNvbmZpZ3VyYXRpb24gdXRpbGl0aWVzLlxuICovXG5cbmltcG9ydCAqIGFzIGNyeXB0byBmcm9tICdjcnlwdG8nO1xuaW1wb3J0IHtcbiAgREVGQVVMVF9DSEFJTV9BUElfQkFTRV9VUkwsXG4gIENIQUlNX0VORFBPSU5UUyxcbiAgREVGQVVMVF9SRVFVRVNUX1RJTUVPVVRfTVMsXG59IGZyb20gJy4uL2NvbmZpZy9jaGFpbS1lbmRwb2ludHMnO1xuXG4vKipcbiAqIENvbmZpZ3VyYXRpb24gZm9yIENoYWltIGluZ2VzdGlvbiBBUEkuXG4gKi9cbmV4cG9ydCBpbnRlcmZhY2UgSW5nZXN0aW9uQ29uZmlnIHtcbiAgLyoqIEJhc2UgVVJMIGZvciBDaGFpbSBBUEkgKi9cbiAgcmVhZG9ubHkgYmFzZVVybDogc3RyaW5nO1xuXG4gIC8qKiBSZXF1ZXN0IHRpbWVvdXQgaW4gbWlsbGlzZWNvbmRzICovXG4gIHJlYWRvbmx5IHRpbWVvdXRNczogbnVtYmVyO1xuXG4gIC8qKiBOdW1iZXIgb2YgcmV0cnkgYXR0ZW1wdHMgKi9cbiAgcmVhZG9ubHkgcmV0cnlBdHRlbXB0czogbnVtYmVyO1xufVxuXG4vKipcbiAqIERlZmF1bHQgaW5nZXN0aW9uIGNvbmZpZ3VyYXRpb24uXG4gKi9cbmV4cG9ydCBjb25zdCBERUZBVUxUX0lOR0VTVElPTl9DT05GSUc6IEluZ2VzdGlvbkNvbmZpZyA9IHtcbiAgYmFzZVVybDogREVGQVVMVF9DSEFJTV9BUElfQkFTRV9VUkwsXG4gIHRpbWVvdXRNczogREVGQVVMVF9SRVFVRVNUX1RJTUVPVVRfTVMsXG4gIHJldHJ5QXR0ZW1wdHM6IDMsXG59O1xuXG4vKipcbiAqIENoYWltIGluZ2VzdGlvbiBBUEkgZW5kcG9pbnRzLlxuICogUmUtZXhwb3J0ZWQgZnJvbSBjZW50cmFsaXplZCBjb25maWcgZm9yIGJhY2t3YXJkcyBjb21wYXRpYmlsaXR5LlxuICovXG5leHBvcnQgY29uc3QgSU5HRVNUSU9OX0VORFBPSU5UUyA9IENIQUlNX0VORFBPSU5UUztcblxuLyoqXG4gKiBJbmdlc3Rpb25TZXJ2aWNlIHByb3ZpZGVzIHV0aWxpdGllcyBmb3IgQ2hhaW0gU2FhUyBpbmdlc3Rpb24uXG4gKiBcbiAqIFRoZSBhY3R1YWwgSFRUUCByZXF1ZXN0cyBhcmUgbWFkZSBieSB0aGUgTGFtYmRhIGhhbmRsZXIgYXQgcnVudGltZS5cbiAqIFRoaXMgc2VydmljZSBwcm92aWRlcyBjb21waWxlLXRpbWUgdHlwZXMgYW5kIGNvbmZpZ3VyYXRpb24uXG4gKi9cbmV4cG9ydCBjbGFzcyBJbmdlc3Rpb25TZXJ2aWNlIHtcbiAgLyoqXG4gICAqIEdldCBpbmdlc3Rpb24gY29uZmlndXJhdGlvbiBmcm9tIGVudmlyb25tZW50IG9yIGRlZmF1bHRzLlxuICAgKi9cbiAgc3RhdGljIGdldENvbmZpZygpOiBJbmdlc3Rpb25Db25maWcge1xuICAgIHJldHVybiB7XG4gICAgICBiYXNlVXJsOiBwcm9jZXNzLmVudi5DSEFJTV9BUElfQkFTRV9VUkwgfHwgREVGQVVMVF9JTkdFU1RJT05fQ09ORklHLmJhc2VVcmwsXG4gICAgICB0aW1lb3V0TXM6IHBhcnNlSW50KHByb2Nlc3MuZW52LkNIQUlNX0FQSV9USU1FT1VUIHx8IFN0cmluZyhERUZBVUxUX0lOR0VTVElPTl9DT05GSUcudGltZW91dE1zKSwgMTApLFxuICAgICAgcmV0cnlBdHRlbXB0czogcGFyc2VJbnQocHJvY2Vzcy5lbnYuQ0hBSU1fUkVUUllfQVRURU1QVFMgfHwgU3RyaW5nKERFRkFVTFRfSU5HRVNUSU9OX0NPTkZJRy5yZXRyeUF0dGVtcHRzKSwgMTApLFxuICAgIH07XG4gIH1cblxuICAvKipcbiAgICogQnVpbGQgZnVsbCBVUkwgZm9yIGFuIGluZ2VzdGlvbiBlbmRwb2ludC5cbiAgICovXG4gIHN0YXRpYyBidWlsZFVybChlbmRwb2ludDoga2V5b2YgdHlwZW9mIENIQUlNX0VORFBPSU5UUywgYmFzZVVybD86IHN0cmluZyk6IHN0cmluZyB7XG4gICAgY29uc3QgYmFzZSA9IGJhc2VVcmwgfHwgREVGQVVMVF9JTkdFU1RJT05fQ09ORklHLmJhc2VVcmw7XG4gICAgcmV0dXJuIGJhc2UgKyBDSEFJTV9FTkRQT0lOVFNbZW5kcG9pbnRdO1xuICB9XG5cbiAgLyoqXG4gICAqIENvbXB1dGUgSE1BQy1TSEEyNTYgc2lnbmF0dXJlIGZvciByZXF1ZXN0IGJvZHkuXG4gICAqL1xuICBzdGF0aWMgY29tcHV0ZVNpZ25hdHVyZShib2R5OiBzdHJpbmcsIHNlY3JldDogc3RyaW5nKTogc3RyaW5nIHtcbiAgICByZXR1cm4gY3J5cHRvLmNyZWF0ZUhtYWMoJ3NoYTI1NicsIHNlY3JldCkudXBkYXRlKGJvZHkpLmRpZ2VzdCgnaGV4Jyk7XG4gIH1cbn1cbiJdfQ==
@@ -0,0 +1,52 @@
1
+ /**
2
+ * Get the default base directory for Chaim snapshots based on OS.
3
+ * - macOS/Linux: ~/.chaim/cache/snapshots
4
+ * - Windows: %LOCALAPPDATA%/chaim/cache/snapshots (or homedir fallback)
5
+ */
6
+ export declare function getDefaultSnapshotBaseDir(): string;
7
+ /**
8
+ * Get the snapshot base directory, respecting CHAIM_SNAPSHOT_DIR override.
9
+ */
10
+ export declare function getSnapshotBaseDir(): string;
11
+ /**
12
+ * Ensure a directory exists, creating it recursively if needed.
13
+ */
14
+ export declare function ensureDirExists(dir: string): void;
15
+ /**
16
+ * Normalize account ID - handles CDK tokens and unresolved values.
17
+ */
18
+ export declare function normalizeAccountId(accountId: string | undefined): string;
19
+ /**
20
+ * Normalize region - handles CDK tokens and unresolved values.
21
+ */
22
+ export declare function normalizeRegion(region: string | undefined): string;
23
+ /**
24
+ * Normalize a resource name by removing CDK tokens and special characters.
25
+ * Used for generating file paths.
26
+ *
27
+ * IMPORTANT: Preserves double underscores (__) as they are used as delimiters
28
+ * in resource IDs (format: {resourceName}__{entityName}).
29
+ */
30
+ export declare function normalizeResourceName(name: string): string;
31
+ /**
32
+ * Parameters for constructing snapshot paths.
33
+ */
34
+ export interface SnapshotPathParams {
35
+ accountId: string;
36
+ region: string;
37
+ stackName: string;
38
+ datastoreType: string;
39
+ resourceId: string;
40
+ }
41
+ /**
42
+ * Get the directory path for LOCAL snapshots.
43
+ */
44
+ export declare function getSnapshotDir(params: Omit<SnapshotPathParams, 'resourceId'>): string;
45
+ /**
46
+ * Get the full path to a LOCAL snapshot file.
47
+ */
48
+ export declare function getLocalSnapshotPath(params: SnapshotPathParams): string;
49
+ /**
50
+ * Write a LOCAL snapshot to the OS cache.
51
+ */
52
+ export declare function writeLocalSnapshot(params: SnapshotPathParams, snapshot: object): string;
@@ -0,0 +1,123 @@
1
+ "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
14
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
15
+ }) : function(o, v) {
16
+ o["default"] = v;
17
+ });
18
+ var __importStar = (this && this.__importStar) || function (mod) {
19
+ if (mod && mod.__esModule) return mod;
20
+ var result = {};
21
+ if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
22
+ __setModuleDefault(result, mod);
23
+ return result;
24
+ };
25
+ Object.defineProperty(exports, "__esModule", { value: true });
26
+ exports.writeLocalSnapshot = exports.getLocalSnapshotPath = exports.getSnapshotDir = exports.normalizeResourceName = exports.normalizeRegion = exports.normalizeAccountId = exports.ensureDirExists = exports.getSnapshotBaseDir = exports.getDefaultSnapshotBaseDir = void 0;
27
+ const os = __importStar(require("os"));
28
+ const path = __importStar(require("path"));
29
+ const fs = __importStar(require("fs"));
30
+ /**
31
+ * Get the default base directory for Chaim snapshots based on OS.
32
+ * - macOS/Linux: ~/.chaim/cache/snapshots
33
+ * - Windows: %LOCALAPPDATA%/chaim/cache/snapshots (or homedir fallback)
34
+ */
35
+ function getDefaultSnapshotBaseDir() {
36
+ if (process.platform === 'win32') {
37
+ const localAppData = process.env.LOCALAPPDATA ?? os.homedir();
38
+ return path.join(localAppData, 'chaim', 'cache', 'snapshots');
39
+ }
40
+ return path.join(os.homedir(), '.chaim', 'cache', 'snapshots');
41
+ }
42
+ exports.getDefaultSnapshotBaseDir = getDefaultSnapshotBaseDir;
43
+ /**
44
+ * Get the snapshot base directory, respecting CHAIM_SNAPSHOT_DIR override.
45
+ */
46
+ function getSnapshotBaseDir() {
47
+ return process.env.CHAIM_SNAPSHOT_DIR ?? getDefaultSnapshotBaseDir();
48
+ }
49
+ exports.getSnapshotBaseDir = getSnapshotBaseDir;
50
+ /**
51
+ * Ensure a directory exists, creating it recursively if needed.
52
+ */
53
+ function ensureDirExists(dir) {
54
+ fs.mkdirSync(dir, { recursive: true });
55
+ }
56
+ exports.ensureDirExists = ensureDirExists;
57
+ /**
58
+ * Normalize account ID - handles CDK tokens and unresolved values.
59
+ */
60
+ function normalizeAccountId(accountId) {
61
+ if (!accountId || accountId.includes('${Token') || accountId.includes('${AWS::')) {
62
+ return 'unknown';
63
+ }
64
+ return accountId;
65
+ }
66
+ exports.normalizeAccountId = normalizeAccountId;
67
+ /**
68
+ * Normalize region - handles CDK tokens and unresolved values.
69
+ */
70
+ function normalizeRegion(region) {
71
+ if (!region || region.includes('${Token') || region.includes('${AWS::')) {
72
+ return 'unknown';
73
+ }
74
+ return region;
75
+ }
76
+ exports.normalizeRegion = normalizeRegion;
77
+ /**
78
+ * Normalize a resource name by removing CDK tokens and special characters.
79
+ * Used for generating file paths.
80
+ *
81
+ * IMPORTANT: Preserves double underscores (__) as they are used as delimiters
82
+ * in resource IDs (format: {resourceName}__{entityName}).
83
+ */
84
+ function normalizeResourceName(name) {
85
+ // Replace CDK tokens with 'token'
86
+ let normalized = name.replace(/\$\{Token\[[^\]]+\]\}/g, 'token');
87
+ // Replace special characters with underscores (except existing underscores)
88
+ normalized = normalized.replace(/[^a-zA-Z0-9_-]/g, '_');
89
+ // Remove triple-or-more consecutive underscores, but PRESERVE double underscores (__)
90
+ // This is important because __ is used as delimiter in resource IDs
91
+ normalized = normalized.replace(/_{3,}/g, '__');
92
+ // Trim leading/trailing underscores
93
+ return normalized.replace(/^_|_$/g, '');
94
+ }
95
+ exports.normalizeResourceName = normalizeResourceName;
96
+ /**
97
+ * Get the directory path for LOCAL snapshots.
98
+ */
99
+ function getSnapshotDir(params) {
100
+ return path.join(getSnapshotBaseDir(), 'aws', normalizeAccountId(params.accountId), normalizeRegion(params.region), params.stackName, params.datastoreType);
101
+ }
102
+ exports.getSnapshotDir = getSnapshotDir;
103
+ /**
104
+ * Get the full path to a LOCAL snapshot file.
105
+ */
106
+ function getLocalSnapshotPath(params) {
107
+ // Normalize resource ID to avoid special characters in path
108
+ const normalizedResourceId = normalizeResourceName(params.resourceId);
109
+ return path.join(getSnapshotDir(params), `${normalizedResourceId}.json`);
110
+ }
111
+ exports.getLocalSnapshotPath = getLocalSnapshotPath;
112
+ /**
113
+ * Write a LOCAL snapshot to the OS cache.
114
+ */
115
+ function writeLocalSnapshot(params, snapshot) {
116
+ const dir = getSnapshotDir(params);
117
+ ensureDirExists(dir);
118
+ const filePath = getLocalSnapshotPath(params);
119
+ fs.writeFileSync(filePath, JSON.stringify(snapshot, null, 2), 'utf-8');
120
+ return filePath;
121
+ }
122
+ exports.writeLocalSnapshot = writeLocalSnapshot;
123
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoib3MtY2FjaGUtcGF0aHMuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi9zcmMvc2VydmljZXMvb3MtY2FjaGUtcGF0aHMudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6Ijs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7QUFBQSx1Q0FBeUI7QUFDekIsMkNBQTZCO0FBQzdCLHVDQUF5QjtBQUV6Qjs7OztHQUlHO0FBQ0gsU0FBZ0IseUJBQXlCO0lBQ3ZDLElBQUksT0FBTyxDQUFDLFFBQVEsS0FBSyxPQUFPLEVBQUU7UUFDaEMsTUFBTSxZQUFZLEdBQUcsT0FBTyxDQUFDLEdBQUcsQ0FBQyxZQUFZLElBQUksRUFBRSxDQUFDLE9BQU8sRUFBRSxDQUFDO1FBQzlELE9BQU8sSUFBSSxDQUFDLElBQUksQ0FBQyxZQUFZLEVBQUUsT0FBTyxFQUFFLE9BQU8sRUFBRSxXQUFXLENBQUMsQ0FBQztLQUMvRDtJQUNELE9BQU8sSUFBSSxDQUFDLElBQUksQ0FBQyxFQUFFLENBQUMsT0FBTyxFQUFFLEVBQUUsUUFBUSxFQUFFLE9BQU8sRUFBRSxXQUFXLENBQUMsQ0FBQztBQUNqRSxDQUFDO0FBTkQsOERBTUM7QUFFRDs7R0FFRztBQUNILFNBQWdCLGtCQUFrQjtJQUNoQyxPQUFPLE9BQU8sQ0FBQyxHQUFHLENBQUMsa0JBQWtCLElBQUkseUJBQXlCLEVBQUUsQ0FBQztBQUN2RSxDQUFDO0FBRkQsZ0RBRUM7QUFFRDs7R0FFRztBQUNILFNBQWdCLGVBQWUsQ0FBQyxHQUFXO0lBQ3pDLEVBQUUsQ0FBQyxTQUFTLENBQUMsR0FBRyxFQUFFLEVBQUUsU0FBUyxFQUFFLElBQUksRUFBRSxDQUFDLENBQUM7QUFDekMsQ0FBQztBQUZELDBDQUVDO0FBRUQ7O0dBRUc7QUFDSCxTQUFnQixrQkFBa0IsQ0FBQyxTQUE2QjtJQUM5RCxJQUFJLENBQUMsU0FBUyxJQUFJLFNBQVMsQ0FBQyxRQUFRLENBQUMsU0FBUyxDQUFDLElBQUksU0FBUyxDQUFDLFFBQVEsQ0FBQyxTQUFTLENBQUMsRUFBRTtRQUNoRixPQUFPLFNBQVMsQ0FBQztLQUNsQjtJQUNELE9BQU8sU0FBUyxDQUFDO0FBQ25CLENBQUM7QUFMRCxnREFLQztBQUVEOztHQUVHO0FBQ0gsU0FBZ0IsZUFBZSxDQUFDLE1BQTBCO0lBQ3hELElBQUksQ0FBQyxNQUFNLElBQUksTUFBTSxDQUFDLFFBQVEsQ0FBQyxTQUFTLENBQUMsSUFBSSxNQUFNLENBQUMsUUFBUSxDQUFDLFNBQVMsQ0FBQyxFQUFFO1FBQ3ZFLE9BQU8sU0FBUyxDQUFDO0tBQ2xCO0lBQ0QsT0FBTyxNQUFNLENBQUM7QUFDaEIsQ0FBQztBQUxELDBDQUtDO0FBRUQ7Ozs7OztHQU1HO0FBQ0gsU0FBZ0IscUJBQXFCLENBQUMsSUFBWTtJQUNoRCxrQ0FBa0M7SUFDbEMsSUFBSSxVQUFVLEdBQUcsSUFBSSxDQUFDLE9BQU8sQ0FBQyx3QkFBd0IsRUFBRSxPQUFPLENBQUMsQ0FBQztJQUNqRSw0RUFBNEU7SUFDNUUsVUFBVSxHQUFHLFVBQVUsQ0FBQyxPQUFPLENBQUMsaUJBQWlCLEVBQUUsR0FBRyxDQUFDLENBQUM7SUFDeEQsc0ZBQXNGO0lBQ3RGLG9FQUFvRTtJQUNwRSxVQUFVLEdBQUcsVUFBVSxDQUFDLE9BQU8sQ0FBQyxRQUFRLEVBQUUsSUFBSSxDQUFDLENBQUM7SUFDaEQsb0NBQW9DO0lBQ3BDLE9BQU8sVUFBVSxDQUFDLE9BQU8sQ0FBQyxRQUFRLEVBQUUsRUFBRSxDQUFDLENBQUM7QUFDMUMsQ0FBQztBQVZELHNEQVVDO0FBYUQ7O0dBRUc7QUFDSCxTQUFnQixjQUFjLENBQUMsTUFBOEM7SUFDM0UsT0FBTyxJQUFJLENBQUMsSUFBSSxDQUNkLGtCQUFrQixFQUFFLEVBQ3BCLEtBQUssRUFDTCxrQkFBa0IsQ0FBQyxNQUFNLENBQUMsU0FBUyxDQUFDLEVBQ3BDLGVBQWUsQ0FBQyxNQUFNLENBQUMsTUFBTSxDQUFDLEVBQzlCLE1BQU0sQ0FBQyxTQUFTLEVBQ2hCLE1BQU0sQ0FBQyxhQUFhLENBQ3JCLENBQUM7QUFDSixDQUFDO0FBVEQsd0NBU0M7QUFFRDs7R0FFRztBQUNILFNBQWdCLG9CQUFvQixDQUFDLE1BQTBCO0lBQzdELDREQUE0RDtJQUM1RCxNQUFNLG9CQUFvQixHQUFHLHFCQUFxQixDQUFDLE1BQU0sQ0FBQyxVQUFVLENBQUMsQ0FBQztJQUN0RSxPQUFPLElBQUksQ0FBQyxJQUFJLENBQ2QsY0FBYyxDQUFDLE1BQU0sQ0FBQyxFQUN0QixHQUFHLG9CQUFvQixPQUFPLENBQy9CLENBQUM7QUFDSixDQUFDO0FBUEQsb0RBT0M7QUFFRDs7R0FFRztBQUNILFNBQWdCLGtCQUFrQixDQUFDLE1BQTBCLEVBQUUsUUFBZ0I7SUFDN0UsTUFBTSxHQUFHLEdBQUcsY0FBYyxDQUFDLE1BQU0sQ0FBQyxDQUFDO0lBQ25DLGVBQWUsQ0FBQyxHQUFHLENBQUMsQ0FBQztJQUVyQixNQUFNLFFBQVEsR0FBRyxvQkFBb0IsQ0FBQyxNQUFNLENBQUMsQ0FBQztJQUM5QyxFQUFFLENBQUMsYUFBYSxDQUFDLFFBQVEsRUFBRSxJQUFJLENBQUMsU0FBUyxDQUFDLFFBQVEsRUFBRSxJQUFJLEVBQUUsQ0FBQyxDQUFDLEVBQUUsT0FBTyxDQUFDLENBQUM7SUFFdkUsT0FBTyxRQUFRLENBQUM7QUFDbEIsQ0FBQztBQVJELGdEQVFDIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0ICogYXMgb3MgZnJvbSAnb3MnO1xuaW1wb3J0ICogYXMgcGF0aCBmcm9tICdwYXRoJztcbmltcG9ydCAqIGFzIGZzIGZyb20gJ2ZzJztcblxuLyoqXG4gKiBHZXQgdGhlIGRlZmF1bHQgYmFzZSBkaXJlY3RvcnkgZm9yIENoYWltIHNuYXBzaG90cyBiYXNlZCBvbiBPUy5cbiAqIC0gbWFjT1MvTGludXg6IH4vLmNoYWltL2NhY2hlL3NuYXBzaG90c1xuICogLSBXaW5kb3dzOiAlTE9DQUxBUFBEQVRBJS9jaGFpbS9jYWNoZS9zbmFwc2hvdHMgKG9yIGhvbWVkaXIgZmFsbGJhY2spXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBnZXREZWZhdWx0U25hcHNob3RCYXNlRGlyKCk6IHN0cmluZyB7XG4gIGlmIChwcm9jZXNzLnBsYXRmb3JtID09PSAnd2luMzInKSB7XG4gICAgY29uc3QgbG9jYWxBcHBEYXRhID0gcHJvY2Vzcy5lbnYuTE9DQUxBUFBEQVRBID8/IG9zLmhvbWVkaXIoKTtcbiAgICByZXR1cm4gcGF0aC5qb2luKGxvY2FsQXBwRGF0YSwgJ2NoYWltJywgJ2NhY2hlJywgJ3NuYXBzaG90cycpO1xuICB9XG4gIHJldHVybiBwYXRoLmpvaW4ob3MuaG9tZWRpcigpLCAnLmNoYWltJywgJ2NhY2hlJywgJ3NuYXBzaG90cycpO1xufVxuXG4vKipcbiAqIEdldCB0aGUgc25hcHNob3QgYmFzZSBkaXJlY3RvcnksIHJlc3BlY3RpbmcgQ0hBSU1fU05BUFNIT1RfRElSIG92ZXJyaWRlLlxuICovXG5leHBvcnQgZnVuY3Rpb24gZ2V0U25hcHNob3RCYXNlRGlyKCk6IHN0cmluZyB7XG4gIHJldHVybiBwcm9jZXNzLmVudi5DSEFJTV9TTkFQU0hPVF9ESVIgPz8gZ2V0RGVmYXVsdFNuYXBzaG90QmFzZURpcigpO1xufVxuXG4vKipcbiAqIEVuc3VyZSBhIGRpcmVjdG9yeSBleGlzdHMsIGNyZWF0aW5nIGl0IHJlY3Vyc2l2ZWx5IGlmIG5lZWRlZC5cbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGVuc3VyZURpckV4aXN0cyhkaXI6IHN0cmluZyk6IHZvaWQge1xuICBmcy5ta2RpclN5bmMoZGlyLCB7IHJlY3Vyc2l2ZTogdHJ1ZSB9KTtcbn1cblxuLyoqXG4gKiBOb3JtYWxpemUgYWNjb3VudCBJRCAtIGhhbmRsZXMgQ0RLIHRva2VucyBhbmQgdW5yZXNvbHZlZCB2YWx1ZXMuXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBub3JtYWxpemVBY2NvdW50SWQoYWNjb3VudElkOiBzdHJpbmcgfCB1bmRlZmluZWQpOiBzdHJpbmcge1xuICBpZiAoIWFjY291bnRJZCB8fCBhY2NvdW50SWQuaW5jbHVkZXMoJyR7VG9rZW4nKSB8fCBhY2NvdW50SWQuaW5jbHVkZXMoJyR7QVdTOjonKSkge1xuICAgIHJldHVybiAndW5rbm93bic7XG4gIH1cbiAgcmV0dXJuIGFjY291bnRJZDtcbn1cblxuLyoqXG4gKiBOb3JtYWxpemUgcmVnaW9uIC0gaGFuZGxlcyBDREsgdG9rZW5zIGFuZCB1bnJlc29sdmVkIHZhbHVlcy5cbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIG5vcm1hbGl6ZVJlZ2lvbihyZWdpb246IHN0cmluZyB8IHVuZGVmaW5lZCk6IHN0cmluZyB7XG4gIGlmICghcmVnaW9uIHx8IHJlZ2lvbi5pbmNsdWRlcygnJHtUb2tlbicpIHx8IHJlZ2lvbi5pbmNsdWRlcygnJHtBV1M6OicpKSB7XG4gICAgcmV0dXJuICd1bmtub3duJztcbiAgfVxuICByZXR1cm4gcmVnaW9uO1xufVxuXG4vKipcbiAqIE5vcm1hbGl6ZSBhIHJlc291cmNlIG5hbWUgYnkgcmVtb3ZpbmcgQ0RLIHRva2VucyBhbmQgc3BlY2lhbCBjaGFyYWN0ZXJzLlxuICogVXNlZCBmb3IgZ2VuZXJhdGluZyBmaWxlIHBhdGhzLlxuICogXG4gKiBJTVBPUlRBTlQ6IFByZXNlcnZlcyBkb3VibGUgdW5kZXJzY29yZXMgKF9fKSBhcyB0aGV5IGFyZSB1c2VkIGFzIGRlbGltaXRlcnNcbiAqIGluIHJlc291cmNlIElEcyAoZm9ybWF0OiB7cmVzb3VyY2VOYW1lfV9fe2VudGl0eU5hbWV9KS5cbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIG5vcm1hbGl6ZVJlc291cmNlTmFtZShuYW1lOiBzdHJpbmcpOiBzdHJpbmcge1xuICAvLyBSZXBsYWNlIENESyB0b2tlbnMgd2l0aCAndG9rZW4nXG4gIGxldCBub3JtYWxpemVkID0gbmFtZS5yZXBsYWNlKC9cXCRcXHtUb2tlblxcW1teXFxdXStcXF1cXH0vZywgJ3Rva2VuJyk7XG4gIC8vIFJlcGxhY2Ugc3BlY2lhbCBjaGFyYWN0ZXJzIHdpdGggdW5kZXJzY29yZXMgKGV4Y2VwdCBleGlzdGluZyB1bmRlcnNjb3JlcylcbiAgbm9ybWFsaXplZCA9IG5vcm1hbGl6ZWQucmVwbGFjZSgvW15hLXpBLVowLTlfLV0vZywgJ18nKTtcbiAgLy8gUmVtb3ZlIHRyaXBsZS1vci1tb3JlIGNvbnNlY3V0aXZlIHVuZGVyc2NvcmVzLCBidXQgUFJFU0VSVkUgZG91YmxlIHVuZGVyc2NvcmVzIChfXylcbiAgLy8gVGhpcyBpcyBpbXBvcnRhbnQgYmVjYXVzZSBfXyBpcyB1c2VkIGFzIGRlbGltaXRlciBpbiByZXNvdXJjZSBJRHNcbiAgbm9ybWFsaXplZCA9IG5vcm1hbGl6ZWQucmVwbGFjZSgvX3szLH0vZywgJ19fJyk7XG4gIC8vIFRyaW0gbGVhZGluZy90cmFpbGluZyB1bmRlcnNjb3Jlc1xuICByZXR1cm4gbm9ybWFsaXplZC5yZXBsYWNlKC9eX3xfJC9nLCAnJyk7XG59XG5cbi8qKlxuICogUGFyYW1ldGVycyBmb3IgY29uc3RydWN0aW5nIHNuYXBzaG90IHBhdGhzLlxuICovXG5leHBvcnQgaW50ZXJmYWNlIFNuYXBzaG90UGF0aFBhcmFtcyB7XG4gIGFjY291bnRJZDogc3RyaW5nO1xuICByZWdpb246IHN0cmluZztcbiAgc3RhY2tOYW1lOiBzdHJpbmc7XG4gIGRhdGFzdG9yZVR5cGU6IHN0cmluZztcbiAgcmVzb3VyY2VJZDogc3RyaW5nO1xufVxuXG4vKipcbiAqIEdldCB0aGUgZGlyZWN0b3J5IHBhdGggZm9yIExPQ0FMIHNuYXBzaG90cy5cbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGdldFNuYXBzaG90RGlyKHBhcmFtczogT21pdDxTbmFwc2hvdFBhdGhQYXJhbXMsICdyZXNvdXJjZUlkJz4pOiBzdHJpbmcge1xuICByZXR1cm4gcGF0aC5qb2luKFxuICAgIGdldFNuYXBzaG90QmFzZURpcigpLFxuICAgICdhd3MnLFxuICAgIG5vcm1hbGl6ZUFjY291bnRJZChwYXJhbXMuYWNjb3VudElkKSxcbiAgICBub3JtYWxpemVSZWdpb24ocGFyYW1zLnJlZ2lvbiksXG4gICAgcGFyYW1zLnN0YWNrTmFtZSxcbiAgICBwYXJhbXMuZGF0YXN0b3JlVHlwZVxuICApO1xufVxuXG4vKipcbiAqIEdldCB0aGUgZnVsbCBwYXRoIHRvIGEgTE9DQUwgc25hcHNob3QgZmlsZS5cbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGdldExvY2FsU25hcHNob3RQYXRoKHBhcmFtczogU25hcHNob3RQYXRoUGFyYW1zKTogc3RyaW5nIHtcbiAgLy8gTm9ybWFsaXplIHJlc291cmNlIElEIHRvIGF2b2lkIHNwZWNpYWwgY2hhcmFjdGVycyBpbiBwYXRoXG4gIGNvbnN0IG5vcm1hbGl6ZWRSZXNvdXJjZUlkID0gbm9ybWFsaXplUmVzb3VyY2VOYW1lKHBhcmFtcy5yZXNvdXJjZUlkKTtcbiAgcmV0dXJuIHBhdGguam9pbihcbiAgICBnZXRTbmFwc2hvdERpcihwYXJhbXMpLFxuICAgIGAke25vcm1hbGl6ZWRSZXNvdXJjZUlkfS5qc29uYFxuICApO1xufVxuXG4vKipcbiAqIFdyaXRlIGEgTE9DQUwgc25hcHNob3QgdG8gdGhlIE9TIGNhY2hlLlxuICovXG5leHBvcnQgZnVuY3Rpb24gd3JpdGVMb2NhbFNuYXBzaG90KHBhcmFtczogU25hcHNob3RQYXRoUGFyYW1zLCBzbmFwc2hvdDogb2JqZWN0KTogc3RyaW5nIHtcbiAgY29uc3QgZGlyID0gZ2V0U25hcHNob3REaXIocGFyYW1zKTtcbiAgZW5zdXJlRGlyRXhpc3RzKGRpcik7XG4gIFxuICBjb25zdCBmaWxlUGF0aCA9IGdldExvY2FsU25hcHNob3RQYXRoKHBhcmFtcyk7XG4gIGZzLndyaXRlRmlsZVN5bmMoZmlsZVBhdGgsIEpTT04uc3RyaW5naWZ5KHNuYXBzaG90LCBudWxsLCAyKSwgJ3V0Zi04Jyk7XG4gIFxuICByZXR1cm4gZmlsZVBhdGg7XG59XG4iXX0=
@@ -0,0 +1,11 @@
1
+ import { SchemaData } from '@chaim-tools/chaim-bprint-spec';
2
+ export declare class SchemaService {
3
+ /**
4
+ * Validates that the schema file path exists and has a .bprint extension
5
+ */
6
+ static validateSchemaPath(schemaPath: string): void;
7
+ /**
8
+ * Reads and parses the schema file using our local validator based on the official spec
9
+ */
10
+ static readSchema(schemaPath: string): SchemaData;
11
+ }
@@ -0,0 +1,67 @@
1
+ "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
14
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
15
+ }) : function(o, v) {
16
+ o["default"] = v;
17
+ });
18
+ var __importStar = (this && this.__importStar) || function (mod) {
19
+ if (mod && mod.__esModule) return mod;
20
+ var result = {};
21
+ if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
22
+ __setModuleDefault(result, mod);
23
+ return result;
24
+ };
25
+ Object.defineProperty(exports, "__esModule", { value: true });
26
+ exports.SchemaService = void 0;
27
+ const fs = __importStar(require("fs"));
28
+ const chaim_bprint_spec_1 = require("@chaim-tools/chaim-bprint-spec");
29
+ class SchemaService {
30
+ /**
31
+ * Validates that the schema file path exists and has a .bprint extension
32
+ */
33
+ static validateSchemaPath(schemaPath) {
34
+ if (!schemaPath) {
35
+ throw new Error('Schema path is required');
36
+ }
37
+ if (!schemaPath.endsWith('.bprint')) {
38
+ throw new Error('Schema file must have a .bprint extension');
39
+ }
40
+ if (!fs.existsSync(schemaPath)) {
41
+ throw new Error(`Schema file not found: ${schemaPath}`);
42
+ }
43
+ }
44
+ /**
45
+ * Reads and parses the schema file using our local validator based on the official spec
46
+ */
47
+ static readSchema(schemaPath) {
48
+ try {
49
+ const content = fs.readFileSync(schemaPath, 'utf-8');
50
+ const rawSchema = JSON.parse(content);
51
+ // Use the official chaim-bprint-spec validator
52
+ return (0, chaim_bprint_spec_1.validateSchema)(rawSchema);
53
+ }
54
+ catch (error) {
55
+ if (error instanceof SyntaxError) {
56
+ throw new Error(`Invalid JSON in schema file: ${schemaPath}`);
57
+ }
58
+ // Re-throw validation errors with context
59
+ if (error instanceof Error) {
60
+ throw new Error(`Schema validation failed for ${schemaPath}: ${error.message}`);
61
+ }
62
+ throw error;
63
+ }
64
+ }
65
+ }
66
+ exports.SchemaService = SchemaService;
67
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoic2NoZW1hLXNlcnZpY2UuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi9zcmMvc2VydmljZXMvc2NoZW1hLXNlcnZpY2UudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6Ijs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7QUFBQSx1Q0FBeUI7QUFDekIsc0VBQTRFO0FBRTVFLE1BQWEsYUFBYTtJQUN4Qjs7T0FFRztJQUNILE1BQU0sQ0FBQyxrQkFBa0IsQ0FBQyxVQUFrQjtRQUMxQyxJQUFJLENBQUMsVUFBVSxFQUFFO1lBQ2YsTUFBTSxJQUFJLEtBQUssQ0FBQyx5QkFBeUIsQ0FBQyxDQUFDO1NBQzVDO1FBRUQsSUFBSSxDQUFDLFVBQVUsQ0FBQyxRQUFRLENBQUMsU0FBUyxDQUFDLEVBQUU7WUFDbkMsTUFBTSxJQUFJLEtBQUssQ0FBQywyQ0FBMkMsQ0FBQyxDQUFDO1NBQzlEO1FBRUQsSUFBSSxDQUFDLEVBQUUsQ0FBQyxVQUFVLENBQUMsVUFBVSxDQUFDLEVBQUU7WUFDOUIsTUFBTSxJQUFJLEtBQUssQ0FBQywwQkFBMEIsVUFBVSxFQUFFLENBQUMsQ0FBQztTQUN6RDtJQUNILENBQUM7SUFFRDs7T0FFRztJQUNILE1BQU0sQ0FBQyxVQUFVLENBQUMsVUFBa0I7UUFDbEMsSUFBSTtZQUNGLE1BQU0sT0FBTyxHQUFHLEVBQUUsQ0FBQyxZQUFZLENBQUMsVUFBVSxFQUFFLE9BQU8sQ0FBQyxDQUFDO1lBQ3JELE1BQU0sU0FBUyxHQUFHLElBQUksQ0FBQyxLQUFLLENBQUMsT0FBTyxDQUFDLENBQUM7WUFFdEMsK0NBQStDO1lBQy9DLE9BQU8sSUFBQSxrQ0FBYyxFQUFDLFNBQVMsQ0FBQyxDQUFDO1NBQ2xDO1FBQUMsT0FBTyxLQUFLLEVBQUU7WUFDZCxJQUFJLEtBQUssWUFBWSxXQUFXLEVBQUU7Z0JBQ2hDLE1BQU0sSUFBSSxLQUFLLENBQUMsZ0NBQWdDLFVBQVUsRUFBRSxDQUFDLENBQUM7YUFDL0Q7WUFDRCwwQ0FBMEM7WUFDMUMsSUFBSSxLQUFLLFlBQVksS0FBSyxFQUFFO2dCQUMxQixNQUFNLElBQUksS0FBSyxDQUFDLGdDQUFnQyxVQUFVLEtBQUssS0FBSyxDQUFDLE9BQU8sRUFBRSxDQUFDLENBQUM7YUFDakY7WUFDRCxNQUFNLEtBQUssQ0FBQztTQUNiO0lBQ0gsQ0FBQztDQUNGO0FBdkNELHNDQXVDQyIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCAqIGFzIGZzIGZyb20gJ2ZzJztcbmltcG9ydCB7IFNjaGVtYURhdGEsIHZhbGlkYXRlU2NoZW1hIH0gZnJvbSAnQGNoYWltLXRvb2xzL2NoYWltLWJwcmludC1zcGVjJztcblxuZXhwb3J0IGNsYXNzIFNjaGVtYVNlcnZpY2Uge1xuICAvKipcbiAgICogVmFsaWRhdGVzIHRoYXQgdGhlIHNjaGVtYSBmaWxlIHBhdGggZXhpc3RzIGFuZCBoYXMgYSAuYnByaW50IGV4dGVuc2lvblxuICAgKi9cbiAgc3RhdGljIHZhbGlkYXRlU2NoZW1hUGF0aChzY2hlbWFQYXRoOiBzdHJpbmcpOiB2b2lkIHtcbiAgICBpZiAoIXNjaGVtYVBhdGgpIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcignU2NoZW1hIHBhdGggaXMgcmVxdWlyZWQnKTtcbiAgICB9XG5cbiAgICBpZiAoIXNjaGVtYVBhdGguZW5kc1dpdGgoJy5icHJpbnQnKSkge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKCdTY2hlbWEgZmlsZSBtdXN0IGhhdmUgYSAuYnByaW50IGV4dGVuc2lvbicpO1xuICAgIH1cblxuICAgIGlmICghZnMuZXhpc3RzU3luYyhzY2hlbWFQYXRoKSkge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKGBTY2hlbWEgZmlsZSBub3QgZm91bmQ6ICR7c2NoZW1hUGF0aH1gKTtcbiAgICB9XG4gIH1cblxuICAvKipcbiAgICogUmVhZHMgYW5kIHBhcnNlcyB0aGUgc2NoZW1hIGZpbGUgdXNpbmcgb3VyIGxvY2FsIHZhbGlkYXRvciBiYXNlZCBvbiB0aGUgb2ZmaWNpYWwgc3BlY1xuICAgKi9cbiAgc3RhdGljIHJlYWRTY2hlbWEoc2NoZW1hUGF0aDogc3RyaW5nKTogU2NoZW1hRGF0YSB7XG4gICAgdHJ5IHtcbiAgICAgIGNvbnN0IGNvbnRlbnQgPSBmcy5yZWFkRmlsZVN5bmMoc2NoZW1hUGF0aCwgJ3V0Zi04Jyk7XG4gICAgICBjb25zdCByYXdTY2hlbWEgPSBKU09OLnBhcnNlKGNvbnRlbnQpO1xuICAgICAgXG4gICAgICAvLyBVc2UgdGhlIG9mZmljaWFsIGNoYWltLWJwcmludC1zcGVjIHZhbGlkYXRvclxuICAgICAgcmV0dXJuIHZhbGlkYXRlU2NoZW1hKHJhd1NjaGVtYSk7XG4gICAgfSBjYXRjaCAoZXJyb3IpIHtcbiAgICAgIGlmIChlcnJvciBpbnN0YW5jZW9mIFN5bnRheEVycm9yKSB7XG4gICAgICAgIHRocm93IG5ldyBFcnJvcihgSW52YWxpZCBKU09OIGluIHNjaGVtYSBmaWxlOiAke3NjaGVtYVBhdGh9YCk7XG4gICAgICB9XG4gICAgICAvLyBSZS10aHJvdyB2YWxpZGF0aW9uIGVycm9ycyB3aXRoIGNvbnRleHRcbiAgICAgIGlmIChlcnJvciBpbnN0YW5jZW9mIEVycm9yKSB7XG4gICAgICAgIHRocm93IG5ldyBFcnJvcihgU2NoZW1hIHZhbGlkYXRpb24gZmFpbGVkIGZvciAke3NjaGVtYVBhdGh9OiAke2Vycm9yLm1lc3NhZ2V9YCk7XG4gICAgICB9XG4gICAgICB0aHJvdyBlcnJvcjtcbiAgICB9XG4gIH1cbn1cbiJdfQ==
@@ -0,0 +1,78 @@
1
+ /**
2
+ * Options for snapshot cleanup operations.
3
+ */
4
+ export interface CleanupOptions {
5
+ /**
6
+ * AWS account ID to scope cleanup.
7
+ * If undefined, operates on 'unknown' account (for local dev).
8
+ */
9
+ accountId?: string;
10
+ /**
11
+ * AWS region to scope cleanup.
12
+ * If undefined, operates on 'unknown' region (for local dev).
13
+ */
14
+ region?: string;
15
+ /**
16
+ * CDK stack name to scope cleanup.
17
+ * REQUIRED for PRUNE_STACK operations.
18
+ */
19
+ stackName: string;
20
+ /**
21
+ * If true, log cleanup operations to console.
22
+ * Default: false
23
+ */
24
+ verbose?: boolean;
25
+ }
26
+ /**
27
+ * Options for TTL-based cleanup.
28
+ */
29
+ export interface TTLCleanupOptions {
30
+ /**
31
+ * Delete snapshots older than this many days.
32
+ * Default: 30 days
33
+ */
34
+ olderThanDays?: number;
35
+ /**
36
+ * If true, perform a dry run without deleting files.
37
+ * Default: false
38
+ */
39
+ dryRun?: boolean;
40
+ /**
41
+ * If true, log cleanup operations to console.
42
+ * Default: false
43
+ */
44
+ verbose?: boolean;
45
+ }
46
+ /**
47
+ * Result of a cleanup operation.
48
+ */
49
+ export interface CleanupResult {
50
+ /** Number of snapshots deleted */
51
+ deletedCount: number;
52
+ /** Number of snapshots found but not deleted (dry run or errors) */
53
+ skippedCount: number;
54
+ /** Paths of deleted snapshot files */
55
+ deletedPaths: string[];
56
+ /** Errors encountered during cleanup */
57
+ errors: string[];
58
+ }
59
+ /**
60
+ * Delete all snapshots for a specific stack.
61
+ *
62
+ * This is the PRUNE_STACK behavior - scoped to a single stack only.
63
+ * Deletes: ~/.chaim/cache/snapshots/aws/{account}/{region}/{stackName}/
64
+ *
65
+ * @param options - Cleanup options
66
+ * @returns Cleanup result summary
67
+ */
68
+ export declare function pruneStackSnapshots(options: CleanupOptions): CleanupResult;
69
+ /**
70
+ * Delete snapshots older than a specified age (TTL cleanup).
71
+ *
72
+ * This is a maintenance operation that can be run periodically
73
+ * to clean up very old snapshots across all stacks.
74
+ *
75
+ * @param options - TTL cleanup options
76
+ * @returns Cleanup result summary
77
+ */
78
+ export declare function pruneOldSnapshots(options?: TTLCleanupOptions): CleanupResult;