@tatara/cli 0.9.1 → 0.10.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.
Files changed (58) hide show
  1. package/dist/bin.mjs +367 -93
  2. package/package.json +1 -1
  3. package/templates/features/admin/files/src/apps/admin/app.ts +1 -1
  4. package/templates/features/admin/files/src/modules/example/routes/admin-greeting.routes.ts +2 -2
  5. package/templates/features/admin/files/src/modules/example/tests/admin.test.ts +11 -4
  6. package/templates/features/admin/files/src/modules/staff/db/seed.ts +27 -0
  7. package/templates/features/admin/files/src/modules/staff/services/auth.ts +46 -0
  8. package/templates/features/admin/files/tests/helpers/staff.ts +8 -0
  9. package/templates/features/admin/files+drizzle+mysql/src/modules/staff/db/staff.schema.ts +58 -0
  10. package/templates/features/admin/files+drizzle+mysql/src/modules/staff/services/adapter.ts +13 -0
  11. package/templates/features/admin/files+drizzle+postgres/src/modules/staff/db/staff.schema.ts +57 -0
  12. package/templates/features/admin/files+drizzle+postgres/src/modules/staff/services/adapter.ts +13 -0
  13. package/templates/features/admin/files+prisma/prisma/models/staff.prisma +61 -0
  14. package/templates/features/admin/files+prisma+mysql/src/modules/staff/services/adapter.ts +5 -0
  15. package/templates/features/admin/files+prisma+postgres/src/modules/staff/services/adapter.ts +5 -0
  16. package/templates/features/auth-keycloak/files/keycloak/realm.json +70 -9
  17. package/templates/features/auth-keycloak/files/src/{core/auth → modules/users}/commands/keycloak-token.ts +3 -1
  18. package/templates/features/auth-keycloak/files/{src/core/auth/tests/keycloak-tokens.test.ts → tests/tatara/auth-keycloak-tokens.test.ts} +2 -2
  19. package/templates/features/auth-keycloak/files+auth-orgs/{src/core/auth/tests/keycloak-organizations.test.ts → tests/tatara/auth-keycloak-organizations.test.ts} +1 -1
  20. package/templates/features/auth-keycloak/files+authz/{src/core/auth/tests/keycloak-authz.test.ts → tests/tatara/auth-keycloak-authz.test.ts} +3 -2
  21. package/templates/features/auth-orgs/files+drizzle+mysql/src/{core/auth → modules/users}/db/organization.schema.ts +1 -1
  22. package/templates/features/auth-orgs/files+drizzle+postgres/src/{core/auth → modules/users}/db/organization.schema.ts +1 -1
  23. package/templates/features/authz/files/src/core/authz/system-roles.ts +1 -0
  24. package/templates/features/authz/files/src/{core/authz → modules/users}/routes/authorization.routes.ts +4 -1
  25. package/templates/features/authz/files/{src/core/authz/tests → tests/tatara}/authz.test.ts +4 -2
  26. package/templates/features/authz/files+drizzle/src/core/authz/index.ts +1 -0
  27. package/templates/features/authz/files+prisma/src/core/authz/index.ts +1 -0
  28. package/templates/features/base/files/src/apps/api/app.ts +1 -1
  29. package/templates/features/base/files/src/core/http/context.ts +2 -0
  30. package/templates/features/better-auth/files/src/{core/auth → modules/users}/db/seed.ts +1 -1
  31. package/templates/features/better-auth/files/src/modules/users/services/auth.ts +37 -0
  32. package/templates/features/better-auth/files/src/{core/auth → modules/users/services}/delivery.ts +1 -1
  33. package/templates/features/better-auth/files/tests/helpers/auth.ts +4 -3
  34. package/templates/features/better-auth/files+admin/tests/tatara/auth-openapi-admin.test.ts +10 -0
  35. package/templates/features/better-auth/files+auth-orgs/{src/core/auth/tests/principal.test.ts → tests/tatara/auth-principal.test.ts} +1 -1
  36. package/templates/features/better-auth/files+auth-orgs+authz/{src/core/auth/tests/principal-authz.test.ts → tests/tatara/auth-principal-authz.test.ts} +1 -1
  37. package/templates/features/better-auth/files+drizzle+mysql/src/{core/auth → modules/users/services}/adapter.ts +1 -1
  38. package/templates/features/better-auth/files+drizzle+postgres/src/{core/auth → modules/users/services}/adapter.ts +1 -1
  39. package/templates/versions.json +4 -4
  40. package/templates/features/better-auth/files/src/core/auth/auth.ts +0 -26
  41. package/templates/features/better-auth/files/src/core/auth/principal.ts +0 -10
  42. package/templates/features/better-auth/files+admin/src/core/auth/tests/openapi-admin.test.ts +0 -8
  43. /package/templates/features/auth/files/src/{core/auth → modules/users}/routes/me.routes.ts +0 -0
  44. /package/templates/features/auth/files/{src/core/auth/tests/me.test.ts → tests/tatara/auth-me.test.ts} +0 -0
  45. /package/templates/features/auth-keycloak/files/src/{core/auth → modules/users/services}/keycloak.ts +0 -0
  46. /package/templates/features/authz/files/{src/core/authz/tests/error-messages.test.ts → tests/tatara/authz-error-messages.test.ts} +0 -0
  47. /package/templates/features/authz/files/{src/core/authz/tests/request-body.test.ts → tests/tatara/authz-request-body.test.ts} +0 -0
  48. /package/templates/features/base/files/src/{core/http/app.ts → apps/http.ts} +0 -0
  49. /package/templates/features/base/files/{src/core/config/tests/env.test.ts → tests/tatara/config-env.test.ts} +0 -0
  50. /package/templates/features/better-auth/files/src/{core/auth → modules/users/services}/sms.ts +0 -0
  51. /package/templates/features/better-auth/files/{src/core/auth/tests/openapi.test.ts → tests/tatara/auth-openapi.test.ts} +0 -0
  52. /package/templates/features/better-auth/files+drizzle+mysql/src/{core/auth → modules/users}/db/auth.schema.ts +0 -0
  53. /package/templates/features/better-auth/files+drizzle+postgres/src/{core/auth → modules/users}/db/auth.schema.ts +0 -0
  54. /package/templates/features/better-auth/files+prisma+mysql/src/{core/auth → modules/users/services}/adapter.ts +0 -0
  55. /package/templates/features/better-auth/files+prisma+postgres/src/{core/auth → modules/users/services}/adapter.ts +0 -0
  56. /package/templates/features/email/files/{src/core/email/tests → tests/tatara}/email.test.ts +0 -0
  57. /package/templates/features/i18n/files/{src/core/i18n/tests → tests/tatara}/i18n.test.ts +0 -0
  58. /package/templates/features/storage/files/{src/core/storage/tests → tests/tatara}/storage.test.ts +0 -0
@@ -0,0 +1,37 @@
1
+ import { createAuthInstance } from "@tatara/auth";
2
+ import { newId } from "@tatara/db";
3
+ import { bearer, openAPI } from "better-auth/plugins";
4
+ import { env } from "#core/config/env";
5
+ import { database } from "#modules/users/services/adapter";
6
+ // tatara:slot imports
7
+
8
+ /**
9
+ * The app's better-auth for its users. The options are the app's own; tatara only adds the
10
+ * principal middleware and the org check that come back with the instance.
11
+ */
12
+ export const { auth, attachPrincipal, requireOrg } = createAuthInstance(
13
+ {
14
+ appName: "__APP_NAME__",
15
+ baseURL: env.APP_URL,
16
+ basePath: "/api/auth",
17
+ secret: env.BETTER_AUTH_SECRET,
18
+ trustedOrigins: env.CORS_ORIGINS,
19
+ database,
20
+ advanced: { database: { generateId: () => newId() } },
21
+ // tatara:slot options
22
+ plugins: [
23
+ // Authorization: Bearer <session token> for mobile and API clients
24
+ bearer(),
25
+ // reference for the auth endpoints at /api/auth/reference
26
+ openAPI(),
27
+ // tatara:slot plugins
28
+ ],
29
+ },
30
+ {
31
+ resolvers: [
32
+ // tatara:slot resolvers
33
+ ],
34
+ },
35
+ );
36
+
37
+ export type Session = typeof auth.$Infer.Session;
@@ -1,5 +1,5 @@
1
1
  import { createOutbox } from "@tatara/auth";
2
- import { smsSender } from "#core/auth/sms";
2
+ import { smsSender } from "#modules/users/services/sms";
3
3
  import { env } from "#core/config/env";
4
4
  // tatara:slot imports
5
5
 
@@ -1,5 +1,5 @@
1
1
  import { createTestUser as createUser, sessionHeaders } from "@tatara/auth/testing";
2
- import { auth } from "#core/auth/auth";
2
+ import { auth } from "#modules/users/services/auth";
3
3
  // tatara:slot imports
4
4
 
5
5
  export interface AsUserOptions {
@@ -24,10 +24,11 @@ export async function createTestUser(options: AsUserOptions = {}): Promise<strin
24
24
  /** A new user with a real session; the token is sent as a bearer token. */
25
25
  export async function authenticate(
26
26
  options: AsUserOptions = {},
27
- ): Promise<{ userId: string; headers: Record<string, string> }> {
27
+ ): Promise<{ userId: string; orgId?: string; headers: Record<string, string> }> {
28
28
  // tatara:slot authenticate
29
29
  const userId = await createTestUser(options);
30
- return { userId, headers: await sessionHeaders(auth, userId) };
30
+ const headers = await sessionHeaders(auth, userId);
31
+ // tatara:slot authenticated
31
32
  }
32
33
 
33
34
  /** Headers that authenticate as a new user. */
@@ -0,0 +1,10 @@
1
+ import { expect, it } from "vitest";
2
+ import { adminApi } from "#tests/helpers/api";
3
+
4
+ it("documents the staff auth on the admin app, not the users' sign-up", async () => {
5
+ const res = await adminApi.get<{ paths: Record<string, unknown> }>("/openapi.json");
6
+ expect(res.status).toBe(200);
7
+ const paths = Object.keys(res.body.paths);
8
+ expect(paths).toContain("/api/auth/sign-in/email");
9
+ expect(paths.some((path) => path.startsWith("/api/auth/sign-in/anonymous"))).toBe(false);
10
+ });
@@ -1,5 +1,5 @@
1
1
  import { beforeEach, describe, expect, it } from "vitest";
2
- import { auth } from "#core/auth/auth";
2
+ import { auth } from "#modules/users/services/auth";
3
3
  import { api } from "#tests/helpers/api";
4
4
  import { authenticate } from "#tests/helpers/auth";
5
5
  import { resetDatabase } from "#tests/helpers/db";
@@ -1,5 +1,5 @@
1
1
  import { beforeEach, expect, it } from "vitest";
2
- import { auth } from "#core/auth/auth";
2
+ import { auth } from "#modules/users/services/auth";
3
3
  import { api } from "#tests/helpers/api";
4
4
  import { authenticate } from "#tests/helpers/auth";
5
5
  import { applyTestAccess } from "#tests/helpers/authz";
@@ -1,5 +1,5 @@
1
1
  import { drizzleAdapter } from "better-auth/adapters/drizzle";
2
- import * as authSchema from "#core/auth/db/auth.schema";
2
+ import * as authSchema from "#modules/users/db/auth.schema";
3
3
  import { db } from "#core/db/client";
4
4
  // tatara:slot imports
5
5
 
@@ -1,5 +1,5 @@
1
1
  import { drizzleAdapter } from "better-auth/adapters/drizzle";
2
- import * as authSchema from "#core/auth/db/auth.schema";
2
+ import * as authSchema from "#modules/users/db/auth.schema";
3
3
  import { db } from "#core/db/client";
4
4
  // tatara:slot imports
5
5
 
@@ -33,11 +33,11 @@
33
33
  "@types/nodemailer": "8.0.2",
34
34
  "@tatara/core": "0.1.1",
35
35
  "@tatara/http": "0.1.1",
36
- "@tatara/db": "0.2.0",
36
+ "@tatara/db": "0.2.1",
37
37
  "@tatara/testing": "0.1.1",
38
- "@tatara/auth": "0.1.1",
39
- "@tatara/keycloak": "0.1.1",
40
- "@tatara/authz": "0.2.0",
38
+ "@tatara/auth": "0.2.0",
39
+ "@tatara/keycloak": "0.1.2",
40
+ "@tatara/authz": "0.3.0",
41
41
  "@tatara/storage": "0.2.0",
42
42
  "@tatara/email": "0.2.0",
43
43
  "@tatara/i18n": "0.1.0",
@@ -1,26 +0,0 @@
1
- import { betterAuth } from "better-auth";
2
- import { bearer, openAPI } from "better-auth/plugins";
3
- import { database } from "#core/auth/adapter";
4
- import { env } from "#core/config/env";
5
- import { newId } from "@tatara/db";
6
- // tatara:slot imports
7
-
8
- export const auth = betterAuth({
9
- appName: "__APP_NAME__",
10
- baseURL: env.APP_URL,
11
- basePath: "/api/auth",
12
- secret: env.BETTER_AUTH_SECRET,
13
- trustedOrigins: env.CORS_ORIGINS,
14
- database,
15
- advanced: { database: { generateId: () => newId() } },
16
- // tatara:slot options
17
- plugins: [
18
- // Authorization: Bearer <session token> for mobile and API clients
19
- bearer(),
20
- // reference for the auth endpoints at /api/auth/reference
21
- openAPI(),
22
- // tatara:slot plugins
23
- ],
24
- });
25
-
26
- export type Session = typeof auth.$Infer.Session;
@@ -1,10 +0,0 @@
1
- import { principalMiddleware, sessionPrincipal } from "@tatara/auth";
2
- import { auth } from "#core/auth/auth";
3
- import type { AppEnv } from "#core/http/context";
4
- // tatara:slot imports
5
-
6
- /** Sets `c.var.principal` from the first resolver that recognises the request's credentials. */
7
- export const attachPrincipal = principalMiddleware<AppEnv>([
8
- (c) => sessionPrincipal(auth, c.req.raw.headers),
9
- // tatara:slot resolvers
10
- ]);
@@ -1,8 +0,0 @@
1
- import { expect, it } from "vitest";
2
- import { adminApi } from "#tests/helpers/api";
3
-
4
- it("leaves auth out of the admin OpenAPI document", async () => {
5
- const res = await adminApi.get<{ paths: Record<string, unknown> }>("/openapi.json");
6
- expect(res.status).toBe(200);
7
- expect(Object.keys(res.body.paths).some((path) => path.startsWith("/api/auth/"))).toBe(false);
8
- });