@withstudiocms/sdk 0.0.0-beta.0 → 0.1.0-beta.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 (71) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +21 -0
  3. package/dist/cache.d.ts +109 -0
  4. package/dist/cache.js +94 -0
  5. package/dist/consts.d.ts +28 -0
  6. package/dist/consts.js +26 -0
  7. package/dist/context.d.ts +188 -0
  8. package/dist/context.js +33 -0
  9. package/dist/index.d.ts +1136 -0
  10. package/dist/index.js +24 -0
  11. package/dist/lib/diff.d.ts +39 -0
  12. package/dist/lib/diff.js +29 -0
  13. package/dist/lib/logger.d.ts +31 -0
  14. package/dist/lib/logger.js +131 -0
  15. package/dist/lib/pluginUtils.d.ts +221 -0
  16. package/dist/lib/pluginUtils.js +80 -0
  17. package/dist/modules/auth/index.d.ts +463 -0
  18. package/dist/modules/auth/index.js +412 -0
  19. package/dist/modules/clear/index.d.ts +72 -0
  20. package/dist/modules/clear/index.js +52 -0
  21. package/dist/modules/config/consts.d.ts +32 -0
  22. package/dist/modules/config/consts.js +18 -0
  23. package/dist/modules/config/index.d.ts +100 -0
  24. package/dist/modules/config/index.js +205 -0
  25. package/dist/modules/config/templates/mailer.d.ts +36 -0
  26. package/dist/modules/config/templates/mailer.js +218 -0
  27. package/dist/modules/config/type-utils.d.ts +13 -0
  28. package/dist/modules/config/type-utils.js +11 -0
  29. package/dist/modules/delete/index.d.ts +140 -0
  30. package/dist/modules/delete/index.js +274 -0
  31. package/dist/modules/diffTracking/index.d.ts +188 -0
  32. package/dist/modules/diffTracking/index.js +276 -0
  33. package/dist/modules/get/index.d.ts +272 -0
  34. package/dist/modules/get/index.js +466 -0
  35. package/dist/modules/index.d.ts +1003 -0
  36. package/dist/modules/index.js +37 -0
  37. package/dist/modules/init/index.d.ts +60 -0
  38. package/dist/modules/init/index.js +38 -0
  39. package/dist/modules/middleware/index.d.ts +56 -0
  40. package/dist/modules/middleware/index.js +50 -0
  41. package/dist/modules/notificationSettings/index.d.ts +57 -0
  42. package/dist/modules/notificationSettings/index.js +39 -0
  43. package/dist/modules/plugins/index.d.ts +166 -0
  44. package/dist/modules/plugins/index.js +261 -0
  45. package/dist/modules/post/index.d.ts +305 -0
  46. package/dist/modules/post/index.js +305 -0
  47. package/dist/modules/resetTokenBucket/index.d.ts +91 -0
  48. package/dist/modules/resetTokenBucket/index.js +93 -0
  49. package/dist/modules/rest_api/index.d.ts +92 -0
  50. package/dist/modules/rest_api/index.js +113 -0
  51. package/dist/modules/update/index.d.ts +184 -0
  52. package/dist/modules/update/index.js +174 -0
  53. package/dist/modules/util/collectors.d.ts +261 -0
  54. package/dist/modules/util/collectors.js +141 -0
  55. package/dist/modules/util/folderTree.d.ts +100 -0
  56. package/dist/modules/util/folderTree.js +176 -0
  57. package/dist/modules/util/generators.d.ts +83 -0
  58. package/dist/modules/util/generators.js +106 -0
  59. package/dist/modules/util/getFromNPM.d.ts +191 -0
  60. package/dist/modules/util/getFromNPM.js +100 -0
  61. package/dist/modules/util/index.d.ts +236 -0
  62. package/dist/modules/util/index.js +20 -0
  63. package/dist/modules/util/parsers.d.ts +60 -0
  64. package/dist/modules/util/parsers.js +43 -0
  65. package/dist/modules/util/slugify.d.ts +22 -0
  66. package/dist/modules/util/slugify.js +19 -0
  67. package/dist/modules/util/users.d.ts +99 -0
  68. package/dist/modules/util/users.js +78 -0
  69. package/dist/types.d.ts +360 -0
  70. package/dist/types.js +10 -0
  71. package/package.json +55 -7
@@ -0,0 +1,463 @@
1
+ import { Effect } from '@withstudiocms/effect';
2
+ import { type DBCallbackFailure } from '@withstudiocms/kysely';
3
+ import type { DatabaseError } from '@withstudiocms/kysely/core/errors';
4
+ import { DBClientLive, SDKDefaults } from '../../context.js';
5
+ import { type AuthDeletionResponse } from '../../types.js';
6
+ /**
7
+ * SDKAuthModule
8
+ *
9
+ * High-level authentication/data-access module implemented as an Effect generator.
10
+ * Returns a collection of sub-modules for working with email verification tokens,
11
+ * OAuth accounts, permissions, sessions and users. Each operation is implemented
12
+ * as composable Effect-driven functions that perform database operations, validate
13
+ * inputs/outputs with codecs/encoders and return typed database entities or
14
+ * domain-level results.
15
+ *
16
+ * Key characteristics
17
+ * - Built on top of an Effect system: most exported operations are Effects or
18
+ * Effect.fn wrappers and should be run within the surrounding Effect runtime.
19
+ * - Uses runtime codecs/encoders to validate and parse inputs/outputs when
20
+ * interacting with the database; DB rows returned conform to the project's
21
+ * table schemas (e.g., StudioCMSUsersTable.Select, StudioCMSSessionTable.Select).
22
+ * - Encapsulates direct Kysely-style DB queries behind safe, validated call-sites.
23
+ * - Contains helper flows for common workflows (e.g., generate + insert verification
24
+ * token, create user + permission, ensure ghost user exists).
25
+ *
26
+ * Returned sub-modules and notable behaviors
27
+ * - verifyEmail
28
+ * - get(id: string): Effect that returns a verification token record or undefined.
29
+ * - create(userId: string): Effect that generates a token, deletes any existing
30
+ * token for the user and inserts a new token with an expiry (default 24h).
31
+ * - delete(userId: string): Effect that deletes tokens for userId.
32
+ *
33
+ * - oAuth
34
+ * - create(input): Effect that inserts a new OAuth account record.
35
+ * - delete({ userId, provider }): Effect that attempts to delete an OAuth account
36
+ * and returns a simple result object: { status: 'success'|'error', message: string }.
37
+ * The delete flow maps common DB error tags (e.g., DBCallbackFailure, NotFoundError,
38
+ * QueryError, QueryParseError) to meaningful status/message responses.
39
+ * - searchByProviderId(input): Effect that finds an OAuth account by providerUserId + userId.
40
+ *
41
+ * - permission
42
+ * - currentStatus(userId: string): Effect that returns the current permission row for a user
43
+ * or undefined if none exists.
44
+ *
45
+ * - session
46
+ * - create(sessionData): Effect that inserts a new session row and returns the created record.
47
+ * - getById(id: string): Effect that returns a session row or undefined.
48
+ * - sessionWithUser(sessionId: string): Effect that returns { session, user } or undefined
49
+ * if either the session or user does not exist.
50
+ * - delete(sessionId: string): Effect that deletes a session and returns a
51
+ * { status, message } result similar to oAuth.delete; common DB failures are mapped to
52
+ * friendly messages.
53
+ * - update({ id, newDate }): Effect that updates a session's expiresAt and returns the
54
+ * updated session record.
55
+ *
56
+ * - user
57
+ * - create(userData, rank): Composed Effect that creates a new user and then creates
58
+ * the corresponding permission record for the supplied rank.
59
+ * - update({ userId, userData }): Effect that updates user fields and returns the updated user.
60
+ * - searchUsersForUsernameOrEmail(username?, email?): Effect that searches by username and/or email
61
+ * and returns both result arrays ({ usernameSearch, emailSearch }).
62
+ * - ghost
63
+ * - verifyExists(): Effect<boolean> that returns true if the configured ghost user exists.
64
+ * - create(): Effect that creates the ghost user if missing and returns the ghost user row.
65
+ * - get(): Effect that returns the ghost user row, creating it if necessary.
66
+ *
67
+ * Errors and failure modes
68
+ * - Most DB operations will propagate DB-level failures as Effect errors that the caller
69
+ * can handle or map. Certain "delete" operations intentionally catch DB error tags and
70
+ * convert them to structured success/error result objects for convenience.
71
+ * - Insert/update operations use returningAll() and executeTakeFirstOrThrow(), so failed
72
+ * inserts/updates typically surface as runtime/DB errors within the Effect system.
73
+ *
74
+ * Usage notes
75
+ * - All exported operations are intended to be composed and executed inside the project's
76
+ * Effect runtime. Consumers should use the project's Effect helpers to run or map results.
77
+ * - The module relies on configured DB client, token generator and default values (e.g.,
78
+ * ghost user defaults). Ensure proper environment wiring before invoking these functions.
79
+ *
80
+ * Example (pseudocode)
81
+ * const auth = yield* SDKAuthModule;
82
+ * // create a user and permission
83
+ * const newUser = yield* auth.user.create(userInsertPayload, 'admin');
84
+ * // create and retrieve a session
85
+ * const session = yield* auth.session.create(sessionPayload);
86
+ * // create an email verification token
87
+ * const token = yield* auth.verifyEmail.create(newUser.id);
88
+ */
89
+ export declare const SDKAuthModule: Effect.Effect<{
90
+ verifyEmail: {
91
+ /**
92
+ * Retrieves an email verification token by its ID.
93
+ *
94
+ * @param id - The ID of the email verification token to retrieve.
95
+ * @returns A promise that resolves to the email verification token if found, otherwise undefined.
96
+ */
97
+ get: (input: string) => Effect.Effect<{
98
+ readonly id: string;
99
+ readonly userId: string;
100
+ readonly token: string;
101
+ readonly expiresAt: Date;
102
+ } | undefined, DBCallbackFailure | DatabaseError, never>;
103
+ /**
104
+ * Creates a new email verification token in the database.
105
+ *
106
+ * @param userId - The ID of the user to create the token for.
107
+ * @returns A promise that resolves to the created email verification token.
108
+ */
109
+ create: (userId: string) => Effect.Effect<{
110
+ readonly id: string;
111
+ readonly userId: string;
112
+ readonly token: string;
113
+ readonly expiresAt: Date;
114
+ }, DBCallbackFailure | DatabaseError | import("../util/generators.js").GeneratorError, never>;
115
+ /**
116
+ * Deletes an email verification token from the database.
117
+ *
118
+ * @param userId - The ID of the user associated with the token.
119
+ * @returns A promise that resolves to the deletion response.
120
+ */
121
+ delete: (input: string) => Effect.Effect<import("kysely").DeleteResult, DBCallbackFailure | DatabaseError, never>;
122
+ };
123
+ oAuth: {
124
+ /**
125
+ * Creates a new OAuth account in the database.
126
+ *
127
+ * @param input - The OAuth account data to create.
128
+ * @returns A promise that resolves to the created OAuth account.
129
+ */
130
+ create: (input: {
131
+ readonly providerUserId: string;
132
+ readonly provider: string;
133
+ readonly userId: string;
134
+ }) => Effect.Effect<{
135
+ readonly providerUserId: string;
136
+ readonly provider: string;
137
+ readonly userId: string;
138
+ }, DBCallbackFailure | DatabaseError, never>;
139
+ /**
140
+ * Deletes an OAuth user account from the database.
141
+ *
142
+ * @param input - An object containing the userId and provider of the OAuth account to delete.
143
+ * @returns A promise that resolves to a status and message indicating the result of the deletion.
144
+ */
145
+ delete: (input: {
146
+ readonly userId: string;
147
+ readonly provider: string;
148
+ }) => AuthDeletionResponse;
149
+ /**
150
+ * Searches for an OAuth account by provider user ID and user ID.
151
+ *
152
+ * @param input - An object containing the providerUserId and userId to search for.
153
+ * @returns A promise that resolves to the found OAuth account if it exists, otherwise undefined.
154
+ */
155
+ searchByProviderId: (input: {
156
+ readonly providerUserId: string;
157
+ readonly userId: string;
158
+ }) => Effect.Effect<{
159
+ readonly providerUserId: string;
160
+ readonly provider: string;
161
+ readonly userId: string;
162
+ } | undefined, DBCallbackFailure | DatabaseError, never>;
163
+ /**
164
+ * Searches for OAuth providers for a given user ID.
165
+ *
166
+ * @param input - An object containing the providerId and userId to search for.
167
+ * @returns A promise that resolves to the found OAuth account if it exists, otherwise undefined.
168
+ */
169
+ searchProvidersForId: (input: {
170
+ readonly userId: string;
171
+ readonly providerId: string;
172
+ }) => Effect.Effect<{
173
+ readonly providerUserId: string;
174
+ readonly provider: string;
175
+ readonly userId: string;
176
+ } | undefined, DBCallbackFailure | DatabaseError, never>;
177
+ };
178
+ permission: {
179
+ /**
180
+ * Retrieves the current permission for a user by their ID.
181
+ *
182
+ * @param id - The ID of the user whose permission is to be retrieved.
183
+ * @returns A promise that resolves to the user's permission if found, otherwise undefined.
184
+ */
185
+ currentStatus: (input: string) => Effect.Effect<{
186
+ readonly user: string;
187
+ readonly rank: "owner" | "admin" | "editor" | "visitor" | "unknown";
188
+ } | undefined, DBCallbackFailure | DatabaseError, never>;
189
+ };
190
+ session: {
191
+ /**
192
+ * Creates a new session for a user.
193
+ *
194
+ * @param data - The session data to create.
195
+ * @returns A promise that resolves to the created session.
196
+ */
197
+ create: (input: {
198
+ readonly id: string;
199
+ readonly userId: string;
200
+ readonly expiresAt: string;
201
+ }) => Effect.Effect<{
202
+ readonly id: string;
203
+ readonly userId: string;
204
+ readonly expiresAt: Date;
205
+ }, DBCallbackFailure | DatabaseError, never>;
206
+ /**
207
+ * Retrieves a user's Session by its ID.
208
+ *
209
+ * @param id - The ID of the session to retrieve.
210
+ * @returns A promise that resolves to the session if found, otherwise undefined.
211
+ */
212
+ getById: (input: string) => Effect.Effect<{
213
+ readonly id: string;
214
+ readonly userId: string;
215
+ readonly expiresAt: Date;
216
+ } | undefined, DBCallbackFailure | DatabaseError, never>;
217
+ /**
218
+ * Retrieves a session along with its associated user by session ID.
219
+ *
220
+ * @param sessionId - The ID of the session to retrieve.
221
+ * @returns A promise that resolves to an object containing the session and user if found, otherwise undefined.
222
+ */
223
+ sessionWithUser: (sessionId: string) => Effect.Effect<{
224
+ session: {
225
+ readonly id: string;
226
+ readonly userId: string;
227
+ readonly expiresAt: Date;
228
+ };
229
+ user: {
230
+ readonly name: string;
231
+ readonly id: string;
232
+ readonly url: string | null | undefined;
233
+ readonly email: string | null | undefined;
234
+ readonly avatar: string | null | undefined;
235
+ readonly username: string;
236
+ readonly password: string | null | undefined;
237
+ readonly updatedAt: Date;
238
+ readonly createdAt: Date;
239
+ readonly emailVerified: boolean;
240
+ readonly notifications: string | null | undefined;
241
+ };
242
+ } | undefined, DBCallbackFailure | DatabaseError, never>;
243
+ /**
244
+ * Deletes a session by its ID.
245
+ *
246
+ * @param input - The ID of the session to delete.
247
+ * @returns A promise that resolves to a status and message indicating the result of the deletion.
248
+ */
249
+ delete: (input: string) => AuthDeletionResponse;
250
+ /**
251
+ * Updates a session's expiration date.
252
+ *
253
+ * @param input - An object containing the session ID and the new expiration date.
254
+ * @returns A promise that resolves to the updated session.
255
+ */
256
+ update: (input: {
257
+ readonly id: string;
258
+ readonly newDate: {
259
+ toString: {};
260
+ toDateString: {};
261
+ toTimeString: {};
262
+ toLocaleString: {};
263
+ toLocaleDateString: {};
264
+ toLocaleTimeString: {};
265
+ valueOf: {};
266
+ getTime: {};
267
+ getFullYear: {};
268
+ getUTCFullYear: {};
269
+ getMonth: {};
270
+ getUTCMonth: {};
271
+ getDate: {};
272
+ getUTCDate: {};
273
+ getDay: {};
274
+ getUTCDay: {};
275
+ getHours: {};
276
+ getUTCHours: {};
277
+ getMinutes: {};
278
+ getUTCMinutes: {};
279
+ getSeconds: {};
280
+ getUTCSeconds: {};
281
+ getMilliseconds: {};
282
+ getUTCMilliseconds: {};
283
+ getTimezoneOffset: {};
284
+ setTime: {};
285
+ setMilliseconds: {};
286
+ setUTCMilliseconds: {};
287
+ setSeconds: {};
288
+ setUTCSeconds: {};
289
+ setMinutes: {};
290
+ setUTCMinutes: {};
291
+ setHours: {};
292
+ setUTCHours: {};
293
+ setDate: {};
294
+ setUTCDate: {};
295
+ setMonth: {};
296
+ setUTCMonth: {};
297
+ setFullYear: {};
298
+ setUTCFullYear: {};
299
+ toUTCString: {};
300
+ toISOString: {};
301
+ toJSON: {};
302
+ getVarDate: {};
303
+ [Symbol.toPrimitive]: {};
304
+ };
305
+ }) => Effect.Effect<{
306
+ readonly id: string;
307
+ readonly userId: string;
308
+ readonly expiresAt: Date;
309
+ }, DBCallbackFailure | DatabaseError, never>;
310
+ };
311
+ user: {
312
+ /**
313
+ * Creates a new user with the specified permissions.
314
+ *
315
+ * @param userData - The data for the new user.
316
+ * @param rank - The permission rank for the new user.
317
+ * @returns A promise that resolves to the created user.
318
+ */
319
+ create: (userData: {
320
+ readonly name: string;
321
+ readonly id: string;
322
+ readonly url: string | null | undefined;
323
+ readonly email: string | null | undefined;
324
+ readonly avatar: string | null | undefined;
325
+ readonly username: string;
326
+ readonly password: string | null | undefined;
327
+ readonly updatedAt: string;
328
+ readonly createdAt: string | undefined;
329
+ readonly emailVerified: boolean;
330
+ readonly notifications: string | null | undefined;
331
+ }, rank: "owner" | "admin" | "editor" | "visitor" | "unknown") => Effect.Effect<{
332
+ readonly name: string;
333
+ readonly id: string;
334
+ readonly url: string | null | undefined;
335
+ readonly email: string | null | undefined;
336
+ readonly avatar: string | null | undefined;
337
+ readonly username: string;
338
+ readonly password: string | null | undefined;
339
+ readonly updatedAt: Date;
340
+ readonly createdAt: Date;
341
+ readonly emailVerified: boolean;
342
+ readonly notifications: string | null | undefined;
343
+ }, DBCallbackFailure | DatabaseError, never>;
344
+ /**
345
+ * Updates user data for a specified user.
346
+ *
347
+ * @param input - An object containing the userId and the userData to update.
348
+ * @returns A promise that resolves to the updated user.
349
+ */
350
+ update: (input: {
351
+ readonly userId: string;
352
+ readonly userData: {
353
+ readonly url?: string | null | undefined;
354
+ readonly email?: string | null | undefined;
355
+ readonly avatar?: string | null | undefined;
356
+ readonly password?: string | null | undefined;
357
+ readonly notifications?: string | null | undefined;
358
+ readonly name: string;
359
+ readonly id: string;
360
+ readonly username: string;
361
+ readonly updatedAt: string;
362
+ readonly emailVerified: boolean;
363
+ };
364
+ }) => Effect.Effect<{
365
+ readonly name: string;
366
+ readonly id: string;
367
+ readonly url: string | null | undefined;
368
+ readonly email: string | null | undefined;
369
+ readonly avatar: string | null | undefined;
370
+ readonly username: string;
371
+ readonly password: string | null | undefined;
372
+ readonly updatedAt: Date;
373
+ readonly createdAt: Date;
374
+ readonly emailVerified: boolean;
375
+ readonly notifications: string | null | undefined;
376
+ }, DBCallbackFailure | DatabaseError, never>;
377
+ /**
378
+ * Searches for users by username.
379
+ *
380
+ * @param username - The username to search for.
381
+ * @param email - The email to search for.
382
+ * @returns A promise that resolves to an array of users matching the username.
383
+ */
384
+ searchUsersForUsernameOrEmail: (username?: string | undefined, email?: string | undefined) => Effect.Effect<{
385
+ usernameSearch: {
386
+ readonly name: string;
387
+ readonly id: string;
388
+ readonly url: string | null | undefined;
389
+ readonly email: string | null | undefined;
390
+ readonly avatar: string | null | undefined;
391
+ readonly username: string;
392
+ readonly password: string | null | undefined;
393
+ readonly updatedAt: Date;
394
+ readonly createdAt: Date;
395
+ readonly emailVerified: boolean;
396
+ readonly notifications: string | null | undefined;
397
+ }[];
398
+ emailSearch: {
399
+ readonly name: string;
400
+ readonly id: string;
401
+ readonly url: string | null | undefined;
402
+ readonly email: string | null | undefined;
403
+ readonly avatar: string | null | undefined;
404
+ readonly username: string;
405
+ readonly password: string | null | undefined;
406
+ readonly updatedAt: Date;
407
+ readonly createdAt: Date;
408
+ readonly emailVerified: boolean;
409
+ readonly notifications: string | null | undefined;
410
+ }[];
411
+ }, DBCallbackFailure | DatabaseError, never>;
412
+ /**
413
+ * Verifies the existence of the ghost user.
414
+ *
415
+ * @returns A promise that resolves to true if the ghost user exists, otherwise false.
416
+ */
417
+ ghost: {
418
+ /**
419
+ * Verifies the existence of the ghost user.
420
+ *
421
+ * @returns A promise that resolves to true if the ghost user exists, otherwise false.
422
+ */
423
+ verifyExists: () => Effect.Effect<boolean, DBCallbackFailure | DatabaseError, never>;
424
+ /**
425
+ * Creates the ghost user if it does not already exist.
426
+ *
427
+ * @returns A promise that resolves to the ghost user.
428
+ */
429
+ create: () => Effect.Effect<{
430
+ readonly name: string;
431
+ readonly id: string;
432
+ readonly url: string | null | undefined;
433
+ readonly email: string | null | undefined;
434
+ readonly avatar: string | null | undefined;
435
+ readonly username: string;
436
+ readonly password: string | null | undefined;
437
+ readonly updatedAt: Date;
438
+ readonly createdAt: Date;
439
+ readonly emailVerified: boolean;
440
+ readonly notifications: string | null | undefined;
441
+ }, DBCallbackFailure | DatabaseError, never>;
442
+ /**
443
+ * Retrieves the ghost user.
444
+ *
445
+ * @returns A promise that resolves to the ghost user.
446
+ */
447
+ get: () => Effect.Effect<{
448
+ readonly name: string;
449
+ readonly id: string;
450
+ readonly url: string | null | undefined;
451
+ readonly email: string | null | undefined;
452
+ readonly avatar: string | null | undefined;
453
+ readonly username: string;
454
+ readonly password: string | null | undefined;
455
+ readonly updatedAt: Date;
456
+ readonly createdAt: Date;
457
+ readonly emailVerified: boolean;
458
+ readonly notifications: string | null | undefined;
459
+ }, DBCallbackFailure | DatabaseError, never>;
460
+ };
461
+ };
462
+ }, import("effect/ConfigError").ConfigError, DBClientLive | SDKDefaults>;
463
+ export default SDKAuthModule;