@yielded/auth-react-native 0.1.0-beta.20 → 0.1.0-beta.22

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.
@@ -39,8 +39,8 @@ const environment = Effect.sync(() => {
39
39
  supported: false,
40
40
  exclusions: false
41
41
  };
42
- const [major = 0, minor = 0] = Schema.decodeUnknownSync(Schema.String.check(Schema.isPattern(/^\d+(?:\.\d+){0,2}$/)))(Platform.Version).split(".").map(Number);
43
- const supported = Schema.decodeUnknownSync(Schema.Boolean)(Passkey.isSupported());
42
+ const [major = 0, minor = 0] = Schema.decodeSync(Schema.String.check(Schema.isPattern(/^\d+(?:\.\d+){0,2}$/)))(Platform.Version).split(".").map(Number);
43
+ const supported = Schema.decodeSync(Schema.Boolean)(Passkey.isSupported());
44
44
  return {
45
45
  supported: major >= 16 && supported,
46
46
  exclusions: major > 17 || major === 17 && minor >= 4
@@ -1 +1 @@
1
- {"version":3,"file":"react-native-passkey.mjs","names":[],"sources":["../../src/internal/react-native-passkey.ts"],"sourcesContent":["import {\n PasskeyAuthenticationStarted,\n PasskeyRegistrationStarted,\n snapshotPasskey,\n} from \"@yielded/auth/Passkey\";\nimport { reportAuthFailure } from \"@yielded/auth/Persistence\";\nimport { Cause, DateTime, Effect, Layer, Predicate, Redacted, Schema } from \"effect\";\nimport { Platform } from \"react-native\";\nimport { Passkey, type PasskeyCreateRequest, type PasskeyGetRequest } from \"react-native-passkey\";\n\nimport {\n PasskeyReactNativeAuthentication,\n PasskeyReactNativeBusy,\n type PasskeyReactNativeFailure,\n PasskeyReactNativeInputRejected,\n PasskeyReactNativeInvalidResponse,\n PasskeyReactNativeNotCompleted,\n PasskeyReactNativeRegistration,\n PasskeyReactNativeUnavailable,\n PasskeyReactNativeUnsupported,\n} from \"./models\";\nimport { PasskeyReactNative } from \"./PasskeyReactNative\";\nimport {\n authenticationWire,\n nativeAuthentication,\n nativeRegistration,\n registrationWire,\n} from \"./wire\";\n\ntype Native = PasskeyReactNative[\"Service\"];\nconst unavailable = () => new PasskeyReactNativeUnavailable({});\nconst rejected = () => new PasskeyReactNativeInputRejected({});\nconst invalid = () => new PasskeyReactNativeInvalidResponse({});\nconst timedOut = () => new PasskeyReactNativeNotCompleted({ reason: \"timed-out\" });\n\nconst redactDefects =\n <Failure>(failure: () => Failure) =>\n <A, E, R>(effect: Effect.Effect<A, E, R>) =>\n effect.pipe(\n Effect.catchCause((cause): Effect.Effect<never, E | Failure> =>\n Cause.hasDies(cause)\n ? reportAuthFailure(\"passkey-react-native\", cause).pipe(\n Effect.andThen(Effect.fail(failure())),\n )\n : Effect.failCause(cause),\n ),\n );\n\nconst unexpected = redactDefects(unavailable);\n\nconst timeout = Schema.Int.check(Schema.isBetween({ minimum: 1, maximum: 300000 }));\n\nconst registrationInput = Schema.Struct({\n ...PasskeyRegistrationStarted.fields,\n options: Schema.Struct({ ...PasskeyRegistrationStarted.fields.options.fields, timeout }),\n});\n\nconst authenticationInput = Schema.Struct({\n started: Schema.Struct({\n ...PasskeyAuthenticationStarted.fields,\n options: Schema.Struct({ ...PasskeyAuthenticationStarted.fields.options.fields, timeout }),\n }),\n mediation: Schema.Literals([\"required\", \"conditional\"]),\n});\n\nconst environment = Effect.sync(() => {\n if (Platform.OS !== \"ios\") return { supported: false, exclusions: false };\n\n // The maintained helper only checks OS version (and includes iOS 15).\n // Decode platform metadata before applying this adapter's iOS 16 minimum.\n // eslint-disable-next-line no-restricted-properties\n const version = Schema.decodeUnknownSync(\n Schema.String.check(Schema.isPattern(/^\\d+(?:\\.\\d+){0,2}$/)),\n )(Platform.Version);\n\n const [major = 0, minor = 0] = version.split(\".\").map(Number);\n // eslint-disable-next-line no-restricted-properties\n const supported = Schema.decodeUnknownSync(Schema.Boolean)(Passkey.isSupported());\n\n return {\n supported: major >= 16 && supported,\n exclusions: major > 17 || (major === 17 && minor >= 4),\n };\n}).pipe(unexpected);\n\ninterface Lease {\n phase: \"pre-native\" | \"native\" | \"settled\";\n listening: boolean;\n}\n// The peer has one native resolver. Coordinate every instance of this installed\n// module; callers must not also use the peer directly or load duplicate copies.\nlet activeLease: Lease | undefined;\n\nconst settle = (lease: Lease): void => {\n lease.phase = \"settled\";\n if (activeLease === lease) activeLease = undefined;\n};\n\nconst acquire = Effect.gen(function* () {\n if (activeLease !== undefined) return yield* new PasskeyReactNativeBusy({});\n const lease: Lease = { phase: \"pre-native\", listening: true };\n\n activeLease = lease;\n\n return lease;\n});\n\nconst release = (lease: Lease) =>\n Effect.sync(() => {\n lease.listening = false;\n // There is no cancel API. Free only a request that has not reached native.\n if (lease.phase === \"pre-native\") settle(lease);\n });\n\nconst nativeFailure = (value: unknown): Effect.Effect<never, PasskeyReactNativeFailure> =>\n Effect.suspend((): Effect.Effect<never, PasskeyReactNativeFailure> => {\n if (!Predicate.isObject(value)) return Effect.die(value);\n // Inspect only the normalized code; never copy message, native stack, or cause.\n // eslint-disable-next-line no-restricted-properties\n const code = Schema.decodeUnknownOption(Schema.String)(value.error);\n\n if (code._tag === \"None\") return Effect.die(value);\n switch (code.value) {\n case \"NotSupported\":\n return Effect.fail(new PasskeyReactNativeUnsupported({}));\n case \"InvalidChallenge\":\n case \"InvalidUserId\":\n return Effect.fail(rejected());\n case \"UserCancelled\":\n return Effect.fail(new PasskeyReactNativeNotCompleted({ reason: \"cancelled\" }));\n case \"NoCredentials\":\n return Effect.fail(new PasskeyReactNativeNotCompleted({ reason: \"no-credentials\" }));\n case \"CredentialAlreadyExists\":\n return Effect.fail(new PasskeyReactNativeNotCompleted({ reason: \"credential-exists\" }));\n case \"Interrupted\":\n return Effect.fail(new PasskeyReactNativeNotCompleted({ reason: \"interrupted\" }));\n case \"TimedOut\":\n return Effect.fail(timedOut());\n case \"RequestFailed\":\n return Effect.fail(new PasskeyReactNativeNotCompleted({ reason: \"request-failed\" }));\n default:\n return Effect.die(value);\n }\n });\n\nconst native = (lease: Lease, call: () => Promise<unknown>) =>\n Effect.callback<unknown, PasskeyReactNativeFailure>((resume, signal) => {\n if (\n signal.aborted ||\n !lease.listening ||\n lease.phase !== \"pre-native\" ||\n activeLease !== lease\n ) {\n resume(Effect.die(new Error(\"Invalid passkey native lease\")));\n\n return;\n }\n lease.phase = \"native\";\n try {\n // The caller owns classification and diagnostic reporting. Callbacks only\n // settle the guard and resume a live caller. After interruption they discard\n // the outcome without inspecting it or retaining/running a scoped logger.\n void Promise.resolve(call()).then(\n (value) => {\n try {\n settle(lease);\n if (!signal.aborted && lease.listening) resume(Effect.succeed(value));\n } catch {\n /* A detached handler must not reject. */\n }\n },\n (error) => {\n try {\n settle(lease);\n if (!signal.aborted && lease.listening) resume(nativeFailure(error));\n } catch {\n /* A detached handler must not reject. */\n }\n },\n );\n } catch (error) {\n settle(lease);\n resume(Effect.die(error));\n }\n });\n\nconst remaining = Effect.fnUntraced(function* (deadline: number) {\n const duration = deadline - DateTime.toEpochMillis(yield* DateTime.now);\n\n if (duration <= 0) return yield* timedOut();\n\n return Math.max(1, Math.floor(duration));\n});\n\nconst runCeremony = Effect.fnUntraced(function* <A>(\n started: { readonly expiresAtMillis: number; readonly options: { readonly timeout: number } },\n use: (lease: Lease, deadline: number) => Effect.Effect<A, PasskeyReactNativeFailure>,\n) {\n const now = DateTime.toEpochMillis(yield* DateTime.now);\n\n if (started.expiresAtMillis <= now) return yield* rejected();\n const deadline = Math.min(started.expiresAtMillis, now + started.options.timeout);\n\n return yield* Effect.scoped(\n Effect.gen(function* () {\n const lease = yield* Effect.acquireRelease(acquire, release);\n const duration = yield* remaining(deadline);\n\n return yield* use(lease, deadline).pipe(\n Effect.timeoutOrElse({ duration, orElse: () => Effect.fail(timedOut()) }),\n );\n }),\n );\n});\n\nconst decodeResponse = <S extends Schema.Codec<unknown, unknown, never, never>>(\n schema: S,\n value: unknown,\n) =>\n // Peer declarations are not validation. Parse bounded base64url fields and\n // discard unknown fields before constructing the server's JSON envelope.\n // eslint-disable-next-line no-restricted-properties\n Schema.decodeUnknownEffect(schema)(value).pipe(Effect.mapError(invalid), redactDefects(invalid));\n\n/** Creates the iOS adapter. Ceremonies own their scopes; construction performs no native I/O. */\nexport const make = (): Effect.Effect<Native> =>\n Effect.sync(() => {\n const register = Effect.fnUntraced(function* (input: Parameters<Native[\"register\"]>[0]) {\n const started = yield* snapshotPasskey(registrationInput, input).pipe(\n Effect.mapError(rejected),\n );\n\n const env = yield* environment;\n\n if (\n !env.supported ||\n !started.options.pubKeyCredParams.some(({ alg }) => alg === -7) ||\n (started.options.excludeCredentials.length > 0 && !env.exclusions)\n )\n return yield* new PasskeyReactNativeUnsupported({});\n\n return yield* runCeremony(started, (lease, deadline) =>\n Effect.gen(function* () {\n const options = started.options;\n\n const request: PasskeyCreateRequest = {\n ...options,\n rp: { ...options.rp },\n user: { ...options.user },\n authenticatorSelection: { ...options.authenticatorSelection },\n pubKeyCredParams: options.pubKeyCredParams.map((value) => ({ ...value })),\n excludeCredentials: options.excludeCredentials.map((value) => ({ ...value })),\n timeout: yield* remaining(deadline),\n };\n\n // The platform path preserves the required attestation: \"none\" policy.\n const credential = yield* decodeResponse(\n nativeRegistration,\n yield* native(lease, () => Passkey.createPlatformKey(request)),\n );\n\n const response = yield* Schema.encodeEffect(registrationWire)({\n id: credential.id,\n rawId: credential.rawId,\n type: \"public-key\",\n response: credential.response,\n clientExtensionResults: {},\n }).pipe(Effect.mapError(invalid));\n\n yield* remaining(deadline);\n\n return yield* snapshotPasskey(PasskeyReactNativeRegistration, {\n flowId: started.flowId,\n response: Redacted.make(response),\n }).pipe(Effect.mapError(invalid));\n }),\n );\n }, unexpected);\n\n const authenticate = Effect.fnUntraced(function* (\n input: Parameters<Native[\"authenticate\"]>[0],\n ) {\n const { started, mediation } = yield* snapshotPasskey(authenticationInput, input).pipe(\n Effect.mapError(rejected),\n );\n\n if (mediation === \"conditional\" || !(yield* environment).supported)\n return yield* new PasskeyReactNativeUnsupported({});\n\n return yield* runCeremony(started, (lease, deadline) =>\n Effect.gen(function* () {\n const request: PasskeyGetRequest = {\n ...started.options,\n allowCredentials: started.options.allowCredentials.map((value) => ({ ...value })),\n timeout: yield* remaining(deadline),\n };\n\n const credential = yield* decodeResponse(\n nativeAuthentication,\n yield* native(lease, () => Passkey.get(request)),\n );\n\n const { userHandle, ...responseFields } = credential.response;\n\n const response = yield* Schema.encodeEffect(authenticationWire)({\n id: credential.id,\n rawId: credential.rawId ?? credential.id,\n type: \"public-key\",\n response: {\n ...responseFields,\n ...(userHandle === null || userHandle === undefined ? {} : { userHandle }),\n },\n clientExtensionResults: {},\n }).pipe(Effect.mapError(invalid));\n\n yield* remaining(deadline);\n\n return yield* snapshotPasskey(PasskeyReactNativeAuthentication, {\n flowId: started.flowId,\n response: Redacted.make(response),\n }).pipe(Effect.mapError(invalid));\n }),\n );\n }, unexpected);\n\n return PasskeyReactNative.of({\n register,\n authenticate,\n capabilities: environment.pipe(\n Effect.map(({ supported }) => ({\n supported,\n conditionalGet: \"unsupported\" as const,\n cancellation: \"unsupported\" as const,\n })),\n ),\n });\n });\n\nexport const layer: Layer.Layer<PasskeyReactNative> = Layer.effect(PasskeyReactNative, make());\n"],"mappings":"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"}
1
+ {"version":3,"file":"react-native-passkey.mjs","names":[],"sources":["../../src/internal/react-native-passkey.ts"],"sourcesContent":["import {\n PasskeyAuthenticationStarted,\n PasskeyRegistrationStarted,\n snapshotPasskey,\n} from \"@yielded/auth/Passkey\";\nimport { reportAuthFailure } from \"@yielded/auth/Persistence\";\nimport { Cause, DateTime, Effect, Layer, Predicate, Redacted, Schema } from \"effect\";\nimport { Platform } from \"react-native\";\nimport { Passkey, type PasskeyCreateRequest, type PasskeyGetRequest } from \"react-native-passkey\";\n\nimport {\n PasskeyReactNativeAuthentication,\n PasskeyReactNativeBusy,\n type PasskeyReactNativeFailure,\n PasskeyReactNativeInputRejected,\n PasskeyReactNativeInvalidResponse,\n PasskeyReactNativeNotCompleted,\n PasskeyReactNativeRegistration,\n PasskeyReactNativeUnavailable,\n PasskeyReactNativeUnsupported,\n} from \"./models\";\nimport { PasskeyReactNative } from \"./PasskeyReactNative\";\nimport {\n authenticationWire,\n nativeAuthentication,\n nativeRegistration,\n registrationWire,\n} from \"./wire\";\n\ntype Native = PasskeyReactNative[\"Service\"];\nconst unavailable = () => new PasskeyReactNativeUnavailable({});\nconst rejected = () => new PasskeyReactNativeInputRejected({});\nconst invalid = () => new PasskeyReactNativeInvalidResponse({});\nconst timedOut = () => new PasskeyReactNativeNotCompleted({ reason: \"timed-out\" });\n\nconst redactDefects =\n <Failure>(failure: () => Failure) =>\n <A, E, R>(effect: Effect.Effect<A, E, R>) =>\n effect.pipe(\n Effect.catchCause((cause): Effect.Effect<never, E | Failure> =>\n Cause.hasDies(cause)\n ? reportAuthFailure(\"passkey-react-native\", cause).pipe(\n Effect.andThen(Effect.fail(failure())),\n )\n : Effect.failCause(cause),\n ),\n );\n\nconst unexpected = redactDefects(unavailable);\n\nconst timeout = Schema.Int.check(Schema.isBetween({ minimum: 1, maximum: 300000 }));\n\nconst registrationInput = Schema.Struct({\n ...PasskeyRegistrationStarted.fields,\n options: Schema.Struct({ ...PasskeyRegistrationStarted.fields.options.fields, timeout }),\n});\n\nconst authenticationInput = Schema.Struct({\n started: Schema.Struct({\n ...PasskeyAuthenticationStarted.fields,\n options: Schema.Struct({ ...PasskeyAuthenticationStarted.fields.options.fields, timeout }),\n }),\n mediation: Schema.Literals([\"required\", \"conditional\"]),\n});\n\nconst environment = Effect.sync(() => {\n if (Platform.OS !== \"ios\") return { supported: false, exclusions: false };\n\n // The maintained helper only checks OS version (and includes iOS 15).\n // Decode platform metadata before applying this adapter's iOS 16 minimum.\n // eslint-disable-next-line no-restricted-properties\n const version = Schema.decodeSync(Schema.String.check(Schema.isPattern(/^\\d+(?:\\.\\d+){0,2}$/)))(\n Platform.Version,\n );\n\n const [major = 0, minor = 0] = version.split(\".\").map(Number);\n // eslint-disable-next-line no-restricted-properties\n const supported = Schema.decodeSync(Schema.Boolean)(Passkey.isSupported());\n\n return {\n supported: major >= 16 && supported,\n exclusions: major > 17 || (major === 17 && minor >= 4),\n };\n}).pipe(unexpected);\n\ninterface Lease {\n phase: \"pre-native\" | \"native\" | \"settled\";\n listening: boolean;\n}\n// The peer has one native resolver. Coordinate every instance of this installed\n// module; callers must not also use the peer directly or load duplicate copies.\nlet activeLease: Lease | undefined;\n\nconst settle = (lease: Lease): void => {\n lease.phase = \"settled\";\n if (activeLease === lease) activeLease = undefined;\n};\n\nconst acquire = Effect.gen(function* () {\n if (activeLease !== undefined) return yield* new PasskeyReactNativeBusy({});\n const lease: Lease = { phase: \"pre-native\", listening: true };\n\n activeLease = lease;\n\n return lease;\n});\n\nconst release = (lease: Lease) =>\n Effect.sync(() => {\n lease.listening = false;\n // There is no cancel API. Free only a request that has not reached native.\n if (lease.phase === \"pre-native\") settle(lease);\n });\n\nconst nativeFailure = (value: unknown): Effect.Effect<never, PasskeyReactNativeFailure> =>\n Effect.suspend((): Effect.Effect<never, PasskeyReactNativeFailure> => {\n if (!Predicate.isObject(value)) return Effect.die(value);\n // Inspect only the normalized code; never copy message, native stack, or cause.\n // eslint-disable-next-line no-restricted-properties\n const code = Schema.decodeUnknownOption(Schema.String)(value.error);\n\n if (code._tag === \"None\") return Effect.die(value);\n switch (code.value) {\n case \"NotSupported\":\n return Effect.fail(new PasskeyReactNativeUnsupported({}));\n case \"InvalidChallenge\":\n case \"InvalidUserId\":\n return Effect.fail(rejected());\n case \"UserCancelled\":\n return Effect.fail(new PasskeyReactNativeNotCompleted({ reason: \"cancelled\" }));\n case \"NoCredentials\":\n return Effect.fail(new PasskeyReactNativeNotCompleted({ reason: \"no-credentials\" }));\n case \"CredentialAlreadyExists\":\n return Effect.fail(new PasskeyReactNativeNotCompleted({ reason: \"credential-exists\" }));\n case \"Interrupted\":\n return Effect.fail(new PasskeyReactNativeNotCompleted({ reason: \"interrupted\" }));\n case \"TimedOut\":\n return Effect.fail(timedOut());\n case \"RequestFailed\":\n return Effect.fail(new PasskeyReactNativeNotCompleted({ reason: \"request-failed\" }));\n default:\n return Effect.die(value);\n }\n });\n\nconst native = (lease: Lease, call: () => Promise<unknown>) =>\n Effect.callback<unknown, PasskeyReactNativeFailure>((resume, signal) => {\n if (\n signal.aborted ||\n !lease.listening ||\n lease.phase !== \"pre-native\" ||\n activeLease !== lease\n ) {\n resume(Effect.die(new Error(\"Invalid passkey native lease\")));\n\n return;\n }\n lease.phase = \"native\";\n try {\n // The caller owns classification and diagnostic reporting. Callbacks only\n // settle the guard and resume a live caller. After interruption they discard\n // the outcome without inspecting it or retaining/running a scoped logger.\n void Promise.resolve(call()).then(\n (value) => {\n try {\n settle(lease);\n if (!signal.aborted && lease.listening) resume(Effect.succeed(value));\n } catch {\n /* A detached handler must not reject. */\n }\n },\n (error) => {\n try {\n settle(lease);\n if (!signal.aborted && lease.listening) resume(nativeFailure(error));\n } catch {\n /* A detached handler must not reject. */\n }\n },\n );\n } catch (error) {\n settle(lease);\n resume(Effect.die(error));\n }\n });\n\nconst remaining = Effect.fnUntraced(function* (deadline: number) {\n const duration = deadline - DateTime.toEpochMillis(yield* DateTime.now);\n\n if (duration <= 0) return yield* timedOut();\n\n return Math.max(1, Math.floor(duration));\n});\n\nconst runCeremony = Effect.fnUntraced(function* <A>(\n started: { readonly expiresAtMillis: number; readonly options: { readonly timeout: number } },\n use: (lease: Lease, deadline: number) => Effect.Effect<A, PasskeyReactNativeFailure>,\n) {\n const now = DateTime.toEpochMillis(yield* DateTime.now);\n\n if (started.expiresAtMillis <= now) return yield* rejected();\n const deadline = Math.min(started.expiresAtMillis, now + started.options.timeout);\n\n return yield* Effect.scoped(\n Effect.gen(function* () {\n const lease = yield* Effect.acquireRelease(acquire, release);\n const duration = yield* remaining(deadline);\n\n return yield* use(lease, deadline).pipe(\n Effect.timeoutOrElse({ duration, orElse: () => Effect.fail(timedOut()) }),\n );\n }),\n );\n});\n\nconst decodeResponse = <S extends Schema.Codec<unknown, unknown, never, never>>(\n schema: S,\n value: unknown,\n) =>\n // Peer declarations are not validation. Parse bounded base64url fields and\n // discard unknown fields before constructing the server's JSON envelope.\n // eslint-disable-next-line no-restricted-properties\n Schema.decodeUnknownEffect(schema)(value).pipe(Effect.mapError(invalid), redactDefects(invalid));\n\n/** Creates the iOS adapter. Ceremonies own their scopes; construction performs no native I/O. */\nexport const make = (): Effect.Effect<Native> =>\n Effect.sync(() => {\n const register = Effect.fnUntraced(function* (input: Parameters<Native[\"register\"]>[0]) {\n const started = yield* snapshotPasskey(registrationInput, input).pipe(\n Effect.mapError(rejected),\n );\n\n const env = yield* environment;\n\n if (\n !env.supported ||\n !started.options.pubKeyCredParams.some(({ alg }) => alg === -7) ||\n (started.options.excludeCredentials.length > 0 && !env.exclusions)\n )\n return yield* new PasskeyReactNativeUnsupported({});\n\n return yield* runCeremony(started, (lease, deadline) =>\n Effect.gen(function* () {\n const options = started.options;\n\n const request: PasskeyCreateRequest = {\n ...options,\n rp: { ...options.rp },\n user: { ...options.user },\n authenticatorSelection: { ...options.authenticatorSelection },\n pubKeyCredParams: options.pubKeyCredParams.map((value) => ({ ...value })),\n excludeCredentials: options.excludeCredentials.map((value) => ({ ...value })),\n timeout: yield* remaining(deadline),\n };\n\n // The platform path preserves the required attestation: \"none\" policy.\n const credential = yield* decodeResponse(\n nativeRegistration,\n yield* native(lease, () => Passkey.createPlatformKey(request)),\n );\n\n const response = yield* Schema.encodeEffect(registrationWire)({\n id: credential.id,\n rawId: credential.rawId,\n type: \"public-key\",\n response: credential.response,\n clientExtensionResults: {},\n }).pipe(Effect.mapError(invalid));\n\n yield* remaining(deadline);\n\n return yield* snapshotPasskey(PasskeyReactNativeRegistration, {\n flowId: started.flowId,\n response: Redacted.make(response),\n }).pipe(Effect.mapError(invalid));\n }),\n );\n }, unexpected);\n\n const authenticate = Effect.fnUntraced(function* (\n input: Parameters<Native[\"authenticate\"]>[0],\n ) {\n const { started, mediation } = yield* snapshotPasskey(authenticationInput, input).pipe(\n Effect.mapError(rejected),\n );\n\n if (mediation === \"conditional\" || !(yield* environment).supported)\n return yield* new PasskeyReactNativeUnsupported({});\n\n return yield* runCeremony(started, (lease, deadline) =>\n Effect.gen(function* () {\n const request: PasskeyGetRequest = {\n ...started.options,\n allowCredentials: started.options.allowCredentials.map((value) => ({ ...value })),\n timeout: yield* remaining(deadline),\n };\n\n const credential = yield* decodeResponse(\n nativeAuthentication,\n yield* native(lease, () => Passkey.get(request)),\n );\n\n const { userHandle, ...responseFields } = credential.response;\n\n const response = yield* Schema.encodeEffect(authenticationWire)({\n id: credential.id,\n rawId: credential.rawId ?? credential.id,\n type: \"public-key\",\n response: {\n ...responseFields,\n ...(userHandle === null || userHandle === undefined ? {} : { userHandle }),\n },\n clientExtensionResults: {},\n }).pipe(Effect.mapError(invalid));\n\n yield* remaining(deadline);\n\n return yield* snapshotPasskey(PasskeyReactNativeAuthentication, {\n flowId: started.flowId,\n response: Redacted.make(response),\n }).pipe(Effect.mapError(invalid));\n }),\n );\n }, unexpected);\n\n return PasskeyReactNative.of({\n register,\n authenticate,\n capabilities: environment.pipe(\n Effect.map(({ supported }) => ({\n supported,\n conditionalGet: \"unsupported\" as const,\n cancellation: \"unsupported\" as const,\n })),\n ),\n });\n });\n\nexport const layer: Layer.Layer<PasskeyReactNative> = Layer.effect(PasskeyReactNative, make());\n"],"mappings":"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"}
package/package.json CHANGED
@@ -1 +1 @@
1
- {"name":"@yielded/auth-react-native","version":"0.1.0-beta.20","dependencies":{"@yielded/auth":"0.1.0-beta.20"},"devDependencies":{"@effect/vitest":"4.0.0","effect":"4.0.0","expo":"54.0.37","expo-secure-store":"15.0.8","expo-web-browser":"15.0.11","react-native":"0.81.4","react-native-passkey":"3.6.2","typescript":"7.0.2","vite-plus":"0.3.3"},"peerDependencies":{"effect":"^4.0.0","expo-secure-store":"~15.0.8 || ~57.0.4","expo-web-browser":"~15.0.11 || ~57.0.3","react-native":">=0.81 <1","react-native-passkey":"~3.6.2"},"exports":{".":{"types":"./dist/index.d.mts","default":"./dist/index.mjs"},"./BrowserLogin":{"types":"./dist/BrowserLogin.d.mts","default":"./dist/BrowserLogin.mjs"}},"description":"iOS passkey and browser login adapters for Yielded Auth and React Native.","homepage":"https://yielded.dev/auth/","bugs":{"url":"https://github.com/yielded-dev/auth/issues"},"license":"MIT","repository":{"type":"git","url":"git+https://github.com/yielded-dev/auth.git","directory":"packages/auth-react-native"},"files":["dist","src"],"type":"module","sideEffects":[],"publishConfig":{"access":"public"},"scripts":{"build":"vp pack","check":"tsc --noEmit -p tsconfig.json","test":"vp test --passWithNoTests"},"peerDependenciesMeta":{"expo-secure-store":{"optional":true},"expo-web-browser":{"optional":true},"react-native-passkey":{"optional":true}}}
1
+ {"name":"@yielded/auth-react-native","version":"0.1.0-beta.22","dependencies":{"@yielded/auth":"0.1.0-beta.22"},"devDependencies":{"@effect/vitest":"4.0.0","effect":"4.0.0","expo":"54.0.37","expo-secure-store":"15.0.8","expo-web-browser":"15.0.11","react-native":"0.81.4","react-native-passkey":"3.6.2","typescript":"7.0.2","vite-plus":"0.3.3"},"peerDependencies":{"effect":"^4.0.0","expo-secure-store":"~15.0.8 || ~57.0.4","expo-web-browser":"~15.0.11 || ~57.0.3","react-native":">=0.81 <1","react-native-passkey":"~3.6.2"},"exports":{".":{"types":"./dist/index.d.mts","default":"./dist/index.mjs"},"./BrowserLogin":{"types":"./dist/BrowserLogin.d.mts","default":"./dist/BrowserLogin.mjs"}},"description":"iOS passkey and browser login adapters for Yielded Auth and React Native.","homepage":"https://yielded.dev/auth/","bugs":{"url":"https://github.com/yielded-dev/auth/issues"},"license":"MIT","repository":{"type":"git","url":"git+https://github.com/yielded-dev/auth.git","directory":"packages/auth-react-native"},"files":["dist","src"],"type":"module","sideEffects":[],"publishConfig":{"access":"public"},"scripts":{"build":"vp pack","check":"tsc --noEmit -p tsconfig.json","test":"vp test --passWithNoTests"},"peerDependenciesMeta":{"expo-secure-store":{"optional":true},"expo-web-browser":{"optional":true},"react-native-passkey":{"optional":true}}}
@@ -69,13 +69,13 @@ const environment = Effect.sync(() => {
69
69
  // The maintained helper only checks OS version (and includes iOS 15).
70
70
  // Decode platform metadata before applying this adapter's iOS 16 minimum.
71
71
  // eslint-disable-next-line no-restricted-properties
72
- const version = Schema.decodeUnknownSync(
73
- Schema.String.check(Schema.isPattern(/^\d+(?:\.\d+){0,2}$/)),
74
- )(Platform.Version);
72
+ const version = Schema.decodeSync(Schema.String.check(Schema.isPattern(/^\d+(?:\.\d+){0,2}$/)))(
73
+ Platform.Version,
74
+ );
75
75
 
76
76
  const [major = 0, minor = 0] = version.split(".").map(Number);
77
77
  // eslint-disable-next-line no-restricted-properties
78
- const supported = Schema.decodeUnknownSync(Schema.Boolean)(Passkey.isSupported());
78
+ const supported = Schema.decodeSync(Schema.Boolean)(Passkey.isSupported());
79
79
 
80
80
  return {
81
81
  supported: major >= 16 && supported,