@exabugs/dynamodb-client 0.2.2 → 0.3.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.
Files changed (65) hide show
  1. package/CHANGELOG.md +39 -0
  2. package/README.md +92 -28
  3. package/dist/index.d.ts +1 -1
  4. package/dist/index.d.ts.map +1 -1
  5. package/dist/index.js +1 -1
  6. package/dist/index.js.map +1 -1
  7. package/dist/server/handler.cjs +137 -178
  8. package/dist/server/handler.cjs.map +4 -4
  9. package/dist/server/handler.d.ts.map +1 -1
  10. package/dist/server/handler.js +2 -15
  11. package/dist/server/handler.js.map +1 -1
  12. package/dist/server/operations/find.d.ts.map +1 -1
  13. package/dist/server/operations/find.js +5 -12
  14. package/dist/server/operations/find.js.map +1 -1
  15. package/dist/server/operations/findManyReference.d.ts.map +1 -1
  16. package/dist/server/operations/findManyReference.js +3 -10
  17. package/dist/server/operations/findManyReference.js.map +1 -1
  18. package/dist/server/operations/insertMany.d.ts.map +1 -1
  19. package/dist/server/operations/insertMany.js +3 -8
  20. package/dist/server/operations/insertMany.js.map +1 -1
  21. package/dist/server/operations/insertOne.d.ts.map +1 -1
  22. package/dist/server/operations/insertOne.js +3 -8
  23. package/dist/server/operations/insertOne.js.map +1 -1
  24. package/dist/server/operations/updateMany.d.ts.map +1 -1
  25. package/dist/server/operations/updateMany.js +3 -4
  26. package/dist/server/operations/updateMany.js.map +1 -1
  27. package/dist/server/operations/updateOne.d.ts.map +1 -1
  28. package/dist/server/operations/updateOne.js +3 -4
  29. package/dist/server/operations/updateOne.js.map +1 -1
  30. package/dist/server/shadow/config.d.ts +18 -112
  31. package/dist/server/shadow/config.d.ts.map +1 -1
  32. package/dist/server/shadow/config.js +33 -131
  33. package/dist/server/shadow/config.js.map +1 -1
  34. package/dist/server/shadow/generator.d.ts +92 -43
  35. package/dist/server/shadow/generator.d.ts.map +1 -1
  36. package/dist/server/shadow/generator.js +175 -56
  37. package/dist/server/shadow/generator.js.map +1 -1
  38. package/dist/server/shadow/index.d.ts +4 -3
  39. package/dist/server/shadow/index.d.ts.map +1 -1
  40. package/dist/server/shadow/index.js +4 -2
  41. package/dist/server/shadow/index.js.map +1 -1
  42. package/dist/server/shadow/typeInference.d.ts +61 -0
  43. package/dist/server/shadow/typeInference.d.ts.map +1 -0
  44. package/dist/server/shadow/typeInference.js +94 -0
  45. package/dist/server/shadow/typeInference.js.map +1 -0
  46. package/dist/server/shadow/types.d.ts +1 -1
  47. package/dist/server/shadow/types.d.ts.map +1 -1
  48. package/dist/server/utils/timestamps.d.ts.map +1 -1
  49. package/dist/server/utils/timestamps.js +3 -26
  50. package/dist/server/utils/timestamps.js.map +1 -1
  51. package/dist/server/utils/ttl.d.ts.map +1 -1
  52. package/dist/server/utils/ttl.js +11 -9
  53. package/dist/server/utils/ttl.js.map +1 -1
  54. package/dist/server/utils/validation.d.ts +14 -8
  55. package/dist/server/utils/validation.d.ts.map +1 -1
  56. package/dist/server/utils/validation.js +19 -26
  57. package/dist/server/utils/validation.js.map +1 -1
  58. package/package.json +1 -1
  59. package/terraform/README.md +3 -3
  60. package/terraform/main.tf +6 -2
  61. package/terraform/variables.tf +32 -2
  62. package/dist/scripts/generate-shadow-config.d.ts +0 -3
  63. package/dist/scripts/generate-shadow-config.d.ts.map +0 -1
  64. package/dist/scripts/generate-shadow-config.js +0 -159
  65. package/dist/scripts/generate-shadow-config.js.map +0 -1
@@ -1,114 +1,48 @@
1
1
  /**
2
- * サーバーサイドシャドウ設定管理
2
+ * サーバーサイドシャドウ設定管理(簡素化版)
3
3
  *
4
4
  * シャドー設定を環境変数から読み込み、グローバル変数にキャッシュします。
5
- * 設定はTerraformデプロイ時に環境変数として埋め込まれるため、
6
- * 実行時のI/Oが不要で、最も高速かつシンプルです。
5
+ * JSON設定ファイルは廃止され、環境変数のみで管理されます。
7
6
  *
8
7
  * キャッシュの動作:
9
- * - 初回呼び出し時: 環境変数からパースしてキャッシュ
8
+ * - 初回呼び出し時: 環境変数から読み込んでキャッシュ
10
9
  * - 2回目以降: キャッシュから即座に取得
11
10
  * - キャッシュ有効期間: Lambda実行環境が存在する間(通常15分〜数時間)
12
11
  *
13
12
  * 設定変更の反映:
14
- * - config/shadow.config.jsonを変更
15
- * - Terraformで再度apply(環境変数が更新される)
13
+ * - Terraformで環境変数を変更
16
14
  * - Lambda関数が自動的に再デプロイされ、新しい設定が反映される
17
15
  *
18
- * 要件: 8.7
16
+ * 要件: 2.9-2.11
19
17
  */
20
- import type { ShadowSchema } from './generator.js';
21
- import type { ShadowFieldConfig } from './types.js';
22
18
  /**
23
- * シャドー設定の全体構造
19
+ * シャドー設定(簡素化版)
24
20
  */
25
21
  export interface ShadowConfig {
26
- /** スキーマバージョン */
27
- $schemaVersion: string;
28
- /** 生成日時 */
29
- $generatedAt?: string;
30
- /** 生成元ファイル */
31
- $generatedFrom?: string;
32
- /** データベース設定 */
33
- database?: {
34
- name: string;
35
- timestamps?: {
36
- createdAt: string;
37
- updatedAt: string;
38
- };
39
- };
40
- /** リソースごとの設定 */
41
- resources: {
42
- [resourceName: string]: {
43
- /** ソート可能なフィールド定義 */
44
- shadows: {
45
- [fieldName: string]: {
46
- /** フィールドの型 */
47
- type: 'string' | 'number' | 'datetime' | 'boolean';
48
- };
49
- };
50
- /** デフォルトソート設定 */
51
- sortDefaults: {
52
- field: string;
53
- order: 'ASC' | 'DESC';
54
- };
55
- /** TTL設定(オプション) */
56
- ttl?: {
57
- days: number;
58
- };
59
- };
60
- };
22
+ /** タイムスタンプフィールド名 */
23
+ createdAtField: string;
24
+ updatedAtField: string;
25
+ /** プリミティブ型の最大バイト数(array/objectは2倍) */
26
+ stringMaxBytes: number;
27
+ /** 数値のパディング桁数 */
28
+ numberPadding: number;
61
29
  }
62
30
  /**
63
- * シャドー設定を取得(キャッシュ付き)
31
+ * シャドー設定を取得(環境変数から)
64
32
  *
65
- * 環境変数SHADOW_CONFIGからbase64エンコードされたJSON文字列をデコードしてパースして取得。
66
- * 初回呼び出し時のみパース処理を行い、以降はキャッシュを使用。
33
+ * 環境変数から設定を読み込み、グローバル変数にキャッシュします。
34
+ * 初回呼び出し時のみ環境変数を読み込み、以降はキャッシュを使用。
67
35
  *
68
36
  * @returns シャドー設定
69
- * @throws 環境変数が未設定、または不正な形式の場合
37
+ * @throws 環境変数が不正な値の場合
70
38
  *
71
39
  * @example
72
40
  * ```typescript
73
41
  * const config = getShadowConfig();
74
- * const articleSchema = getResourceSchema(config, 'articles');
75
- * const shadows = generateShadowRecords(record, articleSchema);
42
+ * // => { createdAtField: 'createdAt', updatedAtField: 'updatedAt', stringMaxBytes: 100, numberPadding: 20 }
76
43
  * ```
77
44
  */
78
45
  export declare function getShadowConfig(): ShadowConfig;
79
- /**
80
- * 特定のリソースのシャドースキーマを取得する
81
- *
82
- * @param config - シャドー設定全体
83
- * @param resourceName - リソース名(例: 'articles', 'tasks')
84
- * @returns シャドースキーマ
85
- * @throws リソースが設定に存在しない場合
86
- *
87
- * @example
88
- * ```typescript
89
- * const config = getShadowConfig();
90
- * const schema = getResourceSchema(config, 'articles');
91
- * // => { resource: 'articles', sortableFields: { name: { type: 'string' }, ... } }
92
- * ```
93
- */
94
- export declare function getResourceSchema(config: ShadowConfig, resourceName: string): ShadowSchema;
95
- /**
96
- * 設定ハッシュを取得
97
- *
98
- * レコード作成時にメタデータとして保存するために使用。
99
- * SHADOW_CONFIG環境変数(base64エンコードされたJSON)からSHA-256ハッシュを生成する。
100
- *
101
- * @returns 設定ハッシュ(SHA-256)
102
- */
103
- export declare function getShadowConfigHash(): string;
104
- /**
105
- * スキーマバージョンを取得
106
- *
107
- * レコード作成時にメタデータとして保存するために使用。
108
- *
109
- * @returns スキーマバージョン
110
- */
111
- export declare function getSchemaVersion(): string;
112
46
  /**
113
47
  * キャッシュをクリアする(テスト用)
114
48
  *
@@ -116,32 +50,4 @@ export declare function getSchemaVersion(): string;
116
50
  * テスト環境でのみ、テスト間でキャッシュをクリアするために使用。
117
51
  */
118
52
  export declare function clearShadowConfigCache(): void;
119
- /**
120
- * リソースの全シャドーフィールドを取得する
121
- *
122
- * @param config - シャドー設定全体
123
- * @param resourceName - リソース名
124
- * @returns 全シャドーフィールドの設定
125
- */
126
- export declare function getAllShadowFields(config: ShadowConfig, resourceName: string): Record<string, ShadowFieldConfig>;
127
- /**
128
- * 指定されたフィールドが有効なシャドーフィールドかどうかを検証する
129
- *
130
- * @param config - シャドー設定全体
131
- * @param resourceName - リソース名
132
- * @param fieldName - 検証するフィールド名
133
- * @returns フィールドが有効な場合true
134
- */
135
- export declare function isValidShadowField(config: ShadowConfig, resourceName: string, fieldName: string): boolean;
136
- /**
137
- * リソースのデフォルトソート設定を取得する
138
- *
139
- * @param config - シャドー設定全体
140
- * @param resourceName - リソース名
141
- * @returns デフォルトソート設定
142
- */
143
- export declare function getDefaultSort(config: ShadowConfig, resourceName: string): {
144
- field: string;
145
- order: 'ASC' | 'DESC';
146
- };
147
53
  //# sourceMappingURL=config.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"config.d.ts","sourceRoot":"","sources":["../../../src/server/shadow/config.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;GAkBG;AACH,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,gBAAgB,CAAC;AACnD,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,YAAY,CAAC;AAEpD;;GAEG;AACH,MAAM,WAAW,YAAY;IAC3B,gBAAgB;IAChB,cAAc,EAAE,MAAM,CAAC;IACvB,WAAW;IACX,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,cAAc;IACd,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,eAAe;IACf,QAAQ,CAAC,EAAE;QACT,IAAI,EAAE,MAAM,CAAC;QACb,UAAU,CAAC,EAAE;YACX,SAAS,EAAE,MAAM,CAAC;YAClB,SAAS,EAAE,MAAM,CAAC;SACnB,CAAC;KACH,CAAC;IACF,gBAAgB;IAChB,SAAS,EAAE;QACT,CAAC,YAAY,EAAE,MAAM,GAAG;YACtB,oBAAoB;YACpB,OAAO,EAAE;gBACP,CAAC,SAAS,EAAE,MAAM,GAAG;oBACnB,cAAc;oBACd,IAAI,EAAE,QAAQ,GAAG,QAAQ,GAAG,UAAU,GAAG,SAAS,CAAC;iBACpD,CAAC;aACH,CAAC;YACF,iBAAiB;YACjB,YAAY,EAAE;gBACZ,KAAK,EAAE,MAAM,CAAC;gBACd,KAAK,EAAE,KAAK,GAAG,MAAM,CAAC;aACvB,CAAC;YACF,mBAAmB;YACnB,GAAG,CAAC,EAAE;gBACJ,IAAI,EAAE,MAAM,CAAC;aACd,CAAC;SACH,CAAC;KACH,CAAC;CACH;AAOD;;;;;;;;;;;;;;;GAeG;AACH,wBAAgB,eAAe,IAAI,YAAY,CA8B9C;AAED;;;;;;;;;;;;;;GAcG;AACH,wBAAgB,iBAAiB,CAAC,MAAM,EAAE,YAAY,EAAE,YAAY,EAAE,MAAM,GAAG,YAAY,CAW1F;AAED;;;;;;;GAOG;AACH,wBAAgB,mBAAmB,IAAI,MAAM,CAiB5C;AAED;;;;;;GAMG;AACH,wBAAgB,gBAAgB,IAAI,MAAM,CAGzC;AAED;;;;;GAKG;AACH,wBAAgB,sBAAsB,IAAI,IAAI,CAE7C;AAED;;;;;;GAMG;AACH,wBAAgB,kBAAkB,CAChC,MAAM,EAAE,YAAY,EACpB,YAAY,EAAE,MAAM,GACnB,MAAM,CAAC,MAAM,EAAE,iBAAiB,CAAC,CAQnC;AAED;;;;;;;GAOG;AACH,wBAAgB,kBAAkB,CAChC,MAAM,EAAE,YAAY,EACpB,YAAY,EAAE,MAAM,EACpB,SAAS,EAAE,MAAM,GAChB,OAAO,CAOT;AAED;;;;;;GAMG;AACH,wBAAgB,cAAc,CAC5B,MAAM,EAAE,YAAY,EACpB,YAAY,EAAE,MAAM,GACnB;IAAE,KAAK,EAAE,MAAM,CAAC;IAAC,KAAK,EAAE,KAAK,GAAG,MAAM,CAAA;CAAE,CAQ1C"}
1
+ {"version":3,"file":"config.d.ts","sourceRoot":"","sources":["../../../src/server/shadow/config.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;GAgBG;AAEH;;GAEG;AACH,MAAM,WAAW,YAAY;IAC3B,oBAAoB;IACpB,cAAc,EAAE,MAAM,CAAC;IACvB,cAAc,EAAE,MAAM,CAAC;IACvB,sCAAsC;IACtC,cAAc,EAAE,MAAM,CAAC;IACvB,iBAAiB;IACjB,aAAa,EAAE,MAAM,CAAC;CACvB;AAOD;;;;;;;;;;;;;;GAcG;AACH,wBAAgB,eAAe,IAAI,YAAY,CAmB9C;AAED;;;;;GAKG;AACH,wBAAgB,sBAAsB,IAAI,IAAI,CAE7C"}
@@ -1,110 +1,57 @@
1
+ /**
2
+ * サーバーサイドシャドウ設定管理(簡素化版)
3
+ *
4
+ * シャドー設定を環境変数から読み込み、グローバル変数にキャッシュします。
5
+ * JSON設定ファイルは廃止され、環境変数のみで管理されます。
6
+ *
7
+ * キャッシュの動作:
8
+ * - 初回呼び出し時: 環境変数から読み込んでキャッシュ
9
+ * - 2回目以降: キャッシュから即座に取得
10
+ * - キャッシュ有効期間: Lambda実行環境が存在する間(通常15分〜数時間)
11
+ *
12
+ * 設定変更の反映:
13
+ * - Terraformで環境変数を変更
14
+ * - Lambda関数が自動的に再デプロイされ、新しい設定が反映される
15
+ *
16
+ * 要件: 2.9-2.11
17
+ */
1
18
  /**
2
19
  * グローバル変数にキャッシュ(Lambda実行環境で再利用)
3
20
  */
4
21
  let cachedShadowConfig = null;
5
22
  /**
6
- * シャドー設定を取得(キャッシュ付き)
23
+ * シャドー設定を取得(環境変数から)
7
24
  *
8
- * 環境変数SHADOW_CONFIGからbase64エンコードされたJSON文字列をデコードしてパースして取得。
9
- * 初回呼び出し時のみパース処理を行い、以降はキャッシュを使用。
25
+ * 環境変数から設定を読み込み、グローバル変数にキャッシュします。
26
+ * 初回呼び出し時のみ環境変数を読み込み、以降はキャッシュを使用。
10
27
  *
11
28
  * @returns シャドー設定
12
- * @throws 環境変数が未設定、または不正な形式の場合
29
+ * @throws 環境変数が不正な値の場合
13
30
  *
14
31
  * @example
15
32
  * ```typescript
16
33
  * const config = getShadowConfig();
17
- * const articleSchema = getResourceSchema(config, 'articles');
18
- * const shadows = generateShadowRecords(record, articleSchema);
34
+ * // => { createdAtField: 'createdAt', updatedAtField: 'updatedAt', stringMaxBytes: 100, numberPadding: 20 }
19
35
  * ```
20
36
  */
21
37
  export function getShadowConfig() {
22
38
  if (!cachedShadowConfig) {
23
- const configBase64 = process.env.SHADOW_CONFIG;
24
- if (!configBase64) {
25
- throw new Error('SHADOW_CONFIG environment variable is not set');
39
+ cachedShadowConfig = {
40
+ createdAtField: process.env.SHADOW_CREATED_AT_FIELD || 'createdAt',
41
+ updatedAtField: process.env.SHADOW_UPDATED_AT_FIELD || 'updatedAt',
42
+ stringMaxBytes: parseInt(process.env.SHADOW_STRING_MAX_BYTES || '100', 10),
43
+ numberPadding: parseInt(process.env.SHADOW_NUMBER_PADDING || '15', 10),
44
+ };
45
+ // バリデーション
46
+ if (cachedShadowConfig.stringMaxBytes <= 0) {
47
+ throw new Error('SHADOW_STRING_MAX_BYTES must be positive');
26
48
  }
27
- try {
28
- // Base64デコード
29
- const configJson = Buffer.from(configBase64, 'base64').toString('utf-8');
30
- cachedShadowConfig = JSON.parse(configJson);
31
- // 基本的なバリデーション
32
- if (!cachedShadowConfig.$schemaVersion) {
33
- throw new Error('Missing $schemaVersion in shadow config');
34
- }
35
- if (!cachedShadowConfig.resources || typeof cachedShadowConfig.resources !== 'object') {
36
- throw new Error('Missing or invalid resources in shadow config');
37
- }
38
- }
39
- catch (error) {
40
- if (error instanceof SyntaxError) {
41
- throw new Error(`Invalid JSON in SHADOW_CONFIG environment variable: ${error.message}`);
42
- }
43
- throw error;
49
+ if (cachedShadowConfig.numberPadding <= 0 || cachedShadowConfig.numberPadding > 15) {
50
+ throw new Error('SHADOW_NUMBER_PADDING must be between 1 and 15');
44
51
  }
45
52
  }
46
53
  return cachedShadowConfig;
47
54
  }
48
- /**
49
- * 特定のリソースのシャドースキーマを取得する
50
- *
51
- * @param config - シャドー設定全体
52
- * @param resourceName - リソース名(例: 'articles', 'tasks')
53
- * @returns シャドースキーマ
54
- * @throws リソースが設定に存在しない場合
55
- *
56
- * @example
57
- * ```typescript
58
- * const config = getShadowConfig();
59
- * const schema = getResourceSchema(config, 'articles');
60
- * // => { resource: 'articles', sortableFields: { name: { type: 'string' }, ... } }
61
- * ```
62
- */
63
- export function getResourceSchema(config, resourceName) {
64
- const resourceConfig = config.resources[resourceName];
65
- if (!resourceConfig) {
66
- throw new Error(`Resource '${resourceName}' not found in shadow config`);
67
- }
68
- return {
69
- resource: resourceName,
70
- sortableFields: resourceConfig.shadows,
71
- };
72
- }
73
- /**
74
- * 設定ハッシュを取得
75
- *
76
- * レコード作成時にメタデータとして保存するために使用。
77
- * SHADOW_CONFIG環境変数(base64エンコードされたJSON)からSHA-256ハッシュを生成する。
78
- *
79
- * @returns 設定ハッシュ(SHA-256)
80
- */
81
- export function getShadowConfigHash() {
82
- // 設定をロード(キャッシュされていなければロードされる)
83
- getShadowConfig();
84
- // 環境変数 SHADOW_CONFIG は Terraform により base64 エンコードされた JSON として設定される
85
- // この値をハッシュ化することで、設定の変更を検知できる
86
- const configBase64 = process.env.SHADOW_CONFIG;
87
- if (!configBase64) {
88
- throw new Error('SHADOW_CONFIG environment variable is not set');
89
- }
90
- // Node.js の crypto モジュールを使用してハッシュを計算
91
- // Lambda 環境では crypto は標準モジュール
92
- // eslint-disable-next-line @typescript-eslint/no-require-imports
93
- const crypto = require('crypto');
94
- const hash = crypto.createHash('sha256').update(configBase64).digest('hex');
95
- return hash;
96
- }
97
- /**
98
- * スキーマバージョンを取得
99
- *
100
- * レコード作成時にメタデータとして保存するために使用。
101
- *
102
- * @returns スキーマバージョン
103
- */
104
- export function getSchemaVersion() {
105
- const config = getShadowConfig();
106
- return config.$schemaVersion;
107
- }
108
55
  /**
109
56
  * キャッシュをクリアする(テスト用)
110
57
  *
@@ -114,49 +61,4 @@ export function getSchemaVersion() {
114
61
  export function clearShadowConfigCache() {
115
62
  cachedShadowConfig = null;
116
63
  }
117
- /**
118
- * リソースの全シャドーフィールドを取得する
119
- *
120
- * @param config - シャドー設定全体
121
- * @param resourceName - リソース名
122
- * @returns 全シャドーフィールドの設定
123
- */
124
- export function getAllShadowFields(config, resourceName) {
125
- const resourceConfig = config.resources[resourceName];
126
- if (!resourceConfig) {
127
- throw new Error(`Resource '${resourceName}' not found in shadow config`);
128
- }
129
- return resourceConfig.shadows;
130
- }
131
- /**
132
- * 指定されたフィールドが有効なシャドーフィールドかどうかを検証する
133
- *
134
- * @param config - シャドー設定全体
135
- * @param resourceName - リソース名
136
- * @param fieldName - 検証するフィールド名
137
- * @returns フィールドが有効な場合true
138
- */
139
- export function isValidShadowField(config, resourceName, fieldName) {
140
- try {
141
- const allFields = getAllShadowFields(config, resourceName);
142
- return fieldName in allFields;
143
- }
144
- catch {
145
- return false;
146
- }
147
- }
148
- /**
149
- * リソースのデフォルトソート設定を取得する
150
- *
151
- * @param config - シャドー設定全体
152
- * @param resourceName - リソース名
153
- * @returns デフォルトソート設定
154
- */
155
- export function getDefaultSort(config, resourceName) {
156
- const resourceConfig = config.resources[resourceName];
157
- if (!resourceConfig) {
158
- throw new Error(`Resource '${resourceName}' not found in shadow config`);
159
- }
160
- return resourceConfig.sortDefaults;
161
- }
162
64
  //# sourceMappingURL=config.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"config.js","sourceRoot":"","sources":["../../../src/server/shadow/config.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"config.js","sourceRoot":"","sources":["../../../src/server/shadow/config.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;GAgBG;AAeH;;GAEG;AACH,IAAI,kBAAkB,GAAwB,IAAI,CAAC;AAEnD;;;;;;;;;;;;;;GAcG;AACH,MAAM,UAAU,eAAe;IAC7B,IAAI,CAAC,kBAAkB,EAAE,CAAC;QACxB,kBAAkB,GAAG;YACnB,cAAc,EAAE,OAAO,CAAC,GAAG,CAAC,uBAAuB,IAAI,WAAW;YAClE,cAAc,EAAE,OAAO,CAAC,GAAG,CAAC,uBAAuB,IAAI,WAAW;YAClE,cAAc,EAAE,QAAQ,CAAC,OAAO,CAAC,GAAG,CAAC,uBAAuB,IAAI,KAAK,EAAE,EAAE,CAAC;YAC1E,aAAa,EAAE,QAAQ,CAAC,OAAO,CAAC,GAAG,CAAC,qBAAqB,IAAI,IAAI,EAAE,EAAE,CAAC;SACvE,CAAC;QAEF,UAAU;QACV,IAAI,kBAAkB,CAAC,cAAc,IAAI,CAAC,EAAE,CAAC;YAC3C,MAAM,IAAI,KAAK,CAAC,0CAA0C,CAAC,CAAC;QAC9D,CAAC;QACD,IAAI,kBAAkB,CAAC,aAAa,IAAI,CAAC,IAAI,kBAAkB,CAAC,aAAa,GAAG,EAAE,EAAE,CAAC;YACnF,MAAM,IAAI,KAAK,CAAC,gDAAgD,CAAC,CAAC;QACpE,CAAC;IACH,CAAC;IAED,OAAO,kBAAkB,CAAC;AAC5B,CAAC;AAED;;;;;GAKG;AACH,MAAM,UAAU,sBAAsB;IACpC,kBAAkB,GAAG,IAAI,CAAC;AAC5B,CAAC"}
@@ -1,13 +1,5 @@
1
- import type { ShadowFieldConfig, ShadowFieldType } from './types.js';
2
- /**
3
- * シャドースキーマ(簡易版)
4
- */
5
- export interface ShadowSchema {
6
- /** リソース名 */
7
- resource: string;
8
- /** ソート可能なフィールド定義 */
9
- sortableFields: Record<string, ShadowFieldConfig>;
10
- }
1
+ import type { ShadowFieldType } from './types.js';
2
+ import type { ShadowConfig } from './config.js';
11
3
  /**
12
4
  * シャドウレコード
13
5
  */
@@ -22,6 +14,42 @@ export interface ShadowRecord {
22
14
  id: string;
23
15
  };
24
16
  }
17
+ /**
18
+ * JSONオブジェクトのフィールドを正規化
19
+ *
20
+ * フィールドの順序を以下のルールで並び替えます:
21
+ * 1. id: 先頭
22
+ * 2. その他: アルファベット順
23
+ * 3. createdAt, updatedAt: 末尾
24
+ *
25
+ * @param value - 正規化する値
26
+ * @returns 正規化された値
27
+ *
28
+ * @example
29
+ * ```typescript
30
+ * normalizeJson({ updatedAt: '...', title: 'A', id: '1', author: 'B' })
31
+ * // => { id: '1', author: 'B', title: 'A', updatedAt: '...' }
32
+ * ```
33
+ */
34
+ export declare function normalizeJson(value: unknown): unknown;
35
+ /**
36
+ * 文字列を先頭Nバイトまで切り詰める(UTF-8)
37
+ *
38
+ * マルチバイト文字の境界を考慮して切り詰めます。
39
+ * 切り詰め位置がマルチバイト文字の途中の場合、前の文字境界まで戻ります。
40
+ *
41
+ * @param value - 切り詰める文字列
42
+ * @param maxBytes - 最大バイト数
43
+ * @returns 切り詰められた文字列
44
+ *
45
+ * @example
46
+ * ```typescript
47
+ * truncateString('Hello World', 5) // => 'Hello'
48
+ * truncateString('こんにちは世界', 9) // => 'こんに' (9バイト = 3文字)
49
+ * truncateString('Hello', 100) // => 'Hello' (そのまま)
50
+ * ```
51
+ */
52
+ export declare function truncateString(value: string, maxBytes: number): string;
25
53
  /**
26
54
  * 文字列値をエスケープする
27
55
  * ルール: # → ##, スペース → #
@@ -31,12 +59,28 @@ export interface ShadowRecord {
31
59
  */
32
60
  export declare function escapeString(value: string): string;
33
61
  /**
34
- * 数値を20桁のゼロ埋め文字列に変換する
62
+ * 数値をオフセット方式でゼロパディング
35
63
  *
36
- * @param value - 変換する数値(null/undefinedも許容)
37
- * @returns 20桁のゼロ埋め文字列
64
+ * 負数を含む数値を文字列としてソート可能にするため、オフセットを加算します。
65
+ *
66
+ * 範囲: -10^padding ~ +10^padding
67
+ * オフセット: 10^padding
68
+ *
69
+ * 注意: padding は15以下を推奨(JavaScriptの安全な整数範囲: 2^53-1 ≈ 9×10^15)
70
+ *
71
+ * @param value - 変換する数値
72
+ * @param padding - パディング桁数(推奨: 15、デフォルト設定で使用)
73
+ * @returns ゼロパディングされた文字列
74
+ * @throws 数値が範囲外の場合
75
+ *
76
+ * @example
77
+ * ```typescript
78
+ * formatNumberWithOffset(-99999, 15) // => "0999999999900001"
79
+ * formatNumberWithOffset(0, 15) // => "1000000000000000"
80
+ * formatNumberWithOffset(99999, 15) // => "1000000000099999"
81
+ * ```
38
82
  */
39
- export declare function formatNumber(value: number | null | undefined): string;
83
+ export declare function formatNumberWithOffset(value: number, padding: number): string;
40
84
  /**
41
85
  * 日時をUTC ISO 8601形式にフォーマットする
42
86
  *
@@ -52,36 +96,22 @@ export declare function formatDatetime(value: string | Date | null | undefined):
52
96
  */
53
97
  export declare function formatBoolean(value: boolean | null | undefined): string;
54
98
  /**
55
- * フィールド値を型に応じてフォーマットする
99
+ * フィールド値を型に応じてフォーマットする(更新版)
56
100
  *
57
101
  * @param type - フィールドの型
58
- * @param value - フォーマットする値(null/undefinedも許容)
102
+ * @param value - フォーマットする値
103
+ * @param config - シャドウ設定
59
104
  * @returns フォーマットされた文字列
60
- */
61
- export declare function formatFieldValue(type: ShadowFieldType, value: string | number | Date | boolean | null | undefined): string;
62
- /**
63
- * シャドーSKを生成する
64
- * フォーマット: {fieldName}#{formattedValue}#id#{recordId}
65
- *
66
- * @param fieldName - フィールド名
67
- * @param value - フィールド値
68
- * @param recordId - レコードID(ULID)
69
- * @param type - フィールドの型(デフォルト: 'string')
70
- * @returns 生成されたシャドーSK
71
- *
72
- * @example
73
- * generateShadowSK('name', 'Tech News', '01HZXY123', 'string')
74
- * // => 'name#Tech#News#id#01HZXY123'
75
105
  *
76
106
  * @example
77
- * generateShadowSK('priority', 123, '01HZXY123', 'number')
78
- * // => 'priority#00000000000000000123#id#01HZXY123'
79
- *
80
- * @example
81
- * generateShadowSK('createdAt', '2025-11-12T10:00:00.000Z', '01HZXY123', 'datetime')
82
- * // => 'createdAt#2025-11-12T10:00:00.000Z#id#01HZXY123'
107
+ * ```typescript
108
+ * const config = { stringMaxBytes: 100, numberPadding: 20, ... };
109
+ * formatFieldValue('string', 'Hello World', config) // => 'Hello#World'
110
+ * formatFieldValue('number', 123, config) // => '10000000000000000123'
111
+ * formatFieldValue('array', ['a', 'b'], config) // => '["a","b"]'
112
+ * ```
83
113
  */
84
- export declare function generateShadowSK(fieldName: string, value: string | number | Date, recordId: string, type?: ShadowFieldType): string;
114
+ export declare function formatFieldValue(type: ShadowFieldType, value: unknown, config: ShadowConfig): string;
85
115
  /**
86
116
  * レコードIDからメインレコードのSKを生成する
87
117
  * フォーマット: id#{recordId}
@@ -91,14 +121,33 @@ export declare function generateShadowSK(fieldName: string, value: string | numb
91
121
  */
92
122
  export declare function generateMainRecordSK(recordId: string): string;
93
123
  /**
94
- * レコードからシャドウレコードを生成する
124
+ * レコードからシャドウレコードを自動生成する(更新版)
95
125
  *
96
- * sortableFieldsに定義されたフィールドのみを処理します。
97
- * 値がundefined/nullの場合は空文字として扱い、シャドウレコードを生成します。
126
+ * レコードに存在するすべてのフィールドを自動的にシャドウ化します。
127
+ * スキーマ定義は不要で、実行時に型を推論します。
98
128
  *
99
129
  * @param record - レコードオブジェクト(idフィールドを含む)
100
- * @param schema - シャドウスキーマ定義
130
+ * @param resourceName - リソース名
131
+ * @param config - シャドウ設定
101
132
  * @returns 生成されたシャドウレコードの配列
133
+ *
134
+ * @example
135
+ * ```typescript
136
+ * const record = {
137
+ * id: '01HQXYZ...',
138
+ * title: 'Article',
139
+ * viewCount: 123,
140
+ * tags: ['tech', 'aws'],
141
+ * };
142
+ * const config = getShadowConfig();
143
+ * const shadows = generateShadowRecords(record, 'articles', config);
144
+ * // => [
145
+ * // { PK: 'articles', SK: 'id#01HQXYZ...#id#01HQXYZ...', data: { id: '01HQXYZ...' } },
146
+ * // { PK: 'articles', SK: 'title#Article#id#01HQXYZ...', data: { id: '01HQXYZ...' } },
147
+ * // { PK: 'articles', SK: 'viewCount#10000000000000000123#id#01HQXYZ...', data: { id: '01HQXYZ...' } },
148
+ * // { PK: 'articles', SK: 'tags#["aws","tech"]#id#01HQXYZ...', data: { id: '01HQXYZ...' } },
149
+ * // ]
150
+ * ```
102
151
  */
103
- export declare function generateShadowRecords(record: Record<string, unknown>, schema: ShadowSchema): ShadowRecord[];
152
+ export declare function generateShadowRecords(record: Record<string, unknown>, resourceName: string, config: ShadowConfig): ShadowRecord[];
104
153
  //# sourceMappingURL=generator.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"generator.d.ts","sourceRoot":"","sources":["../../../src/server/shadow/generator.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,iBAAiB,EAAE,eAAe,EAAE,MAAM,YAAY,CAAC;AAErE;;GAEG;AACH,MAAM,WAAW,YAAY;IAC3B,YAAY;IACZ,QAAQ,EAAE,MAAM,CAAC;IACjB,oBAAoB;IACpB,cAAc,EAAE,MAAM,CAAC,MAAM,EAAE,iBAAiB,CAAC,CAAC;CACnD;AAED;;GAEG;AACH,MAAM,WAAW,YAAY;IAC3B,uBAAuB;IACvB,EAAE,EAAE,MAAM,CAAC;IACX,oBAAoB;IACpB,EAAE,EAAE,MAAM,CAAC;IACX,sBAAsB;IACtB,IAAI,EAAE;QACJ,aAAa;QACb,EAAE,EAAE,MAAM,CAAC;KACZ,CAAC;CACH;AAED;;;;;;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,CAKvE;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;;;;;;;;;;;;;;;;;;;;;GAqBG;AACH,wBAAgB,gBAAgB,CAC9B,SAAS,EAAE,MAAM,EACjB,KAAK,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,EAC7B,QAAQ,EAAE,MAAM,EAChB,IAAI,GAAE,eAA0B,GAC/B,MAAM,CAGR;AAED;;;;;;GAMG;AACH,wBAAgB,oBAAoB,CAAC,QAAQ,EAAE,MAAM,GAAG,MAAM,CAE7D;AAED;;;;;;;;;GASG;AACH,wBAAgB,qBAAqB,CACnC,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAC/B,MAAM,EAAE,YAAY,GACnB,YAAY,EAAE,CAqBhB"}
1
+ {"version":3,"file":"generator.d.ts","sourceRoot":"","sources":["../../../src/server/shadow/generator.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,YAAY,CAAC;AAClD,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AAKhD;;GAEG;AACH,MAAM,WAAW,YAAY;IAC3B,uBAAuB;IACvB,EAAE,EAAE,MAAM,CAAC;IACX,oBAAoB;IACpB,EAAE,EAAE,MAAM,CAAC;IACX,sBAAsB;IACtB,IAAI,EAAE;QACJ,aAAa;QACb,EAAE,EAAE,MAAM,CAAC;KACZ,CAAC;CACH;AAED;;;;;;;;;;;;;;;;GAgBG;AACH,wBAAgB,aAAa,CAAC,KAAK,EAAE,OAAO,GAAG,OAAO,CA2BrD;AAED;;;;;;;;;;;;;;;;GAgBG;AACH,wBAAgB,cAAc,CAAC,KAAK,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,GAAG,MAAM,CAgBtE;AAED;;;;;;GAMG;AACH,wBAAgB,YAAY,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,CAIlD;AAED;;;;;;;;;;;;;;;;;;;;;GAqBG;AACH,wBAAgB,sBAAsB,CAAC,KAAK,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,GAAG,MAAM,CAiB7E;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,CAKvE;AAED;;;;;;;;;;;;;;;GAeG;AACH,wBAAgB,gBAAgB,CAC9B,IAAI,EAAE,eAAe,EACrB,KAAK,EAAE,OAAO,EACd,MAAM,EAAE,YAAY,GACnB,MAAM,CA4BR;AAED;;;;;;GAMG;AACH,wBAAgB,oBAAoB,CAAC,QAAQ,EAAE,MAAM,GAAG,MAAM,CAE7D;AAED;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA4BG;AACH,wBAAgB,qBAAqB,CACnC,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAC/B,YAAY,EAAE,MAAM,EACpB,MAAM,EAAE,YAAY,GACnB,YAAY,EAAE,CAmChB"}