@wcstack/credential 1.20.0 → 1.21.1

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/README.ja.md CHANGED
@@ -61,6 +61,11 @@ npm install @wcstack/credential
61
61
  | `loading` | `wcs-credential:loading-changed` | `get()`/`store()`呼び出し中は`true`。 |
62
62
  | `error` | `wcs-credential:error` | 真のプラットフォーム失敗(正規化された`{ name, message }`)、無ければ`null`。 |
63
63
  | `cancelled` | `wcs-credential:cancelled-changed` | ユーザーがブラウザのアカウント選択UIを閉じたら`true`(Credential Management APIは`NotAllowedError`でrejectする)。`error`には含めない。 |
64
+ | `errorInfo` | `wcs-credential:error-info-changed` | serializable な失敗 taxonomy(安定 `code` / `phase` / `recoverable`)、または `null`。追加的で `error` の shape は不変。`code` は `capability-missing`(unsupported)・`out-of-scope`(`publicKey`/WebAuthn 試行)・`credential-failed`(真の失敗)。`NotAllowedError` のキャンセルは `cancelled` であり `errorInfo` ではない。 |
65
+
66
+ **並行制御。** `get()` と `store()` は 1 つの io-core lane を `latest` policy で共有する:
67
+ 後発の呼び出しが先発を **supersede** する(実際の認証フローでは順次利用される — ログイン後に
68
+ store、その前に get — 並行ではない)。並行実行時は後発の結果が勝つ。
64
69
 
65
70
  ## コマンド
66
71
 
package/README.md CHANGED
@@ -62,6 +62,12 @@ npm install @wcstack/credential
62
62
  | `loading` | `wcs-credential:loading-changed` | `true` while a `get()`/`store()` call is in flight. |
63
63
  | `error` | `wcs-credential:error` | A true platform failure (normalized `{ name, message }`), or `null`. |
64
64
  | `cancelled` | `wcs-credential:cancelled-changed` | `true` when the user dismissed the browser's account-chooser UI (the Credential Management API rejects with `NotAllowedError`). Kept out of `error`. |
65
+ | `errorInfo` | `wcs-credential:error-info-changed` | Serializable failure taxonomy (stable `code` / `phase` / `recoverable`), or `null`. Additive — the `error` shape is unchanged; `code` is `capability-missing` (unsupported), `out-of-scope` (a `publicKey`/WebAuthn attempt), or `credential-failed` (a genuine failure). A `NotAllowedError` cancellation is `cancelled`, not `errorInfo`. |
66
+
67
+ **Concurrency.** `get()` and `store()` share one io-core lane with the `latest`
68
+ policy: a later call **supersedes** the earlier one (these are used sequentially in
69
+ real auth flows — store after login, get before one — not concurrently). If both
70
+ are invoked concurrently, the later call's result wins.
65
71
 
66
72
  ## Commands
67
73
 
package/dist/index.d.ts CHANGED
@@ -1,3 +1,56 @@
1
+ /**
2
+ * platform-capability.ts
3
+ *
4
+ * Phase 6(docs/architecture-hardening/09-remediation-design.md §7.2 /
5
+ * 07-browser-capability-variance.md)の browser capability 判定と error taxonomy の
6
+ * 汎用プリミティブ。node 固有の capability registry / error code は各パッケージが
7
+ * 別ファイルで宣言し、この汎用層(型 + assess 機構)を import する。
8
+ *
9
+ * 原則:
10
+ * - feature detection は境界(利用直前)で行う。module 評価時に browser global を
11
+ * 参照しない(SSR / worker で import が失敗しない)。
12
+ * - capability ID(`web.fetch` 等)は文字列を global property path として eval せず、
13
+ * registry が ID ごとに副作用のない presence probe を対応付ける。
14
+ * - availability / permission / readiness / activity / operation error を 1 つの
15
+ * `ready / unsupported / error` enum に畳まない。required 欠如は開始しない、
16
+ * optional 欠如は宣言済み fallback で readiness を `degraded` にする。
17
+ *
18
+ * 配置: 本ファイルは /io-core/ の単一正典であり、scripts/sync-io-core.mjs が
19
+ * 各 IO ノードの src/core/ へ生成コピー (AUTO-GENERATED, 編集禁止) を配布する。
20
+ * `protocol/wcBindable.ts` と同じ copy-distribution 方式で、ランタイム依存を導入せず
21
+ * 各パッケージのバンドルへ inline される (zero-runtime-dep / 自己完結 CDN を維持)。
22
+ * 編集はこの正典に対して行い、`node scripts/sync-io-core.mjs` で再配布する。
23
+ *
24
+ * pure(module 評価時に browser global 非参照)。
25
+ */
26
+ type Availability = "available" | "missing" | "unknown";
27
+ type PermissionState = "granted" | "denied" | "prompt" | "not-applicable" | "unknown";
28
+ type Readiness = "idle" | "ready" | "degraded";
29
+ type Activity = "inactive" | "active";
30
+ type PreconditionState = "satisfied" | "required" | "not-applicable";
31
+ /** operation error の phase(taxonomy)。 */
32
+ type WcsIoErrorPhase = "probe" | "start" | "execute" | "decode" | "commit" | "dispose";
33
+ /** serializable な error info(non-cloneable な cause とは分離。DevTools / remote へは info のみ)。 */
34
+ interface WcsIoErrorInfo {
35
+ readonly code: string;
36
+ readonly phase: WcsIoErrorPhase;
37
+ readonly recoverable: boolean;
38
+ readonly capabilityId?: string;
39
+ readonly message: string;
40
+ }
41
+ interface PlatformAssessment {
42
+ readonly availability: ReadonlyMap<string, Availability>;
43
+ readonly permission: PermissionState;
44
+ readonly readiness: Readiness;
45
+ readonly activity: Activity;
46
+ readonly preconditions: {
47
+ readonly secureContext: PreconditionState;
48
+ readonly userActivation: PreconditionState;
49
+ };
50
+ readonly epoch: number;
51
+ readonly lastError?: WcsIoErrorInfo;
52
+ }
53
+
1
54
  interface IWcBindableProperty {
2
55
  readonly name: string;
3
56
  readonly event: string;
@@ -13,7 +66,8 @@ interface IWcBindableCommand {
13
66
  }
14
67
  interface IWcBindable {
15
68
  readonly protocol: "wc-bindable";
16
- readonly version: 1;
69
+ /** Integer protocol version. All versions >= 1 are core-compatible. */
70
+ readonly version: number;
17
71
  readonly properties: readonly IWcBindableProperty[];
18
72
  readonly inputs?: readonly IWcBindableInput[];
19
73
  readonly commands?: readonly IWcBindableCommand[];
@@ -60,6 +114,7 @@ interface WcsCredentialCoreValues {
60
114
  loading: boolean;
61
115
  error: any;
62
116
  cancelled: boolean;
117
+ errorInfo: WcsIoErrorInfo | null;
63
118
  }
64
119
  /**
65
120
  * Value types for the Shell (`<wcs-credential>`) — identical observable
@@ -72,37 +127,41 @@ declare function bootstrapCredential(userConfig?: IWritableConfig): void;
72
127
  declare function getConfig(): IConfig;
73
128
 
74
129
  /**
75
- * Headless Credential Management primitive. A thin, framework-agnostic
76
- * wrapper around `navigator.credentials.get()`/`.store()` exposed through the
77
- * wc-bindable protocol.
130
+ * Headless Credential Management primitive. A thin, framework-agnostic wrapper
131
+ * around `navigator.credentials.get()`/`.store()` exposed through the wc-bindable
132
+ * protocol.
78
133
  *
79
- * Reuses batch3's "thin command" archetype established by `@wcstack/share`
80
- * (docs/credential-tag-design.md): single `_gen` generation guard,
81
- * same-value-guarded private setters, never-throw try/catch, no
82
- * `AbortController`/`abort()` command.
134
+ * Concurrency is owned by the shared `OperationLane` (io-core) with the `latest`
135
+ * policy — **`get()` and `store()` share one lane**. A later call supersedes the
136
+ * earlier one (the earlier completion fails the terminal CAS), preserving the v1
137
+ * "single generation" behavior (docs/multi-promise-io-node-design.md): these two
138
+ * operations are used sequentially in real auth flows (store after login, get
139
+ * before one), not naturally concurrently on the same instance. If both ARE
140
+ * invoked concurrently, the later call's result wins; use two separate
141
+ * `<wcs-credential>` instances if that bites. The lane runs with
142
+ * `withSignal: false` — the Credential Management API takes no `AbortSignal`;
143
+ * dispose() invalidates any in-flight call via the owner generation.
83
144
  *
84
- * **v1 scope excludes WebAuthn (`publicKey`)** — see docs/credential-tag-design.md
85
- * §0. `get()` validates and strips a `publicKey` option rather than silently
86
- * forwarding it, surfacing the attempt as a scope-violation `error` instead of
87
- * accidentally supporting WebAuthn through a side door.
145
+ * **v1 scope excludes WebAuthn (`publicKey`)** (docs/credential-tag-design.md §0):
146
+ * `get()` validates+strips a `publicKey` option and `store()` rejects a
147
+ * `PublicKeyCredential`, surfacing the attempt as a scope-violation `error`
148
+ * (`errorInfo.code === "out-of-scope"`) rather than a WebAuthn backdoor.
88
149
  *
89
- * **`get()`/`store()` share one `_gen`** an accepted v1 simplification
90
- * (docs/multi-promise-io-node-design.md): these two operations are used
91
- * sequentially in real auth flows (store after a successful login, get before
92
- * attempting one), not naturally concurrently on the same instance. If both
93
- * ARE invoked concurrently on the same `<wcs-credential>`, the later call's
94
- * generation bump silently drops the earlier call's completion write. If this
95
- * limitation actually bites, use two separate `<wcs-credential>` instances
96
- * (one for get, one for store) rather than reworking the Core.
150
+ * Note the cancellation signal is **`NotAllowedError`, NOT `AbortError`**: unlike
151
+ * Web Share / Contact Picker, `credentials.get()/store()` reject with
152
+ * `NotAllowedError` when the user dismisses the native chooser. That maps to
153
+ * `cancelled`; every other name flows to `error`/`errorInfo`.
97
154
  */
98
155
  declare class CredentialCore extends EventTarget {
99
156
  static wcBindable: IWcBindable;
157
+ private static readonly REQUIRED_CAPABILITIES;
100
158
  private _target;
101
159
  private _value;
102
160
  private _loading;
103
161
  private _error;
104
162
  private _cancelled;
105
- private _gen;
163
+ private _errorInfo;
164
+ private _lane;
106
165
  private _ready;
107
166
  constructor(target?: EventTarget);
108
167
  get ready(): Promise<void>;
@@ -110,37 +169,52 @@ declare class CredentialCore extends EventTarget {
110
169
  get loading(): boolean;
111
170
  get error(): any;
112
171
  get cancelled(): boolean;
172
+ /**
173
+ * The last failure's serializable `WcsIoErrorInfo` (stable `code` / `phase` /
174
+ * `recoverable` / `capabilityId`), or null. Exposed as an additive wc-bindable
175
+ * property (event `wcs-credential:error-info-changed`); the existing `error`
176
+ * property/event are unchanged. A `NotAllowedError` user cancellation is
177
+ * `cancelled`, not `errorInfo`.
178
+ */
179
+ get errorInfo(): WcsIoErrorInfo | null;
180
+ /**
181
+ * Whether the required platform capability (`web.credentials`) is available right
182
+ * now — decided by call-time feature detection, not User-Agent. Core-only,
183
+ * additive.
184
+ */
185
+ get supported(): boolean;
186
+ /**
187
+ * Full platform assessment (availability / readiness / preconditions), probed at
188
+ * call time. Core-only opt-in dev / sidecar view.
189
+ */
190
+ get platformAssessment(): PlatformAssessment;
113
191
  observe(): Promise<void>;
114
192
  dispose(): void;
193
+ private _commitStep;
115
194
  private _setLoading;
116
195
  private _setValue;
117
196
  private _setError;
118
197
  private _setCancelled;
119
- private _api;
198
+ private _setErrorInfo;
199
+ private _commitErrorInfo;
120
200
  private _normalizeError;
121
201
  private _isCancellation;
202
+ private _run;
122
203
  /**
123
- * `get(options)` — v1 scope excludes `publicKey` (WebAuthn). If present, it
124
- * is stripped and the call surfaces a scope-violation `error` instead of
125
- * forwarding it to the platform API (which would accidentally support
126
- * WebAuthn through a side door). `navigator.credentials.get()` does not
127
- * require a user gesture (unlike Web Share/Fullscreen), so this can be
128
- * invoked automatically on page load for a "silent sign-in" flow.
204
+ * `get(options)` — v1 scope excludes `publicKey` (WebAuthn). If present, it is
205
+ * stripped and the call surfaces a scope-violation `error` instead of forwarding
206
+ * it to the platform API. `navigator.credentials.get()` does not require a user
207
+ * gesture, so this can be invoked automatically on page load for silent sign-in.
129
208
  */
130
209
  get(options?: CredentialGetOptions & {
131
210
  publicKey?: unknown;
132
211
  }): Promise<Credential | null>;
133
212
  /**
134
- * `store(credential)` — shares the same single `_gen` as `get()` (see class
135
- * docs). `navigator.credentials.store()` resolves `Promise<void>` (per
136
- * `lib.dom.d.ts`) there is no payload to read off the API, so `value` is
137
- * synthesized as an echo of the caller's `credential`, mirroring
138
- * `ShareCore.share()`'s same accommodation for `navigator.share()`.
139
- *
140
- * A `PublicKeyCredential` (`type === "public-key"`, WebAuthn) is rejected as a
141
- * scope violation before touching the platform API — the same v1 boundary
142
- * `get()` enforces on the `publicKey` option (docs/credential-tag-design.md
143
- * §3.2), so this node never becomes a WebAuthn store backdoor.
213
+ * `store(credential)` — shares the same single lane as `get()`.
214
+ * `navigator.credentials.store()` resolves `Promise<void>`, so `value` is
215
+ * synthesized as an echo of the caller's `credential`. A `PublicKeyCredential`
216
+ * (`type === "public-key"`, WebAuthn) is rejected as a scope violation before
217
+ * touching the platform API.
144
218
  */
145
219
  store(credential: StorableCredential): Promise<Credential | null>;
146
220
  }
@@ -167,6 +241,7 @@ declare class WcsCredential extends HTMLElement {
167
241
  get loading(): boolean;
168
242
  get error(): any;
169
243
  get cancelled(): boolean;
244
+ get errorInfo(): WcsIoErrorInfo | null;
170
245
  get connectedCallbackPromise(): Promise<void>;
171
246
  get(options?: CredentialGetOptions): Promise<Credential | null>;
172
247
  store(credential: StorableCredential): Promise<Credential | null>;
@@ -174,5 +249,23 @@ declare class WcsCredential extends HTMLElement {
174
249
  disconnectedCallback(): void;
175
250
  }
176
251
 
177
- export { CredentialCore, WcsCredential, bootstrapCredential, getConfig };
178
- export type { CredentialGetOptions, IWritableConfig, IWritableTagNames, StorableCredential, WcsCredentialCoreValues, WcsCredentialValues };
252
+ /**
253
+ * credentialCapabilities.ts
254
+ *
255
+ * Credential Management node 固有の capability registry と error code。汎用の assess
256
+ * 機構・型は `./platformCapability.js`(/io-core/ から copy-distribution される生成
257
+ * ファイル)から import する。node 固有の宣言はこのハンドライトファイルに置き、生成
258
+ * コピーとは分離する。
259
+ */
260
+
261
+ /** 安定した credential error code(taxonomy)。値は公開キーとして固定。 */
262
+ declare const WCS_CREDENTIAL_ERROR_CODE: {
263
+ readonly CapabilityMissing: "capability-missing";
264
+ /** WebAuthn(publicKey) は v1 スコープ外 — get()/store() 双方で拒否する。 */
265
+ readonly OutOfScope: "out-of-scope";
266
+ /** get()/store() の真のプラットフォーム失敗(NotAllowedError=cancelled は除く)。 */
267
+ readonly CredentialFailed: "credential-failed";
268
+ };
269
+
270
+ export { CredentialCore, WCS_CREDENTIAL_ERROR_CODE, WcsCredential, bootstrapCredential, getConfig };
271
+ export type { CredentialGetOptions, IWritableConfig, IWritableTagNames, StorableCredential, WcsCredentialCoreValues, WcsCredentialValues, WcsIoErrorInfo, WcsIoErrorPhase };