@apso/cli 0.5.0 → 0.7.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 (69) hide show
  1. package/README.md +510 -1
  2. package/dist/commands/server/new.js +1 -1
  3. package/dist/commands/server/scaffold.js +19 -10
  4. package/dist/lib/apsorc-parser.d.ts +3 -0
  5. package/dist/lib/apsorc-parser.js +11 -6
  6. package/dist/lib/controller.js +3 -1
  7. package/dist/lib/dto.js +9 -9
  8. package/dist/lib/entity.js +6 -5
  9. package/dist/lib/guards.d.ts +4 -3
  10. package/dist/lib/guards.js +64 -25
  11. package/dist/lib/module.js +3 -1
  12. package/dist/lib/templates/guards/auth.guard.eta +228 -0
  13. package/dist/lib/templates/guards/guards.module.eta +73 -13
  14. package/dist/lib/templates/guards/index.eta +18 -0
  15. package/dist/lib/templates/guards/scope.guard.eta +12 -4
  16. package/dist/lib/types/auth.d.ts +203 -0
  17. package/dist/lib/types/auth.js +60 -0
  18. package/dist/lib/types/entity.d.ts +2 -2
  19. package/dist/lib/types/index.d.ts +1 -0
  20. package/dist/lib/types/index.js +8 -0
  21. package/dist/lib/types/relationship.d.ts +1 -1
  22. package/dist/lib/utils/casing.js +5 -5
  23. package/dist/lib/utils/field.js +2 -1
  24. package/dist/lib/utils/file-system.js +1 -1
  25. package/dist/lib/utils/relationships/parse-v1.js +2 -1
  26. package/dist/lib/utils/relationships/parse.js +117 -32
  27. package/dist/lib/utils/relationships/parse.spec.js +168 -141
  28. package/dist/test-nested-relationships.js +10 -10
  29. package/dist/tests/templates/entities/types/array-template.spec.js +45 -45
  30. package/dist/tests/templates/entities/types/bigint-template.spec.js +43 -43
  31. package/dist/tests/templates/entities/types/boolean-template.spec.js +44 -44
  32. package/dist/tests/templates/entities/types/bytea-template.spec.js +35 -35
  33. package/dist/tests/templates/entities/types/char-template.spec.js +35 -35
  34. package/dist/tests/templates/entities/types/date-template.spec.js +29 -29
  35. package/dist/tests/templates/entities/types/decimal-field-validation.spec.js +46 -46
  36. package/dist/tests/templates/entities/types/decimal-template.spec.js +46 -46
  37. package/dist/tests/templates/entities/types/double-template.spec.js +37 -34
  38. package/dist/tests/templates/entities/types/enum-template.spec.js +42 -42
  39. package/dist/tests/templates/entities/types/float-template.spec.js +37 -34
  40. package/dist/tests/templates/entities/types/geometry-template.spec.js +31 -31
  41. package/dist/tests/templates/entities/types/inet-template.spec.js +36 -36
  42. package/dist/tests/templates/entities/types/int4range-template.spec.js +45 -33
  43. package/dist/tests/templates/entities/types/integer-template.spec.js +40 -40
  44. package/dist/tests/templates/entities/types/interval-template.spec.js +35 -35
  45. package/dist/tests/templates/entities/types/json-plain-template.spec.js +27 -27
  46. package/dist/tests/templates/entities/types/json-template.spec.js +19 -19
  47. package/dist/tests/templates/entities/types/jsonb-template.spec.js +19 -19
  48. package/dist/tests/templates/entities/types/money-template.spec.js +35 -35
  49. package/dist/tests/templates/entities/types/numeric-template.spec.js +44 -44
  50. package/dist/tests/templates/entities/types/point-template.spec.js +37 -31
  51. package/dist/tests/templates/entities/types/polygon-template.spec.js +43 -31
  52. package/dist/tests/templates/entities/types/real-template.spec.js +34 -34
  53. package/dist/tests/templates/entities/types/serial-template.spec.js +62 -62
  54. package/dist/tests/templates/entities/types/smallint-template.spec.js +43 -43
  55. package/dist/tests/templates/entities/types/string-template.spec.js +59 -59
  56. package/dist/tests/templates/entities/types/text-template.spec.js +37 -37
  57. package/dist/tests/templates/entities/types/time-template.spec.js +35 -35
  58. package/dist/tests/templates/entities/types/timestamp-template.spec.js +39 -39
  59. package/dist/tests/templates/entities/types/timetz-template.spec.js +35 -35
  60. package/dist/tests/templates/entities/types/tsvector-template.spec.js +28 -28
  61. package/dist/tests/templates/entities/types/uuid-template.spec.js +43 -43
  62. package/dist/tests/templates/entities/types/varchar-template.spec.js +59 -56
  63. package/dist/tests/templates/entities/types/xml-template.spec.js +28 -28
  64. package/dist/tests/templates/entities/utils/template-test-utils.d.ts +1 -1
  65. package/dist/tests/templates/entities/utils/template-test-utils.js +3 -3
  66. package/dist/tests/templates/entities/uuid-entity-template.spec.js +138 -138
  67. package/dist/tests/utils/relationship-deduplication.spec.js +11 -11
  68. package/oclif.manifest.json +1 -1
  69. package/package.json +1 -1
@@ -4,51 +4,111 @@ import { Module, Global } from '@nestjs/common';
4
4
  import { TypeOrmModule } from '@nestjs/typeorm';
5
5
  import { APP_GUARD } from '@nestjs/core';
6
6
 
7
+ <% if (it.scopedEntities && it.scopedEntities.length > 0) { %>
7
8
  import { ScopeGuard } from './scope.guard';
9
+ <% } %>
10
+ <% if (it.authConfig) { %>
11
+ import { AuthGuard } from './auth.guard';
12
+ <% } %>
8
13
 
9
- <% /* Import all entities that have scopeBy defined */ %>
14
+ <% /* Import all entities for ScopeGuard (from sibling autogen folders) */ %>
15
+ <% if (it.scopedEntities && it.scopedEntities.length > 0) { %>
16
+ // Entities for ScopeGuard
10
17
  <% it.scopedEntities.forEach((entity) => { %>
11
- import { <%= entity.name %> } from '../autogen/<%= entity.name %>/<%= entity.name %>.entity';
18
+ import { <%= entity.name %> } from '../<%= entity.name %>/<%= entity.name %>.entity';
12
19
  <% }) %>
20
+ <% } %>
21
+
22
+ <% /* Import entities for AuthGuard (from sibling autogen folders) */ %>
23
+ <% if (it.authConfig) { %>
24
+ // Entities for AuthGuard
25
+ import { <%= it.authConfig.sessionEntity %> } from '../<%= it.authConfig.sessionEntity %>/<%= it.authConfig.sessionEntity %>.entity';
26
+ import { <%= it.authConfig.userEntity %> } from '../<%= it.authConfig.userEntity %>/<%= it.authConfig.userEntity %>.entity';
27
+ <% if (it.authConfig.accountUserEntity) { %>
28
+ import { <%= it.authConfig.accountUserEntity %> } from '../<%= it.authConfig.accountUserEntity %>/<%= it.authConfig.accountUserEntity %>.entity';
29
+ <% } %>
30
+ <% } %>
13
31
 
14
32
  /**
15
- * GuardsModule provides scope-based data isolation guards.
33
+ * GuardsModule provides authentication and scope-based data isolation guards.
16
34
  *
17
- * Auto-generated from .apsorc scopeBy definitions.
35
+ * Auto-generated from .apsorc configuration.
36
+ * Generated at: <%= it.generatedAt %>
18
37
  *
19
38
  * Usage:
20
39
  * 1. Import GuardsModule in your AppModule
21
40
  * 2. Guards are NOT enabled globally by default (for backward compatibility)
22
- * 3. To enable guards globally, uncomment the APP_GUARD provider below
23
- * 4. Or apply guards selectively using @UseGuards(ScopeGuard) on controllers/routes
41
+ * 3. To enable guards globally, uncomment the APP_GUARD providers below
42
+ * 4. Or apply guards selectively using @UseGuards(AuthGuard, ScopeGuard) on controllers
43
+ *
44
+ <% if (it.authConfig) { %>
45
+ * AuthGuard:
46
+ * - Validates session tokens from cookies/headers
47
+ * - Loads user and organization context
48
+ * - Attaches normalized AuthContext to request.auth
49
+ * - Provider: <%= it.authConfig.provider %>
24
50
  *
25
- * When guards are enabled:
26
- * - All scoped routes enforce data isolation based on scopeBy config
27
- * - POST requests auto-inject scope fields from request context
51
+ <% } %>
52
+ <% if (it.scopedEntities && it.scopedEntities.length > 0) { %>
53
+ * ScopeGuard:
54
+ * - Enforces data isolation based on scopeBy config
55
+ * - POST requests auto-inject scope fields from request.auth
28
56
  * - GET requests auto-filter by scope fields
29
57
  * - GET/PUT/PATCH/DELETE by ID verify resource ownership
30
58
  *
59
+ <% } %>
31
60
  * Decorators:
32
61
  * - @Public() - Skip all guards for a route
62
+ <% if (it.scopedEntities && it.scopedEntities.length > 0) { %>
33
63
  * - @SkipScopeCheck() - Skip only scope checking
64
+ <% } %>
34
65
  */
35
66
  @Global()
36
67
  @Module({
37
68
  imports: [
38
69
  TypeOrmModule.forFeature([
39
- <% it.scopedEntities.forEach((entity, index) => { %>
40
- <%= entity.name %><%= index < it.scopedEntities.length - 1 ? ',' : '' %>
70
+ <% /* Collect all unique entities */ %>
71
+ <% const allEntities = new Set(); %>
72
+ <% if (it.scopedEntities) { it.scopedEntities.forEach(e => allEntities.add(e.name)); } %>
73
+ <% if (it.authConfig) { %>
74
+ <% allEntities.add(it.authConfig.sessionEntity); %>
75
+ <% allEntities.add(it.authConfig.userEntity); %>
76
+ <% if (it.authConfig.accountUserEntity) { allEntities.add(it.authConfig.accountUserEntity); } %>
77
+ <% } %>
78
+ <% const entityArray = Array.from(allEntities); %>
79
+ <% entityArray.forEach((entity, index) => { %>
80
+ <%= entity %><%= index < entityArray.length - 1 ? ',' : '' %>
41
81
  <% }) %>
42
82
  ]),
43
83
  ],
44
84
  providers: [
85
+ <% if (it.authConfig) { %>
86
+ AuthGuard,
87
+ <% } %>
88
+ <% if (it.scopedEntities && it.scopedEntities.length > 0) { %>
45
89
  ScopeGuard,
46
- // UNCOMMENT BELOW TO ENABLE GLOBAL SCOPE ENFORCEMENT
90
+ <% } %>
91
+ // UNCOMMENT BELOW TO ENABLE GLOBAL GUARDS
92
+ <% if (it.authConfig) { %>
93
+ // {
94
+ // provide: APP_GUARD,
95
+ // useClass: AuthGuard,
96
+ // },
97
+ <% } %>
98
+ <% if (it.scopedEntities && it.scopedEntities.length > 0) { %>
47
99
  // {
48
100
  // provide: APP_GUARD,
49
101
  // useClass: ScopeGuard,
50
102
  // },
103
+ <% } %>
104
+ ],
105
+ exports: [
106
+ <% if (it.authConfig) { %>
107
+ AuthGuard,
108
+ <% } %>
109
+ <% if (it.scopedEntities && it.scopedEntities.length > 0) { %>
110
+ ScopeGuard,
111
+ <% } %>
51
112
  ],
52
- exports: [ScopeGuard],
53
113
  })
54
114
  export class GuardsModule {}
@@ -1,4 +1,22 @@
1
1
  <%~ includeFile('../header.eta') %>
2
2
 
3
+ <% if (it.authConfig) { %>
4
+ export * from './auth.guard';
5
+ <% } %>
6
+ <% if (it.scopedEntities && it.scopedEntities.length > 0) { %>
7
+ <% if (it.authConfig) { %>
8
+ // When auth is configured, only export scope-specific items from scope.guard
9
+ // to avoid duplicate exports (Public, IS_PUBLIC_KEY come from auth.guard)
10
+ export {
11
+ ScopeGuard,
12
+ SKIP_SCOPE_CHECK,
13
+ SkipScopeCheck,
14
+ ScopeConfig,
15
+ ScopeField,
16
+ ENTITY_SCOPES,
17
+ } from './scope.guard';
18
+ <% } else { %>
3
19
  export * from './scope.guard';
20
+ <% } %>
21
+ <% } %>
4
22
  export * from './guards.module';
@@ -10,9 +10,9 @@ import { Reflector } from '@nestjs/core';
10
10
  import { InjectRepository } from '@nestjs/typeorm';
11
11
  import { Repository } from 'typeorm';
12
12
 
13
- <% /* Import all entities that have scoped relationships */ %>
13
+ <% /* Import all entities that have scoped relationships (from sibling autogen folders) */ %>
14
14
  <% it.scopedEntities.forEach((entity) => { %>
15
- import { <%= entity.name %> } from '../autogen/<%= entity.name %>/<%= entity.name %>.entity';
15
+ import { <%= entity.name %> } from '../<%= entity.name %>/<%= entity.name %>.entity';
16
16
  <% }) %>
17
17
 
18
18
  /**
@@ -28,6 +28,13 @@ export const SkipScopeCheck = () =>
28
28
  );
29
29
  };
30
30
 
31
+ <% if (it.authConfig) { %>
32
+ /**
33
+ * Import Public decorator from auth.guard to avoid duplicate exports
34
+ */
35
+ import { IS_PUBLIC_KEY, Public } from './auth.guard';
36
+ export { IS_PUBLIC_KEY, Public };
37
+ <% } else { %>
31
38
  /**
32
39
  * Decorator to mark routes as public (no auth required)
33
40
  */
@@ -40,6 +47,7 @@ export const Public = () =>
40
47
  descriptor?.value || target,
41
48
  );
42
49
  };
50
+ <% } %>
43
51
 
44
52
  /**
45
53
  * Scope configuration for each entity
@@ -87,8 +95,8 @@ export const ENTITY_SCOPES: Record<string, ScopeConfig> = {
87
95
  <% }) %>
88
96
  ],
89
97
  injectOnCreate: <%= entity.injectOnCreate %>,
90
- enforceOn: [<%= entity.enforceOn.map(op => `'${op}'`).join(', ') %>],
91
- bypassRoles: [<%= entity.bypassRoles.map(role => `'${role}'`).join(', ') %>],
98
+ enforceOn: [<%~ entity.enforceOn.map(op => `'${op}'`).join(', ') %>],
99
+ bypassRoles: [<%~ entity.bypassRoles.map(role => `'${role}'`).join(', ') %>],
92
100
  }<%= index < it.scopedEntities.length - 1 ? ',' : '' %>
93
101
  <% }) %>
94
102
  };
@@ -0,0 +1,203 @@
1
+ /**
2
+ * Supported authentication provider types
3
+ */
4
+ export type AuthProviderType = "better-auth" | "custom-db-session" | "auth0" | "clerk" | "cognito" | "api-key";
5
+ /**
6
+ * Base configuration common to all auth providers
7
+ */
8
+ export interface BaseAuthConfig {
9
+ /**
10
+ * The authentication provider type
11
+ */
12
+ provider: AuthProviderType;
13
+ }
14
+ /**
15
+ * Configuration for DB-backed session providers (Better Auth, custom-db-session)
16
+ */
17
+ export interface DbSessionAuthConfig extends BaseAuthConfig {
18
+ provider: "better-auth" | "custom-db-session";
19
+ /**
20
+ * Entity name for sessions. Default: "session"
21
+ */
22
+ sessionEntity?: string;
23
+ /**
24
+ * Entity name for users. Default: "User"
25
+ */
26
+ userEntity?: string;
27
+ /**
28
+ * Junction entity for user-organization mapping. Default: "AccountUser"
29
+ */
30
+ accountUserEntity?: string;
31
+ /**
32
+ * Cookie name prefix for session tokens. Default: service name
33
+ */
34
+ cookiePrefix?: string;
35
+ /**
36
+ * Field name on accountUserEntity for organization ID. Default: "organizationId"
37
+ */
38
+ organizationField?: string;
39
+ /**
40
+ * Field name on accountUserEntity for user's role. Default: "role"
41
+ */
42
+ roleField?: string;
43
+ }
44
+ /**
45
+ * JWT configuration for token-based providers
46
+ */
47
+ export interface JwtConfig {
48
+ /**
49
+ * The JWT issuer URL (e.g., "https://your-tenant.auth0.com/")
50
+ */
51
+ issuer: string;
52
+ /**
53
+ * Expected audience for the JWT
54
+ */
55
+ audience: string;
56
+ /**
57
+ * JWKS URI for key rotation. If not provided, uses issuer + /.well-known/jwks.json
58
+ */
59
+ jwksUri?: string;
60
+ /**
61
+ * Algorithms to accept. Default: ["RS256"]
62
+ */
63
+ algorithms?: string[];
64
+ }
65
+ /**
66
+ * Claim mapping for JWT providers
67
+ */
68
+ export interface JwtClaimsMapping {
69
+ /**
70
+ * Claim for user ID. Default: "sub"
71
+ */
72
+ userId?: string;
73
+ /**
74
+ * Claim for workspace/organization ID
75
+ */
76
+ workspaceId?: string;
77
+ /**
78
+ * Claim for organization ID (alias for workspaceId)
79
+ */
80
+ organizationId?: string;
81
+ /**
82
+ * Claim for user roles array
83
+ */
84
+ roles?: string;
85
+ /**
86
+ * Claim for user email
87
+ */
88
+ email?: string;
89
+ }
90
+ /**
91
+ * Configuration for JWT-based providers (Auth0, Cognito, Clerk)
92
+ */
93
+ export interface JwtAuthConfig extends BaseAuthConfig {
94
+ provider: "auth0" | "clerk" | "cognito";
95
+ /**
96
+ * JWT verification configuration
97
+ */
98
+ jwt: JwtConfig;
99
+ /**
100
+ * Mapping of JWT claims to AuthContext fields
101
+ */
102
+ claims?: JwtClaimsMapping;
103
+ /**
104
+ * Optional: If you want to sync/verify users against a local User entity
105
+ */
106
+ userEntity?: string;
107
+ }
108
+ /**
109
+ * Configuration for API key authentication
110
+ */
111
+ export interface ApiKeyAuthConfig extends BaseAuthConfig {
112
+ provider: "api-key";
113
+ /**
114
+ * Header name for API key. Default: "x-api-key"
115
+ */
116
+ apiKeyHeader?: string;
117
+ /**
118
+ * Entity name for API keys. Default: "ApiKey"
119
+ */
120
+ apiKeyEntity?: string;
121
+ /**
122
+ * Field name on apiKeyEntity for workspace/organization ID
123
+ */
124
+ workspaceField?: string;
125
+ /**
126
+ * Field name on apiKeyEntity for role/permissions
127
+ */
128
+ roleField?: string;
129
+ }
130
+ /**
131
+ * Union type of all auth configurations
132
+ */
133
+ export type AuthConfig = DbSessionAuthConfig | JwtAuthConfig | ApiKeyAuthConfig;
134
+ /**
135
+ * The normalized AuthContext that all providers produce.
136
+ * This is what scopeBy and RBAC consume.
137
+ */
138
+ export interface AuthContext {
139
+ /**
140
+ * The authenticated user's ID
141
+ */
142
+ userId?: string;
143
+ /**
144
+ * The user's email (if available)
145
+ */
146
+ email?: string;
147
+ /**
148
+ * The workspace/tenant ID (generic term)
149
+ */
150
+ workspaceId?: string;
151
+ /**
152
+ * The organization ID (alias for workspaceId in multi-tenant contexts)
153
+ */
154
+ organizationId?: string;
155
+ /**
156
+ * Array of roles/permissions the user has
157
+ */
158
+ roles: string[];
159
+ /**
160
+ * For API key auth: the service/key identifier
161
+ */
162
+ serviceId?: string;
163
+ /**
164
+ * Raw user object (provider-specific, for advanced use cases)
165
+ */
166
+ user?: unknown;
167
+ /**
168
+ * Raw session object (provider-specific, for advanced use cases)
169
+ */
170
+ session?: unknown;
171
+ }
172
+ /**
173
+ * Default values for DB session auth configuration
174
+ */
175
+ export declare const DB_SESSION_AUTH_DEFAULTS: Required<Omit<DbSessionAuthConfig, "provider" | "cookiePrefix">> & {
176
+ cookiePrefix?: string;
177
+ };
178
+ /**
179
+ * Default values for JWT auth configuration
180
+ */
181
+ export declare const JWT_AUTH_DEFAULTS: Required<Pick<JwtAuthConfig, "claims">> & Partial<JwtConfig>;
182
+ /**
183
+ * Default values for API key auth configuration
184
+ */
185
+ export declare const API_KEY_AUTH_DEFAULTS: Required<Omit<ApiKeyAuthConfig, "provider" | "workspaceField" | "roleField">>;
186
+ /**
187
+ * Type guard: Check if auth config is DB session based
188
+ * @param {AuthConfig} auth - The auth configuration to check
189
+ * @returns {boolean} True if the auth config is DB session based
190
+ */
191
+ export declare function isDbSessionAuth(auth: AuthConfig): auth is DbSessionAuthConfig;
192
+ /**
193
+ * Type guard: Check if auth config is JWT based
194
+ * @param {AuthConfig} auth - The auth configuration to check
195
+ * @returns {boolean} True if the auth config is JWT based
196
+ */
197
+ export declare function isJwtAuth(auth: AuthConfig): auth is JwtAuthConfig;
198
+ /**
199
+ * Type guard: Check if auth config is API key based
200
+ * @param {AuthConfig} auth - The auth configuration to check
201
+ * @returns {boolean} True if the auth config is API key based
202
+ */
203
+ export declare function isApiKeyAuth(auth: AuthConfig): auth is ApiKeyAuthConfig;
@@ -0,0 +1,60 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.isApiKeyAuth = exports.isJwtAuth = exports.isDbSessionAuth = exports.API_KEY_AUTH_DEFAULTS = exports.JWT_AUTH_DEFAULTS = exports.DB_SESSION_AUTH_DEFAULTS = void 0;
4
+ /**
5
+ * Default values for DB session auth configuration
6
+ */
7
+ exports.DB_SESSION_AUTH_DEFAULTS = {
8
+ sessionEntity: "session",
9
+ userEntity: "User",
10
+ accountUserEntity: "AccountUser",
11
+ organizationField: "organizationId",
12
+ roleField: "role",
13
+ cookiePrefix: undefined, // Will use service name if not specified
14
+ };
15
+ /**
16
+ * Default values for JWT auth configuration
17
+ */
18
+ exports.JWT_AUTH_DEFAULTS = {
19
+ claims: {
20
+ userId: "sub",
21
+ email: "email",
22
+ roles: "roles",
23
+ },
24
+ };
25
+ /**
26
+ * Default values for API key auth configuration
27
+ */
28
+ exports.API_KEY_AUTH_DEFAULTS = {
29
+ apiKeyHeader: "x-api-key",
30
+ apiKeyEntity: "ApiKey",
31
+ };
32
+ /**
33
+ * Type guard: Check if auth config is DB session based
34
+ * @param {AuthConfig} auth - The auth configuration to check
35
+ * @returns {boolean} True if the auth config is DB session based
36
+ */
37
+ function isDbSessionAuth(auth) {
38
+ return auth.provider === "better-auth" || auth.provider === "custom-db-session";
39
+ }
40
+ exports.isDbSessionAuth = isDbSessionAuth;
41
+ /**
42
+ * Type guard: Check if auth config is JWT based
43
+ * @param {AuthConfig} auth - The auth configuration to check
44
+ * @returns {boolean} True if the auth config is JWT based
45
+ */
46
+ function isJwtAuth(auth) {
47
+ return (auth.provider === "auth0" ||
48
+ auth.provider === "clerk" ||
49
+ auth.provider === "cognito");
50
+ }
51
+ exports.isJwtAuth = isJwtAuth;
52
+ /**
53
+ * Type guard: Check if auth config is API key based
54
+ * @param {AuthConfig} auth - The auth configuration to check
55
+ * @returns {boolean} True if the auth config is API key based
56
+ */
57
+ function isApiKeyAuth(auth) {
58
+ return auth.provider === "api-key";
59
+ }
60
+ exports.isApiKeyAuth = isApiKeyAuth;
@@ -5,7 +5,7 @@ import { Association } from "./relationship";
5
5
  /**
6
6
  * Operations that can have scope enforcement applied
7
7
  */
8
- export type ScopeOperation = 'find' | 'get' | 'create' | 'update' | 'delete';
8
+ export type ScopeOperation = "find" | "get" | "create" | "update" | "delete";
9
9
  /**
10
10
  * Configuration options for scope enforcement behavior
11
11
  */
@@ -28,7 +28,7 @@ export interface Entity {
28
28
  name: string;
29
29
  created_at?: boolean;
30
30
  updated_at?: boolean;
31
- primaryKeyType?: 'serial' | 'uuid';
31
+ primaryKeyType?: "serial" | "uuid";
32
32
  fields?: Field[];
33
33
  indexes?: Index[];
34
34
  uniques?: Unique[];
@@ -3,3 +3,4 @@ export { FieldType, Field, ComputedField } from "./field";
3
3
  export { Index } from "./indices";
4
4
  export { JSONValue } from "./json";
5
5
  export { RelationshipType, Association, ApsorcRelationship, Relationship, RelationshipForTemplate, RelationshipMap, } from "./relationship";
6
+ export { AuthProviderType, BaseAuthConfig, DbSessionAuthConfig, JwtConfig, JwtClaimsMapping, JwtAuthConfig, ApiKeyAuthConfig, AuthConfig, AuthContext, DB_SESSION_AUTH_DEFAULTS, JWT_AUTH_DEFAULTS, API_KEY_AUTH_DEFAULTS, isDbSessionAuth, isJwtAuth, isApiKeyAuth, } from "./auth";
@@ -1,2 +1,10 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.isApiKeyAuth = exports.isJwtAuth = exports.isDbSessionAuth = exports.API_KEY_AUTH_DEFAULTS = exports.JWT_AUTH_DEFAULTS = exports.DB_SESSION_AUTH_DEFAULTS = void 0;
4
+ var auth_1 = require("./auth");
5
+ Object.defineProperty(exports, "DB_SESSION_AUTH_DEFAULTS", { enumerable: true, get: function () { return auth_1.DB_SESSION_AUTH_DEFAULTS; } });
6
+ Object.defineProperty(exports, "JWT_AUTH_DEFAULTS", { enumerable: true, get: function () { return auth_1.JWT_AUTH_DEFAULTS; } });
7
+ Object.defineProperty(exports, "API_KEY_AUTH_DEFAULTS", { enumerable: true, get: function () { return auth_1.API_KEY_AUTH_DEFAULTS; } });
8
+ Object.defineProperty(exports, "isDbSessionAuth", { enumerable: true, get: function () { return auth_1.isDbSessionAuth; } });
9
+ Object.defineProperty(exports, "isJwtAuth", { enumerable: true, get: function () { return auth_1.isJwtAuth; } });
10
+ Object.defineProperty(exports, "isApiKeyAuth", { enumerable: true, get: function () { return auth_1.isApiKeyAuth; } });
@@ -36,7 +36,7 @@ export interface RelationshipForTemplate extends Relationship {
36
36
  joinTable: boolean;
37
37
  biDirectional: boolean;
38
38
  inversePropertyName?: string;
39
- referencedEntityPrimaryKeyType?: 'serial' | 'uuid';
39
+ referencedEntityPrimaryKeyType?: "serial" | "uuid";
40
40
  }
41
41
  export type RelationshipMap = {
42
42
  [key: string]: Relationship[];
@@ -2,16 +2,16 @@
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.pascalCase = exports.snakeCase = exports.camelCase = void 0;
4
4
  function camelCase(str) {
5
- return str
5
+ return (str
6
6
  // Insert a space before all caps that are followed by lower case (for PascalCase)
7
- .replace(/([\da-z])([A-Z])/g, '$1 $2')
7
+ .replace(/([\da-z])([A-Z])/g, "$1 $2")
8
8
  // Replace all separators with spaces
9
- .replace(/[ _-]+/g, ' ')
9
+ .replace(/[ _-]+/g, " ")
10
10
  // Lowercase the string, then uppercase the first letter of each word (except the first)
11
11
  .toLowerCase()
12
- .replace(/ (\w)/g, (_, c) => c ? c.toUpperCase() : '')
12
+ .replace(/ (\w)/g, (_, c) => (c ? c.toUpperCase() : ""))
13
13
  // Remove spaces
14
- .replace(/ /g, '');
14
+ .replace(/ /g, ""));
15
15
  }
16
16
  exports.camelCase = camelCase;
17
17
  const snakeCase = (str) => str[0].toLowerCase() +
@@ -102,7 +102,8 @@ const validateDecimalField = (field) => {
102
102
  return;
103
103
  }
104
104
  // Validate precision
105
- if (field.precision !== undefined && (field.precision < 1 || field.precision > 131072)) {
105
+ if (field.precision !== undefined &&
106
+ (field.precision < 1 || field.precision > 131072)) {
106
107
  throw new Error(`${field.name}: Invalid precision value ${field.precision}. Must be between 1 and 131072.`);
107
108
  }
108
109
  // Validate scale
@@ -54,7 +54,7 @@ function withGeneratedMeta(data) {
54
54
  return {
55
55
  ...data,
56
56
  generatedAt: new Date().toISOString(),
57
- generatedBy: process.env.USER || process.env.USERNAME || 'unknown',
57
+ generatedBy: process.env.USER || process.env.USERNAME || "unknown",
58
58
  };
59
59
  }
60
60
  exports.withGeneratedMeta = withGeneratedMeta;
@@ -79,7 +79,8 @@ const parseV1Relationships = (entities) => {
79
79
  for (const apsorcRelationship of apsorcRelationships) {
80
80
  const parsedResult = (0, parse_1.parseRelationship)(apsorcRelationship, apsorcRelationships);
81
81
  for (const key of Object.keys(parsedResult)) {
82
- if (parsedResult[key] && parsedResult[key].length > 0) { // Ensure non-empty result
82
+ if (parsedResult[key] && parsedResult[key].length > 0) {
83
+ // Ensure non-empty result
83
84
  relationshipMap[key] = [
84
85
  ...(relationshipMap[key] || []),
85
86
  ...parsedResult[key],