@authhero/adapter-interfaces 3.10.0 → 3.11.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 {};
@@ -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
@@ -4,3 +4,4 @@ export * from "./connection-attributes";
4
4
  export * from "./guards";
5
5
  export * from "./base64url";
6
6
  export * from "./cursor";
7
+ 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.11.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": {