@enslo/sd-metadata 2.3.0 → 3.0.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 +34 -0
- package/README.ja.md +53 -3
- package/README.md +55 -5
- package/dist/index.d.ts +58 -3
- package/dist/index.d.ts.map +1 -1
- package/dist/index.global.js +3 -3
- package/dist/index.js +251 -21
- package/dist/index.js.map +1 -1
- package/docs/types.ja.md +80 -1
- package/docs/types.md +80 -1
- package/package.json +2 -2
package/docs/types.ja.md
CHANGED
|
@@ -10,6 +10,8 @@
|
|
|
10
10
|
- [`ParseResult`](#parseresult)
|
|
11
11
|
- [`GenerationMetadata`](#generationmetadata)
|
|
12
12
|
- [`GenerationSoftware`](#generationsoftware)
|
|
13
|
+
- [`C2paMetadata`](#c2pametadata)
|
|
14
|
+
- [`C2paVendor`](#c2pavendor)
|
|
13
15
|
- [`EmbedMetadata`](#embedmetadata)
|
|
14
16
|
- [`RawMetadata`](#rawmetadata)
|
|
15
17
|
- [`WriteResult`](#writeresult)
|
|
@@ -47,6 +49,7 @@
|
|
|
47
49
|
```typescript
|
|
48
50
|
type ParseResult =
|
|
49
51
|
| { status: 'success'; metadata: GenerationMetadata; raw: RawMetadata }
|
|
52
|
+
| { status: 'c2pa'; c2pa: C2paMetadata }
|
|
50
53
|
| { status: 'unrecognized'; raw: RawMetadata }
|
|
51
54
|
| { status: 'empty' }
|
|
52
55
|
| { status: 'invalid'; message?: string };
|
|
@@ -57,6 +60,8 @@ type ParseResult =
|
|
|
57
60
|
- **`success`**: メタデータのパースに成功
|
|
58
61
|
- `metadata`: 統一されたメタデータオブジェクト
|
|
59
62
|
- `raw`: ラウンドトリップ変換用の元のフォーマット固有データ
|
|
63
|
+
- **`c2pa`**: 画像が C2PA Content Credentials を持つが、パース可能な生成メタデータがない
|
|
64
|
+
- `c2pa`: 未検証の Content Credentials を表す `C2paMetadata`。`raw` フィールドは存在しません — 署名済みマニフェストはラウンドトリップ書き込み用に公開されません。
|
|
60
65
|
- **`unrecognized`**: 画像にメタデータがあるがフォーマットが認識できない
|
|
61
66
|
- `raw`: 元のメタデータが保持される
|
|
62
67
|
- **`empty`**: 画像にメタデータが見つからない
|
|
@@ -75,7 +80,14 @@ switch (result.status) {
|
|
|
75
80
|
console.log(`Generated by ${result.metadata.software}`);
|
|
76
81
|
console.log(`Prompt: ${result.metadata.prompt}`);
|
|
77
82
|
break;
|
|
78
|
-
|
|
83
|
+
|
|
84
|
+
case 'c2pa':
|
|
85
|
+
// Content Credentials を検出(例:OpenAI ChatGPT、Google Gemini)。
|
|
86
|
+
// 検出のみ — 署名は検証されません。
|
|
87
|
+
console.log(`生成元(未検証): ${result.c2pa.vendor}`);
|
|
88
|
+
console.log(`Claim generator: ${result.c2pa.claimGenerator ?? 'unknown'}`);
|
|
89
|
+
break;
|
|
90
|
+
|
|
79
91
|
case 'unrecognized':
|
|
80
92
|
console.log('不明なメタデータフォーマット');
|
|
81
93
|
break;
|
|
@@ -172,6 +184,73 @@ function displaySoftware(software: GenerationSoftware): string {
|
|
|
172
184
|
|
|
173
185
|
---
|
|
174
186
|
|
|
187
|
+
### `C2paMetadata`
|
|
188
|
+
|
|
189
|
+
画像に埋め込まれた C2PA Content Credentials から読み取った内容。
|
|
190
|
+
|
|
191
|
+
C2PAマニフェストを持つ画像(現在は **OpenAI ChatGPT** と **Google Gemini**)で、パース可能な生成メタデータがない場合に `read()` が `{ status: 'c2pa', c2pa }` として返します。`GenerationMetadata` とは異なり、**プロンプト・シード・モデル・サイズを一切持ちません**: これらのツールは生成パラメータではなく Content Credentials を埋め込むためです。`C2paMetadata` は `BaseMetadata` を**拡張しません**。
|
|
192
|
+
|
|
193
|
+
```typescript
|
|
194
|
+
export interface C2paMetadata {
|
|
195
|
+
/** マニフェストの claim generator/署名者から特定した粗いベンダー。 */
|
|
196
|
+
vendor: C2paVendor;
|
|
197
|
+
/**
|
|
198
|
+
* マニフェストが学習アルゴリズム由来(AI生成)の IPTC DigitalSourceType を
|
|
199
|
+
* 宣言している場合に `true`。カメラ/スキャンのソースタイプはフラグされません。
|
|
200
|
+
*/
|
|
201
|
+
aiGenerated: boolean;
|
|
202
|
+
/** 生の IPTC DigitalSourceType URI。存在する場合はそのまま提供されます。 */
|
|
203
|
+
digitalSourceType?: string;
|
|
204
|
+
/** C2PA の `claim_generator_info.name`(存在する場合)。 */
|
|
205
|
+
claimGenerator?: string;
|
|
206
|
+
}
|
|
207
|
+
```
|
|
208
|
+
|
|
209
|
+
> **重要 — 検証ではなく検出のみ。** Content Credentials の存在は真正性の証明にはなりません(文字列は偽造可能)。不在も人間由来の証明にはなりません: Content Credentials はスクリーンショット、SNSへの再アップロード、再エンコードによって日常的に剥奪されます。
|
|
210
|
+
>
|
|
211
|
+
> **現時点ではPNGのみ。** マニフェストはPNGの `caBX` チャンクから読み取られます。JPEG/WebP対応は予定されています。
|
|
212
|
+
|
|
213
|
+
**例:**
|
|
214
|
+
|
|
215
|
+
```typescript
|
|
216
|
+
import { read, c2paVendorLabels } from '@enslo/sd-metadata';
|
|
217
|
+
|
|
218
|
+
const result = read(imageData);
|
|
219
|
+
|
|
220
|
+
if (result.status === 'c2pa') {
|
|
221
|
+
const { vendor, aiGenerated, claimGenerator } = result.c2pa;
|
|
222
|
+
console.log('Vendor:', c2paVendorLabels[vendor]);
|
|
223
|
+
console.log('Declared AI-generated:', aiGenerated);
|
|
224
|
+
console.log('Claim generator:', claimGenerator ?? 'unknown');
|
|
225
|
+
}
|
|
226
|
+
```
|
|
227
|
+
|
|
228
|
+
---
|
|
229
|
+
|
|
230
|
+
### `C2paVendor`
|
|
231
|
+
|
|
232
|
+
画像の C2PA Content Credentials の粗いベンダー特定。[`C2paMetadata`](#c2pametadata) の `vendor` 判別子として、また `c2paVendorLabels` のキー型として使用します。
|
|
233
|
+
|
|
234
|
+
```typescript
|
|
235
|
+
export type C2paVendor = 'openai' | 'google' | 'unknown';
|
|
236
|
+
```
|
|
237
|
+
|
|
238
|
+
設計上、これは粗い特定です: C2PAマニフェストは生成元ベンダー(`'openai'` → ChatGPT、`'google'` → Gemini、`'unknown'` → ベンダーが具体的に認識されないAI生成マニフェスト)を特定しますが、具体的なモデルは特定**しません**。
|
|
239
|
+
|
|
240
|
+
**例:**
|
|
241
|
+
|
|
242
|
+
```typescript
|
|
243
|
+
import { c2paVendorLabels } from '@enslo/sd-metadata';
|
|
244
|
+
import type { C2paVendor } from '@enslo/sd-metadata';
|
|
245
|
+
|
|
246
|
+
function displayVendor(vendor: C2paVendor): string {
|
|
247
|
+
return c2paVendorLabels[vendor];
|
|
248
|
+
// => "OpenAI (ChatGPT)", "Google (Gemini)", "AI-generated (Content Credentials)"
|
|
249
|
+
}
|
|
250
|
+
```
|
|
251
|
+
|
|
252
|
+
---
|
|
253
|
+
|
|
175
254
|
### `EmbedMetadata`
|
|
176
255
|
|
|
177
256
|
`embed()` と `stringify()` で使用するユーザー作成カスタムメタデータ型。`GenerationMetadata` が既知のAIツールからのパース結果を表すのに対し、`EmbedMetadata` はユーザーが独自にメタデータを組み立てるための型です。`BaseMetadata` にオプションのNovelAIキャラクタープロンプトと設定行への任意キーバリュー(`extras`)を追加。
|
package/docs/types.md
CHANGED
|
@@ -10,6 +10,8 @@ Complete type reference for `@enslo/sd-metadata`.
|
|
|
10
10
|
- [`ParseResult`](#parseresult)
|
|
11
11
|
- [`GenerationMetadata`](#generationmetadata)
|
|
12
12
|
- [`GenerationSoftware`](#generationsoftware)
|
|
13
|
+
- [`C2paMetadata`](#c2pametadata)
|
|
14
|
+
- [`C2paVendor`](#c2pavendor)
|
|
13
15
|
- [`EmbedMetadata`](#embedmetadata)
|
|
14
16
|
- [`RawMetadata`](#rawmetadata)
|
|
15
17
|
- [`WriteResult`](#writeresult)
|
|
@@ -47,6 +49,7 @@ The result type returned by the `read()` function.
|
|
|
47
49
|
```typescript
|
|
48
50
|
type ParseResult =
|
|
49
51
|
| { status: 'success'; metadata: GenerationMetadata; raw: RawMetadata }
|
|
52
|
+
| { status: 'c2pa'; c2pa: C2paMetadata }
|
|
50
53
|
| { status: 'unrecognized'; raw: RawMetadata }
|
|
51
54
|
| { status: 'empty' }
|
|
52
55
|
| { status: 'invalid'; message?: string };
|
|
@@ -57,6 +60,8 @@ type ParseResult =
|
|
|
57
60
|
- **`success`**: Metadata was successfully parsed
|
|
58
61
|
- `metadata`: Unified metadata object
|
|
59
62
|
- `raw`: Original format-specific data for round-trip conversion
|
|
63
|
+
- **`c2pa`**: Image carries C2PA Content Credentials (AI provenance) but no parseable generation metadata
|
|
64
|
+
- `c2pa`: `C2paMetadata` describing the declared (unverified) provenance. There is no `raw` field — the signed manifest is not exposed for round-trip writing.
|
|
60
65
|
- **`unrecognized`**: Image has metadata but format is not recognized
|
|
61
66
|
- `raw`: Original metadata is preserved
|
|
62
67
|
- **`empty`**: No metadata found in the image
|
|
@@ -75,7 +80,14 @@ switch (result.status) {
|
|
|
75
80
|
console.log(`Generated by ${result.metadata.software}`);
|
|
76
81
|
console.log(`Prompt: ${result.metadata.prompt}`);
|
|
77
82
|
break;
|
|
78
|
-
|
|
83
|
+
|
|
84
|
+
case 'c2pa':
|
|
85
|
+
// Content Credentials detected (e.g. OpenAI ChatGPT, Google Gemini).
|
|
86
|
+
// Detection only — the signature is NOT verified.
|
|
87
|
+
console.log(`Provenance vendor: ${result.c2pa.vendor} (unverified)`);
|
|
88
|
+
console.log(`Claim generator: ${result.c2pa.claimGenerator ?? 'unknown'}`);
|
|
89
|
+
break;
|
|
90
|
+
|
|
79
91
|
case 'unrecognized':
|
|
80
92
|
console.log('Unknown metadata format');
|
|
81
93
|
break;
|
|
@@ -172,6 +184,73 @@ function displaySoftware(software: GenerationSoftware): string {
|
|
|
172
184
|
|
|
173
185
|
---
|
|
174
186
|
|
|
187
|
+
### `C2paMetadata`
|
|
188
|
+
|
|
189
|
+
Content Credentials (C2PA) read from an image's signed provenance manifest.
|
|
190
|
+
|
|
191
|
+
This is returned by `read()` as `{ status: 'c2pa', c2pa }` for images that carry a C2PA manifest — currently **OpenAI ChatGPT** and **Google Gemini** — but no parseable generation metadata. Unlike `GenerationMetadata`, it carries **no prompt, seed, model, or size**: these tools embed provenance, not generation parameters. `C2paMetadata` does **not** extend `BaseMetadata`.
|
|
192
|
+
|
|
193
|
+
```typescript
|
|
194
|
+
export interface C2paMetadata {
|
|
195
|
+
/** Coarse vendor attribution from the manifest's claim generator / signer. */
|
|
196
|
+
vendor: C2paVendor;
|
|
197
|
+
/**
|
|
198
|
+
* `true` when the manifest declares a trained-algorithmic (AI-generated)
|
|
199
|
+
* IPTC DigitalSourceType. Camera/scan source types are not flagged.
|
|
200
|
+
*/
|
|
201
|
+
aiGenerated: boolean;
|
|
202
|
+
/** Raw IPTC DigitalSourceType URI, surfaced verbatim when present. */
|
|
203
|
+
digitalSourceType?: string;
|
|
204
|
+
/** C2PA `claim_generator_info.name`, when present. */
|
|
205
|
+
claimGenerator?: string;
|
|
206
|
+
}
|
|
207
|
+
```
|
|
208
|
+
|
|
209
|
+
> **Important — detection only, not verification.** Presence of Content Credentials is not proof of authenticity (the strings are forgeable). Absence is not proof of human origin either: Content Credentials are routinely stripped by screenshots, social-media re-uploads, and re-encoding.
|
|
210
|
+
>
|
|
211
|
+
> **PNG only today.** The manifest is read from the PNG `caBX` chunk; JPEG/WebP support is planned.
|
|
212
|
+
|
|
213
|
+
**Example:**
|
|
214
|
+
|
|
215
|
+
```typescript
|
|
216
|
+
import { read, c2paVendorLabels } from '@enslo/sd-metadata';
|
|
217
|
+
|
|
218
|
+
const result = read(imageData);
|
|
219
|
+
|
|
220
|
+
if (result.status === 'c2pa') {
|
|
221
|
+
const { vendor, aiGenerated, claimGenerator } = result.c2pa;
|
|
222
|
+
console.log('Vendor:', c2paVendorLabels[vendor]);
|
|
223
|
+
console.log('Declared AI-generated:', aiGenerated);
|
|
224
|
+
console.log('Claim generator:', claimGenerator ?? 'unknown');
|
|
225
|
+
}
|
|
226
|
+
```
|
|
227
|
+
|
|
228
|
+
---
|
|
229
|
+
|
|
230
|
+
### `C2paVendor`
|
|
231
|
+
|
|
232
|
+
Coarse vendor attribution for an image's C2PA Content Credentials. Used as the `vendor` discriminator on [`C2paMetadata`](#c2pametadata) and as the key type for `c2paVendorLabels`.
|
|
233
|
+
|
|
234
|
+
```typescript
|
|
235
|
+
export type C2paVendor = 'openai' | 'google' | 'unknown';
|
|
236
|
+
```
|
|
237
|
+
|
|
238
|
+
By design this is coarse: a C2PA manifest identifies the producing vendor (`'openai'` → ChatGPT, `'google'` → Gemini, `'unknown'` → an AI-generated manifest whose vendor is not specifically recognized) but **not** the specific model.
|
|
239
|
+
|
|
240
|
+
**Example:**
|
|
241
|
+
|
|
242
|
+
```typescript
|
|
243
|
+
import { c2paVendorLabels } from '@enslo/sd-metadata';
|
|
244
|
+
import type { C2paVendor } from '@enslo/sd-metadata';
|
|
245
|
+
|
|
246
|
+
function displayVendor(vendor: C2paVendor): string {
|
|
247
|
+
return c2paVendorLabels[vendor];
|
|
248
|
+
// => "OpenAI (ChatGPT)", "Google (Gemini)", "AI-generated (Content Credentials)"
|
|
249
|
+
}
|
|
250
|
+
```
|
|
251
|
+
|
|
252
|
+
---
|
|
253
|
+
|
|
175
254
|
### `EmbedMetadata`
|
|
176
255
|
|
|
177
256
|
User-created custom metadata for the `embed()` and `stringify()` functions. While `GenerationMetadata` represents parsed output from a known AI tool, `EmbedMetadata` is designed for composing metadata from scratch. Extends `BaseMetadata` with optional NovelAI character prompts and arbitrary key-value extras for the settings line.
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@enslo/sd-metadata",
|
|
3
|
-
"version": "
|
|
3
|
+
"version": "3.0.0",
|
|
4
4
|
"description": "Read and write AI-generated image metadata",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "./dist/index.js",
|
|
@@ -55,7 +55,7 @@
|
|
|
55
55
|
"devDependencies": {
|
|
56
56
|
"@biomejs/biome": "catalog:",
|
|
57
57
|
"@types/node": "catalog:",
|
|
58
|
-
"@vitest/coverage-v8": "^4.1.
|
|
58
|
+
"@vitest/coverage-v8": "^4.1.8",
|
|
59
59
|
"tsdown": "catalog:",
|
|
60
60
|
"typescript": "catalog:",
|
|
61
61
|
"vitest": "catalog:"
|