@authhero/adapter-interfaces 3.10.0 → 3.12.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.
@@ -0,0 +1,49 @@
1
+ /**
2
+ * Date conversion utilities shared by the SQL adapters (kysely, drizzle).
3
+ *
4
+ * Databases may hold timestamps in either of two formats during migration:
5
+ * - Old format: varchar(35) ISO 8601 strings (e.g., "2024-01-15T10:30:00.000Z")
6
+ * - New format: bigint Unix timestamps in milliseconds (e.g., 1705315800000),
7
+ * stored in `_ts`-suffixed columns
8
+ *
9
+ * The adapter interface always uses ISO strings, so adapters convert:
10
+ * - On READ: detect the stored format and convert to an ISO string
11
+ * - On WRITE: write as bigint timestamp (new format)
12
+ *
13
+ * This allows zero-downtime migration where:
14
+ * 1. Deploy code that reads both formats, writes new format
15
+ * 2. Run migration to convert existing data
16
+ * 3. (Optional) Remove old format support after migration completes
17
+ */
18
+ /**
19
+ * Type for a date field that could be either format from the database
20
+ */
21
+ export type DbDateField = string | number | null | undefined;
22
+ /**
23
+ * Convert a database date field (either format) to an ISO string for the
24
+ * adapter interface. Returns undefined if the value is null/undefined/empty.
25
+ */
26
+ export declare function dbDateToIso(value: DbDateField): string | undefined;
27
+ /**
28
+ * Convert a database date field to ISO string, with a required fallback.
29
+ * Use this for non-nullable date fields like created_at.
30
+ */
31
+ export declare function dbDateToIsoRequired(value: DbDateField, fallback?: string): string;
32
+ /**
33
+ * Convert an ISO string from the adapter interface to a bigint timestamp
34
+ * for writing to the database.
35
+ */
36
+ export declare function isoToDbDate(isoString: string | null | undefined): number | null;
37
+ /**
38
+ * Get current timestamp as ISO string (for adapter interface)
39
+ */
40
+ export declare function nowIso(): string;
41
+ /**
42
+ * Convert date fields from DB format to adapter format (ISO strings).
43
+ * Strips the _ts suffix from column names (e.g., created_at_ts -> created_at).
44
+ * @param row - The database row object
45
+ * @param requiredColumns - Columns that must have a value (will use fallback if null)
46
+ * @param optionalColumns - Columns that can be undefined
47
+ * @returns Object with converted date fields (with _ts suffix stripped)
48
+ */
49
+ export declare function convertDatesToAdapter<T extends Record<string, DbDateField>, R extends Extract<keyof T, string>, O extends Extract<keyof T, string> = never>(row: T, requiredColumns: R[], optionalColumns?: O[]): Record<string, string | undefined>;
@@ -0,0 +1,7 @@
1
+ /**
2
+ * Helpers shared by the SQL adapters (kysely, drizzle), published as the
3
+ * `@authhero/adapter-interfaces/sql` subpath so they stay out of the main
4
+ * adapter-contract surface: non-SQL adapters (e.g. DynamoDB) never see them.
5
+ */
6
+ export * from "./dates";
7
+ export * from "./transform";
@@ -0,0 +1,62 @@
1
+ /**
2
+ * Row/entity transformation helpers shared by the SQL adapters (kysely,
3
+ * drizzle). They convert between the adapter interface's rich entity shapes
4
+ * (nested objects, booleans, optional fields) and the flat SQL row shapes
5
+ * (JSON strings, 0/1 integers, no undefined values).
6
+ */
7
+ /**
8
+ * Stringify a value to JSON if it's defined, otherwise return undefined.
9
+ * This is useful for converting objects to JSON strings for database storage.
10
+ */
11
+ export declare function stringifyIfDefined<T>(value: T | undefined): string | undefined;
12
+ /**
13
+ * Stringify multiple properties of an object to JSON strings.
14
+ * Only properties that are defined will be stringified.
15
+ *
16
+ * @param obj - The source object containing properties to stringify
17
+ * @param properties - Array of property names to stringify
18
+ * @param target - The target object to write stringified values to (defaults to a new object based on obj)
19
+ * @returns The target object with stringified properties
20
+ *
21
+ * @example
22
+ * const source = { flags: { enabled: true }, sessions: { timeout: 300 }, name: "Test" };
23
+ * const result = stringifyProperties(source, ['flags', 'sessions']);
24
+ * // result = { flags: '{"enabled":true}', sessions: '{"timeout":300}', name: "Test" }
25
+ */
26
+ type StringifiedProperties<T, K extends keyof T> = {
27
+ [P in keyof T]: P extends K ? undefined extends T[P] ? string | undefined : string : T[P];
28
+ };
29
+ export declare function stringifyProperties<T extends Record<string, unknown>, K extends keyof T & string>(obj: T, properties: K[]): StringifiedProperties<T, K>;
30
+ export declare function stringifyProperties<T extends Record<string, unknown>, U extends Record<string, unknown>>(obj: T, properties: (keyof T & string)[], target: U): U;
31
+ /**
32
+ * Convert boolean properties to integers (1 for true, 0 for false).
33
+ * Only properties that are defined will be converted.
34
+ *
35
+ * @param source - The source object containing boolean properties to convert
36
+ * @param properties - Array of property names to convert
37
+ * @param target - The target object to write integer values to (defaults to source)
38
+ *
39
+ * @example
40
+ * const source = { enabled: true, active: false, name: "Test" };
41
+ * const result = {};
42
+ * booleanToInt(source, ['enabled', 'active'], result);
43
+ * // result = { enabled: 1, active: 0 }
44
+ */
45
+ export declare function booleanToInt<T extends Record<string, unknown>>(source: Partial<T>, properties: (keyof T & string)[], target?: Record<string, unknown>): void;
46
+ /**
47
+ * Remove undefined and null properties from an object.
48
+ * This keeps the SQL payload clean by only including defined values.
49
+ */
50
+ export declare function removeUndefinedAndNull<T extends Record<string, unknown>>(obj: T): Partial<T>;
51
+ /**
52
+ * Remove null properties from an object recursively. Used when mapping SQL
53
+ * rows (where missing values are NULL) back to adapter entities (where they
54
+ * are absent).
55
+ */
56
+ export declare function removeNullProperties<T>(obj: unknown): T;
57
+ /**
58
+ * Get a COUNT(*) result as an integer regardless of how the DB driver
59
+ * returns it (string, number, or bigint).
60
+ */
61
+ export declare function getCountAsInt(count: string | number | bigint): number;
62
+ export {};
@@ -0,0 +1,16 @@
1
+ /**
2
+ * Base32 (RFC 4648 §6, uppercase alphabet), the canonical implementation
3
+ * for the AuthHero packages. Replaces the `oslo/encoding` dependency we
4
+ * are migrating away from.
5
+ *
6
+ * The primary consumer is TOTP secret handling (RFC 6238 secrets are
7
+ * conventionally shared as unpadded base32). Encoding is padding-free;
8
+ * decoding is lenient and accepts input with or without padding.
9
+ */
10
+ /** Encode raw bytes as a padding-free base32 string. */
11
+ export declare function encodeBase32(bytes: Uint8Array): string;
12
+ /** Decode a base32 string (with or without padding, case-insensitive)
13
+ * back to raw bytes. Throws on non-canonical input: characters outside
14
+ * the alphabet, impossible unpadded lengths, or non-zero trailing bits —
15
+ * so distinct malformed strings can never normalize to the same bytes. */
16
+ export declare function decodeBase32(input: string): Uint8Array;
@@ -0,0 +1,13 @@
1
+ /**
2
+ * Standard base64 (RFC 4648 §4), the canonical implementation for the
3
+ * AuthHero packages (see base64url.ts for the URL-safe variant). Replaces
4
+ * the `oslo/encoding` dependency we are migrating away from.
5
+ *
6
+ * Encoding emits padding ("=") to match the conventional wire format
7
+ * (PEM bodies, `openssl rand -base64` keys). Decoding is lenient and
8
+ * accepts input with or without padding.
9
+ */
10
+ /** Encode raw bytes as a padded standard-base64 string. */
11
+ export declare function encodeBase64(bytes: Uint8Array): string;
12
+ /** Decode a standard-base64 string (with or without padding) to raw bytes. */
13
+ export declare function decodeBase64(input: string): Uint8Array;
@@ -6,6 +6,13 @@ export interface CursorPayload {
6
6
  s?: string | number | null;
7
7
  /** Id of the last row of the previous page — the unique tiebreaker. */
8
8
  i: string;
9
+ /**
10
+ * Sort spec the cursor was minted under (e.g. `date:desc`). Set by endpoints
11
+ * that honor a caller-chosen sort in checkpoint mode, so a token replayed
12
+ * with a different sort is rejected instead of silently returning pages from
13
+ * the wrong position. Absent on fixed-sort endpoints.
14
+ */
15
+ k?: string;
9
16
  }
10
17
  /**
11
18
  * Encode a keyset position into an opaque cursor token suitable for returning
@@ -0,0 +1,8 @@
1
+ /**
2
+ * Lowercase hex encoding, the canonical implementation for the AuthHero
3
+ * packages. Replaces the `oslo/encoding` dependency we are migrating
4
+ * away from.
5
+ */
6
+ /** Encode bytes as a lowercase hex string. Accepts an ArrayBuffer so
7
+ * Web Crypto digest/thumbprint results can be passed directly. */
8
+ export declare function encodeHex(data: Uint8Array | ArrayBuffer): string;
@@ -3,4 +3,8 @@ export * from "./passthrough";
3
3
  export * from "./connection-attributes";
4
4
  export * from "./guards";
5
5
  export * from "./base64url";
6
+ export * from "./base64";
7
+ export * from "./base32";
8
+ export * from "./hex";
6
9
  export * from "./cursor";
10
+ export * from "./lucene";
@@ -0,0 +1,6 @@
1
+ /**
2
+ * Shared pieces of the Lucene-style `q` filter handling. The SQL generation
3
+ * itself is ORM-specific and lives in each adapter; what is shared here is
4
+ * the query-string sanitization that enforces the tenant boundary.
5
+ */
6
+ export declare function sanitizeLuceneQuery(query: string, allowedFields: string[]): string;
package/package.json CHANGED
@@ -11,7 +11,7 @@
11
11
  "type": "git",
12
12
  "url": "https://github.com/markusahlstrand/authhero"
13
13
  },
14
- "version": "3.10.0",
14
+ "version": "3.12.0",
15
15
  "files": [
16
16
  "dist"
17
17
  ],
@@ -20,9 +20,14 @@
20
20
  "types": "dist/adapter-interfaces.d.ts",
21
21
  "exports": {
22
22
  ".": {
23
+ "types": "./dist/adapter-interfaces.d.ts",
23
24
  "require": "./dist/adapter-interfaces.cjs",
24
- "import": "./dist/adapter-interfaces.mjs",
25
- "types": "./dist/adapter-interfaces.d.ts"
25
+ "import": "./dist/adapter-interfaces.mjs"
26
+ },
27
+ "./sql": {
28
+ "types": "./dist/sql.d.ts",
29
+ "require": "./dist/sql.cjs",
30
+ "import": "./dist/sql.mjs"
26
31
  }
27
32
  },
28
33
  "devDependencies": {