@stacksjs/defaults 0.75.12 → 0.75.14
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.
- package/ide/vscode/package.json +1 -1
- package/package.json +2 -2
- package/project/storage/framework/types/authenticated-user.d.ts +41 -0
- package/project/storage/framework/types/billing.ts +60 -0
- package/project/storage/framework/types/env.d.ts +34 -0
- package/project/storage/framework/types/gates.d.ts +58 -0
- package/project/storage/framework/types/git.ts +293 -0
- package/project/storage/framework/types/model-events.d.ts +60 -0
- package/project/storage/framework/types/models.d.ts +28 -0
- package/project/storage/framework/types/orm-globals.d.ts +94 -0
- package/project/storage/framework/types/registries.d.ts +140 -0
- package/project/storage/framework/types/request-context.d.ts +57 -0
- package/project/storage/framework/types/reset.d.ts +1 -0
- package/project/storage/framework/types/shims.d.ts +20 -0
- package/project/storage/framework/types/src/auth.ts +25 -0
- package/project/storage/framework/types/traits.d.ts +230 -0
package/ide/vscode/package.json
CHANGED
package/package.json
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
"name": "@stacksjs/defaults",
|
|
3
3
|
"type": "module",
|
|
4
4
|
"sideEffects": false,
|
|
5
|
-
"version": "0.75.
|
|
5
|
+
"version": "0.75.14",
|
|
6
6
|
"repository": {
|
|
7
7
|
"type": "git",
|
|
8
8
|
"url": "git+https://github.com/stacksjs/stacks.git",
|
|
@@ -55,7 +55,7 @@
|
|
|
55
55
|
"dependencies": {
|
|
56
56
|
"@iconify-json/f7": "^1.2.2",
|
|
57
57
|
"@iconify-json/hugeicons": "^1.2.27",
|
|
58
|
-
"@stacksjs/mobile": "^0.75.
|
|
58
|
+
"@stacksjs/mobile": "^0.75.14",
|
|
59
59
|
"@stacksjs/sanitizer": "^0.2.113",
|
|
60
60
|
"ts-qr-codes": "^0.1.8"
|
|
61
61
|
}
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
// The signed-in user's columns, derived rather than declared.
|
|
2
|
+
//
|
|
3
|
+
// `request.user()` resolves to `AuthenticatedUser` from `@stacksjs/types`. That
|
|
4
|
+
// package cannot import the ORM (it sits underneath it), so on its own it knows
|
|
5
|
+
// only `id` and `email`, and every other field is `unknown` until something
|
|
6
|
+
// says otherwise. This is what says otherwise: the columns of the User model
|
|
7
|
+
// the application actually runs, read off the same barrel
|
|
8
|
+
// `injectGlobalAutoImports` loads at runtime. Override `app/Models/User.ts` and
|
|
9
|
+
// the type follows with nothing to regenerate; add a column and `user.team_id`
|
|
10
|
+
// is typed the moment the model declares it.
|
|
11
|
+
//
|
|
12
|
+
// When that model declares `traits: { billable: true }`, the billable instance
|
|
13
|
+
// methods (`user.checkout(...)`, `user.newSubscription(...)`) come with it,
|
|
14
|
+
// because every record it hydrates carries them. With the trait off, they are
|
|
15
|
+
// absent, and `isBillable(user)` from `@stacksjs/orm` is how to ask.
|
|
16
|
+
//
|
|
17
|
+
// `id` stays as `@stacksjs/types` declares it, `number | string`, rather than
|
|
18
|
+
// the model's `number`: a BIGINT key comes back from Postgres as a string.
|
|
19
|
+
|
|
20
|
+
import type { BillableMethods, Def, ModelRow } from '@stacksjs/orm'
|
|
21
|
+
|
|
22
|
+
/** Every model, by the name the ORM exposes it under. */
|
|
23
|
+
type Models = typeof import('../auto-imports/models')
|
|
24
|
+
|
|
25
|
+
/** `true` for `any`, which is what an unresolvable barrel reads as. */
|
|
26
|
+
type IsAny<T> = 0 extends 1 & T ? true : false
|
|
27
|
+
|
|
28
|
+
/** The application's User model, or nothing when there is none to read. */
|
|
29
|
+
type AppUser = IsAny<Models> extends true ? never : Models extends { User: infer TUser } ? TUser : never
|
|
30
|
+
|
|
31
|
+
/** Its columns, minus the `id` the base interface declares more honestly. */
|
|
32
|
+
type AppUserColumns = [AppUser] extends [never] ? {} : Omit<ModelRow<AppUser>, 'id'>
|
|
33
|
+
|
|
34
|
+
/** Its billable methods, when it declares the trait. */
|
|
35
|
+
type AppUserBillable = [AppUser] extends [never]
|
|
36
|
+
? {}
|
|
37
|
+
: Def<AppUser> extends { readonly traits: { readonly billable: true } } ? BillableMethods : {}
|
|
38
|
+
|
|
39
|
+
declare module '@stacksjs/types' {
|
|
40
|
+
interface AuthenticatedUser extends AppUserColumns, AppUserBillable {}
|
|
41
|
+
}
|
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
export interface TransactionHistory {
|
|
2
|
+
id?: number
|
|
3
|
+
uuid?: string
|
|
4
|
+
name: string
|
|
5
|
+
description?: string
|
|
6
|
+
amount: number
|
|
7
|
+
type: string
|
|
8
|
+
provider_id?: string
|
|
9
|
+
user_id?: number
|
|
10
|
+
paymentmethod_id?: number
|
|
11
|
+
created_at: string
|
|
12
|
+
updated_at?: string
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
export interface PaymentMethod {
|
|
16
|
+
id?: number
|
|
17
|
+
uuid?: string
|
|
18
|
+
type: string
|
|
19
|
+
last_four: number
|
|
20
|
+
brand: string
|
|
21
|
+
exp_month: number
|
|
22
|
+
exp_year: number
|
|
23
|
+
is_default?: boolean
|
|
24
|
+
provider_id?: string
|
|
25
|
+
user_id?: number
|
|
26
|
+
created_at: string
|
|
27
|
+
updated_at?: string
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
export interface Product {
|
|
31
|
+
id?: number
|
|
32
|
+
uuid?: string
|
|
33
|
+
name: string
|
|
34
|
+
description?: number
|
|
35
|
+
key: number
|
|
36
|
+
unit_price?: number
|
|
37
|
+
status?: string
|
|
38
|
+
image?: string
|
|
39
|
+
provider_id?: string
|
|
40
|
+
created_at: string
|
|
41
|
+
updated_at?: string
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
export interface Subscription {
|
|
45
|
+
id?: number
|
|
46
|
+
uuid?: string
|
|
47
|
+
type: string
|
|
48
|
+
provider_id: string
|
|
49
|
+
provider_status: string
|
|
50
|
+
unit_price?: number
|
|
51
|
+
provider_type: string
|
|
52
|
+
provider_price_id?: string
|
|
53
|
+
quantity?: number
|
|
54
|
+
trial_ends_at?: string
|
|
55
|
+
ends_at?: string
|
|
56
|
+
last_used_at?: string
|
|
57
|
+
user_id?: number
|
|
58
|
+
created_at: string
|
|
59
|
+
updated_at?: string
|
|
60
|
+
}
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
// The application's environment variables, derived rather than generated.
|
|
2
|
+
//
|
|
3
|
+
// `config/env.ts` declares them with `defineEnv`, and this teaches `env` about
|
|
4
|
+
// them. The application used to have to write that itself, at the bottom of the
|
|
5
|
+
// file it had just filled in:
|
|
6
|
+
//
|
|
7
|
+
// declare module '@stacksjs/env' {
|
|
8
|
+
// interface StacksEnv extends InferEnv<typeof envSchema> {}
|
|
9
|
+
// }
|
|
10
|
+
//
|
|
11
|
+
// which is boilerplate that only ever has one correct spelling, and silently
|
|
12
|
+
// leaves every variable untyped when it is missing. The framework can read the
|
|
13
|
+
// schema itself.
|
|
14
|
+
//
|
|
15
|
+
// `@stacksjs/env` cannot do this from inside the package: a published `.d.ts`
|
|
16
|
+
// naming `../../../config/env` resolves to nothing under `node_modules/`. So it
|
|
17
|
+
// lives here, in the project, alongside the other derivations.
|
|
18
|
+
|
|
19
|
+
import type { InferEnv } from '@stacksjs/env'
|
|
20
|
+
|
|
21
|
+
/** The schema `config/env.ts` default-exports. */
|
|
22
|
+
type EnvSchema = typeof import('../../../config/env')['default']
|
|
23
|
+
|
|
24
|
+
declare module '@stacksjs/env' {
|
|
25
|
+
/**
|
|
26
|
+
* Each variable typed by its validator - `schema.number()` is a `number`,
|
|
27
|
+
* `schema.enum([...])` the union of those literals - and optional, because
|
|
28
|
+
* the process may simply not have it set. `InferEnv` drops the keys the
|
|
29
|
+
* framework already declares, so restating one cannot conflict.
|
|
30
|
+
*/
|
|
31
|
+
interface StacksEnv extends InferEnv<EnvSchema> {}
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
export {}
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
// Gates and policies, derived rather than listed.
|
|
2
|
+
//
|
|
3
|
+
// Both halves of `app/Gates.ts` name things that exist elsewhere - an ability
|
|
4
|
+
// the file itself defines, and a model the ORM exposes - and both used to be
|
|
5
|
+
// `string`. A mapping to a policy that is not there, or for a model that is not
|
|
6
|
+
// there, registered nothing and then denied every check against it, which is
|
|
7
|
+
// indistinguishable from a policy that means to say no.
|
|
8
|
+
//
|
|
9
|
+
// Nothing here is generated. The gates ARE the declaration, read back off the
|
|
10
|
+
// file, and the models come from the same barrel `injectGlobalAutoImports`
|
|
11
|
+
// loads at runtime - so neither can drift from what the application has.
|
|
12
|
+
|
|
13
|
+
/** Every model, by the name the ORM exposes it under. */
|
|
14
|
+
type Models = typeof import('../auto-imports/models')
|
|
15
|
+
|
|
16
|
+
/** The application's own `app/Gates.ts`, as it is written. */
|
|
17
|
+
type Authorization = typeof import('../../../app/Gates')['default']
|
|
18
|
+
|
|
19
|
+
/**
|
|
20
|
+
* The ability names its gates define, and the arguments each one takes.
|
|
21
|
+
*
|
|
22
|
+
* Bound with `infer` rather than looked up as `Authorization['gates']` behind
|
|
23
|
+
* an `extends GatesDefinition` check. That check passes, but inside its true
|
|
24
|
+
* branch the lookup reads back through the constraint's own index signature -
|
|
25
|
+
* `Readonly<Record<string, GateCallback>>` - so `keyof` came out `string`.
|
|
26
|
+
* `AppGates` then had a string index signature, `GateName` was `string`, and
|
|
27
|
+
* nothing was constrained: `Gate.allows('definitely-not-a-real-gate', user)`
|
|
28
|
+
* typechecked, which is exactly what this file exists to prevent.
|
|
29
|
+
*
|
|
30
|
+
* `A extends { gates: infer G }` binds the real object, so the names survive.
|
|
31
|
+
* It also still degrades to nothing rather than to an error when a project has
|
|
32
|
+
* replaced `Gates.ts` with something of another shape.
|
|
33
|
+
*/
|
|
34
|
+
type GateNames = Authorization extends { gates: infer G }
|
|
35
|
+
? Extract<keyof G, string>
|
|
36
|
+
: never
|
|
37
|
+
|
|
38
|
+
/**
|
|
39
|
+
* Each gate mapped to the arguments it takes AFTER the user.
|
|
40
|
+
*
|
|
41
|
+
* The registry used to map every name to `true`, recording that a gate existed
|
|
42
|
+
* and nothing about how to call it, so `Gate.allows('view-dashboard', user,
|
|
43
|
+
* 'junk', 42)` passed against a gate declared `(user) => boolean`.
|
|
44
|
+
*/
|
|
45
|
+
type GateArgsOf = Authorization extends { gates: infer G }
|
|
46
|
+
? {
|
|
47
|
+
[K in Extract<keyof G, string>]: G[K] extends (..._args: infer P) => unknown
|
|
48
|
+
? (P extends [unknown, ...infer Rest] ? Rest : [])
|
|
49
|
+
: never
|
|
50
|
+
}
|
|
51
|
+
: Record<never, never>
|
|
52
|
+
|
|
53
|
+
declare module '@stacksjs/auth' {
|
|
54
|
+
interface AppGates extends GateArgsOf {}
|
|
55
|
+
interface PolicyModels extends Record<keyof Models & string, true> {}
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
export {}
|
|
@@ -0,0 +1,293 @@
|
|
|
1
|
+
export interface GitHubCommit {
|
|
2
|
+
sha: string
|
|
3
|
+
node_id: string
|
|
4
|
+
commit: {
|
|
5
|
+
author: {
|
|
6
|
+
name: string
|
|
7
|
+
email: string
|
|
8
|
+
date: string
|
|
9
|
+
}
|
|
10
|
+
committer: {
|
|
11
|
+
name: string
|
|
12
|
+
email: string
|
|
13
|
+
date: string
|
|
14
|
+
}
|
|
15
|
+
message: string
|
|
16
|
+
tree: {
|
|
17
|
+
sha: string
|
|
18
|
+
url: string
|
|
19
|
+
}
|
|
20
|
+
url: string
|
|
21
|
+
comment_count: number
|
|
22
|
+
verification: {
|
|
23
|
+
verified: boolean
|
|
24
|
+
reason: string
|
|
25
|
+
signature: string | null
|
|
26
|
+
payload: string | null
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
url: string
|
|
30
|
+
html_url: string
|
|
31
|
+
comments_url: string
|
|
32
|
+
author: {
|
|
33
|
+
login: string
|
|
34
|
+
id: number
|
|
35
|
+
node_id: string
|
|
36
|
+
avatar_url: string
|
|
37
|
+
gravatar_id: string
|
|
38
|
+
url: string
|
|
39
|
+
html_url: string
|
|
40
|
+
followers_url: string
|
|
41
|
+
following_url: string
|
|
42
|
+
gists_url: string
|
|
43
|
+
starred_url: string
|
|
44
|
+
subscriptions_url: string
|
|
45
|
+
organizations_url: string
|
|
46
|
+
repos_url: string
|
|
47
|
+
events_url: string
|
|
48
|
+
received_events_url: string
|
|
49
|
+
type: string
|
|
50
|
+
site_admin: boolean
|
|
51
|
+
}
|
|
52
|
+
committer: {
|
|
53
|
+
login: string
|
|
54
|
+
id: number
|
|
55
|
+
node_id: string
|
|
56
|
+
avatar_url: string
|
|
57
|
+
gravatar_id: string
|
|
58
|
+
url: string
|
|
59
|
+
html_url: string
|
|
60
|
+
followers_url: string
|
|
61
|
+
following_url: string
|
|
62
|
+
gists_url: string
|
|
63
|
+
starred_url: string
|
|
64
|
+
subscriptions_url: string
|
|
65
|
+
organizations_url: string
|
|
66
|
+
repos_url: string
|
|
67
|
+
events_url: string
|
|
68
|
+
received_events_url: string
|
|
69
|
+
type: string
|
|
70
|
+
site_admin: boolean
|
|
71
|
+
}
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
export interface WorkflowRun {
|
|
75
|
+
id: number
|
|
76
|
+
name: string
|
|
77
|
+
node_id: string
|
|
78
|
+
head_branch: string
|
|
79
|
+
head_sha: string
|
|
80
|
+
path: string
|
|
81
|
+
display_title: string
|
|
82
|
+
run_number: number
|
|
83
|
+
event: string
|
|
84
|
+
status: string
|
|
85
|
+
conclusion: string
|
|
86
|
+
workflow_id: number
|
|
87
|
+
check_suite_id: number
|
|
88
|
+
check_suite_node_id: string
|
|
89
|
+
url: string
|
|
90
|
+
html_url: string
|
|
91
|
+
pull_requests: any[] // You might want to create a more detailed interface for pull requests
|
|
92
|
+
created_at: string
|
|
93
|
+
updated_at: string
|
|
94
|
+
actor: {
|
|
95
|
+
login: string
|
|
96
|
+
id: number
|
|
97
|
+
node_id: string
|
|
98
|
+
avatar_url: string
|
|
99
|
+
gravatar_id: string
|
|
100
|
+
url: string
|
|
101
|
+
html_url: string
|
|
102
|
+
followers_url: string
|
|
103
|
+
following_url: string
|
|
104
|
+
gists_url: string
|
|
105
|
+
starred_url: string
|
|
106
|
+
subscriptions_url: string
|
|
107
|
+
organizations_url: string
|
|
108
|
+
repos_url: string
|
|
109
|
+
events_url: string
|
|
110
|
+
received_events_url: string
|
|
111
|
+
type: string
|
|
112
|
+
site_admin: boolean
|
|
113
|
+
}
|
|
114
|
+
run_attempt: number
|
|
115
|
+
referenced_workflows: any[] // You might want to create a more detailed interface for workflows
|
|
116
|
+
run_started_at: string
|
|
117
|
+
triggering_actor: {
|
|
118
|
+
login: string
|
|
119
|
+
id: number
|
|
120
|
+
node_id: string
|
|
121
|
+
avatar_url: string
|
|
122
|
+
gravatar_id: string
|
|
123
|
+
url: string
|
|
124
|
+
html_url: string
|
|
125
|
+
followers_url: string
|
|
126
|
+
following_url: string
|
|
127
|
+
gists_url: string
|
|
128
|
+
starred_url: string
|
|
129
|
+
subscriptions_url: string
|
|
130
|
+
organizations_url: string
|
|
131
|
+
repos_url: string
|
|
132
|
+
events_url: string
|
|
133
|
+
received_events_url: string
|
|
134
|
+
type: string
|
|
135
|
+
site_admin: boolean
|
|
136
|
+
}
|
|
137
|
+
jobs_url: string
|
|
138
|
+
logs_url: string
|
|
139
|
+
check_suite_url: string
|
|
140
|
+
artifacts_url: string
|
|
141
|
+
cancel_url: string
|
|
142
|
+
rerun_url: string
|
|
143
|
+
previous_attempt_url: string | null
|
|
144
|
+
workflow_url: string
|
|
145
|
+
head_commit: {
|
|
146
|
+
id: string
|
|
147
|
+
tree_id: string
|
|
148
|
+
message: string
|
|
149
|
+
timestamp: string
|
|
150
|
+
author: {
|
|
151
|
+
name: string
|
|
152
|
+
email: string
|
|
153
|
+
}
|
|
154
|
+
committer: {
|
|
155
|
+
name: string
|
|
156
|
+
email: string
|
|
157
|
+
}
|
|
158
|
+
}
|
|
159
|
+
repository: {
|
|
160
|
+
id: number
|
|
161
|
+
node_id: string
|
|
162
|
+
name: string
|
|
163
|
+
full_name: string
|
|
164
|
+
private: boolean
|
|
165
|
+
owner: {
|
|
166
|
+
login: string
|
|
167
|
+
id: number
|
|
168
|
+
node_id: string
|
|
169
|
+
avatar_url: string
|
|
170
|
+
gravatar_id: string
|
|
171
|
+
url: string
|
|
172
|
+
html_url: string
|
|
173
|
+
followers_url: string
|
|
174
|
+
following_url: string
|
|
175
|
+
gists_url: string
|
|
176
|
+
starred_url: string
|
|
177
|
+
subscriptions_url: string
|
|
178
|
+
organizations_url: string
|
|
179
|
+
repos_url: string
|
|
180
|
+
events_url: string
|
|
181
|
+
received_events_url: string
|
|
182
|
+
type: string
|
|
183
|
+
site_admin: boolean
|
|
184
|
+
}
|
|
185
|
+
html_url: string
|
|
186
|
+
description: string
|
|
187
|
+
fork: boolean
|
|
188
|
+
url: string
|
|
189
|
+
forks_url: string
|
|
190
|
+
keys_url: string
|
|
191
|
+
collaborators_url: string
|
|
192
|
+
teams_url: string
|
|
193
|
+
hooks_url: string
|
|
194
|
+
issue_events_url: string
|
|
195
|
+
events_url: string
|
|
196
|
+
assignees_url: string
|
|
197
|
+
branches_url: string
|
|
198
|
+
tags_url: string
|
|
199
|
+
blobs_url: string
|
|
200
|
+
git_tags_url: string
|
|
201
|
+
git_refs_url: string
|
|
202
|
+
trees_url: string
|
|
203
|
+
statuses_url: string
|
|
204
|
+
languages_url: string
|
|
205
|
+
stargazers_url: string
|
|
206
|
+
contributors_url: string
|
|
207
|
+
subscribers_url: string
|
|
208
|
+
subscription_url: string
|
|
209
|
+
commits_url: string
|
|
210
|
+
git_commits_url: string
|
|
211
|
+
comments_url: string
|
|
212
|
+
issue_comment_url: string
|
|
213
|
+
contents_url: string
|
|
214
|
+
compare_url: string
|
|
215
|
+
merges_url: string
|
|
216
|
+
archive_url: string
|
|
217
|
+
downloads_url: string
|
|
218
|
+
issues_url: string
|
|
219
|
+
pulls_url: string
|
|
220
|
+
milestones_url: string
|
|
221
|
+
notifications_url: string
|
|
222
|
+
labels_url: string
|
|
223
|
+
releases_url: string
|
|
224
|
+
deployments_url: string
|
|
225
|
+
}
|
|
226
|
+
head_repository: {
|
|
227
|
+
id: number
|
|
228
|
+
node_id: string
|
|
229
|
+
name: string
|
|
230
|
+
full_name: string
|
|
231
|
+
private: boolean
|
|
232
|
+
owner: {
|
|
233
|
+
login: string
|
|
234
|
+
id: number
|
|
235
|
+
node_id: string
|
|
236
|
+
avatar_url: string
|
|
237
|
+
gravatar_id: string
|
|
238
|
+
url: string
|
|
239
|
+
html_url: string
|
|
240
|
+
followers_url: string
|
|
241
|
+
following_url: string
|
|
242
|
+
gists_url: string
|
|
243
|
+
starred_url: string
|
|
244
|
+
subscriptions_url: string
|
|
245
|
+
organizations_url: string
|
|
246
|
+
repos_url: string
|
|
247
|
+
events_url: string
|
|
248
|
+
received_events_url: string
|
|
249
|
+
type: string
|
|
250
|
+
site_admin: boolean
|
|
251
|
+
}
|
|
252
|
+
html_url: string
|
|
253
|
+
description: string
|
|
254
|
+
fork: boolean
|
|
255
|
+
url: string
|
|
256
|
+
forks_url: string
|
|
257
|
+
keys_url: string
|
|
258
|
+
collaborators_url: string
|
|
259
|
+
teams_url: string
|
|
260
|
+
hooks_url: string
|
|
261
|
+
issue_events_url: string
|
|
262
|
+
events_url: string
|
|
263
|
+
assignees_url: string
|
|
264
|
+
branches_url: string
|
|
265
|
+
tags_url: string
|
|
266
|
+
blobs_url: string
|
|
267
|
+
git_tags_url: string
|
|
268
|
+
git_refs_url: string
|
|
269
|
+
trees_url: string
|
|
270
|
+
statuses_url: string
|
|
271
|
+
languages_url: string
|
|
272
|
+
stargazers_url: string
|
|
273
|
+
contributors_url: string
|
|
274
|
+
subscribers_url: string
|
|
275
|
+
subscription_url: string
|
|
276
|
+
commits_url: string
|
|
277
|
+
git_commits_url: string
|
|
278
|
+
comments_url: string
|
|
279
|
+
issue_comment_url: string
|
|
280
|
+
contents_url: string
|
|
281
|
+
compare_url: string
|
|
282
|
+
merges_url: string
|
|
283
|
+
archive_url: string
|
|
284
|
+
downloads_url: string
|
|
285
|
+
issues_url: string
|
|
286
|
+
pulls_url: string
|
|
287
|
+
milestones_url: string
|
|
288
|
+
notifications_url: string
|
|
289
|
+
labels_url: string
|
|
290
|
+
releases_url: string
|
|
291
|
+
deployments_url: string
|
|
292
|
+
}
|
|
293
|
+
}
|
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
// Model events, derived rather than listed.
|
|
2
|
+
//
|
|
3
|
+
// This file used to be generated: 97 models x 8 events, 817 lines, rebuilt by
|
|
4
|
+
// `buddy generate:types` and stale the moment a model was added without it.
|
|
5
|
+
// None of that is necessary. A mapped type with key remapping turns the models
|
|
6
|
+
// barrel into the event map directly, so `User` becoming a model is the same
|
|
7
|
+
// event as `'user:created'` existing - not two facts that have to be kept in
|
|
8
|
+
// agreement.
|
|
9
|
+
//
|
|
10
|
+
// The barrel it reads is generated, but for the RUNTIME: `injectGlobalAutoImports`
|
|
11
|
+
// imports it to put the models on `globalThis`. So this adds no generation step
|
|
12
|
+
// of its own, and cannot drift from what the runtime actually has.
|
|
13
|
+
|
|
14
|
+
import type { ModelRow } from '@stacksjs/orm'
|
|
15
|
+
|
|
16
|
+
/** Every model, by the name the ORM exposes it under. */
|
|
17
|
+
type Models = typeof import('../auto-imports/models')
|
|
18
|
+
|
|
19
|
+
/**
|
|
20
|
+
* Fired after the write, with the row.
|
|
21
|
+
*
|
|
22
|
+
* `define-model.ts` dispatches these with `toEventPayload(model)`, which
|
|
23
|
+
* returns `{...attributes}` plus the primary key.
|
|
24
|
+
*/
|
|
25
|
+
type AfterEvent = 'created' | 'updated' | 'saved' | 'deleted'
|
|
26
|
+
|
|
27
|
+
/**
|
|
28
|
+
* Fired before the write, with the model object; returning `false` cancels.
|
|
29
|
+
*/
|
|
30
|
+
type BeforeEvent = 'saving' | 'creating' | 'updating' | 'deleting'
|
|
31
|
+
|
|
32
|
+
/**
|
|
33
|
+
* `'user:created'`, `'productcategory:saved'` - the model's name lowercased,
|
|
34
|
+
* matching `definition.name.toLowerCase()` in `define-model.ts`.
|
|
35
|
+
*/
|
|
36
|
+
type ModelAfterEvents = {
|
|
37
|
+
[K in keyof Models & string as `${Lowercase<K>}:${AfterEvent}`]: ModelRow<Models[K]>
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
type ModelBeforeEvents = {
|
|
41
|
+
[K in keyof Models & string as `${Lowercase<K>}:${BeforeEvent}`]: ModelWriteEventOf<Models[K]>
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
/**
|
|
45
|
+
* What a BEFORE event carries: the model object, not the row.
|
|
46
|
+
*
|
|
47
|
+
* `toEventPayload` reading `model?.attributes` is what establishes that the
|
|
48
|
+
* object has one. Typed as far as that goes and no further - the rest of the
|
|
49
|
+
* instance belongs to the query builder.
|
|
50
|
+
*/
|
|
51
|
+
interface ModelWriteEventOf<TModel> {
|
|
52
|
+
attributes: ModelRow<TModel>
|
|
53
|
+
[key: string]: unknown
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
declare module '@stacksjs/events' {
|
|
57
|
+
interface AppEvents extends ModelAfterEvents, ModelBeforeEvents {}
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
export {}
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
// The models, and their tables, derived rather than listed.
|
|
2
|
+
//
|
|
3
|
+
// `ModelNames` and `TableNames` were hand-written unions in `@stacksjs/types`:
|
|
4
|
+
// 50 model names against the 97 the application had, and 62 table names with
|
|
5
|
+
// two duplicates. A list maintained alongside the thing it lists only ever
|
|
6
|
+
// drifts one way, and the drift is silent until somebody writes
|
|
7
|
+
// `belongsTo: ['Site']` for a model that plainly exists and is told it does not.
|
|
8
|
+
//
|
|
9
|
+
// The barrel this reads is generated, but for the RUNTIME:
|
|
10
|
+
// `injectGlobalAutoImports` imports it to put the models on `globalThis`. So
|
|
11
|
+
// this adds no generation step of its own, and cannot drift from what the
|
|
12
|
+
// runtime actually has.
|
|
13
|
+
|
|
14
|
+
/** Every model, by the name the ORM exposes it under. */
|
|
15
|
+
type Models = typeof import('../auto-imports/models')
|
|
16
|
+
|
|
17
|
+
/** A model's own `table`, when it declares one as a literal. */
|
|
18
|
+
type TableOf<TModel> = TModel extends { table: infer TTable extends string } ? TTable : never
|
|
19
|
+
|
|
20
|
+
/** Every table the models write to. */
|
|
21
|
+
type Tables = { [K in keyof Models]: TableOf<Models[K]> }[keyof Models]
|
|
22
|
+
|
|
23
|
+
declare module '@stacksjs/types' {
|
|
24
|
+
interface ModelRegistry extends Record<keyof Models & string, true> {}
|
|
25
|
+
interface TableRegistry extends Record<Tables, true> {}
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
export {}
|
|
@@ -0,0 +1,94 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Global type declarations for ORM utilities and request types.
|
|
3
|
+
*
|
|
4
|
+
* These types are available globally without imports in all Stacks application code.
|
|
5
|
+
* Model types are derived dynamically from defineModel() definitions via `as const`.
|
|
6
|
+
*
|
|
7
|
+
* @example
|
|
8
|
+
* // No imports needed — all of these are global:
|
|
9
|
+
* type PostRow = ModelRow<typeof Post>
|
|
10
|
+
* type NewPost = NewModelData<typeof Post>
|
|
11
|
+
*
|
|
12
|
+
* // Actions with model: Post get fully typed requests automatically:
|
|
13
|
+
* new Action({
|
|
14
|
+
* model: Post,
|
|
15
|
+
* async handle(request) {
|
|
16
|
+
* request.get('title') // autocompletes to Post fields, returns string
|
|
17
|
+
* request.get('invalid') // TS error!
|
|
18
|
+
* }
|
|
19
|
+
* })
|
|
20
|
+
*/
|
|
21
|
+
|
|
22
|
+
import type { UserLoggedInEvent as _UserLoggedInEvent, UserLoggedOutEvent as _UserLoggedOutEvent, UserPasswordEvent as _UserPasswordEvent, UserRegisteredEvent as _UserRegisteredEvent } from '@stacksjs/events'
|
|
23
|
+
import type { NotificationChannel as _NotificationChannel } from '@stacksjs/notifications'
|
|
24
|
+
import type { ModelRow as _ModelRow, NewModelData as _NewModelData, UpdateModelData as _UpdateModelData } from '@stacksjs/orm'
|
|
25
|
+
import type { RequestInstance as _RequestInstance } from '@stacksjs/types'
|
|
26
|
+
|
|
27
|
+
export {}
|
|
28
|
+
|
|
29
|
+
declare global {
|
|
30
|
+
/**
|
|
31
|
+
* Full database row type derived from a defineModel() definition.
|
|
32
|
+
* Includes model attributes + system fields (id, uuid, timestamps) + FK columns.
|
|
33
|
+
*
|
|
34
|
+
* @example
|
|
35
|
+
* type PostRow = ModelRow<typeof Post>
|
|
36
|
+
*/
|
|
37
|
+
type ModelRow<T> = _ModelRow<T>
|
|
38
|
+
|
|
39
|
+
/**
|
|
40
|
+
* Insertable data type derived from a defineModel() definition.
|
|
41
|
+
* All fields are optional for flexible creation.
|
|
42
|
+
*
|
|
43
|
+
* @example
|
|
44
|
+
* type NewPost = NewModelData<typeof Post>
|
|
45
|
+
*/
|
|
46
|
+
type NewModelData<T> = _NewModelData<T>
|
|
47
|
+
|
|
48
|
+
/**
|
|
49
|
+
* Updateable data type derived from a defineModel() definition.
|
|
50
|
+
* All fields are optional for partial updates.
|
|
51
|
+
*
|
|
52
|
+
* @example
|
|
53
|
+
* type PostUpdate = UpdateModelData<typeof Post>
|
|
54
|
+
*/
|
|
55
|
+
type UpdateModelData<T> = _UpdateModelData<T>
|
|
56
|
+
|
|
57
|
+
/**
|
|
58
|
+
* Model-aware request interface.
|
|
59
|
+
*
|
|
60
|
+
* When parameterized with a model type, all input methods narrow to that model's
|
|
61
|
+
* field names and types. Automatically inferred in Action handlers via `model: Post`.
|
|
62
|
+
*
|
|
63
|
+
* @example
|
|
64
|
+
* // Bare — accepts any key:
|
|
65
|
+
* function handle(_request: RequestInstance) { ... }
|
|
66
|
+
*
|
|
67
|
+
* @example
|
|
68
|
+
* // Model-aware — full narrowing:
|
|
69
|
+
* function handle(request: RequestInstance<typeof Post>) {
|
|
70
|
+
* request.get('title') // autocompletes, typed return
|
|
71
|
+
* }
|
|
72
|
+
*/
|
|
73
|
+
type RequestInstance<TModel = never> = [TModel] extends [never]
|
|
74
|
+
? _RequestInstance
|
|
75
|
+
: _RequestInstance<_ModelRow<TModel>>
|
|
76
|
+
|
|
77
|
+
/**
|
|
78
|
+
* Auth event payloads — surfaced as globals so listener actions in
|
|
79
|
+
* `app/Actions/` can type their `handle(input)` parameter without an
|
|
80
|
+
* explicit import (matching the rest of Stacks' "no imports needed"
|
|
81
|
+
* authoring style).
|
|
82
|
+
*/
|
|
83
|
+
type UserRegisteredEvent = _UserRegisteredEvent
|
|
84
|
+
type UserLoggedInEvent = _UserLoggedInEvent
|
|
85
|
+
type UserLoggedOutEvent = _UserLoggedOutEvent
|
|
86
|
+
type UserPasswordEvent = _UserPasswordEvent
|
|
87
|
+
|
|
88
|
+
/**
|
|
89
|
+
* Channel name accepted by `notify()`. Lifted to a global so listener
|
|
90
|
+
* actions can declare `const channels: NotificationChannel[] = []`
|
|
91
|
+
* without importing from `@stacksjs/notifications`.
|
|
92
|
+
*/
|
|
93
|
+
type NotificationChannel = _NotificationChannel
|
|
94
|
+
}
|
|
@@ -0,0 +1,140 @@
|
|
|
1
|
+
// The name-addressed registries, derived rather than generated.
|
|
2
|
+
//
|
|
3
|
+
// Actions, listeners, policies, middleware and jobs are all resolved by NAME at
|
|
4
|
+
// runtime - out of a route string, an `app/Events.ts` entry, an `app/Gates.ts`
|
|
5
|
+
// mapping, a `.middleware(...)` call, a `job(...)` dispatch. Every one of those
|
|
6
|
+
// names used to be `string` to the compiler, and the fix for that used to be
|
|
7
|
+
// `storage/framework/types/actions.d.ts`: 1500 lines of hand-generated unions
|
|
8
|
+
// that were correct only until somebody added a file without re-running
|
|
9
|
+
// `buddy generate:types`.
|
|
10
|
+
//
|
|
11
|
+
// Nothing is generated for the types now. Each registry is a lazy map the
|
|
12
|
+
// RESOLVER reads - `storage/framework/auto-imports/*.ts`, written by
|
|
13
|
+
// `generateAutoImportFiles()` for the runtime - and the type is `keyof` over
|
|
14
|
+
// the same object. A name that type-checks is a name that resolves, because
|
|
15
|
+
// there is only one list.
|
|
16
|
+
//
|
|
17
|
+
// Every registry falls back to "any string" when its barrel is missing, so a
|
|
18
|
+
// project that has not run `buddy generate` yet compiles exactly as before.
|
|
19
|
+
|
|
20
|
+
/** Every action, by the path a route string names it with. */
|
|
21
|
+
type Actions = typeof import('../auto-imports/actions')['actions']
|
|
22
|
+
|
|
23
|
+
/** Every listener module under `app/Listeners/`, and the defaults behind it. */
|
|
24
|
+
type Listeners = typeof import('../auto-imports/listeners')['listeners']
|
|
25
|
+
|
|
26
|
+
/** Every policy class under `app/Policies/`, and the defaults behind it. */
|
|
27
|
+
type Policies = typeof import('../auto-imports/policies')['policies']
|
|
28
|
+
|
|
29
|
+
/** Every middleware class under `app/Middleware/`, and the defaults behind it. */
|
|
30
|
+
type Middlewares = typeof import('../auto-imports/middleware')['middleware']
|
|
31
|
+
|
|
32
|
+
/** Every email template under `resources/emails/`, and the defaults behind it. */
|
|
33
|
+
type EmailTemplates = typeof import('../auto-imports/emails')['emails']
|
|
34
|
+
|
|
35
|
+
/** Every job, by the name `resolveJobFile` finds it under. */
|
|
36
|
+
type JobRegistry = typeof import('../auto-imports/jobs')
|
|
37
|
+
type Jobs = JobRegistry
|
|
38
|
+
|
|
39
|
+
/** The application's middleware alias map, and the framework's behind it. */
|
|
40
|
+
type AppAliases = typeof import('../../../app/Middleware')['default']
|
|
41
|
+
type DefaultAliases = typeof import('../defaults/app/Middleware')['default']
|
|
42
|
+
|
|
43
|
+
type ActionName = keyof Actions & string
|
|
44
|
+
type ListenerModuleName = keyof Listeners & string
|
|
45
|
+
type PolicyClassName = keyof Policies & string
|
|
46
|
+
type MiddlewareClassName = keyof Middlewares & string
|
|
47
|
+
type JobName = keyof Jobs & string
|
|
48
|
+
type EmailTemplateName = keyof EmailTemplates & string
|
|
49
|
+
|
|
50
|
+
/**
|
|
51
|
+
* `'Actions/Auth/LoginAction'` → `'Auth/LoginAction'`.
|
|
52
|
+
*
|
|
53
|
+
* A generic, so the conditional distributes over the union. A conditional whose
|
|
54
|
+
* checked type is a union ALIAS rather than a naked type parameter does not
|
|
55
|
+
* distribute, and would collapse the whole set to `never`.
|
|
56
|
+
*/
|
|
57
|
+
type WithoutActionsPrefix<T> = T extends `Actions/${infer TRest}` ? TRest : never
|
|
58
|
+
|
|
59
|
+
/**
|
|
60
|
+
* `'SendEmailJob'` → `'SendEmail'`. `resolveJobFile` tries `<name>.ts` and then
|
|
61
|
+
* `<name>Job.ts`, so a job is reachable by either spelling; `@stacksjs/queue`
|
|
62
|
+
* derives the same for `job(…)` from the `Jobs` registry below.
|
|
63
|
+
*/
|
|
64
|
+
type WithoutJobSuffix<T> = T extends `${infer TBase}Job` ? (TBase extends '' ? never : TBase) : never
|
|
65
|
+
|
|
66
|
+
/**
|
|
67
|
+
* What `app/Events.ts` may name against an event: a listener module, or an
|
|
68
|
+
* action by the name `resolveListener` joins back on (no `Actions/` prefix).
|
|
69
|
+
*/
|
|
70
|
+
type EventListenerName = ListenerModuleName | WithoutActionsPrefix<ActionName>
|
|
71
|
+
|
|
72
|
+
/**
|
|
73
|
+
* A middleware reference, in every form the resolver reads.
|
|
74
|
+
*
|
|
75
|
+
* The aliases come from the alias maps themselves - they are ordinary modules,
|
|
76
|
+
* and `defineMiddleware` keeps their literal keys - so there is nothing to
|
|
77
|
+
* generate for them either. Class names are included because they resolve:
|
|
78
|
+
* an unaliased middleware is reached by name through `toPascalCase`.
|
|
79
|
+
*/
|
|
80
|
+
type MiddlewareAliasName = (keyof DefaultAliases | keyof AppAliases) & string
|
|
81
|
+
type MiddlewareReferenceName = MiddlewareAliasName | MiddlewareClassName
|
|
82
|
+
|
|
83
|
+
/**
|
|
84
|
+
* Every named route, and the path it resolves to.
|
|
85
|
+
*
|
|
86
|
+
* The one name here that is not read off the filesystem: a route name is
|
|
87
|
+
* produced by running code, so `buddy generate:types` loads the route table and
|
|
88
|
+
* writes the answer as a runtime map. Read here the same way as the others.
|
|
89
|
+
*/
|
|
90
|
+
type NamedRoutes = typeof import('../auto-imports/routes')['routeNames']
|
|
91
|
+
|
|
92
|
+
// Augment the public entry so declarations follow the router's own dependency instance.
|
|
93
|
+
declare module '@stacksjs/router' {
|
|
94
|
+
interface RouterTypeRegistry {
|
|
95
|
+
actions: ActionName | `${string}Controller@${string}`
|
|
96
|
+
middleware: MiddlewareReferenceName | `!${MiddlewareReferenceName}`
|
|
97
|
+
routes: NamedRoutes
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
interface MiddlewareClasses extends Record<MiddlewareClassName, true> {}
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
declare module '@stacksjs/events' {
|
|
104
|
+
interface EventListeners extends Record<EventListenerName, true> {}
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
declare module '@stacksjs/auth' {
|
|
108
|
+
interface PolicyClasses extends Record<PolicyClassName, true> {}
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
declare module '@stacksjs/email' {
|
|
112
|
+
interface EmailTemplates extends Record<EmailTemplateName, true> {}
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
declare module '@stacksjs/queue' {
|
|
116
|
+
/*
|
|
117
|
+
* The job MODULES, not `Record<JobName, true>`.
|
|
118
|
+
*
|
|
119
|
+
* The names are the same either way - `JobName` is `keyof` this - but the
|
|
120
|
+
* value carries the `Job<Payload>` instance, so dispatching by name can be
|
|
121
|
+
* checked against the payload its handler declares. Mapped to `true`, the
|
|
122
|
+
* registry knew a job existed and nothing about how to call it, and
|
|
123
|
+
* `job('SendWelcomeEmail', { emial: … })` was accepted.
|
|
124
|
+
*
|
|
125
|
+
* Free here: the jobs auto-import is a real re-export barrel rather than a
|
|
126
|
+
* name-to-path map, so `JobName` already resolves these modules.
|
|
127
|
+
*/
|
|
128
|
+
interface Jobs extends JobRegistry {}
|
|
129
|
+
}
|
|
130
|
+
|
|
131
|
+
declare module '@stacksjs/actions' {
|
|
132
|
+
interface RunnableActions extends Record<ActionName, true> {}
|
|
133
|
+
}
|
|
134
|
+
|
|
135
|
+
declare module '@stacksjs/scheduler' {
|
|
136
|
+
interface SchedulableJobs extends Record<JobName | WithoutJobSuffix<JobName>, true> {}
|
|
137
|
+
interface SchedulableActions extends Record<ActionName, true> {}
|
|
138
|
+
}
|
|
139
|
+
|
|
140
|
+
export {}
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
// Hand-written, unlike its neighbours — `server-auto-imports.d.ts` is
|
|
2
|
+
// regenerated whenever the API starts and would lose these.
|
|
3
|
+
//
|
|
4
|
+
// What a `<script server>` block can reach (stacksjs/stacks#2232). tsc cannot
|
|
5
|
+
// see inside a `.stx` file, but `typecheck:views` hands this file to
|
|
6
|
+
// `stx typecheck` with `--lib`, so the templates are checked against it. It
|
|
7
|
+
// also gives an editor something to complete against.
|
|
8
|
+
//
|
|
9
|
+
// `requestContext` is typed as the object the servers install
|
|
10
|
+
// (`StacksRequestContext` in @stacksjs/config), not restated here. A copy of
|
|
11
|
+
// its methods written out in this file drifted: it had no `site()`, so a
|
|
12
|
+
// template calling `requestContext.site()` as core/sites/README.md tells it to
|
|
13
|
+
// failed `typecheck:views`. The import is relative, as the paths in
|
|
14
|
+
// `browser-auto-imports.d.ts` are: through `@stacksjs/config`, `stx typecheck`
|
|
15
|
+
// resolved the type to `any` and passed a call to a method that does not
|
|
16
|
+
// exist.
|
|
17
|
+
|
|
18
|
+
export {}
|
|
19
|
+
|
|
20
|
+
declare global {
|
|
21
|
+
/**
|
|
22
|
+
* The request this server script is rendering.
|
|
23
|
+
*
|
|
24
|
+
* Installed by `buddy dev` and `buddy serve` (`installRequestScope`), and
|
|
25
|
+
* read from the scope each server opens for a request, so a page, its
|
|
26
|
+
* layout and its components each read their own request while others are
|
|
27
|
+
* in flight. Outside a request, every accessor answers with its empty
|
|
28
|
+
* value rather than throwing. Only those two servers install it: in a
|
|
29
|
+
* process that started neither, `requestContext` is undefined.
|
|
30
|
+
*/
|
|
31
|
+
const requestContext: import('../core/config/src/request-context').StacksRequestContext
|
|
32
|
+
|
|
33
|
+
/**
|
|
34
|
+
* Query parameters injected onto the render context by the serve path.
|
|
35
|
+
*
|
|
36
|
+
* Declared optional-shaped for a reason: this is injected by
|
|
37
|
+
* bun-plugin-stx's serve path only. A standalone render (the SSG path, or
|
|
38
|
+
* `processDirectives` called without a request) supplies nothing, and a bare
|
|
39
|
+
* `query` is a ReferenceError there rather than an empty result. Until that
|
|
40
|
+
* path injects an empty-but-shaped object, reads still need a guard:
|
|
41
|
+
*
|
|
42
|
+
* const params = typeof query !== 'undefined' ? query : {}
|
|
43
|
+
*
|
|
44
|
+
* In a process that installed `requestContext`, `requestContext.query()`
|
|
45
|
+
* answers `{}` there instead.
|
|
46
|
+
*/
|
|
47
|
+
const query: Record<string, string>
|
|
48
|
+
|
|
49
|
+
/**
|
|
50
|
+
* Cookies injected onto the render context by the serve path.
|
|
51
|
+
*
|
|
52
|
+
* Same caveat as `query`: absent in a standalone render, where a process
|
|
53
|
+
* that installed `requestContext` answers `requestContext.cookie(name)`
|
|
54
|
+
* with null.
|
|
55
|
+
*/
|
|
56
|
+
const cookies: Record<string, string>
|
|
57
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import '@total-typescript/ts-reset'
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
/* eslint-disable */
|
|
2
|
+
|
|
3
|
+
declare interface Window {
|
|
4
|
+
// extend the window
|
|
5
|
+
}
|
|
6
|
+
|
|
7
|
+
// Markdown files can be treated as components
|
|
8
|
+
declare module '*.md' {
|
|
9
|
+
import type { DefineComponent } from '@stacksjs/stx'
|
|
10
|
+
|
|
11
|
+
const component: DefineComponent<{}, {}, any>
|
|
12
|
+
export default component
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
declare module '*.stx' {
|
|
16
|
+
import type { DefineComponent } from '@stacksjs/stx'
|
|
17
|
+
|
|
18
|
+
const component: DefineComponent<{}, {}, any>
|
|
19
|
+
export default component
|
|
20
|
+
}
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
export interface AuthGuard {
|
|
2
|
+
driver: 'session' | 'token'
|
|
3
|
+
provider: string
|
|
4
|
+
}
|
|
5
|
+
|
|
6
|
+
export interface AuthProvider {
|
|
7
|
+
driver: 'database'
|
|
8
|
+
table: string
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
export interface AuthConfig {
|
|
12
|
+
default: string
|
|
13
|
+
guards: {
|
|
14
|
+
[key: string]: AuthGuard
|
|
15
|
+
}
|
|
16
|
+
providers: {
|
|
17
|
+
[key: string]: AuthProvider
|
|
18
|
+
}
|
|
19
|
+
username: string
|
|
20
|
+
password: string
|
|
21
|
+
tokenExpiry: number
|
|
22
|
+
tokenRotation: number
|
|
23
|
+
defaultAbilities: string[]
|
|
24
|
+
defaultTokenName: string
|
|
25
|
+
}
|
|
@@ -0,0 +1,230 @@
|
|
|
1
|
+
import { Request } from '../core/router/src/request'
|
|
2
|
+
|
|
3
|
+
interface ValidationRule {
|
|
4
|
+
validate: (value: unknown) => { valid: boolean, errors?: Array<{ message: string }> }
|
|
5
|
+
}
|
|
6
|
+
|
|
7
|
+
interface ValidationField {
|
|
8
|
+
rule: ValidationRule
|
|
9
|
+
message: Record<string, string>
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
interface CustomAttributes {
|
|
13
|
+
[key: string]: ValidationField
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
interface RequestDataMigrations {
|
|
17
|
+
name: string
|
|
18
|
+
timestamp: string
|
|
19
|
+
|
|
20
|
+
}
|
|
21
|
+
export interface MigrationsRequestType extends Request {
|
|
22
|
+
validate(attributes?: CustomAttributes): void
|
|
23
|
+
get: <T = string>(element: string, defaultValue?: T) => T
|
|
24
|
+
all(): RequestDataMigrations
|
|
25
|
+
name: string
|
|
26
|
+
timestamp: string
|
|
27
|
+
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
interface RequestDataPasswordResets {
|
|
31
|
+
email: string
|
|
32
|
+
token: string
|
|
33
|
+
created_at: string
|
|
34
|
+
|
|
35
|
+
}
|
|
36
|
+
export interface PasswordResetsRequestType extends Request {
|
|
37
|
+
validate(attributes?: CustomAttributes): void
|
|
38
|
+
get: <T = string>(element: string, defaultValue?: T) => T
|
|
39
|
+
all(): RequestDataPasswordResets
|
|
40
|
+
email: string
|
|
41
|
+
token: string
|
|
42
|
+
created_at: string
|
|
43
|
+
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
interface RequestDataPasskeys {
|
|
47
|
+
id: number
|
|
48
|
+
cred_public_key: string
|
|
49
|
+
user_id: number
|
|
50
|
+
webauthn_user_id: string
|
|
51
|
+
counter: number
|
|
52
|
+
credential_type: string
|
|
53
|
+
device_type: string
|
|
54
|
+
backup_eligible: boolean
|
|
55
|
+
backup_status: boolean
|
|
56
|
+
transports: string
|
|
57
|
+
created_at: string
|
|
58
|
+
updated_at: string
|
|
59
|
+
last_used_at: string
|
|
60
|
+
|
|
61
|
+
}
|
|
62
|
+
export interface PasskeysRequestType extends Request {
|
|
63
|
+
validate(attributes?: CustomAttributes): void
|
|
64
|
+
get: <T = string>(element: string, defaultValue?: T) => T
|
|
65
|
+
all(): RequestDataPasskeys
|
|
66
|
+
id: number
|
|
67
|
+
cred_public_key: string
|
|
68
|
+
user_id: number
|
|
69
|
+
webauthn_user_id: string
|
|
70
|
+
counter: number
|
|
71
|
+
credential_type: string
|
|
72
|
+
device_type: string
|
|
73
|
+
backup_eligible: boolean
|
|
74
|
+
backup_status: boolean
|
|
75
|
+
transports: string
|
|
76
|
+
created_at: string
|
|
77
|
+
updated_at: string
|
|
78
|
+
last_used_at: string
|
|
79
|
+
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
interface RequestDataCommentables {
|
|
83
|
+
id: number
|
|
84
|
+
title: string
|
|
85
|
+
body: string
|
|
86
|
+
status: string
|
|
87
|
+
approved_at: number | null
|
|
88
|
+
rejected_at: number | null
|
|
89
|
+
commentables_id: number
|
|
90
|
+
commentables_type: string
|
|
91
|
+
user_id: number | null
|
|
92
|
+
created_at: string
|
|
93
|
+
updated_at: string | null
|
|
94
|
+
|
|
95
|
+
}
|
|
96
|
+
export interface CommentablesRequestType extends Request {
|
|
97
|
+
validate(attributes?: CustomAttributes): void
|
|
98
|
+
get: <T = string>(element: string, defaultValue?: T) => T
|
|
99
|
+
all(): RequestDataCommentables
|
|
100
|
+
id: number
|
|
101
|
+
title: string
|
|
102
|
+
body: string
|
|
103
|
+
status: string
|
|
104
|
+
approved_at: number | null
|
|
105
|
+
rejected_at: number | null
|
|
106
|
+
commentables_id: number
|
|
107
|
+
commentables_type: string
|
|
108
|
+
user_id: number | null
|
|
109
|
+
created_at: string
|
|
110
|
+
updated_at: string | null
|
|
111
|
+
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
interface RequestDataCommentableUpvotes {
|
|
115
|
+
id: number
|
|
116
|
+
user_id: number
|
|
117
|
+
upvoteable_id: number
|
|
118
|
+
upvoteable_type: string
|
|
119
|
+
created_at: string
|
|
120
|
+
|
|
121
|
+
}
|
|
122
|
+
export interface CommentableUpvotesRequestType extends Request {
|
|
123
|
+
validate(attributes?: CustomAttributes): void
|
|
124
|
+
get: <T = string>(element: string, defaultValue?: T) => T
|
|
125
|
+
all(): RequestDataCommentableUpvotes
|
|
126
|
+
id: number
|
|
127
|
+
user_id: number
|
|
128
|
+
upvoteable_id: number
|
|
129
|
+
upvoteable_type: string
|
|
130
|
+
created_at: string
|
|
131
|
+
|
|
132
|
+
}
|
|
133
|
+
|
|
134
|
+
interface RequestDataCategorizable {
|
|
135
|
+
id: number
|
|
136
|
+
name: string
|
|
137
|
+
slug: string
|
|
138
|
+
description: string
|
|
139
|
+
is_active: boolean
|
|
140
|
+
categorizable_type: string
|
|
141
|
+
created_at: string
|
|
142
|
+
updated_at: string
|
|
143
|
+
|
|
144
|
+
}
|
|
145
|
+
export interface CategorizableRequestType extends Request {
|
|
146
|
+
validate(attributes?: CustomAttributes): void
|
|
147
|
+
get: <T = string>(element: string, defaultValue?: T) => T
|
|
148
|
+
all(): RequestDataCategorizable
|
|
149
|
+
id: number
|
|
150
|
+
name: string
|
|
151
|
+
slug: string
|
|
152
|
+
description: string
|
|
153
|
+
is_active: boolean
|
|
154
|
+
categorizable_type: string
|
|
155
|
+
created_at: string
|
|
156
|
+
updated_at: string
|
|
157
|
+
|
|
158
|
+
}
|
|
159
|
+
|
|
160
|
+
interface RequestDataTaggable {
|
|
161
|
+
id: number
|
|
162
|
+
name: string
|
|
163
|
+
slug: string
|
|
164
|
+
description: string
|
|
165
|
+
is_active: boolean
|
|
166
|
+
taggable_type: string
|
|
167
|
+
created_at: string
|
|
168
|
+
updated_at: string
|
|
169
|
+
|
|
170
|
+
}
|
|
171
|
+
export interface TaggableRequestType extends Request {
|
|
172
|
+
validate(attributes?: CustomAttributes): void
|
|
173
|
+
get: <T = string>(element: string, defaultValue?: T) => T
|
|
174
|
+
all(): RequestDataTaggable
|
|
175
|
+
id: number
|
|
176
|
+
name: string
|
|
177
|
+
slug: string
|
|
178
|
+
description: string
|
|
179
|
+
is_active: boolean
|
|
180
|
+
taggable_type: string
|
|
181
|
+
created_at: string
|
|
182
|
+
updated_at: string
|
|
183
|
+
|
|
184
|
+
}
|
|
185
|
+
|
|
186
|
+
interface RequestDataTaggableModels {
|
|
187
|
+
id: number
|
|
188
|
+
tag_id: number
|
|
189
|
+
taggable_id: number
|
|
190
|
+
taggable_type: string
|
|
191
|
+
created_at: string
|
|
192
|
+
updated_at: string | null
|
|
193
|
+
|
|
194
|
+
}
|
|
195
|
+
export interface TaggableModelsRequestType extends Request {
|
|
196
|
+
validate(attributes?: CustomAttributes): void
|
|
197
|
+
get: <T = string>(element: string, defaultValue?: T) => T
|
|
198
|
+
all(): RequestDataTaggableModels
|
|
199
|
+
id: number
|
|
200
|
+
tag_id: number
|
|
201
|
+
taggable_id: number
|
|
202
|
+
taggable_type: string
|
|
203
|
+
created_at: string
|
|
204
|
+
updated_at: string | null
|
|
205
|
+
|
|
206
|
+
}
|
|
207
|
+
|
|
208
|
+
interface RequestDataCategorizableModels {
|
|
209
|
+
id: number
|
|
210
|
+
category_id: number
|
|
211
|
+
categorizable_id: number
|
|
212
|
+
categorizable_type: string
|
|
213
|
+
created_at: string
|
|
214
|
+
updated_at: string | null
|
|
215
|
+
|
|
216
|
+
}
|
|
217
|
+
export interface CategorizableModelsRequestType extends Request {
|
|
218
|
+
validate(attributes?: CustomAttributes): void
|
|
219
|
+
get: <T = string>(element: string, defaultValue?: T) => T
|
|
220
|
+
all(): RequestDataCategorizableModels
|
|
221
|
+
id: number
|
|
222
|
+
category_id: number
|
|
223
|
+
categorizable_id: number
|
|
224
|
+
categorizable_type: string
|
|
225
|
+
created_at: string
|
|
226
|
+
updated_at: string | null
|
|
227
|
+
|
|
228
|
+
}
|
|
229
|
+
|
|
230
|
+
export type TraitRequest = MigrationsRequestType | PasswordResetsRequestType | PasskeysRequestType | CommentablesRequestType | CommentableUpvotesRequestType | CategorizableRequestType | TaggableRequestType | TaggableModelsRequestType | CategorizableModelsRequestType
|