@exabugs/dynamodb-client 0.1.0 → 0.1.2
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/CHANGELOG.md +16 -0
- package/README.md +205 -197
- package/dist/client/Collection.d.ts +13 -6
- package/dist/client/Collection.d.ts.map +1 -1
- package/dist/client/Collection.js +1 -1
- package/dist/client/Collection.js.map +1 -1
- package/dist/client/index.iam.d.ts +1 -1
- package/dist/client/index.iam.d.ts.map +1 -1
- package/dist/client/index.iam.js.map +1 -1
- package/dist/scripts/generate-shadow-config.d.ts +16 -0
- package/dist/scripts/generate-shadow-config.d.ts.map +1 -0
- package/dist/scripts/generate-shadow-config.js +161 -0
- package/dist/scripts/generate-shadow-config.js.map +1 -0
- package/dist/server/handler.cjs +2 -2
- package/dist/shadows/generator.d.ts +14 -3
- package/dist/shadows/generator.d.ts.map +1 -1
- package/dist/shadows/generator.js +19 -0
- package/dist/shadows/generator.js.map +1 -1
- package/dist/shadows/index.d.ts +3 -2
- package/dist/shadows/index.d.ts.map +1 -1
- package/dist/shadows/index.js +1 -1
- package/dist/shadows/index.js.map +1 -1
- package/dist/shadows/schema.d.ts +62 -0
- package/dist/shadows/schema.d.ts.map +1 -0
- package/dist/shadows/schema.js +8 -0
- package/dist/shadows/schema.js.map +1 -0
- package/dist/shadows/types.d.ts +1 -5
- package/dist/shadows/types.d.ts.map +1 -1
- package/package.json +7 -4
- package/dist/server/handler.zip +0 -0
- package/terraform/examples/advanced/README.md +0 -129
- package/terraform/examples/advanced/main.tf +0 -158
- package/terraform/examples/advanced/shadow.config.json +0 -35
- package/terraform/examples/advanced/variables.tf +0 -28
- package/terraform/examples/basic/README.md +0 -53
- package/terraform/examples/basic/main.tf +0 -99
- package/terraform/examples/basic/variables.tf +0 -17
|
@@ -0,0 +1,161 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
/**
|
|
3
|
+
* Shadow Config 自動生成スクリプト
|
|
4
|
+
*
|
|
5
|
+
* TypeScript スキーマファイルから shadow.config.json を自動生成する。
|
|
6
|
+
* TypeScript のスキーマ定義が唯一の情報源(Single Source of Truth)となり、
|
|
7
|
+
* 設定ファイルとの不整合を防ぐ。
|
|
8
|
+
*
|
|
9
|
+
* 使用方法:
|
|
10
|
+
* npx generate-shadow-config <schema-file> -o <output-file>
|
|
11
|
+
*
|
|
12
|
+
* 例:
|
|
13
|
+
* npx generate-shadow-config schema.ts -o shadow.config.json
|
|
14
|
+
*/
|
|
15
|
+
import { writeFileSync } from 'fs';
|
|
16
|
+
import { resolve } from 'path';
|
|
17
|
+
/**
|
|
18
|
+
* コマンドライン引数をパース
|
|
19
|
+
*/
|
|
20
|
+
function parseArgs() {
|
|
21
|
+
const args = process.argv.slice(2);
|
|
22
|
+
if (args.length === 0 || args.includes('-h') || args.includes('--help')) {
|
|
23
|
+
console.log(`
|
|
24
|
+
Usage: generate-shadow-config <schema-file> [options]
|
|
25
|
+
|
|
26
|
+
Arguments:
|
|
27
|
+
<schema-file> TypeScript schema file path
|
|
28
|
+
|
|
29
|
+
Options:
|
|
30
|
+
-o, --output Output file path (default: shadow.config.json)
|
|
31
|
+
-h, --help Show this help message
|
|
32
|
+
|
|
33
|
+
Example:
|
|
34
|
+
generate-shadow-config schema.ts -o shadow.config.json
|
|
35
|
+
`);
|
|
36
|
+
process.exit(0);
|
|
37
|
+
}
|
|
38
|
+
const schemaFile = args[0];
|
|
39
|
+
const outputIndex = args.findIndex((arg) => arg === '-o' || arg === '--output');
|
|
40
|
+
const outputFile = outputIndex !== -1 ? args[outputIndex + 1] : 'shadow.config.json';
|
|
41
|
+
if (!schemaFile) {
|
|
42
|
+
console.error('❌ Error: Schema file is required');
|
|
43
|
+
process.exit(1);
|
|
44
|
+
}
|
|
45
|
+
return { schemaFile, outputFile };
|
|
46
|
+
}
|
|
47
|
+
/**
|
|
48
|
+
* TypeScript スキーマファイルから SchemaRegistryConfig を読み込む
|
|
49
|
+
*/
|
|
50
|
+
async function loadSchemaFile(schemaFile) {
|
|
51
|
+
const absolutePath = resolve(process.cwd(), schemaFile);
|
|
52
|
+
console.log(`📖 Loading schema from: ${absolutePath}`);
|
|
53
|
+
try {
|
|
54
|
+
// 動的インポートでスキーマファイルを読み込む
|
|
55
|
+
const module = await import(absolutePath);
|
|
56
|
+
// エクスポートされた SchemaRegistryConfig を探す
|
|
57
|
+
const schemaConfig = module.default ||
|
|
58
|
+
module.SchemaRegistryConfig ||
|
|
59
|
+
module.MySchema ||
|
|
60
|
+
module.schema ||
|
|
61
|
+
module.config;
|
|
62
|
+
if (!schemaConfig) {
|
|
63
|
+
throw new Error('SchemaRegistryConfig not found. Please export as default or named export (SchemaRegistryConfig, MySchema, schema, config)');
|
|
64
|
+
}
|
|
65
|
+
// 基本的な検証
|
|
66
|
+
if (!schemaConfig.database || !schemaConfig.resources) {
|
|
67
|
+
throw new Error('Invalid schema: missing database or resources');
|
|
68
|
+
}
|
|
69
|
+
return schemaConfig;
|
|
70
|
+
}
|
|
71
|
+
catch (error) {
|
|
72
|
+
if (error instanceof Error) {
|
|
73
|
+
console.error(`❌ Failed to load schema file: ${error.message}`);
|
|
74
|
+
}
|
|
75
|
+
throw error;
|
|
76
|
+
}
|
|
77
|
+
}
|
|
78
|
+
/**
|
|
79
|
+
* SchemaRegistryConfig から shadow.config.json を生成
|
|
80
|
+
*/
|
|
81
|
+
function generateShadowConfig(schemaConfig, schemaFile) {
|
|
82
|
+
console.log('🔄 Generating shadow.config.json...');
|
|
83
|
+
// データベース設定の検証
|
|
84
|
+
if (!schemaConfig.database.timestamps) {
|
|
85
|
+
throw new Error('Database timestamps configuration is required');
|
|
86
|
+
}
|
|
87
|
+
// リソーススキーマの変換
|
|
88
|
+
const resources = {};
|
|
89
|
+
for (const [resourceName, schema] of Object.entries(schemaConfig.resources)) {
|
|
90
|
+
// ソート可能フィールドを変換
|
|
91
|
+
const shadows = {};
|
|
92
|
+
for (const [fieldName, fieldDef] of Object.entries(schema.shadows.sortableFields)) {
|
|
93
|
+
shadows[fieldName] = {
|
|
94
|
+
type: fieldDef.type,
|
|
95
|
+
};
|
|
96
|
+
}
|
|
97
|
+
// デフォルトソート設定を決定
|
|
98
|
+
// schema.sortDefaults が指定されていればそれを使用
|
|
99
|
+
// なければ updatedAt が存在する場合は updatedAt DESC、なければ最初のフィールド ASC
|
|
100
|
+
let sortDefaults;
|
|
101
|
+
if (schema.sortDefaults) {
|
|
102
|
+
sortDefaults = schema.sortDefaults;
|
|
103
|
+
}
|
|
104
|
+
else {
|
|
105
|
+
const sortableFieldNames = Object.keys(shadows);
|
|
106
|
+
const defaultSortField = 'updatedAt' in shadows ? 'updatedAt' : sortableFieldNames[0];
|
|
107
|
+
const defaultSortOrder = 'updatedAt' in shadows ? 'DESC' : 'ASC';
|
|
108
|
+
sortDefaults = {
|
|
109
|
+
field: defaultSortField,
|
|
110
|
+
order: defaultSortOrder,
|
|
111
|
+
};
|
|
112
|
+
}
|
|
113
|
+
resources[resourceName] = {
|
|
114
|
+
shadows,
|
|
115
|
+
sortDefaults,
|
|
116
|
+
...(schema.ttl && { ttl: schema.ttl }),
|
|
117
|
+
};
|
|
118
|
+
}
|
|
119
|
+
// 設定オブジェクトの構築
|
|
120
|
+
const config = {
|
|
121
|
+
$schemaVersion: '2.0',
|
|
122
|
+
$generatedFrom: schemaFile,
|
|
123
|
+
database: {
|
|
124
|
+
name: schemaConfig.database.name,
|
|
125
|
+
timestamps: schemaConfig.database.timestamps,
|
|
126
|
+
},
|
|
127
|
+
resources,
|
|
128
|
+
};
|
|
129
|
+
return config;
|
|
130
|
+
}
|
|
131
|
+
/**
|
|
132
|
+
* メイン処理
|
|
133
|
+
*/
|
|
134
|
+
async function main() {
|
|
135
|
+
try {
|
|
136
|
+
// コマンドライン引数をパース
|
|
137
|
+
const { schemaFile, outputFile } = parseArgs();
|
|
138
|
+
// スキーマファイルを読み込む
|
|
139
|
+
const schemaConfig = await loadSchemaFile(schemaFile);
|
|
140
|
+
// shadow.config.json を生成
|
|
141
|
+
const config = generateShadowConfig(schemaConfig, schemaFile);
|
|
142
|
+
// ファイルに出力
|
|
143
|
+
const outputPath = resolve(process.cwd(), outputFile);
|
|
144
|
+
const output = JSON.stringify(config, null, 2);
|
|
145
|
+
writeFileSync(outputPath, output, 'utf-8');
|
|
146
|
+
console.log(`✅ Generated shadow.config.json at ${outputPath}`);
|
|
147
|
+
console.log(`📊 Database: ${config.database.name}`);
|
|
148
|
+
console.log(`📊 Resources: ${Object.keys(config.resources).join(', ')}`);
|
|
149
|
+
process.exit(0);
|
|
150
|
+
}
|
|
151
|
+
catch (error) {
|
|
152
|
+
console.error('❌ Failed to generate shadow.config.json:', error);
|
|
153
|
+
if (error instanceof Error) {
|
|
154
|
+
console.error(error.stack);
|
|
155
|
+
}
|
|
156
|
+
process.exit(1);
|
|
157
|
+
}
|
|
158
|
+
}
|
|
159
|
+
// スクリプト実行
|
|
160
|
+
main();
|
|
161
|
+
//# sourceMappingURL=generate-shadow-config.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"generate-shadow-config.js","sourceRoot":"","sources":["../../src/scripts/generate-shadow-config.ts"],"names":[],"mappings":"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"}
|
package/dist/server/handler.cjs
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import type { ShadowFieldType } from './
|
|
1
|
+
import type { ShadowFieldType } from './schema.js';
|
|
2
2
|
/**
|
|
3
3
|
* 文字列値をエスケープする
|
|
4
4
|
* ルール: # → ##, スペース → #
|
|
@@ -21,6 +21,13 @@ export declare function formatNumber(value: number | null | undefined): string;
|
|
|
21
21
|
* @returns UTC ISO 8601形式の文字列
|
|
22
22
|
*/
|
|
23
23
|
export declare function formatDatetime(value: string | Date | null | undefined): string;
|
|
24
|
+
/**
|
|
25
|
+
* boolean値をフォーマットする
|
|
26
|
+
*
|
|
27
|
+
* @param value - boolean値(null/undefinedも許容)
|
|
28
|
+
* @returns 'true' または 'false' または空文字
|
|
29
|
+
*/
|
|
30
|
+
export declare function formatBoolean(value: boolean | null | undefined): string;
|
|
24
31
|
/**
|
|
25
32
|
* フィールド値を型に応じてフォーマットする
|
|
26
33
|
*
|
|
@@ -28,7 +35,7 @@ export declare function formatDatetime(value: string | Date | null | undefined):
|
|
|
28
35
|
* @param value - フォーマットする値(null/undefinedも許容)
|
|
29
36
|
* @returns フォーマットされた文字列
|
|
30
37
|
*/
|
|
31
|
-
export declare function formatFieldValue(type: ShadowFieldType, value: string | number | Date | null | undefined): string;
|
|
38
|
+
export declare function formatFieldValue(type: ShadowFieldType, value: string | number | Date | boolean | null | undefined): string;
|
|
32
39
|
/**
|
|
33
40
|
* シャドーSKを生成する
|
|
34
41
|
* フォーマット: {fieldName}#{formattedValue}#id#{recordId}
|
|
@@ -50,8 +57,12 @@ export declare function formatFieldValue(type: ShadowFieldType, value: string |
|
|
|
50
57
|
* @example
|
|
51
58
|
* generateShadowSK('createdAt', '2025-11-12T10:00:00.000Z', '01HZXY123', 'datetime')
|
|
52
59
|
* // => 'createdAt#2025-11-12T10:00:00.000Z#id#01HZXY123'
|
|
60
|
+
*
|
|
61
|
+
* @example
|
|
62
|
+
* generateShadowSK('isPublished', true, '01HZXY123', 'boolean')
|
|
63
|
+
* // => 'isPublished#true#id#01HZXY123'
|
|
53
64
|
*/
|
|
54
|
-
export declare function generateShadowSK(fieldName: string, value: string | number | Date, recordId: string, type?: ShadowFieldType): string;
|
|
65
|
+
export declare function generateShadowSK(fieldName: string, value: string | number | Date | boolean, recordId: string, type?: ShadowFieldType): string;
|
|
55
66
|
/**
|
|
56
67
|
* レコードIDからメインレコードのSKを生成する
|
|
57
68
|
* フォーマット: id#{recordId}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"generator.d.ts","sourceRoot":"","sources":["../../src/shadows/generator.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,
|
|
1
|
+
{"version":3,"file":"generator.d.ts","sourceRoot":"","sources":["../../src/shadows/generator.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,aAAa,CAAC;AAEnD;;;;;;GAMG;AACH,wBAAgB,YAAY,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,CAIlD;AAED;;;;;GAKG;AACH,wBAAgB,YAAY,CAAC,KAAK,EAAE,MAAM,GAAG,IAAI,GAAG,SAAS,GAAG,MAAM,CAcrE;AAED;;;;;GAKG;AACH,wBAAgB,cAAc,CAAC,KAAK,EAAE,MAAM,GAAG,IAAI,GAAG,IAAI,GAAG,SAAS,GAAG,MAAM,CAa9E;AAED;;;;;GAKG;AACH,wBAAgB,aAAa,CAAC,KAAK,EAAE,OAAO,GAAG,IAAI,GAAG,SAAS,GAAG,MAAM,CAOvE;AAED;;;;;;GAMG;AACH,wBAAgB,gBAAgB,CAC9B,IAAI,EAAE,eAAe,EACrB,KAAK,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,GAAG,OAAO,GAAG,IAAI,GAAG,SAAS,GACzD,MAAM,CAiBR;AAED;;;;;;;;;;;;;;;;;;;;;;;;;GAyBG;AACH,wBAAgB,gBAAgB,CAC9B,SAAS,EAAE,MAAM,EACjB,KAAK,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,GAAG,OAAO,EACvC,QAAQ,EAAE,MAAM,EAChB,IAAI,GAAE,eAA0B,GAC/B,MAAM,CAGR;AAED;;;;;;GAMG;AACH,wBAAgB,oBAAoB,CAAC,QAAQ,EAAE,MAAM,GAAG,MAAM,CAE7D"}
|
|
@@ -45,6 +45,19 @@ export function formatDatetime(value) {
|
|
|
45
45
|
}
|
|
46
46
|
return date.toISOString();
|
|
47
47
|
}
|
|
48
|
+
/**
|
|
49
|
+
* boolean値をフォーマットする
|
|
50
|
+
*
|
|
51
|
+
* @param value - boolean値(null/undefinedも許容)
|
|
52
|
+
* @returns 'true' または 'false' または空文字
|
|
53
|
+
*/
|
|
54
|
+
export function formatBoolean(value) {
|
|
55
|
+
// null/undefined は空文字を返す
|
|
56
|
+
if (value === null || value === undefined) {
|
|
57
|
+
return '';
|
|
58
|
+
}
|
|
59
|
+
return value ? 'true' : 'false';
|
|
60
|
+
}
|
|
48
61
|
/**
|
|
49
62
|
* フィールド値を型に応じてフォーマットする
|
|
50
63
|
*
|
|
@@ -64,6 +77,8 @@ export function formatFieldValue(type, value) {
|
|
|
64
77
|
return formatNumber(value);
|
|
65
78
|
case 'datetime':
|
|
66
79
|
return formatDatetime(value);
|
|
80
|
+
case 'boolean':
|
|
81
|
+
return formatBoolean(value);
|
|
67
82
|
default:
|
|
68
83
|
throw new Error(`Unknown shadow field type: ${type}`);
|
|
69
84
|
}
|
|
@@ -89,6 +104,10 @@ export function formatFieldValue(type, value) {
|
|
|
89
104
|
* @example
|
|
90
105
|
* generateShadowSK('createdAt', '2025-11-12T10:00:00.000Z', '01HZXY123', 'datetime')
|
|
91
106
|
* // => 'createdAt#2025-11-12T10:00:00.000Z#id#01HZXY123'
|
|
107
|
+
*
|
|
108
|
+
* @example
|
|
109
|
+
* generateShadowSK('isPublished', true, '01HZXY123', 'boolean')
|
|
110
|
+
* // => 'isPublished#true#id#01HZXY123'
|
|
92
111
|
*/
|
|
93
112
|
export function generateShadowSK(fieldName, value, recordId, type = 'string') {
|
|
94
113
|
const formattedValue = formatFieldValue(type, value);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"generator.js","sourceRoot":"","sources":["../../src/shadows/generator.ts"],"names":[],"mappings":"AAEA;;;;;;GAMG;AACH,MAAM,UAAU,YAAY,CAAC,KAAa;IACxC,OAAO,KAAK;SACT,OAAO,CAAC,IAAI,EAAE,IAAI,CAAC,CAAC,aAAa;SACjC,OAAO,CAAC,IAAI,EAAE,GAAG,CAAC,CAAC,CAAC,cAAc;AACvC,CAAC;AAED;;;;;GAKG;AACH,MAAM,UAAU,YAAY,CAAC,KAAgC;IAC3D,yBAAyB;IACzB,IAAI,KAAK,KAAK,IAAI,IAAI,KAAK,KAAK,SAAS,EAAE,CAAC;QAC1C,OAAO,EAAE,CAAC;IACZ,CAAC;IAED,IAAI,CAAC,MAAM,CAAC,QAAQ,CAAC,KAAK,CAAC,EAAE,CAAC;QAC5B,MAAM,IAAI,KAAK,CAAC,yBAAyB,KAAK,EAAE,CAAC,CAAC;IACpD,CAAC;IAED,8BAA8B;IAC9B,MAAM,UAAU,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,IAAI,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC,CAAC;IAElD,OAAO,UAAU,CAAC,QAAQ,EAAE,CAAC,QAAQ,CAAC,EAAE,EAAE,GAAG,CAAC,CAAC;AACjD,CAAC;AAED;;;;;GAKG;AACH,MAAM,UAAU,cAAc,CAAC,KAAuC;IACpE,yBAAyB;IACzB,IAAI,KAAK,KAAK,IAAI,IAAI,KAAK,KAAK,SAAS,EAAE,CAAC;QAC1C,OAAO,EAAE,CAAC;IACZ,CAAC;IAED,MAAM,IAAI,GAAG,OAAO,KAAK,KAAK,QAAQ,CAAC,CAAC,CAAC,IAAI,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC;IAEjE,IAAI,KAAK,CAAC,IAAI,CAAC,OAAO,EAAE,CAAC,EAAE,CAAC;QAC1B,MAAM,IAAI,KAAK,CAAC,2BAA2B,KAAK,EAAE,CAAC,CAAC;IACtD,CAAC;IAED,OAAO,IAAI,CAAC,WAAW,EAAE,CAAC;AAC5B,CAAC;AAED;;;;;;GAMG;AACH,MAAM,UAAU,gBAAgB,CAC9B,IAAqB,EACrB,
|
|
1
|
+
{"version":3,"file":"generator.js","sourceRoot":"","sources":["../../src/shadows/generator.ts"],"names":[],"mappings":"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"}
|
package/dist/shadows/index.d.ts
CHANGED
|
@@ -8,8 +8,9 @@
|
|
|
8
8
|
* - シャドー差分計算(旧影と新影の比較)
|
|
9
9
|
* - shadow.config.json読み込みと検証
|
|
10
10
|
*/
|
|
11
|
-
export type {
|
|
12
|
-
export {
|
|
11
|
+
export type { ShadowFieldConfig, ResourceShadowConfig, ShadowConfig, ShadowDiff } from './types.js';
|
|
12
|
+
export type { ShadowFieldType, ShadowFieldDefinition, ResourceSchema, SchemaRegistryConfig, } from './schema.js';
|
|
13
|
+
export { escapeString, formatNumber, formatDatetime, formatBoolean, formatFieldValue, generateShadowSK, generateMainRecordSK, } from './generator.js';
|
|
13
14
|
export { calculateShadowDiff, isDiffEmpty, mergeShadowDiffs } from './differ.js';
|
|
14
15
|
export { loadShadowConfig, getResourceConfig, getAllShadowFields, isValidShadowField, getDefaultSort, getConfigPathFromEnv, } from './config.js';
|
|
15
16
|
//# sourceMappingURL=index.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/shadows/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAGH,YAAY,
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/shadows/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAGH,YAAY,EAAE,iBAAiB,EAAE,oBAAoB,EAAE,YAAY,EAAE,UAAU,EAAE,MAAM,YAAY,CAAC;AAGpG,YAAY,EACV,eAAe,EACf,qBAAqB,EACrB,cAAc,EACd,oBAAoB,GACrB,MAAM,aAAa,CAAC;AAGrB,OAAO,EACL,YAAY,EACZ,YAAY,EACZ,cAAc,EACd,aAAa,EACb,gBAAgB,EAChB,gBAAgB,EAChB,oBAAoB,GACrB,MAAM,gBAAgB,CAAC;AAGxB,OAAO,EAAE,mBAAmB,EAAE,WAAW,EAAE,gBAAgB,EAAE,MAAM,aAAa,CAAC;AAGjF,OAAO,EACL,gBAAgB,EAChB,iBAAiB,EACjB,kBAAkB,EAClB,kBAAkB,EAClB,cAAc,EACd,oBAAoB,GACrB,MAAM,aAAa,CAAC"}
|
package/dist/shadows/index.js
CHANGED
|
@@ -9,7 +9,7 @@
|
|
|
9
9
|
* - shadow.config.json読み込みと検証
|
|
10
10
|
*/
|
|
11
11
|
// ジェネレーター関数のエクスポート
|
|
12
|
-
export { escapeString, formatNumber, formatDatetime, formatFieldValue, generateShadowSK, generateMainRecordSK, } from './generator.js';
|
|
12
|
+
export { escapeString, formatNumber, formatDatetime, formatBoolean, formatFieldValue, generateShadowSK, generateMainRecordSK, } from './generator.js';
|
|
13
13
|
// 差分計算関数のエクスポート
|
|
14
14
|
export { calculateShadowDiff, isDiffEmpty, mergeShadowDiffs } from './differ.js';
|
|
15
15
|
// 設定管理関数のエクスポート
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/shadows/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/shadows/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAaH,mBAAmB;AACnB,OAAO,EACL,YAAY,EACZ,YAAY,EACZ,cAAc,EACd,aAAa,EACb,gBAAgB,EAChB,gBAAgB,EAChB,oBAAoB,GACrB,MAAM,gBAAgB,CAAC;AAExB,gBAAgB;AAChB,OAAO,EAAE,mBAAmB,EAAE,WAAW,EAAE,gBAAgB,EAAE,MAAM,aAAa,CAAC;AAEjF,gBAAgB;AAChB,OAAO,EACL,gBAAgB,EAChB,iBAAiB,EACjB,kBAAkB,EAClB,kBAAkB,EAClB,cAAc,EACd,oBAAoB,GACrB,MAAM,aAAa,CAAC"}
|
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Shadow Config スキーマ定義
|
|
3
|
+
*
|
|
4
|
+
* TypeScript でリソーススキーマを定義し、shadow.config.json を自動生成するための型定義。
|
|
5
|
+
* これにより、型安全性を保ちながら Shadow Config を管理できる。
|
|
6
|
+
*/
|
|
7
|
+
/**
|
|
8
|
+
* シャドーフィールドの型
|
|
9
|
+
*/
|
|
10
|
+
export type ShadowFieldType = 'string' | 'number' | 'datetime' | 'boolean';
|
|
11
|
+
/**
|
|
12
|
+
* シャドーフィールドの定義
|
|
13
|
+
*/
|
|
14
|
+
export interface ShadowFieldDefinition {
|
|
15
|
+
type: ShadowFieldType;
|
|
16
|
+
}
|
|
17
|
+
/**
|
|
18
|
+
* リソーススキーマの定義
|
|
19
|
+
*
|
|
20
|
+
* @template T - リソースの型(例: Article, Task など)
|
|
21
|
+
*/
|
|
22
|
+
export interface ResourceSchema<T = any> {
|
|
23
|
+
/** リソース名(複数形、例: "articles", "tasks") */
|
|
24
|
+
resource: string;
|
|
25
|
+
/** リソースの型定義(型チェック用) */
|
|
26
|
+
type: T;
|
|
27
|
+
/** シャドー設定 */
|
|
28
|
+
shadows: {
|
|
29
|
+
/** ソート可能なフィールドの定義 */
|
|
30
|
+
sortableFields: Record<string, ShadowFieldDefinition>;
|
|
31
|
+
};
|
|
32
|
+
/** デフォルトソート設定(省略時は自動決定) */
|
|
33
|
+
sortDefaults?: {
|
|
34
|
+
field: string;
|
|
35
|
+
order: 'ASC' | 'DESC';
|
|
36
|
+
};
|
|
37
|
+
/** TTL 設定(省略可) */
|
|
38
|
+
ttl?: {
|
|
39
|
+
days: number;
|
|
40
|
+
};
|
|
41
|
+
}
|
|
42
|
+
/**
|
|
43
|
+
* スキーマレジストリの設定
|
|
44
|
+
*
|
|
45
|
+
* アプリケーション全体のリソーススキーマを定義する。
|
|
46
|
+
* この設定から shadow.config.json を自動生成する。
|
|
47
|
+
*/
|
|
48
|
+
export interface SchemaRegistryConfig {
|
|
49
|
+
/** データベース設定 */
|
|
50
|
+
database: {
|
|
51
|
+
/** データベース名 */
|
|
52
|
+
name: string;
|
|
53
|
+
/** タイムスタンプフィールド名 */
|
|
54
|
+
timestamps: {
|
|
55
|
+
createdAt: string;
|
|
56
|
+
updatedAt: string;
|
|
57
|
+
};
|
|
58
|
+
};
|
|
59
|
+
/** リソーススキーマの定義 */
|
|
60
|
+
resources: Record<string, ResourceSchema>;
|
|
61
|
+
}
|
|
62
|
+
//# sourceMappingURL=schema.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"schema.d.ts","sourceRoot":"","sources":["../../src/shadows/schema.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH;;GAEG;AACH,MAAM,MAAM,eAAe,GAAG,QAAQ,GAAG,QAAQ,GAAG,UAAU,GAAG,SAAS,CAAC;AAE3E;;GAEG;AACH,MAAM,WAAW,qBAAqB;IACpC,IAAI,EAAE,eAAe,CAAC;CACvB;AAED;;;;GAIG;AACH,MAAM,WAAW,cAAc,CAAC,CAAC,GAAG,GAAG;IACrC,wCAAwC;IACxC,QAAQ,EAAE,MAAM,CAAC;IAEjB,uBAAuB;IACvB,IAAI,EAAE,CAAC,CAAC;IAER,aAAa;IACb,OAAO,EAAE;QACP,qBAAqB;QACrB,cAAc,EAAE,MAAM,CAAC,MAAM,EAAE,qBAAqB,CAAC,CAAC;KACvD,CAAC;IAEF,2BAA2B;IAC3B,YAAY,CAAC,EAAE;QACb,KAAK,EAAE,MAAM,CAAC;QACd,KAAK,EAAE,KAAK,GAAG,MAAM,CAAC;KACvB,CAAC;IAEF,kBAAkB;IAClB,GAAG,CAAC,EAAE;QACJ,IAAI,EAAE,MAAM,CAAC;KACd,CAAC;CACH;AAED;;;;;GAKG;AACH,MAAM,WAAW,oBAAoB;IACnC,eAAe;IACf,QAAQ,EAAE;QACR,cAAc;QACd,IAAI,EAAE,MAAM,CAAC;QAEb,oBAAoB;QACpB,UAAU,EAAE;YACV,SAAS,EAAE,MAAM,CAAC;YAClB,SAAS,EAAE,MAAM,CAAC;SACnB,CAAC;KACH,CAAC;IAEF,kBAAkB;IAClB,SAAS,EAAE,MAAM,CAAC,MAAM,EAAE,cAAc,CAAC,CAAC;CAC3C"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"schema.js","sourceRoot":"","sources":["../../src/shadows/schema.ts"],"names":[],"mappings":"AAAA;;;;;GAKG"}
|
package/dist/shadows/types.d.ts
CHANGED
|
@@ -1,12 +1,8 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* シャドーフィールドの型定義
|
|
3
|
-
*/
|
|
4
|
-
export type ShadowFieldType = 'string' | 'number' | 'datetime';
|
|
5
1
|
/**
|
|
6
2
|
* シャドー設定のフィールド定義
|
|
7
3
|
*/
|
|
8
4
|
export interface ShadowFieldConfig {
|
|
9
|
-
type:
|
|
5
|
+
type: 'string' | 'number' | 'datetime';
|
|
10
6
|
}
|
|
11
7
|
/**
|
|
12
8
|
* リソースごとのシャドー設定
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/shadows/types.ts"],"names":[],"mappings":"AAAA;;GAEG;AACH,MAAM,
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/shadows/types.ts"],"names":[],"mappings":"AAAA;;GAEG;AACH,MAAM,WAAW,iBAAiB;IAChC,IAAI,EAAE,QAAQ,GAAG,QAAQ,GAAG,UAAU,CAAC;CACxC;AAED;;GAEG;AACH,MAAM,WAAW,oBAAoB;IACnC,YAAY,EAAE;QACZ,KAAK,EAAE,MAAM,CAAC;QACd,KAAK,EAAE,KAAK,GAAG,MAAM,CAAC;KACvB,CAAC;IACF,OAAO,EAAE;QACP,CAAC,SAAS,EAAE,MAAM,GAAG,iBAAiB,CAAC;KACxC,CAAC;IACF,GAAG,CAAC,EAAE;QACJ,IAAI,EAAE,MAAM,CAAC;KACd,CAAC;CACH;AAED;;GAEG;AACH,MAAM,WAAW,YAAY;IAC3B,cAAc,EAAE,MAAM,CAAC;IACvB,SAAS,EAAE;QACT,CAAC,YAAY,EAAE,MAAM,GAAG,oBAAoB,CAAC;KAC9C,CAAC;CACH;AAED;;GAEG;AACH,MAAM,WAAW,UAAU;IACzB,sBAAsB;IACtB,QAAQ,EAAE,MAAM,EAAE,CAAC;IACnB,sBAAsB;IACtB,KAAK,EAAE,MAAM,EAAE,CAAC;CACjB"}
|
package/package.json
CHANGED
|
@@ -1,12 +1,15 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@exabugs/dynamodb-client",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.2",
|
|
4
4
|
"description": "DynamoDB Single-Table Client SDK with MongoDB-like API, Shadow Records, and Lambda implementation for serverless applications",
|
|
5
5
|
"author": "exabugs",
|
|
6
6
|
"license": "MIT",
|
|
7
7
|
"type": "module",
|
|
8
8
|
"main": "./dist/index.js",
|
|
9
9
|
"types": "./dist/index.d.ts",
|
|
10
|
+
"bin": {
|
|
11
|
+
"generate-shadow-config": "./dist/scripts/generate-shadow-config.js"
|
|
12
|
+
},
|
|
10
13
|
"keywords": [
|
|
11
14
|
"dynamodb",
|
|
12
15
|
"single-table",
|
|
@@ -95,8 +98,8 @@
|
|
|
95
98
|
"build:lambda": "node esbuild.config.js",
|
|
96
99
|
"clean": "rm -rf dist",
|
|
97
100
|
"lint": "eslint src --ext ts --max-warnings 10",
|
|
98
|
-
"format": "prettier --write \"src/**/*.ts\"",
|
|
99
|
-
"format:check": "prettier --check \"src/**/*.ts\"",
|
|
101
|
+
"format": "prettier --write \"src/**/*.ts\" \".github/**/*.yml\"",
|
|
102
|
+
"format:check": "prettier --check \"src/**/*.ts\" \".github/**/*.yml\"",
|
|
100
103
|
"test": "vitest run",
|
|
101
104
|
"test:coverage": "vitest run --coverage",
|
|
102
105
|
"test:watch": "vitest",
|
|
@@ -116,7 +119,7 @@
|
|
|
116
119
|
},
|
|
117
120
|
"devDependencies": {
|
|
118
121
|
"@eslint/js": "^9.0.0",
|
|
119
|
-
"@trivago/prettier-plugin-sort-imports": "^4.
|
|
122
|
+
"@trivago/prettier-plugin-sort-imports": "^4.3.0",
|
|
120
123
|
"@types/aws-lambda": "^8.10.0",
|
|
121
124
|
"@types/node": "^22.0.0",
|
|
122
125
|
"@typescript-eslint/eslint-plugin": "^8.0.0",
|
package/dist/server/handler.zip
DELETED
|
Binary file
|
|
@@ -1,129 +0,0 @@
|
|
|
1
|
-
# Advanced Example
|
|
2
|
-
|
|
3
|
-
This example demonstrates an advanced deployment with:
|
|
4
|
-
|
|
5
|
-
- Multi-environment support (dev/stg/prd)
|
|
6
|
-
- External shadow configuration file
|
|
7
|
-
- CloudWatch Alarms
|
|
8
|
-
- TTL configuration
|
|
9
|
-
- Point-in-time Recovery (production only)
|
|
10
|
-
- MFA configuration (production only)
|
|
11
|
-
- Environment-specific settings
|
|
12
|
-
|
|
13
|
-
## What This Example Creates
|
|
14
|
-
|
|
15
|
-
- DynamoDB table with TTL and PITR
|
|
16
|
-
- Cognito User Pool with advanced security settings
|
|
17
|
-
- Cognito App Client with token validity configuration
|
|
18
|
-
- Records Lambda function with Function URL
|
|
19
|
-
- CloudWatch Alarms for error monitoring
|
|
20
|
-
- IAM roles and policies
|
|
21
|
-
- CloudWatch Logs
|
|
22
|
-
|
|
23
|
-
## Usage
|
|
24
|
-
|
|
25
|
-
1. Review and customize `shadow.config.json`:
|
|
26
|
-
|
|
27
|
-
```bash
|
|
28
|
-
cat shadow.config.json
|
|
29
|
-
```
|
|
30
|
-
|
|
31
|
-
2. Initialize Terraform:
|
|
32
|
-
|
|
33
|
-
```bash
|
|
34
|
-
terraform init
|
|
35
|
-
```
|
|
36
|
-
|
|
37
|
-
3. Review the plan:
|
|
38
|
-
|
|
39
|
-
```bash
|
|
40
|
-
terraform plan -var="environment=dev"
|
|
41
|
-
```
|
|
42
|
-
|
|
43
|
-
4. Apply the configuration:
|
|
44
|
-
|
|
45
|
-
```bash
|
|
46
|
-
terraform apply -var="environment=dev"
|
|
47
|
-
```
|
|
48
|
-
|
|
49
|
-
5. Get the outputs:
|
|
50
|
-
|
|
51
|
-
```bash
|
|
52
|
-
terraform output
|
|
53
|
-
```
|
|
54
|
-
|
|
55
|
-
## Environment-Specific Settings
|
|
56
|
-
|
|
57
|
-
### Development (dev)
|
|
58
|
-
- Log retention: 7 days
|
|
59
|
-
- Log level: debug
|
|
60
|
-
- MFA: Optional
|
|
61
|
-
- PITR: Disabled
|
|
62
|
-
|
|
63
|
-
### Staging (stg)
|
|
64
|
-
- Log retention: 7 days
|
|
65
|
-
- Log level: info
|
|
66
|
-
- MFA: Optional
|
|
67
|
-
- PITR: Disabled
|
|
68
|
-
|
|
69
|
-
### Production (prd)
|
|
70
|
-
- Log retention: 30 days
|
|
71
|
-
- Log level: warn
|
|
72
|
-
- MFA: Required
|
|
73
|
-
- PITR: Enabled
|
|
74
|
-
|
|
75
|
-
## Shadow Configuration
|
|
76
|
-
|
|
77
|
-
The `shadow.config.json` file defines sortable fields for each resource:
|
|
78
|
-
|
|
79
|
-
```json
|
|
80
|
-
{
|
|
81
|
-
"$schemaVersion": "1.0",
|
|
82
|
-
"resources": {
|
|
83
|
-
"articles": {
|
|
84
|
-
"sortDefaults": {
|
|
85
|
-
"field": "updatedAt",
|
|
86
|
-
"order": "DESC"
|
|
87
|
-
},
|
|
88
|
-
"shadows": {
|
|
89
|
-
"title": { "type": "string" },
|
|
90
|
-
"status": { "type": "string" },
|
|
91
|
-
"publishedAt": { "type": "datetime" },
|
|
92
|
-
"createdAt": { "type": "datetime" },
|
|
93
|
-
"updatedAt": { "type": "datetime" }
|
|
94
|
-
}
|
|
95
|
-
}
|
|
96
|
-
}
|
|
97
|
-
}
|
|
98
|
-
```
|
|
99
|
-
|
|
100
|
-
## CloudWatch Alarms
|
|
101
|
-
|
|
102
|
-
The example includes a CloudWatch Alarm that triggers when:
|
|
103
|
-
- Lambda function errors exceed 10 in a 5-minute period
|
|
104
|
-
|
|
105
|
-
To receive notifications, provide an SNS topic ARN:
|
|
106
|
-
|
|
107
|
-
```bash
|
|
108
|
-
terraform apply -var="sns_topic_arn=arn:aws:sns:us-east-1:123456789012:alerts"
|
|
109
|
-
```
|
|
110
|
-
|
|
111
|
-
## Clean Up
|
|
112
|
-
|
|
113
|
-
To destroy all resources:
|
|
114
|
-
|
|
115
|
-
```bash
|
|
116
|
-
terraform destroy
|
|
117
|
-
```
|
|
118
|
-
|
|
119
|
-
## Customization
|
|
120
|
-
|
|
121
|
-
You can customize the deployment by modifying variables:
|
|
122
|
-
|
|
123
|
-
```bash
|
|
124
|
-
terraform apply \
|
|
125
|
-
-var="project_name=my-app" \
|
|
126
|
-
-var="environment=prd" \
|
|
127
|
-
-var="region=ap-northeast-1" \
|
|
128
|
-
-var="sns_topic_arn=arn:aws:sns:..."
|
|
129
|
-
```
|