@exabugs/dynamodb-client 1.16.0 → 1.18.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.
- package/CHANGELOG.md +26 -0
- package/README.md +1 -0
- package/dist/notify/alerts-cleanup.d.ts +63 -0
- package/dist/notify/alerts-cleanup.d.ts.map +1 -0
- package/dist/notify/alerts-cleanup.js +75 -0
- package/dist/notify/alerts-cleanup.js.map +1 -0
- package/dist/notify/channels/slack.d.ts +8 -0
- package/dist/notify/channels/slack.d.ts.map +1 -1
- package/dist/notify/channels/slack.js +27 -19
- package/dist/notify/channels/slack.js.map +1 -1
- package/dist/notify/index.d.ts +2 -0
- package/dist/notify/index.d.ts.map +1 -1
- package/dist/notify/index.js +1 -0
- package/dist/notify/index.js.map +1 -1
- package/dist/server/handler.cjs +3 -3
- package/dist/server/media-handler.cjs +2 -2
- package/dist/server/media-process-handler-dlq.cjs +2 -2
- package/dist/server/media-process-handler.cjs +2 -2
- package/dist/system-changes/handler.d.ts +47 -0
- package/dist/system-changes/handler.d.ts.map +1 -0
- package/dist/system-changes/handler.js +74 -0
- package/dist/system-changes/handler.js.map +1 -0
- package/dist/system-changes/index.d.ts +15 -0
- package/dist/system-changes/index.d.ts.map +1 -0
- package/dist/system-changes/index.js +12 -0
- package/dist/system-changes/index.js.map +1 -0
- package/dist/system-changes/record.d.ts +92 -0
- package/dist/system-changes/record.d.ts.map +1 -0
- package/dist/system-changes/record.js +198 -0
- package/dist/system-changes/record.js.map +1 -0
- package/dist/system-changes/recorder.d.ts +104 -0
- package/dist/system-changes/recorder.d.ts.map +1 -0
- package/dist/system-changes/recorder.js +184 -0
- package/dist/system-changes/recorder.js.map +1 -0
- package/dist/system-changes/slack.d.ts +19 -0
- package/dist/system-changes/slack.d.ts.map +1 -0
- package/dist/system-changes/slack.js +124 -0
- package/dist/system-changes/slack.js.map +1 -0
- package/docs/NOTIFY.md +24 -15
- package/docs/RECORDS_CLIENT.md +2 -0
- package/docs/SYSTEM_CHANGES.md +117 -0
- package/package.json +7 -2
package/CHANGELOG.md
CHANGED
|
@@ -7,6 +7,32 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
|
|
7
7
|
|
|
8
8
|
## [Unreleased]
|
|
9
9
|
|
|
10
|
+
## [1.18.0] - 2026-10-24
|
|
11
|
+
|
|
12
|
+
### Added
|
|
13
|
+
|
|
14
|
+
- **`createAlertsCleanupHandler(options?)`**(`@exabugs/dynamodb-client/notify`。ADR 0006 の段階 3 = (e)): alerts の定時削除 Lambda のハンドラのファクトリ。asanowa・astro に複製されていた入口(`runCleanup` と環境変数の確認・接続)を 1 つにした。呼び出しごとに `withCollection('alerts', …)` で Records に接続し、`cleanupAlerts` を 1 回行い、結果を構造化ログに出す(失敗は error `ALERTS_CLEANUP_FAILED`、上限で止めたら warn `ALERTS_CLEANUP_BACKLOG`、それ以外は info。削除の失敗は例外にしない)。アプリ名・Records の URL はオプションか環境変数(`PROJECT_NAME` / `RECORDS_IAM_URL`)。読み取りの包み方(`collection`。権限チェック層を通すアプリ用)、保存期間(`olderThanDays`)、1 回の上限(`maxPerRun`)、ログ(`log`)を注入できる。使い方は `docs/NOTIFY.md`
|
|
15
|
+
- `runAlertsCleanup(collection, options)`(削除 1 回と結果のログ)、定数 `ALERTS_CLEANUP_MAX_PER_RUN`(500)、型 `AlertsCleanupHandlerOptions` / `RunAlertsCleanupOptions` / `AlertsCleanupLog` / `AlertsCleanupRow`
|
|
16
|
+
|
|
17
|
+
### Changed
|
|
18
|
+
|
|
19
|
+
- 統合テスト(DynamoDB Local)の土台を `src/__tests__/helpers/recordsLocal.ts` に共通化した(テストのみ。公開 API・dist に変更なし)。DynamoDB アクセスの許可リストは、`src/system-changes/__tests__/*.integration.test.ts` をこの 1 ファイルに置き換えた。`tsconfig.json` はビルドから `**/__tests__/**` を除く(今は該当する非テストのファイルがこの土台だけで、dist は変わらない)
|
|
20
|
+
|
|
21
|
+
## [1.17.0] - 2026-10-24
|
|
22
|
+
|
|
23
|
+
### Added
|
|
24
|
+
|
|
25
|
+
- **`@exabugs/dynamodb-client/system-changes`**(ADR 0006 の段階 2 = (a)): システム変更履歴(`systemChanges`)の記録と Slack 通知。asanowa・astro に複製されていたロジックを 1 つにした。使い方は `docs/SYSTEM_CHANGES.md`
|
|
26
|
+
- `createSystemChangeHandler(options?)`: 記録 Lambda のハンドラのファクトリ。呼び出しごとに `withCollection` で Records に接続する。アプリ名・Records の URL・Slack の設定(SSM の名前、環境名、管理画面の URL、開始も送るか)は、オプションか環境変数(`PROJECT_NAME` / `RECORDS_IAM_URL` / `SLACK_WEBHOOK_PARAM` / `ENV_NAME` / `ADMIN_BASE_URL` / `NOTIFY_STARTED`)。書き込み先の包み方(`collection`。権限チェック層を通すアプリ用)、ログ(`log`)、SSM のクライアントを注入できる
|
|
27
|
+
- `recordSystemChange` / `recordAndNotify` / `systemChangesCollectionOf`、純粋な関数 `parseSystemChangeInput` / `toSystemChangeRecord` / `decideRunWrite` / `formatSystemChangeMessage` / `formatDuration` / `lambdaReleaseNames` / `shouldNotify`、定数・型
|
|
28
|
+
- Slack の文言は asanowa の版に揃えた(ADR 0006 の決定)。`details.lambdaReleases` の取り出しは公開関数 `lambdaReleaseNames` の 1 つ
|
|
29
|
+
- 既定の書き込み先は、`changeId` の読み取りを `find({ id }, { sort: { id: 'asc' }, limit: 1 })`(Records の ID の経路。PK/SK の Query 1 回) で行う(`findOne` の 404 で Records が ITEM_NOT_FOUND の warn を出さない)
|
|
30
|
+
- **`postSlackText(url, text, options?)`**(`src/notify/channels/slack.ts`。内部用、notify の index からは出さない): `createSlackChannel` の送信処理を切り出したもの。`system-changes` が使う
|
|
31
|
+
|
|
32
|
+
### Changed
|
|
33
|
+
|
|
34
|
+
- `createSlackChannel` の送信は、切り出した `postSlackText` を呼ぶ。挙動は同じ(URL の接頭辞の確認、timeout 既定 5 秒、URL を出さないエラー)。違いは、`fetchImpl` を省略したときの `fetch` を、チャネルの作成時ではなく送信のたびに読むことだけ
|
|
35
|
+
|
|
10
36
|
## [1.16.0] - 2026-10-20
|
|
11
37
|
|
|
12
38
|
### Added
|
package/README.md
CHANGED
|
@@ -198,6 +198,7 @@ const article = await articles.findOne({ title: 'Hello DynamoDB' });
|
|
|
198
198
|
- **[疎な検索の警告と対応](docs/SCAN_WARNING.md)** - 検索を打ち切らず、警告(SPARSE_SCAN)で気づいてインデックス・スキーマ・ロジックを見直す
|
|
199
199
|
- **[Records クライアントのヘルパー](docs/RECORDS_CLIENT.md)** - Lambda から Records を呼ぶ定型(`createRecordsClient` / `withCollection` / `lazyCollection`)
|
|
200
200
|
- **[運用通知](docs/NOTIFY.md)** - ログ・アラームを、Slack・メールで管理者へ通知する部品(`@exabugs/dynamodb-client/notify`)
|
|
201
|
+
- **[システム変更履歴](docs/SYSTEM_CHANGES.md)** - インフラの変更・リリースを `systemChanges` に記録し、Slack に送る部品と記録 Lambda のハンドラ(`@exabugs/dynamodb-client/system-changes`)
|
|
201
202
|
- **[Deployment](docs/DEPLOYMENT.md)** - Production deployment guide
|
|
202
203
|
- **[Terraform Modules](terraform/README.md)** - Infrastructure as Code
|
|
203
204
|
|
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* alerts の定時削除 Lambda のハンドラのファクトリ(ADR 0006 の (e)。ADR 0003 の保存期間)。
|
|
3
|
+
*
|
|
4
|
+
* 運用通知の記録(alerts)のうち、最後の発生から保存期間(既定 28 日)を過ぎたものを消す
|
|
5
|
+
* (ネイティブ TTL は効かない)。削除そのものは `cleanupAlerts`(変えない)。ここは、その周りの定型
|
|
6
|
+
* (1 回の上限、結果の構造化ログ、環境変数の確認、Records への接続と close)を持つ。docs/NOTIFY.md
|
|
7
|
+
*
|
|
8
|
+
* 設定は、オプションが環境変数より優先される(どちらも呼び出しのたびに読む):
|
|
9
|
+
* - `app`: PROJECT_NAME(必須)
|
|
10
|
+
* - `records.url` / `records.region`: RECORDS_IAM_URL(必須)/ AWS_REGION
|
|
11
|
+
*
|
|
12
|
+
* 失敗の扱い: 削除の失敗は握りつぶさず、構造化ログ(error。target は alerts)に出す。例外にはしない
|
|
13
|
+
* (このロググループは通知 Lambda が購読するので管理者に届く。Lambda の失敗としても通知すると 2 通になる。
|
|
14
|
+
* target が alerts なので alerts には記録されず、ループしない)。接続などの想定外の例外は、そのまま Lambda の
|
|
15
|
+
* 失敗になる。
|
|
16
|
+
*/
|
|
17
|
+
import { type RecordsClientOptions, type RecordsCollection } from '../client/recordsClient.js';
|
|
18
|
+
import { type AlertsCleanupCollection, type CleanupAlertsResult } from './alerts.js';
|
|
19
|
+
/**
|
|
20
|
+
* 1 回の実行で消す上限の既定。1 日 1 回の実行で、1 日に増える数より十分大きくする
|
|
21
|
+
* (指紋ごとに 1 件なので、通常は数件〜数十件。50 件 × 10 ページ = 読み・削除が 20 回で、時間切れにならない)
|
|
22
|
+
*/
|
|
23
|
+
export declare const ALERTS_CLEANUP_MAX_PER_RUN = 500;
|
|
24
|
+
/** 削除の結果のログの出力先。fields には app・target(alerts)が入る */
|
|
25
|
+
export type AlertsCleanupLog = (level: 'info' | 'warn' | 'error', fields: Record<string, unknown>) => void;
|
|
26
|
+
export interface RunAlertsCleanupOptions {
|
|
27
|
+
/** アプリ名(ログの app) */
|
|
28
|
+
app: string;
|
|
29
|
+
/** 保存期間(日)。既定 ALERT_RETENTION_DAYS(28) */
|
|
30
|
+
olderThanDays?: number;
|
|
31
|
+
/** 1 回の実行で消す上限。既定 ALERTS_CLEANUP_MAX_PER_RUN(500) */
|
|
32
|
+
maxPerRun?: number;
|
|
33
|
+
/** ログの出力先(既定は logJson。app と target: alerts を付ける) */
|
|
34
|
+
log?: AlertsCleanupLog;
|
|
35
|
+
/** 現在時刻(テスト用) */
|
|
36
|
+
now?: () => Date;
|
|
37
|
+
}
|
|
38
|
+
/** 削除を 1 回行い、結果を構造化ログに出す(失敗は error、上限で止めたら warn、それ以外は info) */
|
|
39
|
+
export declare function runAlertsCleanup(collection: AlertsCleanupCollection, options: RunAlertsCleanupOptions): Promise<CleanupAlertsResult>;
|
|
40
|
+
/** 削除で読む alerts の行(使う項目だけ) */
|
|
41
|
+
export type AlertsCleanupRow = {
|
|
42
|
+
id: string;
|
|
43
|
+
lastSeenAt?: unknown;
|
|
44
|
+
[key: string]: unknown;
|
|
45
|
+
};
|
|
46
|
+
export interface AlertsCleanupHandlerOptions extends Omit<RunAlertsCleanupOptions, 'app'> {
|
|
47
|
+
/** アプリ名。省略時は環境変数 PROJECT_NAME */
|
|
48
|
+
app?: string;
|
|
49
|
+
/** Records のクライアント。url / region は省略時に環境変数。timeout は DynamoClient の既定 */
|
|
50
|
+
records?: RecordsClientOptions;
|
|
51
|
+
/**
|
|
52
|
+
* 削除で使う形を作る(既定は生のコレクションをそのまま使う)。読み取りを権限チェック層(astro の
|
|
53
|
+
* authorizedCollection など)に通すアプリは、受け取った生のコレクションを自分の層で包んで返す
|
|
54
|
+
*/
|
|
55
|
+
collection?: (raw: RecordsCollection<AlertsCleanupRow>) => AlertsCleanupCollection;
|
|
56
|
+
}
|
|
57
|
+
/**
|
|
58
|
+
* 削除の定時 Lambda のハンドラを作る。アプリのエントリは、これを export するだけ:
|
|
59
|
+
* `export const handler = createAlertsCleanupHandler();`
|
|
60
|
+
* 呼び出しごとに Records(IAM 版 Function URL)に接続し、終わったら閉じる(`withCollection`)。
|
|
61
|
+
*/
|
|
62
|
+
export declare function createAlertsCleanupHandler(options?: AlertsCleanupHandlerOptions): () => Promise<CleanupAlertsResult>;
|
|
63
|
+
//# sourceMappingURL=alerts-cleanup.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"alerts-cleanup.d.ts","sourceRoot":"","sources":["../../src/notify/alerts-cleanup.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;GAeG;AACH,OAAO,EACL,KAAK,oBAAoB,EACzB,KAAK,iBAAiB,EAEvB,MAAM,4BAA4B,CAAC;AACpC,OAAO,EAGL,KAAK,uBAAuB,EAC5B,KAAK,mBAAmB,EAEzB,MAAM,aAAa,CAAC;AAGrB;;;GAGG;AACH,eAAO,MAAM,0BAA0B,MAAM,CAAC;AAE9C,mDAAmD;AACnD,MAAM,MAAM,gBAAgB,GAAG,CAC7B,KAAK,EAAE,MAAM,GAAG,MAAM,GAAG,OAAO,EAChC,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,KAC5B,IAAI,CAAC;AAEV,MAAM,WAAW,uBAAuB;IACtC,oBAAoB;IACpB,GAAG,EAAE,MAAM,CAAC;IACZ,0CAA0C;IAC1C,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,qDAAqD;IACrD,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,oDAAoD;IACpD,GAAG,CAAC,EAAE,gBAAgB,CAAC;IACvB,iBAAiB;IACjB,GAAG,CAAC,EAAE,MAAM,IAAI,CAAC;CAClB;AAED,+DAA+D;AAC/D,wBAAsB,gBAAgB,CACpC,UAAU,EAAE,uBAAuB,EACnC,OAAO,EAAE,uBAAuB,GAC/B,OAAO,CAAC,mBAAmB,CAAC,CA+B9B;AAED,8BAA8B;AAC9B,MAAM,MAAM,gBAAgB,GAAG;IAAE,EAAE,EAAE,MAAM,CAAC;IAAC,UAAU,CAAC,EAAE,OAAO,CAAC;IAAC,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAA;CAAE,CAAC;AAE5F,MAAM,WAAW,2BAA4B,SAAQ,IAAI,CAAC,uBAAuB,EAAE,KAAK,CAAC;IACvF,iCAAiC;IACjC,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,wEAAwE;IACxE,OAAO,CAAC,EAAE,oBAAoB,CAAC;IAC/B;;;OAGG;IACH,UAAU,CAAC,EAAE,CAAC,GAAG,EAAE,iBAAiB,CAAC,gBAAgB,CAAC,KAAK,uBAAuB,CAAC;CACpF;AAED;;;;GAIG;AACH,wBAAgB,0BAA0B,CACxC,OAAO,GAAE,2BAAgC,GACxC,MAAM,OAAO,CAAC,mBAAmB,CAAC,CAapC"}
|
|
@@ -0,0 +1,75 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* alerts の定時削除 Lambda のハンドラのファクトリ(ADR 0006 の (e)。ADR 0003 の保存期間)。
|
|
3
|
+
*
|
|
4
|
+
* 運用通知の記録(alerts)のうち、最後の発生から保存期間(既定 28 日)を過ぎたものを消す
|
|
5
|
+
* (ネイティブ TTL は効かない)。削除そのものは `cleanupAlerts`(変えない)。ここは、その周りの定型
|
|
6
|
+
* (1 回の上限、結果の構造化ログ、環境変数の確認、Records への接続と close)を持つ。docs/NOTIFY.md
|
|
7
|
+
*
|
|
8
|
+
* 設定は、オプションが環境変数より優先される(どちらも呼び出しのたびに読む):
|
|
9
|
+
* - `app`: PROJECT_NAME(必須)
|
|
10
|
+
* - `records.url` / `records.region`: RECORDS_IAM_URL(必須)/ AWS_REGION
|
|
11
|
+
*
|
|
12
|
+
* 失敗の扱い: 削除の失敗は握りつぶさず、構造化ログ(error。target は alerts)に出す。例外にはしない
|
|
13
|
+
* (このロググループは通知 Lambda が購読するので管理者に届く。Lambda の失敗としても通知すると 2 通になる。
|
|
14
|
+
* target が alerts なので alerts には記録されず、ループしない)。接続などの想定外の例外は、そのまま Lambda の
|
|
15
|
+
* 失敗になる。
|
|
16
|
+
*/
|
|
17
|
+
import { withCollection, } from '../client/recordsClient.js';
|
|
18
|
+
import { ALERTS_RESOURCE, ALERT_RETENTION_DAYS, cleanupAlerts, } from './alerts.js';
|
|
19
|
+
import { logJson } from './logger.js';
|
|
20
|
+
/**
|
|
21
|
+
* 1 回の実行で消す上限の既定。1 日 1 回の実行で、1 日に増える数より十分大きくする
|
|
22
|
+
* (指紋ごとに 1 件なので、通常は数件〜数十件。50 件 × 10 ページ = 読み・削除が 20 回で、時間切れにならない)
|
|
23
|
+
*/
|
|
24
|
+
export const ALERTS_CLEANUP_MAX_PER_RUN = 500;
|
|
25
|
+
/** 削除を 1 回行い、結果を構造化ログに出す(失敗は error、上限で止めたら warn、それ以外は info) */
|
|
26
|
+
export async function runAlertsCleanup(collection, options) {
|
|
27
|
+
const maxPerRun = options.maxPerRun ?? ALERTS_CLEANUP_MAX_PER_RUN;
|
|
28
|
+
const log = options.log ??
|
|
29
|
+
((level, fields) => logJson(level, { app: options.app, target: ALERTS_RESOURCE, ...fields }));
|
|
30
|
+
const r = await cleanupAlerts({
|
|
31
|
+
collection,
|
|
32
|
+
olderThanDays: options.olderThanDays ?? ALERT_RETENTION_DAYS,
|
|
33
|
+
maxPerRun,
|
|
34
|
+
now: options.now,
|
|
35
|
+
});
|
|
36
|
+
const summary = { deleted: r.deleted, failed: r.failed, more: r.more };
|
|
37
|
+
if (r.errors.length > 0) {
|
|
38
|
+
log('error', {
|
|
39
|
+
event: 'ALERTS_CLEANUP_FAILED',
|
|
40
|
+
message: `alerts の削除に失敗しました: ${r.errors.join(' / ')}`.slice(0, 1000),
|
|
41
|
+
action: '翌日の定時実行で再試行されます。続く場合は Records Lambda のログを確認してください',
|
|
42
|
+
...summary,
|
|
43
|
+
});
|
|
44
|
+
}
|
|
45
|
+
else if (r.more) {
|
|
46
|
+
log('warn', {
|
|
47
|
+
event: 'ALERTS_CLEANUP_BACKLOG',
|
|
48
|
+
message: `1 回の上限(${maxPerRun} 件)まで消しました。残りは翌日に消します`,
|
|
49
|
+
action: '毎日続く場合は、通知の発生源(同じ指紋で増え続けていないか)を確認してください',
|
|
50
|
+
...summary,
|
|
51
|
+
});
|
|
52
|
+
}
|
|
53
|
+
else {
|
|
54
|
+
log('info', { message: 'alerts cleanup completed', ...summary });
|
|
55
|
+
}
|
|
56
|
+
return r;
|
|
57
|
+
}
|
|
58
|
+
/**
|
|
59
|
+
* 削除の定時 Lambda のハンドラを作る。アプリのエントリは、これを export するだけ:
|
|
60
|
+
* `export const handler = createAlertsCleanupHandler();`
|
|
61
|
+
* 呼び出しごとに Records(IAM 版 Function URL)に接続し、終わったら閉じる(`withCollection`)。
|
|
62
|
+
*/
|
|
63
|
+
export function createAlertsCleanupHandler(options = {}) {
|
|
64
|
+
const { app: appOption, records, collection: wrap, ...run } = options;
|
|
65
|
+
return async () => {
|
|
66
|
+
const app = appOption ?? (process.env.PROJECT_NAME || undefined);
|
|
67
|
+
if (!app)
|
|
68
|
+
throw new Error('PROJECT_NAME environment variable is required');
|
|
69
|
+
const url = records?.url ?? (process.env.RECORDS_IAM_URL || undefined);
|
|
70
|
+
if (!url)
|
|
71
|
+
throw new Error('RECORDS_IAM_URL environment variable is required');
|
|
72
|
+
return withCollection(ALERTS_RESOURCE, (raw) => runAlertsCleanup(wrap ? wrap(raw) : raw, { ...run, app }), { ...records, url });
|
|
73
|
+
};
|
|
74
|
+
}
|
|
75
|
+
//# sourceMappingURL=alerts-cleanup.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"alerts-cleanup.js","sourceRoot":"","sources":["../../src/notify/alerts-cleanup.ts"],"names":[],"mappings":"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"}
|
|
@@ -8,5 +8,13 @@ export interface SlackOptions {
|
|
|
8
8
|
fetchImpl?: typeof fetch;
|
|
9
9
|
timeoutMs?: number;
|
|
10
10
|
}
|
|
11
|
+
/** `postSlackText` のオプション(`createSlackChannel` と共通) */
|
|
12
|
+
export type SlackPostOptions = Pick<SlackOptions, 'urlPrefix' | 'fetchImpl' | 'timeoutMs'>;
|
|
13
|
+
/**
|
|
14
|
+
* 文字列(mrkdwn)を 1 通、Webhook に送る。失敗は例外(メッセージに URL を出さない)。
|
|
15
|
+
* `createSlackChannel` の送信と同じ処理(URL の接頭辞の確認、timeout 既定 5 秒)。
|
|
16
|
+
* Notice を経由しない直接の投稿(システム変更履歴など)に使う
|
|
17
|
+
*/
|
|
18
|
+
export declare function postSlackText(url: string, text: string, options?: SlackPostOptions): Promise<void>;
|
|
11
19
|
export declare function createSlackChannel(options: SlackOptions): Channel;
|
|
12
20
|
//# sourceMappingURL=slack.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"slack.d.ts","sourceRoot":"","sources":["../../../src/notify/channels/slack.ts"],"names":[],"mappings":"AAKA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,EAAE,MAAM,aAAa,CAAC;AAQnD,wBAAgB,SAAS,CAAC,OAAO,EAAE,MAAM,EAAE,GAAG,MAAM,CAKnD;AAED,MAAM,WAAW,YAAY;IAC3B,0CAA0C;IAC1C,aAAa,EAAE,MAAM,OAAO,CAAC,MAAM,CAAC,CAAC;IACrC,+EAA+E;IAC/E,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,SAAS,CAAC,EAAE,OAAO,KAAK,CAAC;IACzB,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AAED,wBAAgB,kBAAkB,CAAC,OAAO,EAAE,YAAY,GAAG,OAAO,
|
|
1
|
+
{"version":3,"file":"slack.d.ts","sourceRoot":"","sources":["../../../src/notify/channels/slack.ts"],"names":[],"mappings":"AAKA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,EAAE,MAAM,aAAa,CAAC;AAQnD,wBAAgB,SAAS,CAAC,OAAO,EAAE,MAAM,EAAE,GAAG,MAAM,CAKnD;AAED,MAAM,WAAW,YAAY;IAC3B,0CAA0C;IAC1C,aAAa,EAAE,MAAM,OAAO,CAAC,MAAM,CAAC,CAAC;IACrC,+EAA+E;IAC/E,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,SAAS,CAAC,EAAE,OAAO,KAAK,CAAC;IACzB,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AAED,uDAAuD;AACvD,MAAM,MAAM,gBAAgB,GAAG,IAAI,CAAC,YAAY,EAAE,WAAW,GAAG,WAAW,GAAG,WAAW,CAAC,CAAC;AAE3F;;;;GAIG;AACH,wBAAsB,aAAa,CACjC,GAAG,EAAE,MAAM,EACX,IAAI,EAAE,MAAM,EACZ,OAAO,GAAE,gBAAqB,GAC7B,OAAO,CAAC,IAAI,CAAC,CAkBf;AAED,wBAAgB,kBAAkB,CAAC,OAAO,EAAE,YAAY,GAAG,OAAO,CAUjE"}
|
|
@@ -13,8 +13,33 @@ export function slackText(notices) {
|
|
|
13
13
|
parts.push(`…ほか ${notices.length - shown.length} 件`);
|
|
14
14
|
return parts.join('\n\n');
|
|
15
15
|
}
|
|
16
|
-
|
|
16
|
+
/**
|
|
17
|
+
* 文字列(mrkdwn)を 1 通、Webhook に送る。失敗は例外(メッセージに URL を出さない)。
|
|
18
|
+
* `createSlackChannel` の送信と同じ処理(URL の接頭辞の確認、timeout 既定 5 秒)。
|
|
19
|
+
* Notice を経由しない直接の投稿(システム変更履歴など)に使う
|
|
20
|
+
*/
|
|
21
|
+
export async function postSlackText(url, text, options = {}) {
|
|
22
|
+
if (!url.startsWith(options.urlPrefix ?? 'https://hooks.slack.com/')) {
|
|
23
|
+
throw new Error('Slack の Webhook の URL が不正です(許可した接頭辞で始まっていません)');
|
|
24
|
+
}
|
|
17
25
|
const doFetch = options.fetchImpl ?? fetch;
|
|
26
|
+
let res;
|
|
27
|
+
try {
|
|
28
|
+
res = await doFetch(url, {
|
|
29
|
+
method: 'POST',
|
|
30
|
+
headers: { 'Content-Type': 'application/json' },
|
|
31
|
+
body: JSON.stringify({ text }),
|
|
32
|
+
signal: AbortSignal.timeout(options.timeoutMs ?? 5000),
|
|
33
|
+
});
|
|
34
|
+
}
|
|
35
|
+
catch (e) {
|
|
36
|
+
// fetch のエラーには URL(秘密)が入ることがあるので、原因の種類だけを残す
|
|
37
|
+
throw new Error(`Slack への送信に失敗しました (${e instanceof Error ? e.name : 'error'})`);
|
|
38
|
+
}
|
|
39
|
+
if (!res.ok)
|
|
40
|
+
throw new Error(`Slack への送信に失敗しました (HTTP ${res.status})`);
|
|
41
|
+
}
|
|
42
|
+
export function createSlackChannel(options) {
|
|
18
43
|
return {
|
|
19
44
|
name: 'slack',
|
|
20
45
|
needsRecipients: false,
|
|
@@ -22,24 +47,7 @@ export function createSlackChannel(options) {
|
|
|
22
47
|
if (notices.length === 0)
|
|
23
48
|
return;
|
|
24
49
|
const url = await options.getWebhookUrl();
|
|
25
|
-
|
|
26
|
-
throw new Error('Slack の Webhook の URL が不正です(許可した接頭辞で始まっていません)');
|
|
27
|
-
}
|
|
28
|
-
let res;
|
|
29
|
-
try {
|
|
30
|
-
res = await doFetch(url, {
|
|
31
|
-
method: 'POST',
|
|
32
|
-
headers: { 'Content-Type': 'application/json' },
|
|
33
|
-
body: JSON.stringify({ text: slackText(notices) }),
|
|
34
|
-
signal: AbortSignal.timeout(options.timeoutMs ?? 5000),
|
|
35
|
-
});
|
|
36
|
-
}
|
|
37
|
-
catch (e) {
|
|
38
|
-
// fetch のエラーには URL(秘密)が入ることがあるので、原因の種類だけを残す
|
|
39
|
-
throw new Error(`Slack への送信に失敗しました (${e instanceof Error ? e.name : 'error'})`);
|
|
40
|
-
}
|
|
41
|
-
if (!res.ok)
|
|
42
|
-
throw new Error(`Slack への送信に失敗しました (HTTP ${res.status})`);
|
|
50
|
+
await postSlackText(url, slackText(notices), options);
|
|
43
51
|
},
|
|
44
52
|
};
|
|
45
53
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"slack.js","sourceRoot":"","sources":["../../../src/notify/channels/slack.ts"],"names":[],"mappings":"AAAA;;;GAGG;AACH,OAAO,EAAE,MAAM,EAAE,IAAI,EAAE,SAAS,EAAE,MAAM,cAAc,CAAC;AAGvD,MAAM,eAAe,GAAG,EAAE,CAAC;AAE3B,kCAAkC;AAClC,MAAM,GAAG,GAAG,CAAC,CAAS,EAAU,EAAE,CAChC,CAAC,CAAC,OAAO,CAAC,IAAI,EAAE,OAAO,CAAC,CAAC,OAAO,CAAC,IAAI,EAAE,MAAM,CAAC,CAAC,OAAO,CAAC,IAAI,EAAE,MAAM,CAAC,CAAC;AAEvE,MAAM,UAAU,SAAS,CAAC,OAAiB;IACzC,MAAM,KAAK,GAAG,OAAO,CAAC,KAAK,CAAC,CAAC,EAAE,eAAe,CAAC,CAAC;IAChD,MAAM,KAAK,GAAG,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,GAAG,IAAI,CAAC,CAAC,CAAC,KAAK,GAAG,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC,MAAM,GAAG,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC;IACvF,IAAI,OAAO,CAAC,MAAM,GAAG,KAAK,CAAC,MAAM;QAAE,KAAK,CAAC,IAAI,CAAC,OAAO,OAAO,CAAC,MAAM,GAAG,KAAK,CAAC,MAAM,IAAI,CAAC,CAAC;IACxF,OAAO,KAAK,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;AAC5B,CAAC;
|
|
1
|
+
{"version":3,"file":"slack.js","sourceRoot":"","sources":["../../../src/notify/channels/slack.ts"],"names":[],"mappings":"AAAA;;;GAGG;AACH,OAAO,EAAE,MAAM,EAAE,IAAI,EAAE,SAAS,EAAE,MAAM,cAAc,CAAC;AAGvD,MAAM,eAAe,GAAG,EAAE,CAAC;AAE3B,kCAAkC;AAClC,MAAM,GAAG,GAAG,CAAC,CAAS,EAAU,EAAE,CAChC,CAAC,CAAC,OAAO,CAAC,IAAI,EAAE,OAAO,CAAC,CAAC,OAAO,CAAC,IAAI,EAAE,MAAM,CAAC,CAAC,OAAO,CAAC,IAAI,EAAE,MAAM,CAAC,CAAC;AAEvE,MAAM,UAAU,SAAS,CAAC,OAAiB;IACzC,MAAM,KAAK,GAAG,OAAO,CAAC,KAAK,CAAC,CAAC,EAAE,eAAe,CAAC,CAAC;IAChD,MAAM,KAAK,GAAG,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,GAAG,IAAI,CAAC,CAAC,CAAC,KAAK,GAAG,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC,MAAM,GAAG,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC;IACvF,IAAI,OAAO,CAAC,MAAM,GAAG,KAAK,CAAC,MAAM;QAAE,KAAK,CAAC,IAAI,CAAC,OAAO,OAAO,CAAC,MAAM,GAAG,KAAK,CAAC,MAAM,IAAI,CAAC,CAAC;IACxF,OAAO,KAAK,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;AAC5B,CAAC;AAcD;;;;GAIG;AACH,MAAM,CAAC,KAAK,UAAU,aAAa,CACjC,GAAW,EACX,IAAY,EACZ,UAA4B,EAAE;IAE9B,IAAI,CAAC,GAAG,CAAC,UAAU,CAAC,OAAO,CAAC,SAAS,IAAI,0BAA0B,CAAC,EAAE,CAAC;QACrE,MAAM,IAAI,KAAK,CAAC,+CAA+C,CAAC,CAAC;IACnE,CAAC;IACD,MAAM,OAAO,GAAG,OAAO,CAAC,SAAS,IAAI,KAAK,CAAC;IAC3C,IAAI,GAAa,CAAC;IAClB,IAAI,CAAC;QACH,GAAG,GAAG,MAAM,OAAO,CAAC,GAAG,EAAE;YACvB,MAAM,EAAE,MAAM;YACd,OAAO,EAAE,EAAE,cAAc,EAAE,kBAAkB,EAAE;YAC/C,IAAI,EAAE,IAAI,CAAC,SAAS,CAAC,EAAE,IAAI,EAAE,CAAC;YAC9B,MAAM,EAAE,WAAW,CAAC,OAAO,CAAC,OAAO,CAAC,SAAS,IAAI,IAAI,CAAC;SACvD,CAAC,CAAC;IACL,CAAC;IAAC,OAAO,CAAC,EAAE,CAAC;QACX,4CAA4C;QAC5C,MAAM,IAAI,KAAK,CAAC,sBAAsB,CAAC,YAAY,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,OAAO,GAAG,CAAC,CAAC;IAClF,CAAC;IACD,IAAI,CAAC,GAAG,CAAC,EAAE;QAAE,MAAM,IAAI,KAAK,CAAC,2BAA2B,GAAG,CAAC,MAAM,GAAG,CAAC,CAAC;AACzE,CAAC;AAED,MAAM,UAAU,kBAAkB,CAAC,OAAqB;IACtD,OAAO;QACL,IAAI,EAAE,OAAO;QACb,eAAe,EAAE,KAAK;QACtB,KAAK,CAAC,IAAI,CAAC,OAAO;YAChB,IAAI,OAAO,CAAC,MAAM,KAAK,CAAC;gBAAE,OAAO;YACjC,MAAM,GAAG,GAAG,MAAM,OAAO,CAAC,aAAa,EAAE,CAAC;YAC1C,MAAM,aAAa,CAAC,GAAG,EAAE,SAAS,CAAC,OAAO,CAAC,EAAE,OAAO,CAAC,CAAC;QACxD,CAAC;KACF,CAAC;AACJ,CAAC"}
|
package/dist/notify/index.d.ts
CHANGED
|
@@ -7,6 +7,8 @@
|
|
|
7
7
|
export { createAdminDirectory, emailsOf, normalizeEmail } from './admins.js';
|
|
8
8
|
export type { AdminDirectoryOptions, AdminRecord, AdminsLister } from './admins.js';
|
|
9
9
|
export { ALERTS_RESOURCE, ALERT_RETENTION_DAYS, alertKeyOf, cleanupAlerts, createAlertRecorder, } from './alerts.js';
|
|
10
|
+
export { ALERTS_CLEANUP_MAX_PER_RUN, createAlertsCleanupHandler, runAlertsCleanup, } from './alerts-cleanup.js';
|
|
11
|
+
export type { AlertsCleanupHandlerOptions, AlertsCleanupLog, AlertsCleanupRow, RunAlertsCleanupOptions, } from './alerts-cleanup.js';
|
|
10
12
|
export type { AlertInput, AlertOccurrence, AlertRecord, AlertRecorder, AlertRecorderOptions, AlertsCleanupCollection, AlertsCollection, CleanupAlertsOptions, CleanupAlertsResult, } from './alerts.js';
|
|
11
13
|
export { createEmailChannel, sesSender } from './channels/email.js';
|
|
12
14
|
export type { EmailMessage, EmailOptions, EmailSender, SesSendInput } from './channels/email.js';
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/notify/index.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AACH,OAAO,EAAE,oBAAoB,EAAE,QAAQ,EAAE,cAAc,EAAE,MAAM,aAAa,CAAC;AAC7E,YAAY,EAAE,qBAAqB,EAAE,WAAW,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AACpF,OAAO,EACL,eAAe,EACf,oBAAoB,EACpB,UAAU,EACV,aAAa,EACb,mBAAmB,GACpB,MAAM,aAAa,CAAC;AACrB,YAAY,EACV,UAAU,EACV,eAAe,EACf,WAAW,EACX,aAAa,EACb,oBAAoB,EACpB,uBAAuB,EACvB,gBAAgB,EAChB,oBAAoB,EACpB,mBAAmB,GACpB,MAAM,aAAa,CAAC;AACrB,OAAO,EAAE,kBAAkB,EAAE,SAAS,EAAE,MAAM,qBAAqB,CAAC;AACpE,YAAY,EAAE,YAAY,EAAE,YAAY,EAAE,WAAW,EAAE,YAAY,EAAE,MAAM,qBAAqB,CAAC;AACjG,OAAO,EAAE,kBAAkB,EAAE,MAAM,qBAAqB,CAAC;AACzD,YAAY,EAAE,YAAY,EAAE,MAAM,qBAAqB,CAAC;AACxD,OAAO,EAAE,mBAAmB,EAAE,MAAM,cAAc,CAAC;AACnD,YAAY,EAAE,oBAAoB,EAAE,YAAY,EAAE,MAAM,cAAc,CAAC;AACvE,OAAO,EACL,mBAAmB,EACnB,gBAAgB,EAChB,qBAAqB,EACrB,QAAQ,EACR,OAAO,GACR,MAAM,aAAa,CAAC;AACrB,YAAY,EAAE,YAAY,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AAC5D,OAAO,EAAE,iBAAiB,EAAE,SAAS,EAAE,iBAAiB,EAAE,MAAM,gBAAgB,CAAC;AACjF,YAAY,EAAE,gBAAgB,EAAE,MAAM,gBAAgB,CAAC;AACvD,OAAO,EAAE,YAAY,EAAE,eAAe,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;AAC3E,OAAO,EAAE,iBAAiB,EAAE,iBAAiB,EAAE,MAAM,YAAY,CAAC;AAClE,YAAY,EACV,cAAc,EACd,UAAU,EACV,eAAe,EACf,gBAAgB,EAChB,OAAO,EACP,MAAM,EACN,WAAW,EACX,MAAM,EACN,WAAW,EACX,WAAW,EACX,YAAY,GACb,MAAM,YAAY,CAAC"}
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/notify/index.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AACH,OAAO,EAAE,oBAAoB,EAAE,QAAQ,EAAE,cAAc,EAAE,MAAM,aAAa,CAAC;AAC7E,YAAY,EAAE,qBAAqB,EAAE,WAAW,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AACpF,OAAO,EACL,eAAe,EACf,oBAAoB,EACpB,UAAU,EACV,aAAa,EACb,mBAAmB,GACpB,MAAM,aAAa,CAAC;AACrB,OAAO,EACL,0BAA0B,EAC1B,0BAA0B,EAC1B,gBAAgB,GACjB,MAAM,qBAAqB,CAAC;AAC7B,YAAY,EACV,2BAA2B,EAC3B,gBAAgB,EAChB,gBAAgB,EAChB,uBAAuB,GACxB,MAAM,qBAAqB,CAAC;AAC7B,YAAY,EACV,UAAU,EACV,eAAe,EACf,WAAW,EACX,aAAa,EACb,oBAAoB,EACpB,uBAAuB,EACvB,gBAAgB,EAChB,oBAAoB,EACpB,mBAAmB,GACpB,MAAM,aAAa,CAAC;AACrB,OAAO,EAAE,kBAAkB,EAAE,SAAS,EAAE,MAAM,qBAAqB,CAAC;AACpE,YAAY,EAAE,YAAY,EAAE,YAAY,EAAE,WAAW,EAAE,YAAY,EAAE,MAAM,qBAAqB,CAAC;AACjG,OAAO,EAAE,kBAAkB,EAAE,MAAM,qBAAqB,CAAC;AACzD,YAAY,EAAE,YAAY,EAAE,MAAM,qBAAqB,CAAC;AACxD,OAAO,EAAE,mBAAmB,EAAE,MAAM,cAAc,CAAC;AACnD,YAAY,EAAE,oBAAoB,EAAE,YAAY,EAAE,MAAM,cAAc,CAAC;AACvE,OAAO,EACL,mBAAmB,EACnB,gBAAgB,EAChB,qBAAqB,EACrB,QAAQ,EACR,OAAO,GACR,MAAM,aAAa,CAAC;AACrB,YAAY,EAAE,YAAY,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AAC5D,OAAO,EAAE,iBAAiB,EAAE,SAAS,EAAE,iBAAiB,EAAE,MAAM,gBAAgB,CAAC;AACjF,YAAY,EAAE,gBAAgB,EAAE,MAAM,gBAAgB,CAAC;AACvD,OAAO,EAAE,YAAY,EAAE,eAAe,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;AAC3E,OAAO,EAAE,iBAAiB,EAAE,iBAAiB,EAAE,MAAM,YAAY,CAAC;AAClE,YAAY,EACV,cAAc,EACd,UAAU,EACV,eAAe,EACf,gBAAgB,EAChB,OAAO,EACP,MAAM,EACN,WAAW,EACX,MAAM,EACN,WAAW,EACX,WAAW,EACX,YAAY,GACb,MAAM,YAAY,CAAC"}
|
package/dist/notify/index.js
CHANGED
|
@@ -6,6 +6,7 @@
|
|
|
6
6
|
*/
|
|
7
7
|
export { createAdminDirectory, emailsOf, normalizeEmail } from './admins.js';
|
|
8
8
|
export { ALERTS_RESOURCE, ALERT_RETENTION_DAYS, alertKeyOf, cleanupAlerts, createAlertRecorder, } from './alerts.js';
|
|
9
|
+
export { ALERTS_CLEANUP_MAX_PER_RUN, createAlertsCleanupHandler, runAlertsCleanup, } from './alerts-cleanup.js';
|
|
9
10
|
export { createEmailChannel, sesSender } from './channels/email.js';
|
|
10
11
|
export { createSlackChannel } from './channels/slack.js';
|
|
11
12
|
export { createNotifyHandler } from './handler.js';
|
package/dist/notify/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/notify/index.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AACH,OAAO,EAAE,oBAAoB,EAAE,QAAQ,EAAE,cAAc,EAAE,MAAM,aAAa,CAAC;AAE7E,OAAO,EACL,eAAe,EACf,oBAAoB,EACpB,UAAU,EACV,aAAa,EACb,mBAAmB,GACpB,MAAM,aAAa,CAAC;
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/notify/index.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AACH,OAAO,EAAE,oBAAoB,EAAE,QAAQ,EAAE,cAAc,EAAE,MAAM,aAAa,CAAC;AAE7E,OAAO,EACL,eAAe,EACf,oBAAoB,EACpB,UAAU,EACV,aAAa,EACb,mBAAmB,GACpB,MAAM,aAAa,CAAC;AACrB,OAAO,EACL,0BAA0B,EAC1B,0BAA0B,EAC1B,gBAAgB,GACjB,MAAM,qBAAqB,CAAC;AAkB7B,OAAO,EAAE,kBAAkB,EAAE,SAAS,EAAE,MAAM,qBAAqB,CAAC;AAEpE,OAAO,EAAE,kBAAkB,EAAE,MAAM,qBAAqB,CAAC;AAEzD,OAAO,EAAE,mBAAmB,EAAE,MAAM,cAAc,CAAC;AAEnD,OAAO,EACL,mBAAmB,EACnB,gBAAgB,EAChB,qBAAqB,EACrB,QAAQ,EACR,OAAO,GACR,MAAM,aAAa,CAAC;AAErB,OAAO,EAAE,iBAAiB,EAAE,SAAS,EAAE,iBAAiB,EAAE,MAAM,gBAAgB,CAAC;AAEjF,OAAO,EAAE,YAAY,EAAE,eAAe,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;AAC3E,OAAO,EAAE,iBAAiB,EAAE,iBAAiB,EAAE,MAAM,YAAY,CAAC"}
|
package/dist/server/handler.cjs
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
// @exabugs/dynamodb-client v1.
|
|
2
|
-
// Built: 2026-10-
|
|
1
|
+
// @exabugs/dynamodb-client v1.18.0
|
|
2
|
+
// Built: 2026-10-24T04:27:35.011Z
|
|
3
3
|
"use strict";
|
|
4
4
|
var __create = Object.create;
|
|
5
5
|
var __defProp = Object.defineProperty;
|
|
@@ -38980,7 +38980,7 @@ async function handler(event) {
|
|
|
38980
38980
|
return createCorsResponse(HTTP_STATUS.OK);
|
|
38981
38981
|
}
|
|
38982
38982
|
if (event.requestContext.http.method === "GET" && event.requestContext.http.path === "/version") {
|
|
38983
|
-
const version = "1.
|
|
38983
|
+
const version = "1.18.0";
|
|
38984
38984
|
return createSuccessResponse({ version, timestamp: (/* @__PURE__ */ new Date()).toISOString() }, requestId);
|
|
38985
38985
|
}
|
|
38986
38986
|
if (event.requestContext.http.method !== "POST") {
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* システム変更履歴の記録 Lambda のハンドラのファクトリ(ADR 0006 の (a))。
|
|
3
|
+
*
|
|
4
|
+
* 直接呼び出し(`aws lambda invoke`。terraform のラッパー・人・CI)で使う。入力と応答は docs/SYSTEM_CHANGES.md。
|
|
5
|
+
* 呼び出しごとに Records(IAM 版 Function URL)のクライアントを作り、終わったら閉じる(`withCollection`)。
|
|
6
|
+
*
|
|
7
|
+
* 設定は、オプションが環境変数より優先される(どちらも呼び出しのたびに読む):
|
|
8
|
+
* - `app`: PROJECT_NAME(必須)
|
|
9
|
+
* - `records.url` / `records.region`: RECORDS_IAM_URL(必須)/ AWS_REGION
|
|
10
|
+
* - Slack(任意。webhookParam が無ければ送らない): SLACK_WEBHOOK_PARAM(SSM の SecureString の名前)/ ENV_NAME /
|
|
11
|
+
* ADMIN_BASE_URL / NOTIFY_STARTED('true' で開始も送る)
|
|
12
|
+
*
|
|
13
|
+
* 失敗の扱い: 入力の誤り・Records への書き込みの失敗は、構造化ログ(warn / error)に出し、例外にする(呼び出し元が
|
|
14
|
+
* `FunctionError` で分かるように)。Slack への送信の失敗は、記録を失敗にしない。
|
|
15
|
+
*/
|
|
16
|
+
import { SSMClient } from '@aws-sdk/client-ssm';
|
|
17
|
+
import { type RecordsClientOptions, type RecordsCollection } from '../client/recordsClient.js';
|
|
18
|
+
import { type StoredSystemChange } from './record.js';
|
|
19
|
+
import { type SystemChangeLog, type SystemChangeResponse, type SystemChangeSlackOptions, type SystemChangesCollection } from './recorder.js';
|
|
20
|
+
export interface SystemChangeHandlerOptions {
|
|
21
|
+
/** アプリ名。省略時は環境変数 PROJECT_NAME */
|
|
22
|
+
app?: string;
|
|
23
|
+
/** Records のクライアント。url / region は省略時に環境変数。timeout の既定は RECORD_HTTP_TIMEOUT_MS(5 秒) */
|
|
24
|
+
records?: RecordsClientOptions;
|
|
25
|
+
/**
|
|
26
|
+
* 書き込み先を作る(既定 systemChangesCollectionOf)。権限チェック層(astro の authorizedCollection など)を
|
|
27
|
+
* 通すアプリは、受け取った生のコレクションを自分の層で包んで返す
|
|
28
|
+
*/
|
|
29
|
+
collection?: (raw: RecordsCollection<StoredSystemChange>) => SystemChangesCollection;
|
|
30
|
+
/**
|
|
31
|
+
* Slack の設定。各項目は省略時に環境変数(上記)。getWebhookUrl の既定は SSM(SecureString。実行環境の間は
|
|
32
|
+
* キャッシュ)。false で送らない
|
|
33
|
+
*/
|
|
34
|
+
slack?: Partial<SystemChangeSlackOptions> | false;
|
|
35
|
+
/** SSM のクライアント(既定は AWS_REGION の SSMClient。テスト用) */
|
|
36
|
+
ssmClient?: Pick<SSMClient, 'send'>;
|
|
37
|
+
/** ログの出力先(既定は notify の logJson) */
|
|
38
|
+
log?: SystemChangeLog;
|
|
39
|
+
/** 現在時刻(テスト用) */
|
|
40
|
+
now?: () => Date;
|
|
41
|
+
}
|
|
42
|
+
/**
|
|
43
|
+
* 記録 Lambda のハンドラを作る。アプリのエントリは、これを export するだけ:
|
|
44
|
+
* `export const handler = createSystemChangeHandler();`
|
|
45
|
+
*/
|
|
46
|
+
export declare function createSystemChangeHandler(options?: SystemChangeHandlerOptions): (event: unknown) => Promise<SystemChangeResponse>;
|
|
47
|
+
//# sourceMappingURL=handler.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"handler.d.ts","sourceRoot":"","sources":["../../src/system-changes/handler.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;GAcG;AACH,OAAO,EAAuB,SAAS,EAAE,MAAM,qBAAqB,CAAC;AAErE,OAAO,EACL,KAAK,oBAAoB,EACzB,KAAK,iBAAiB,EAEvB,MAAM,4BAA4B,CAAC;AACpC,OAAO,EAA2B,KAAK,kBAAkB,EAAE,MAAM,aAAa,CAAC;AAC/E,OAAO,EAEL,KAAK,eAAe,EACpB,KAAK,oBAAoB,EACzB,KAAK,wBAAwB,EAC7B,KAAK,uBAAuB,EAG7B,MAAM,eAAe,CAAC;AAEvB,MAAM,WAAW,0BAA0B;IACzC,iCAAiC;IACjC,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,sFAAsF;IACtF,OAAO,CAAC,EAAE,oBAAoB,CAAC;IAC/B;;;OAGG;IACH,UAAU,CAAC,EAAE,CAAC,GAAG,EAAE,iBAAiB,CAAC,kBAAkB,CAAC,KAAK,uBAAuB,CAAC;IACrF;;;OAGG;IACH,KAAK,CAAC,EAAE,OAAO,CAAC,wBAAwB,CAAC,GAAG,KAAK,CAAC;IAClD,mDAAmD;IACnD,SAAS,CAAC,EAAE,IAAI,CAAC,SAAS,EAAE,MAAM,CAAC,CAAC;IACpC,mCAAmC;IACnC,GAAG,CAAC,EAAE,eAAe,CAAC;IACtB,iBAAiB;IACjB,GAAG,CAAC,EAAE,MAAM,IAAI,CAAC;CAClB;AAmCD;;;GAGG;AACH,wBAAgB,yBAAyB,CACvC,OAAO,GAAE,0BAA+B,GACvC,CAAC,KAAK,EAAE,OAAO,KAAK,OAAO,CAAC,oBAAoB,CAAC,CAwBnD"}
|
|
@@ -0,0 +1,74 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* システム変更履歴の記録 Lambda のハンドラのファクトリ(ADR 0006 の (a))。
|
|
3
|
+
*
|
|
4
|
+
* 直接呼び出し(`aws lambda invoke`。terraform のラッパー・人・CI)で使う。入力と応答は docs/SYSTEM_CHANGES.md。
|
|
5
|
+
* 呼び出しごとに Records(IAM 版 Function URL)のクライアントを作り、終わったら閉じる(`withCollection`)。
|
|
6
|
+
*
|
|
7
|
+
* 設定は、オプションが環境変数より優先される(どちらも呼び出しのたびに読む):
|
|
8
|
+
* - `app`: PROJECT_NAME(必須)
|
|
9
|
+
* - `records.url` / `records.region`: RECORDS_IAM_URL(必須)/ AWS_REGION
|
|
10
|
+
* - Slack(任意。webhookParam が無ければ送らない): SLACK_WEBHOOK_PARAM(SSM の SecureString の名前)/ ENV_NAME /
|
|
11
|
+
* ADMIN_BASE_URL / NOTIFY_STARTED('true' で開始も送る)
|
|
12
|
+
*
|
|
13
|
+
* 失敗の扱い: 入力の誤り・Records への書き込みの失敗は、構造化ログ(warn / error)に出し、例外にする(呼び出し元が
|
|
14
|
+
* `FunctionError` で分かるように)。Slack への送信の失敗は、記録を失敗にしない。
|
|
15
|
+
*/
|
|
16
|
+
import { GetParameterCommand, SSMClient } from '@aws-sdk/client-ssm';
|
|
17
|
+
import { withCollection, } from '../client/recordsClient.js';
|
|
18
|
+
import { SYSTEM_CHANGES_RESOURCE } from './record.js';
|
|
19
|
+
import { RECORD_HTTP_TIMEOUT_MS, recordAndNotify, systemChangesCollectionOf, } from './recorder.js';
|
|
20
|
+
/** SSM(SecureString)から webhook の URL を取る関数。param ごとに、実行環境の間は使い回す */
|
|
21
|
+
function ssmWebhookGetter(client) {
|
|
22
|
+
const cache = new Map();
|
|
23
|
+
return async (param) => {
|
|
24
|
+
const hit = cache.get(param);
|
|
25
|
+
if (hit)
|
|
26
|
+
return hit;
|
|
27
|
+
const r = await client().send(new GetParameterCommand({ Name: param, WithDecryption: true }));
|
|
28
|
+
const url = r.Parameter?.Value;
|
|
29
|
+
if (!url)
|
|
30
|
+
throw new Error('webhook の値が空です');
|
|
31
|
+
cache.set(param, url);
|
|
32
|
+
return url;
|
|
33
|
+
};
|
|
34
|
+
}
|
|
35
|
+
const envOf = (name) => process.env[name] || undefined;
|
|
36
|
+
/** Slack の設定を、オプションと環境変数から決める */
|
|
37
|
+
function slackOf(options, defaultGetter) {
|
|
38
|
+
if (options.slack === false)
|
|
39
|
+
return undefined;
|
|
40
|
+
const s = options.slack ?? {};
|
|
41
|
+
return {
|
|
42
|
+
...s,
|
|
43
|
+
webhookParam: s.webhookParam ?? envOf('SLACK_WEBHOOK_PARAM'),
|
|
44
|
+
env: s.env ?? envOf('ENV_NAME'),
|
|
45
|
+
adminBaseUrl: s.adminBaseUrl ?? envOf('ADMIN_BASE_URL'),
|
|
46
|
+
notifyStarted: s.notifyStarted ?? process.env.NOTIFY_STARTED === 'true',
|
|
47
|
+
getWebhookUrl: s.getWebhookUrl ?? defaultGetter,
|
|
48
|
+
};
|
|
49
|
+
}
|
|
50
|
+
/**
|
|
51
|
+
* 記録 Lambda のハンドラを作る。アプリのエントリは、これを export するだけ:
|
|
52
|
+
* `export const handler = createSystemChangeHandler();`
|
|
53
|
+
*/
|
|
54
|
+
export function createSystemChangeHandler(options = {}) {
|
|
55
|
+
let ssm = options.ssmClient;
|
|
56
|
+
const getFromSsm = ssmWebhookGetter(() => (ssm ??= new SSMClient({ region: options.records?.region ?? process.env.AWS_REGION })));
|
|
57
|
+
const wrap = options.collection ?? systemChangesCollectionOf;
|
|
58
|
+
return async (event) => {
|
|
59
|
+
const app = options.app ?? envOf('PROJECT_NAME');
|
|
60
|
+
if (!app)
|
|
61
|
+
throw new Error('PROJECT_NAME environment variable is required');
|
|
62
|
+
const url = options.records?.url ?? envOf('RECORDS_IAM_URL');
|
|
63
|
+
if (!url)
|
|
64
|
+
throw new Error('RECORDS_IAM_URL environment variable is required');
|
|
65
|
+
const records = {
|
|
66
|
+
...options.records,
|
|
67
|
+
url,
|
|
68
|
+
timeout: options.records?.timeout ?? RECORD_HTTP_TIMEOUT_MS,
|
|
69
|
+
};
|
|
70
|
+
const slack = slackOf(options, getFromSsm);
|
|
71
|
+
return withCollection(SYSTEM_CHANGES_RESOURCE, (raw) => recordAndNotify(wrap(raw), event, { app, slack, log: options.log, now: options.now }), records);
|
|
72
|
+
};
|
|
73
|
+
}
|
|
74
|
+
//# sourceMappingURL=handler.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"handler.js","sourceRoot":"","sources":["../../src/system-changes/handler.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* システム変更履歴(`@exabugs/dynamodb-client/system-changes`。ADR 0006 の (a))
|
|
3
|
+
*
|
|
4
|
+
* 環境に起きたシステム変更(インフラの変更・Lambda のリリース・アプリのリリース・OTA)を、Records の
|
|
5
|
+
* `systemChanges` に記録し、結果を Slack に送る部品。記録 Lambda のハンドラのファクトリも持つ。
|
|
6
|
+
* アプリが渡すのは設定(アプリ名、SSM の名前、管理画面の URL、書き込み先の包み方)だけ。docs/SYSTEM_CHANGES.md
|
|
7
|
+
*/
|
|
8
|
+
export { createSystemChangeHandler } from './handler.js';
|
|
9
|
+
export type { SystemChangeHandlerOptions } from './handler.js';
|
|
10
|
+
export { CHANGE_ID_PATTERN, LIMITS, SYSTEM_CHANGES_RESOURCE, SYSTEM_CHANGE_KINDS, SYSTEM_CHANGE_RESULTS, SystemChangeInputError, decideRunWrite, isFinished, parseSystemChangeInput, toSystemChangeRecord, } from './record.js';
|
|
11
|
+
export type { RunDecision, StoredSystemChange, SystemChangeInput, SystemChangeKind, SystemChangeRecord, SystemChangeResult, } from './record.js';
|
|
12
|
+
export { RECORD_HTTP_TIMEOUT_MS, SLACK_HTTP_TIMEOUT_MS, recordAndNotify, recordSystemChange, systemChangesCollectionOf, } from './recorder.js';
|
|
13
|
+
export type { RecordAndNotifyOptions, RecordOutcome, RecordSystemChangeOptions, SystemChangeLog, SystemChangeLogLevel, SystemChangeResponse, SystemChangeSlackOptions, SystemChangesCollection, } from './recorder.js';
|
|
14
|
+
export { formatDuration, formatSystemChangeMessage, lambdaReleaseNames, shouldNotify, } from './slack.js';
|
|
15
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/system-changes/index.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AACH,OAAO,EAAE,yBAAyB,EAAE,MAAM,cAAc,CAAC;AACzD,YAAY,EAAE,0BAA0B,EAAE,MAAM,cAAc,CAAC;AAC/D,OAAO,EACL,iBAAiB,EACjB,MAAM,EACN,uBAAuB,EACvB,mBAAmB,EACnB,qBAAqB,EACrB,sBAAsB,EACtB,cAAc,EACd,UAAU,EACV,sBAAsB,EACtB,oBAAoB,GACrB,MAAM,aAAa,CAAC;AACrB,YAAY,EACV,WAAW,EACX,kBAAkB,EAClB,iBAAiB,EACjB,gBAAgB,EAChB,kBAAkB,EAClB,kBAAkB,GACnB,MAAM,aAAa,CAAC;AACrB,OAAO,EACL,sBAAsB,EACtB,qBAAqB,EACrB,eAAe,EACf,kBAAkB,EAClB,yBAAyB,GAC1B,MAAM,eAAe,CAAC;AACvB,YAAY,EACV,sBAAsB,EACtB,aAAa,EACb,yBAAyB,EACzB,eAAe,EACf,oBAAoB,EACpB,oBAAoB,EACpB,wBAAwB,EACxB,uBAAuB,GACxB,MAAM,eAAe,CAAC;AACvB,OAAO,EACL,cAAc,EACd,yBAAyB,EACzB,kBAAkB,EAClB,YAAY,GACb,MAAM,YAAY,CAAC"}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* システム変更履歴(`@exabugs/dynamodb-client/system-changes`。ADR 0006 の (a))
|
|
3
|
+
*
|
|
4
|
+
* 環境に起きたシステム変更(インフラの変更・Lambda のリリース・アプリのリリース・OTA)を、Records の
|
|
5
|
+
* `systemChanges` に記録し、結果を Slack に送る部品。記録 Lambda のハンドラのファクトリも持つ。
|
|
6
|
+
* アプリが渡すのは設定(アプリ名、SSM の名前、管理画面の URL、書き込み先の包み方)だけ。docs/SYSTEM_CHANGES.md
|
|
7
|
+
*/
|
|
8
|
+
export { createSystemChangeHandler } from './handler.js';
|
|
9
|
+
export { CHANGE_ID_PATTERN, LIMITS, SYSTEM_CHANGES_RESOURCE, SYSTEM_CHANGE_KINDS, SYSTEM_CHANGE_RESULTS, SystemChangeInputError, decideRunWrite, isFinished, parseSystemChangeInput, toSystemChangeRecord, } from './record.js';
|
|
10
|
+
export { RECORD_HTTP_TIMEOUT_MS, SLACK_HTTP_TIMEOUT_MS, recordAndNotify, recordSystemChange, systemChangesCollectionOf, } from './recorder.js';
|
|
11
|
+
export { formatDuration, formatSystemChangeMessage, lambdaReleaseNames, shouldNotify, } from './slack.js';
|
|
12
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/system-changes/index.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AACH,OAAO,EAAE,yBAAyB,EAAE,MAAM,cAAc,CAAC;AAEzD,OAAO,EACL,iBAAiB,EACjB,MAAM,EACN,uBAAuB,EACvB,mBAAmB,EACnB,qBAAqB,EACrB,sBAAsB,EACtB,cAAc,EACd,UAAU,EACV,sBAAsB,EACtB,oBAAoB,GACrB,MAAM,aAAa,CAAC;AASrB,OAAO,EACL,sBAAsB,EACtB,qBAAqB,EACrB,eAAe,EACf,kBAAkB,EAClB,yBAAyB,GAC1B,MAAM,eAAe,CAAC;AAWvB,OAAO,EACL,cAAc,EACd,yBAAyB,EACzB,kBAAkB,EAClB,YAAY,GACb,MAAM,YAAY,CAAC"}
|