@lti-tool/postgresql 1.0.0 → 1.0.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.
Files changed (33) hide show
  1. package/CHANGELOG.md +6 -0
  2. package/README.md +294 -0
  3. package/dist/cacheConfig.d.ts +11 -0
  4. package/dist/cacheConfig.d.ts.map +1 -0
  5. package/dist/cacheConfig.js +14 -0
  6. package/dist/db/schema/clients.schema.d.ts +133 -0
  7. package/dist/db/schema/clients.schema.d.ts.map +1 -0
  8. package/dist/db/schema/clients.schema.js +13 -0
  9. package/dist/db/schema/deployments.schema.d.ts +97 -0
  10. package/dist/db/schema/deployments.schema.d.ts.map +1 -0
  11. package/dist/db/schema/deployments.schema.js +14 -0
  12. package/dist/db/schema/index.d.ts +6 -0
  13. package/dist/db/schema/index.d.ts.map +1 -0
  14. package/dist/db/schema/index.js +5 -0
  15. package/dist/db/schema/nonces.schema.d.ts +44 -0
  16. package/dist/db/schema/nonces.schema.d.ts.map +1 -0
  17. package/dist/db/schema/nonces.schema.js +5 -0
  18. package/dist/db/schema/registrationSessions.schema.d.ts +62 -0
  19. package/dist/db/schema/registrationSessions.schema.d.ts.map +1 -0
  20. package/dist/db/schema/registrationSessions.schema.js +8 -0
  21. package/dist/db/schema/sessions.schema.d.ts +62 -0
  22. package/dist/db/schema/sessions.schema.d.ts.map +1 -0
  23. package/dist/db/schema/sessions.schema.js +6 -0
  24. package/dist/index.d.ts +3 -0
  25. package/dist/index.d.ts.map +1 -0
  26. package/dist/index.js +1 -0
  27. package/dist/interfaces/postgresStorageConfig.d.ts +35 -0
  28. package/dist/interfaces/postgresStorageConfig.d.ts.map +1 -0
  29. package/dist/interfaces/postgresStorageConfig.js +1 -0
  30. package/dist/postgresStorage.d.ts +53 -0
  31. package/dist/postgresStorage.d.ts.map +1 -0
  32. package/dist/postgresStorage.js +443 -0
  33. package/package.json +1 -1
package/CHANGELOG.md CHANGED
@@ -1,5 +1,11 @@
1
1
  # @lti-tool/postgresql
2
2
 
3
+ ## 1.0.1
4
+
5
+ ### Patch Changes
6
+
7
+ - 834b75e: Add README file
8
+
3
9
  ## 1.0.0
4
10
 
5
11
  ### Major Changes
package/README.md ADDED
@@ -0,0 +1,294 @@
1
+ # @lti-tool/postgresql
2
+
3
+ <p align="center">Production-ready PostgreSQL storage adapter for LTI 1.3. Includes caching and optimized for AWS Lambda.</p>
4
+
5
+ <p align="center">
6
+ <a href="https://www.npmjs.com/package/@lti-tool/postgresql"><img alt="npm" src="https://img.shields.io/npm/v/%40lti-tool%2Fpostgresql" /></a>
7
+ </p>
8
+
9
+ ## Installation
10
+
11
+ ```bash
12
+ npm install @lti-tool/postgresql
13
+ ```
14
+
15
+ ## Quick Start
16
+
17
+ ```typescript
18
+ import { PostgresStorage } from '@lti-tool/postgresql';
19
+ import { LTITool } from '@lti-tool/core';
20
+
21
+ const storage = new PostgresStorage({
22
+ connectionUrl: process.env.DATABASE_URL!,
23
+ });
24
+
25
+ const ltiTool = new LTITool({
26
+ storage,
27
+ // ... other config
28
+ });
29
+ ```
30
+
31
+ ## Features
32
+
33
+ - **Production Ready** - Handles high-scale LTI deployments
34
+ - **Built-in Caching** - LRU cache for frequently accessed data
35
+ - **Type-safe** - Uses Drizzle ORM for database operations
36
+ - **Transaction Support** - Handles data integrity on deletes
37
+ - **Tuned Connection Pool Defaults** - Connection pool defaults based on hosting environment
38
+
39
+ ## API Reference
40
+
41
+ - [API Reference](https://docs.lti-tool.dev/modules/_lti-tool_postgresql.html) - Complete API documentation
42
+
43
+ ## Configuration
44
+
45
+ ### Using Drizzle Kit Push (Recommended for Development)
46
+
47
+ ```bash
48
+ # Set your DATABASE_URL
49
+ export DATABASE_URL="postgresql://user:password@host:port/database"
50
+
51
+ # Push schema to database
52
+ npx drizzle-kit push
53
+ ```
54
+
55
+ ### Using Migrations (Recommended for Production)
56
+
57
+ ```bash
58
+ # Apply migrations
59
+ npx drizzle-kit migrate
60
+ ```
61
+
62
+ ### PostgresStorageConfig
63
+
64
+ - **connectionUrl** (required): PostgreSQL connection URL
65
+ Format: `postgresql://user:password@host:port/database`
66
+ - **poolOptions** (optional): postgres.js connection options
67
+ - `max`: Max connections (auto: 1 for serverless, 10 for servers)
68
+ - `idleTimeout`: Idle timeout in seconds before connection is closed (default: 20)
69
+ - **nonceExpirationSeconds** (optional): Nonce TTL in seconds (default: 600)
70
+
71
+ - **logger** (optional): Pino logger for debugging
72
+
73
+ ## Database Schema
74
+
75
+ The adapter uses these tables:
76
+
77
+ - **clients**: LTI platform clients
78
+ Unique constraint: `(iss, clientId)`
79
+ - **deployments**: Platform deployments (many-to-one with clients)
80
+ Unique constraint: `(clientId, deploymentId)`
81
+ - **sessions**: LTI sessions with expiration
82
+ Indexed: `expiresAt`
83
+ - **nonces**: One-time use nonces
84
+ Primary key: `nonce`
85
+ Indexed: `expiresAt`
86
+ - **registration_sessions**: Dynamic registration sessions
87
+ Indexed: `expiresAt`
88
+
89
+ All tables use native PostgreSQL UUIDs for primary keys and include indexes for performance.
90
+
91
+ ### clients
92
+
93
+ | Column | Type | Constraints | Description |
94
+ | ---------- | ------------ | --------------------- | ------------------------------ |
95
+ | `id` | UUID | PRIMARY KEY, NOT NULL | Internal UUID for the client |
96
+ | `name` | VARCHAR(255) | NOT NULL | Human-readable platform name |
97
+ | `iss` | VARCHAR(255) | NOT NULL | Issuer URL (LMS platform) |
98
+ | `clientId` | VARCHAR(255) | NOT NULL | LMS-provided client identifier |
99
+ | `authUrl` | TEXT | NOT NULL | OAuth2 authorization endpoint |
100
+ | `tokenUrl` | TEXT | NOT NULL | OAuth2 token endpoint |
101
+ | `jwksUrl` | TEXT | NOT NULL | JWKS endpoint for public keys |
102
+
103
+ **Indexes:**
104
+
105
+ - `issuer_client_idx`: `(clientId, iss)` - For fast client lookups
106
+ - `iss_client_id_unique`: `(iss, clientId)` - Unique constraint preventing duplicate clients
107
+
108
+ ### deployments
109
+
110
+ | Column | Type | Constraints | Description |
111
+ | -------------- | ------------ | --------------------- | ---------------------------------- |
112
+ | `id` | UUID | PRIMARY KEY, NOT NULL | Internal UUID for the deployment |
113
+ | `deploymentId` | VARCHAR(255) | NOT NULL | LMS-provided deployment identifier |
114
+ | `name` | VARCHAR(255) | NULL | Optional human-readable name |
115
+ | `description` | TEXT | NULL | Optional description |
116
+ | `clientId` | UUID | NOT NULL, FOREIGN KEY | References `clients.id` |
117
+
118
+ **Indexes:**
119
+
120
+ - `deployment_id_idx`: `(deploymentId)` - For fast deployment lookups
121
+ - `client_deployment_unique`: `(clientId, deploymentId)` - Unique constraint per client
122
+
123
+ ### sessions
124
+
125
+ | Column | Type | Constraints | Description |
126
+ | ----------- | ------------------------ | --------------------- | ---------------------------- |
127
+ | `id` | UUID | PRIMARY KEY, NOT NULL | Session UUID |
128
+ | `data` | JSONB | NOT NULL | Complete LTI session data |
129
+ | `expiresAt` | TIMESTAMP WITH TIME ZONE | NOT NULL | Session expiration timestamp |
130
+
131
+ **Indexes:**
132
+
133
+ - `sessions_expires_at_idx`: `(expiresAt)` - For cleanup queries and expiration checks
134
+
135
+ ### nonces
136
+
137
+ | Column | Type | Constraints | Description |
138
+ | ----------- | ------------------------ | --------------------- | -------------------------- |
139
+ | `nonce` | VARCHAR(255) | PRIMARY KEY, NOT NULL | One-time use nonce value |
140
+ | `expiresAt` | TIMESTAMP WITH TIME ZONE | NOT NULL | Nonce expiration timestamp |
141
+
142
+ ### registration_sessions
143
+
144
+ | Column | Type | Constraints | Description |
145
+ | ----------- | ------------------------ | --------------------- | --------------------------------- |
146
+ | `id` | UUID | PRIMARY KEY, NOT NULL | Registration session UUID |
147
+ | `data` | JSONB | NOT NULL | Dynamic registration session data |
148
+ | `expiresAt` | TIMESTAMP WITH TIME ZONE | NOT NULL | Session expiration timestamp |
149
+
150
+ **Indexes:**
151
+
152
+ - `reg_sessions_expires_at_idx`: `(expiresAt)` - For cleanup queries and expiration checks
153
+
154
+ ## Connection Pool Behavior
155
+
156
+ The adapter automatically detects your deployment environment:
157
+
158
+ - **Serverless** (Lambda, Cloud Functions, Vercel, Netlify): `max: 1`
159
+ - **Traditional Servers** (EC2, containers, VMs): `max: 10`
160
+
161
+ ### How Connection Pooling Works
162
+
163
+ - Starts with **0 connections**
164
+ - Creates connections **on-demand** when queries execute
165
+ - Reuses idle connections before creating new ones
166
+ - Increases to `max` based on concurrent load
167
+ - Closes idle connections after `idleTimeout` seconds (default: 20)
168
+
169
+ ### Manual Override
170
+
171
+ ```typescript
172
+ const storage = new PostgresStorage({
173
+ connectionUrl: process.env.DATABASE_URL!,
174
+ poolOptions: {
175
+ max: 20, // Override auto-detection
176
+ idleTimeout: 30, // Keep connections alive longer
177
+ },
178
+ });
179
+ ```
180
+
181
+ ## Deployment Patterns
182
+
183
+ ### Long-Running Servers
184
+
185
+ ```typescript
186
+ import { PostgresStorage } from '@lti-tool/postgresql';
187
+
188
+ export const storage = new PostgresStorage({
189
+ connectionUrl: process.env.DATABASE_URL!,
190
+ });
191
+
192
+ // Optional: Graceful shutdown
193
+ const shutdown = async () => {
194
+ await storage.close();
195
+ process.exit(0);
196
+ };
197
+
198
+ process.on('SIGTERM', shutdown);
199
+ process.on('SIGINT', shutdown);
200
+ ```
201
+
202
+ **Connection Limits:**
203
+
204
+ - Low traffic: `5-10 connections`
205
+ - Medium traffic: `10-20 connections`
206
+ - High traffic: `20-50 connections`
207
+ - Never exceed PostgreSQL `max_connections`
208
+
209
+ ### AWS Lambda / Serverless
210
+
211
+ ```typescript
212
+ import { PostgresStorage } from '@lti-tool/postgresql';
213
+
214
+ let storage: PostgresStorage | undefined;
215
+
216
+ export const handler = async (event) => {
217
+ if (!storage) {
218
+ storage = new PostgresStorage({
219
+ connectionUrl: process.env.DATABASE_URL!,
220
+ // Auto-detects Lambda, uses max: 1
221
+ });
222
+ }
223
+
224
+ // Use storage...
225
+ };
226
+ ```
227
+
228
+ **Why `max: 1`?**
229
+ Lambda containers handle one request at a time. The connection is reused across warm invocations.
230
+
231
+ **Do I need `close()`?**
232
+ No! Lambda freezes containers efficiently. Calling `close()` destroys reusable connections.
233
+
234
+ ### Edge Runtime Warning
235
+
236
+ ⚠️ **Not supported!**
237
+
238
+ ## Periodic Cleanup
239
+
240
+ The adapter requires periodic cleanup of expired nonces and sessions.
241
+
242
+ ```typescript
243
+ // Example - AWS Lambda with EventBridge (every 30 minutes)
244
+ export const handler = async () => {
245
+ const result = await storage.cleanup();
246
+ console.log('Cleanup:', result);
247
+ // { noncesDeleted: 42, sessionsDeleted: 15, registrationSessionsDeleted: 3 }
248
+ };
249
+ ```
250
+
251
+ ## Development & Testing
252
+
253
+ ### Start Local PostgreSQL
254
+
255
+ ```bash
256
+ # Using Docker
257
+ docker-compose up -d
258
+
259
+ # Using Podman
260
+ podman-compose up -d
261
+
262
+ # Or Podman directly
263
+ podman run -d \
264
+ --name lti-postgres \
265
+ -e POSTGRES_PASSWORD=postgres \
266
+ -e POSTGRES_DB=lti_test \
267
+ -e POSTGRES_USER=lti_user \
268
+ -p 5432:5432 \
269
+ postgres:16
270
+ ```
271
+
272
+ ### Run Tests
273
+
274
+ ```bash
275
+ DATABASE_URL="postgresql://lti_user:postgres@localhost:5432/lti_test" npm test
276
+ ```
277
+
278
+ **Important:** Always close the pool after tests:
279
+
280
+ ```typescript
281
+ afterAll(async () => {
282
+ await storage.close();
283
+ });
284
+ ```
285
+
286
+ ## Environment Detection
287
+
288
+ Auto-detects serverless by checking:
289
+
290
+ - AWS Lambda: `AWS_LAMBDA_FUNCTION_NAME`, `AWS_EXECUTION_ENV`
291
+ - Google Cloud: `FUNCTION_NAME`, `K_SERVICE`
292
+ - Azure: `FUNCTIONS_WORKER_RUNTIME`
293
+ - Vercel: `VERCEL`
294
+ - Netlify: `NETLIFY`
@@ -0,0 +1,11 @@
1
+ import type { LTILaunchConfig, LTISession } from '@lti-tool/core';
2
+ import { LRUCache } from 'lru-cache';
3
+ export declare const LAUNCH_CONFIG_CACHE: LRUCache<string, LTILaunchConfig | typeof undefinedLaunchConfigValue, unknown>;
4
+ export declare const SESSION_CACHE: LRUCache<string, LTISession | typeof undefinedSessionValue, unknown>;
5
+ export declare const SESSION_TTL: number;
6
+ export declare const NONCE_TTL: number;
7
+ export declare const undefinedLaunchConfigValue: unique symbol;
8
+ export type undefinedLaunchConfig = typeof undefinedLaunchConfigValue;
9
+ export declare const undefinedSessionValue: unique symbol;
10
+ export type undefinedSession = typeof undefinedSessionValue;
11
+ //# sourceMappingURL=cacheConfig.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"cacheConfig.d.ts","sourceRoot":"","sources":["../src/cacheConfig.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,eAAe,EAAE,UAAU,EAAE,MAAM,gBAAgB,CAAC;AAClE,OAAO,EAAE,QAAQ,EAAE,MAAM,WAAW,CAAC;AAErC,eAAO,MAAM,mBAAmB,gFAM9B,CAAC;AACH,eAAO,MAAM,aAAa,sEAGxB,CAAC;AAEH,eAAO,MAAM,WAAW,QAAe,CAAC;AACxC,eAAO,MAAM,SAAS,QAAU,CAAC;AAGjC,eAAO,MAAM,0BAA0B,eAAkC,CAAC;AAC1E,MAAM,MAAM,qBAAqB,GAAG,OAAO,0BAA0B,CAAC;AACtE,eAAO,MAAM,qBAAqB,eAA6B,CAAC;AAChE,MAAM,MAAM,gBAAgB,GAAG,OAAO,qBAAqB,CAAC"}
@@ -0,0 +1,14 @@
1
+ import { LRUCache } from 'lru-cache';
2
+ export const LAUNCH_CONFIG_CACHE = new LRUCache({
3
+ max: 1000,
4
+ ttl: 1000 * 60 * 15, // 15 minutes
5
+ });
6
+ export const SESSION_CACHE = new LRUCache({
7
+ max: 1000,
8
+ ttl: 1000 * 60 * 5, // 5 minutes (shorter than clients)
9
+ });
10
+ export const SESSION_TTL = 60 * 60 * 24; // session ttl is one day
11
+ export const NONCE_TTL = 60 * 15; // nonce ttl is fifteen minutes
12
+ // we need an undefined value to handle cache misses and cache them
13
+ export const undefinedLaunchConfigValue = Symbol('undefinedLaunchConfig');
14
+ export const undefinedSessionValue = Symbol('undefinedSession');
@@ -0,0 +1,133 @@
1
+ export declare const clientsTable: import("drizzle-orm/pg-core").PgTableWithColumns<{
2
+ name: "clients";
3
+ schema: undefined;
4
+ columns: {
5
+ id: import("drizzle-orm/pg-core").PgColumn<{
6
+ name: "id";
7
+ tableName: "clients";
8
+ dataType: "string";
9
+ columnType: "PgUUID";
10
+ data: string;
11
+ driverParam: string;
12
+ notNull: true;
13
+ hasDefault: true;
14
+ isPrimaryKey: true;
15
+ isAutoincrement: false;
16
+ hasRuntimeDefault: false;
17
+ enumValues: undefined;
18
+ baseColumn: never;
19
+ identity: undefined;
20
+ generated: undefined;
21
+ }, {}, {}>;
22
+ name: import("drizzle-orm/pg-core").PgColumn<{
23
+ name: "name";
24
+ tableName: "clients";
25
+ dataType: "string";
26
+ columnType: "PgVarchar";
27
+ data: string;
28
+ driverParam: string;
29
+ notNull: true;
30
+ hasDefault: false;
31
+ isPrimaryKey: false;
32
+ isAutoincrement: false;
33
+ hasRuntimeDefault: false;
34
+ enumValues: [string, ...string[]];
35
+ baseColumn: never;
36
+ identity: undefined;
37
+ generated: undefined;
38
+ }, {}, {
39
+ length: 255;
40
+ }>;
41
+ iss: import("drizzle-orm/pg-core").PgColumn<{
42
+ name: "iss";
43
+ tableName: "clients";
44
+ dataType: "string";
45
+ columnType: "PgVarchar";
46
+ data: string;
47
+ driverParam: string;
48
+ notNull: true;
49
+ hasDefault: false;
50
+ isPrimaryKey: false;
51
+ isAutoincrement: false;
52
+ hasRuntimeDefault: false;
53
+ enumValues: [string, ...string[]];
54
+ baseColumn: never;
55
+ identity: undefined;
56
+ generated: undefined;
57
+ }, {}, {
58
+ length: 255;
59
+ }>;
60
+ clientId: import("drizzle-orm/pg-core").PgColumn<{
61
+ name: "client_id";
62
+ tableName: "clients";
63
+ dataType: "string";
64
+ columnType: "PgVarchar";
65
+ data: string;
66
+ driverParam: string;
67
+ notNull: true;
68
+ hasDefault: false;
69
+ isPrimaryKey: false;
70
+ isAutoincrement: false;
71
+ hasRuntimeDefault: false;
72
+ enumValues: [string, ...string[]];
73
+ baseColumn: never;
74
+ identity: undefined;
75
+ generated: undefined;
76
+ }, {}, {
77
+ length: 255;
78
+ }>;
79
+ authUrl: import("drizzle-orm/pg-core").PgColumn<{
80
+ name: "auth_url";
81
+ tableName: "clients";
82
+ dataType: "string";
83
+ columnType: "PgText";
84
+ data: string;
85
+ driverParam: string;
86
+ notNull: true;
87
+ hasDefault: false;
88
+ isPrimaryKey: false;
89
+ isAutoincrement: false;
90
+ hasRuntimeDefault: false;
91
+ enumValues: [string, ...string[]];
92
+ baseColumn: never;
93
+ identity: undefined;
94
+ generated: undefined;
95
+ }, {}, {}>;
96
+ tokenUrl: import("drizzle-orm/pg-core").PgColumn<{
97
+ name: "token_url";
98
+ tableName: "clients";
99
+ dataType: "string";
100
+ columnType: "PgText";
101
+ data: string;
102
+ driverParam: string;
103
+ notNull: true;
104
+ hasDefault: false;
105
+ isPrimaryKey: false;
106
+ isAutoincrement: false;
107
+ hasRuntimeDefault: false;
108
+ enumValues: [string, ...string[]];
109
+ baseColumn: never;
110
+ identity: undefined;
111
+ generated: undefined;
112
+ }, {}, {}>;
113
+ jwksUrl: import("drizzle-orm/pg-core").PgColumn<{
114
+ name: "jwks_url";
115
+ tableName: "clients";
116
+ dataType: "string";
117
+ columnType: "PgText";
118
+ data: string;
119
+ driverParam: string;
120
+ notNull: true;
121
+ hasDefault: false;
122
+ isPrimaryKey: false;
123
+ isAutoincrement: false;
124
+ hasRuntimeDefault: false;
125
+ enumValues: [string, ...string[]];
126
+ baseColumn: never;
127
+ identity: undefined;
128
+ generated: undefined;
129
+ }, {}, {}>;
130
+ };
131
+ dialect: "pg";
132
+ }>;
133
+ //# sourceMappingURL=clients.schema.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"clients.schema.d.ts","sourceRoot":"","sources":["../../../src/db/schema/clients.schema.ts"],"names":[],"mappings":"AAEA,eAAO,MAAM,YAAY;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EAexB,CAAC"}
@@ -0,0 +1,13 @@
1
+ import { index, pgTable, text, uniqueIndex, uuid, varchar } from 'drizzle-orm/pg-core';
2
+ export const clientsTable = pgTable('clients', {
3
+ id: uuid('id').primaryKey().defaultRandom(),
4
+ name: varchar('name', { length: 255 }).notNull(),
5
+ iss: varchar('iss', { length: 255 }).notNull(),
6
+ clientId: varchar('client_id', { length: 255 }).notNull(),
7
+ authUrl: text('auth_url').notNull(),
8
+ tokenUrl: text('token_url').notNull(),
9
+ jwksUrl: text('jwks_url').notNull(),
10
+ }, (table) => [
11
+ index('issuer_client_idx').on(table.clientId, table.iss),
12
+ uniqueIndex('iss_client_id_unique').on(table.iss, table.clientId),
13
+ ]);
@@ -0,0 +1,97 @@
1
+ export declare const deploymentsTable: import("drizzle-orm/pg-core").PgTableWithColumns<{
2
+ name: "deployments";
3
+ schema: undefined;
4
+ columns: {
5
+ id: import("drizzle-orm/pg-core").PgColumn<{
6
+ name: "id";
7
+ tableName: "deployments";
8
+ dataType: "string";
9
+ columnType: "PgUUID";
10
+ data: string;
11
+ driverParam: string;
12
+ notNull: true;
13
+ hasDefault: true;
14
+ isPrimaryKey: true;
15
+ isAutoincrement: false;
16
+ hasRuntimeDefault: false;
17
+ enumValues: undefined;
18
+ baseColumn: never;
19
+ identity: undefined;
20
+ generated: undefined;
21
+ }, {}, {}>;
22
+ deploymentId: import("drizzle-orm/pg-core").PgColumn<{
23
+ name: "deployment_id";
24
+ tableName: "deployments";
25
+ dataType: "string";
26
+ columnType: "PgVarchar";
27
+ data: string;
28
+ driverParam: string;
29
+ notNull: true;
30
+ hasDefault: false;
31
+ isPrimaryKey: false;
32
+ isAutoincrement: false;
33
+ hasRuntimeDefault: false;
34
+ enumValues: [string, ...string[]];
35
+ baseColumn: never;
36
+ identity: undefined;
37
+ generated: undefined;
38
+ }, {}, {
39
+ length: 255;
40
+ }>;
41
+ name: import("drizzle-orm/pg-core").PgColumn<{
42
+ name: "name";
43
+ tableName: "deployments";
44
+ dataType: "string";
45
+ columnType: "PgVarchar";
46
+ data: string;
47
+ driverParam: string;
48
+ notNull: false;
49
+ hasDefault: false;
50
+ isPrimaryKey: false;
51
+ isAutoincrement: false;
52
+ hasRuntimeDefault: false;
53
+ enumValues: [string, ...string[]];
54
+ baseColumn: never;
55
+ identity: undefined;
56
+ generated: undefined;
57
+ }, {}, {
58
+ length: 255;
59
+ }>;
60
+ description: import("drizzle-orm/pg-core").PgColumn<{
61
+ name: "description";
62
+ tableName: "deployments";
63
+ dataType: "string";
64
+ columnType: "PgText";
65
+ data: string;
66
+ driverParam: string;
67
+ notNull: false;
68
+ hasDefault: false;
69
+ isPrimaryKey: false;
70
+ isAutoincrement: false;
71
+ hasRuntimeDefault: false;
72
+ enumValues: [string, ...string[]];
73
+ baseColumn: never;
74
+ identity: undefined;
75
+ generated: undefined;
76
+ }, {}, {}>;
77
+ clientId: import("drizzle-orm/pg-core").PgColumn<{
78
+ name: "client_id";
79
+ tableName: "deployments";
80
+ dataType: "string";
81
+ columnType: "PgUUID";
82
+ data: string;
83
+ driverParam: string;
84
+ notNull: true;
85
+ hasDefault: false;
86
+ isPrimaryKey: false;
87
+ isAutoincrement: false;
88
+ hasRuntimeDefault: false;
89
+ enumValues: undefined;
90
+ baseColumn: never;
91
+ identity: undefined;
92
+ generated: undefined;
93
+ }, {}, {}>;
94
+ };
95
+ dialect: "pg";
96
+ }>;
97
+ //# sourceMappingURL=deployments.schema.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"deployments.schema.d.ts","sourceRoot":"","sources":["../../../src/db/schema/deployments.schema.ts"],"names":[],"mappings":"AAIA,eAAO,MAAM,gBAAgB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EAe5B,CAAC"}
@@ -0,0 +1,14 @@
1
+ import { index, pgTable, text, uniqueIndex, uuid, varchar } from 'drizzle-orm/pg-core';
2
+ import { clientsTable } from './clients.schema';
3
+ export const deploymentsTable = pgTable('deployments', {
4
+ id: uuid('id').primaryKey().defaultRandom(),
5
+ deploymentId: varchar('deployment_id', { length: 255 }).notNull(),
6
+ name: varchar('name', { length: 255 }),
7
+ description: text('description'),
8
+ clientId: uuid('client_id')
9
+ .notNull()
10
+ .references(() => clientsTable.id),
11
+ }, (table) => [
12
+ index('deployment_id_idx').on(table.deploymentId),
13
+ uniqueIndex('client_deployment_unique').on(table.clientId, table.deploymentId),
14
+ ]);
@@ -0,0 +1,6 @@
1
+ export * from './clients.schema';
2
+ export * from './deployments.schema';
3
+ export * from './nonces.schema';
4
+ export * from './registrationSessions.schema';
5
+ export * from './sessions.schema';
6
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/db/schema/index.ts"],"names":[],"mappings":"AAAA,cAAc,kBAAkB,CAAC;AACjC,cAAc,sBAAsB,CAAC;AACrC,cAAc,iBAAiB,CAAC;AAChC,cAAc,+BAA+B,CAAC;AAC9C,cAAc,mBAAmB,CAAC"}
@@ -0,0 +1,5 @@
1
+ export * from './clients.schema';
2
+ export * from './deployments.schema';
3
+ export * from './nonces.schema';
4
+ export * from './registrationSessions.schema';
5
+ export * from './sessions.schema';
@@ -0,0 +1,44 @@
1
+ export declare const noncesTable: import("drizzle-orm/pg-core").PgTableWithColumns<{
2
+ name: "nonces";
3
+ schema: undefined;
4
+ columns: {
5
+ nonce: import("drizzle-orm/pg-core").PgColumn<{
6
+ name: "nonce";
7
+ tableName: "nonces";
8
+ dataType: "string";
9
+ columnType: "PgVarchar";
10
+ data: string;
11
+ driverParam: string;
12
+ notNull: true;
13
+ hasDefault: false;
14
+ isPrimaryKey: true;
15
+ isAutoincrement: false;
16
+ hasRuntimeDefault: false;
17
+ enumValues: [string, ...string[]];
18
+ baseColumn: never;
19
+ identity: undefined;
20
+ generated: undefined;
21
+ }, {}, {
22
+ length: 255;
23
+ }>;
24
+ expiresAt: import("drizzle-orm/pg-core").PgColumn<{
25
+ name: "expires_at";
26
+ tableName: "nonces";
27
+ dataType: "date";
28
+ columnType: "PgTimestamp";
29
+ data: Date;
30
+ driverParam: string;
31
+ notNull: true;
32
+ hasDefault: false;
33
+ isPrimaryKey: false;
34
+ isAutoincrement: false;
35
+ hasRuntimeDefault: false;
36
+ enumValues: undefined;
37
+ baseColumn: never;
38
+ identity: undefined;
39
+ generated: undefined;
40
+ }, {}, {}>;
41
+ };
42
+ dialect: "pg";
43
+ }>;
44
+ //# sourceMappingURL=nonces.schema.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"nonces.schema.d.ts","sourceRoot":"","sources":["../../../src/db/schema/nonces.schema.ts"],"names":[],"mappings":"AAEA,eAAO,MAAM,WAAW;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EAGtB,CAAC"}
@@ -0,0 +1,5 @@
1
+ import { pgTable, timestamp, varchar } from 'drizzle-orm/pg-core';
2
+ export const noncesTable = pgTable('nonces', {
3
+ nonce: varchar('nonce', { length: 255 }).primaryKey(),
4
+ expiresAt: timestamp('expires_at', { withTimezone: true }).notNull(),
5
+ });