@stacksjs/orm 0.72.16 → 0.72.18
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/dist/index.d.ts +97 -97
- package/dist/index.js +7 -7
- package/dist/models/Activity.ts +95 -0
- package/dist/models/AnalyticsEvent.ts +70 -0
- package/dist/models/Automation.ts +23 -0
- package/dist/models/AutomationRun.ts +26 -0
- package/dist/models/Board.ts +104 -0
- package/dist/models/BoardColumn.ts +88 -0
- package/dist/models/Campaign.ts +321 -0
- package/dist/models/CampaignSend.ts +191 -0
- package/dist/models/CampaignVariant.ts +25 -0
- package/dist/models/Card.ts +118 -0
- package/dist/models/CardComment.ts +68 -0
- package/dist/models/Comment.ts +109 -0
- package/dist/models/CommunicationSuppression.ts +22 -0
- package/dist/models/ConsentEvent.ts +30 -0
- package/dist/models/Content/Author.ts +109 -0
- package/dist/models/Content/Menu.ts +56 -0
- package/dist/models/Content/MenuItem.ts +91 -0
- package/dist/models/Content/Page.ts +205 -0
- package/dist/models/Content/PageRevision.ts +86 -0
- package/dist/models/Content/Post.ts +230 -0
- package/dist/models/Content/Redirect.ts +80 -0
- package/dist/models/Deployment.ts +117 -0
- package/dist/models/EmailIdempotency.ts +64 -0
- package/dist/models/EmailList.ts +134 -0
- package/dist/models/EmailListSubscriber.ts +91 -0
- package/dist/models/EmailSuppression.ts +52 -0
- package/dist/models/EmailWebhookEvent.ts +51 -0
- package/dist/models/Error.ts +77 -0
- package/dist/models/FailedJob.ts +84 -0
- package/dist/models/Forms/Form.ts +91 -0
- package/dist/models/Forms/FormField.ts +127 -0
- package/dist/models/Forms/FormSubmission.ts +114 -0
- package/dist/models/Job.ts +69 -0
- package/dist/models/Label.ts +67 -0
- package/dist/models/Log.ts +134 -0
- package/dist/models/MagicLinkToken.ts +97 -0
- package/dist/models/MailPreference.ts +213 -0
- package/dist/models/Notification.ts +68 -0
- package/dist/models/NotificationDelivery.ts +102 -0
- package/dist/models/PaymentMethod.ts +98 -0
- package/dist/models/PaymentProduct.ts +91 -0
- package/dist/models/PaymentTransaction.ts +78 -0
- package/dist/models/QueryLog.ts +182 -0
- package/dist/models/README.md +31 -0
- package/dist/models/Release.ts +90 -0
- package/dist/models/Request.ts +133 -0
- package/dist/models/SenderDomain.ts +22 -0
- package/dist/models/Site.ts +112 -0
- package/dist/models/SiteDomain.ts +74 -0
- package/dist/models/SmsOptOut.ts +65 -0
- package/dist/models/SocialAccount.ts +70 -0
- package/dist/models/SocialPost.ts +144 -0
- package/dist/models/Subscriber.ts +89 -0
- package/dist/models/SubscriberEmail.ts +55 -0
- package/dist/models/Subscription.ts +153 -0
- package/dist/models/Tag.ts +105 -0
- package/dist/models/Team.ts +75 -0
- package/dist/models/TeamInvitation.ts +159 -0
- package/dist/models/TeamMember.ts +88 -0
- package/dist/models/UsageEvent.ts +24 -0
- package/dist/models/User.ts +142 -0
- package/dist/models/commerce/Auction.ts +173 -0
- package/dist/models/commerce/AuctionItem.ts +204 -0
- package/dist/models/commerce/Bid.ts +129 -0
- package/dist/models/commerce/Cart.ts +140 -0
- package/dist/models/commerce/CartItem.ts +138 -0
- package/dist/models/commerce/Category.ts +125 -0
- package/dist/models/commerce/Coupon.ts +186 -0
- package/dist/models/commerce/Customer.ts +132 -0
- package/dist/models/commerce/DeliveryRoute.ts +127 -0
- package/dist/models/commerce/DeliveryStop.ts +166 -0
- package/dist/models/commerce/DigitalDelivery.ts +106 -0
- package/dist/models/commerce/Driver.ts +168 -0
- package/dist/models/commerce/DriverPing.ts +103 -0
- package/dist/models/commerce/GiftCard.ts +195 -0
- package/dist/models/commerce/LicenseKey.ts +89 -0
- package/dist/models/commerce/LoyaltyPoint.ts +108 -0
- package/dist/models/commerce/LoyaltyReward.ts +129 -0
- package/dist/models/commerce/Manufacturer.ts +90 -0
- package/dist/models/commerce/Order.ts +198 -0
- package/dist/models/commerce/OrderIdempotency.ts +34 -0
- package/dist/models/commerce/OrderItem.ts +51 -0
- package/dist/models/commerce/Payment.ts +182 -0
- package/dist/models/commerce/Pledge.ts +112 -0
- package/dist/models/commerce/PrintDevice.ts +120 -0
- package/dist/models/commerce/Product.ts +153 -0
- package/dist/models/commerce/ProductUnit.ts +113 -0
- package/dist/models/commerce/ProductVariant.ts +111 -0
- package/dist/models/commerce/Receipt.ts +144 -0
- package/dist/models/commerce/Review.ts +171 -0
- package/dist/models/commerce/ShippingMethod.ts +102 -0
- package/dist/models/commerce/ShippingRate.ts +79 -0
- package/dist/models/commerce/ShippingZone.ts +116 -0
- package/dist/models/commerce/TaxRate.ts +167 -0
- package/dist/models/commerce/Transaction.ts +127 -0
- package/dist/models/commerce/WaitlistProduct.ts +151 -0
- package/dist/models/commerce/WaitlistRestaurant.ts +189 -0
- package/dist/models/realtime/Websocket.ts +78 -0
- package/dist/password-policy.ts +46 -0
- package/package.json +4 -4
|
@@ -0,0 +1,151 @@
|
|
|
1
|
+
import { defineModel } from '@stacksjs/orm'
|
|
2
|
+
import { schema } from '@stacksjs/validation'
|
|
3
|
+
|
|
4
|
+
export default defineModel({
|
|
5
|
+
name: 'WaitlistProduct',
|
|
6
|
+
table: 'waitlist_products',
|
|
7
|
+
primaryKey: 'id',
|
|
8
|
+
autoIncrement: true,
|
|
9
|
+
belongsTo: ['Product', 'Customer'],
|
|
10
|
+
traits: {
|
|
11
|
+
useUuid: true,
|
|
12
|
+
useTimestamps: true,
|
|
13
|
+
useSearch: {
|
|
14
|
+
displayable: ['id', 'name', 'email', 'phone', 'partySize', 'notificationPreference', 'source', 'notes', 'status'],
|
|
15
|
+
searchable: ['name', 'email', 'phone', 'source'],
|
|
16
|
+
sortable: ['name', 'partySize', 'createdAt', 'updatedAt', 'status'],
|
|
17
|
+
filterable: ['notificationPreference', 'source', 'status'],
|
|
18
|
+
},
|
|
19
|
+
|
|
20
|
+
useSeeder: {
|
|
21
|
+
count: 10,
|
|
22
|
+
},
|
|
23
|
+
|
|
24
|
+
useApi: {
|
|
25
|
+
uri: 'waitlist-products',
|
|
26
|
+
routes: ['index', 'store', 'show', 'update', 'destroy'],
|
|
27
|
+
middleware: ['auth'],
|
|
28
|
+
},
|
|
29
|
+
|
|
30
|
+
observe: true,
|
|
31
|
+
},
|
|
32
|
+
|
|
33
|
+
attributes: {
|
|
34
|
+
name: {
|
|
35
|
+
order: 1,
|
|
36
|
+
fillable: true,
|
|
37
|
+
validation: {
|
|
38
|
+
rule: schema.string().required().max(255),
|
|
39
|
+
message: {
|
|
40
|
+
max: 'Name must have a maximum of 255 characters',
|
|
41
|
+
},
|
|
42
|
+
},
|
|
43
|
+
factory: faker => faker.person.fullName(),
|
|
44
|
+
},
|
|
45
|
+
|
|
46
|
+
email: {
|
|
47
|
+
order: 2,
|
|
48
|
+
fillable: true,
|
|
49
|
+
validation: {
|
|
50
|
+
rule: schema.string().required().email().max(255),
|
|
51
|
+
message: {
|
|
52
|
+
max: 'Email must have a maximum of 255 characters',
|
|
53
|
+
},
|
|
54
|
+
},
|
|
55
|
+
factory: faker => faker.internet.email(),
|
|
56
|
+
},
|
|
57
|
+
|
|
58
|
+
phone: {
|
|
59
|
+
order: 3,
|
|
60
|
+
fillable: true,
|
|
61
|
+
validation: {
|
|
62
|
+
rule: schema.string().max(100),
|
|
63
|
+
message: {
|
|
64
|
+
max: 'Phone number must have a maximum of 100 characters',
|
|
65
|
+
},
|
|
66
|
+
},
|
|
67
|
+
factory: faker => faker.phone.number(),
|
|
68
|
+
},
|
|
69
|
+
|
|
70
|
+
quantity: {
|
|
71
|
+
order: 4,
|
|
72
|
+
fillable: true,
|
|
73
|
+
validation: {
|
|
74
|
+
rule: schema.number().required().min(1),
|
|
75
|
+
message: {
|
|
76
|
+
min: 'Quantity must be at least 1',
|
|
77
|
+
},
|
|
78
|
+
},
|
|
79
|
+
factory: faker => faker.number.int({ min: 1, max: 20 }),
|
|
80
|
+
},
|
|
81
|
+
|
|
82
|
+
notificationPreference: {
|
|
83
|
+
order: 5,
|
|
84
|
+
fillable: true,
|
|
85
|
+
validation: {
|
|
86
|
+
rule: schema.enum(['sms', 'email', 'both']).required(),
|
|
87
|
+
},
|
|
88
|
+
factory: faker => faker.helpers.arrayElement(['sms', 'email', 'both']),
|
|
89
|
+
},
|
|
90
|
+
|
|
91
|
+
source: {
|
|
92
|
+
order: 6,
|
|
93
|
+
fillable: true,
|
|
94
|
+
validation: {
|
|
95
|
+
rule: schema.string().required().max(100),
|
|
96
|
+
message: {
|
|
97
|
+
max: 'Source must have a maximum of 100 characters',
|
|
98
|
+
},
|
|
99
|
+
},
|
|
100
|
+
factory: faker => faker.helpers.arrayElement(['website', 'social_media', 'in-store', 'email', 'app', 'referral', 'other']),
|
|
101
|
+
},
|
|
102
|
+
|
|
103
|
+
notes: {
|
|
104
|
+
order: 7,
|
|
105
|
+
fillable: true,
|
|
106
|
+
validation: {
|
|
107
|
+
rule: schema.string().max(500),
|
|
108
|
+
},
|
|
109
|
+
factory: faker => faker.lorem.paragraph(),
|
|
110
|
+
},
|
|
111
|
+
|
|
112
|
+
status: {
|
|
113
|
+
default: 'waiting',
|
|
114
|
+
order: 8,
|
|
115
|
+
fillable: true,
|
|
116
|
+
validation: {
|
|
117
|
+
rule: schema.enum(['waiting', 'purchased', 'notified', 'cancelled']).required(),
|
|
118
|
+
},
|
|
119
|
+
factory: faker => faker.helpers.arrayElement(['waiting', 'purchased', 'notified', 'cancelled']),
|
|
120
|
+
},
|
|
121
|
+
|
|
122
|
+
notifiedAt: {
|
|
123
|
+
order: 9,
|
|
124
|
+
fillable: true,
|
|
125
|
+
validation: {
|
|
126
|
+
rule: schema.date(),
|
|
127
|
+
},
|
|
128
|
+
factory: faker => faker.date.future().toISOString().slice(0, 19).replace('T', ' '),
|
|
129
|
+
},
|
|
130
|
+
purchasedAt: {
|
|
131
|
+
order: 10,
|
|
132
|
+
fillable: true,
|
|
133
|
+
validation: {
|
|
134
|
+
rule: schema.date(),
|
|
135
|
+
},
|
|
136
|
+
factory: faker => faker.date.future().toISOString().slice(0, 19).replace('T', ' '),
|
|
137
|
+
},
|
|
138
|
+
cancelledAt: {
|
|
139
|
+
order: 11,
|
|
140
|
+
fillable: true,
|
|
141
|
+
validation: {
|
|
142
|
+
rule: schema.date(),
|
|
143
|
+
},
|
|
144
|
+
factory: faker => faker.date.future().toISOString().slice(0, 19).replace('T', ' '),
|
|
145
|
+
},
|
|
146
|
+
},
|
|
147
|
+
|
|
148
|
+
dashboard: {
|
|
149
|
+
highlight: true,
|
|
150
|
+
},
|
|
151
|
+
} as const)
|
|
@@ -0,0 +1,189 @@
|
|
|
1
|
+
import { defineModel } from '@stacksjs/orm'
|
|
2
|
+
import { schema } from '@stacksjs/validation'
|
|
3
|
+
|
|
4
|
+
export default defineModel({
|
|
5
|
+
name: 'WaitlistRestaurant',
|
|
6
|
+
table: 'waitlist_restaurants',
|
|
7
|
+
primaryKey: 'id',
|
|
8
|
+
autoIncrement: true,
|
|
9
|
+
belongsTo: ['Customer'],
|
|
10
|
+
traits: {
|
|
11
|
+
useUuid: true,
|
|
12
|
+
useTimestamps: true,
|
|
13
|
+
useSearch: {
|
|
14
|
+
displayable: ['id', 'name', 'email', 'phone', 'partySize', 'checkInTime', 'tablePreference', 'status', 'quotedWaitTime', 'actualWaitTime', 'queuePosition'],
|
|
15
|
+
searchable: ['name', 'email', 'phone'],
|
|
16
|
+
sortable: ['name', 'partySize', 'checkInTime', 'createdAt', 'updatedAt', 'status', 'queuePosition'],
|
|
17
|
+
filterable: ['tablePreference', 'status'],
|
|
18
|
+
},
|
|
19
|
+
|
|
20
|
+
useSeeder: {
|
|
21
|
+
count: 10,
|
|
22
|
+
},
|
|
23
|
+
|
|
24
|
+
useApi: {
|
|
25
|
+
uri: 'waitlist-restaurants',
|
|
26
|
+
routes: ['index', 'store', 'show', 'update', 'destroy'],
|
|
27
|
+
middleware: ['auth'],
|
|
28
|
+
},
|
|
29
|
+
|
|
30
|
+
observe: true,
|
|
31
|
+
},
|
|
32
|
+
|
|
33
|
+
attributes: {
|
|
34
|
+
name: {
|
|
35
|
+
order: 1,
|
|
36
|
+
fillable: true,
|
|
37
|
+
validation: {
|
|
38
|
+
rule: schema.string().required().max(255),
|
|
39
|
+
message: {
|
|
40
|
+
max: 'Name must have a maximum of 255 characters',
|
|
41
|
+
},
|
|
42
|
+
},
|
|
43
|
+
factory: faker => faker.person.fullName(),
|
|
44
|
+
},
|
|
45
|
+
|
|
46
|
+
email: {
|
|
47
|
+
order: 2,
|
|
48
|
+
fillable: true,
|
|
49
|
+
validation: {
|
|
50
|
+
rule: schema.string().required().email().max(255),
|
|
51
|
+
message: {
|
|
52
|
+
max: 'Email must have a maximum of 255 characters',
|
|
53
|
+
},
|
|
54
|
+
},
|
|
55
|
+
factory: faker => faker.internet.email(),
|
|
56
|
+
},
|
|
57
|
+
|
|
58
|
+
phone: {
|
|
59
|
+
order: 3,
|
|
60
|
+
fillable: true,
|
|
61
|
+
validation: {
|
|
62
|
+
rule: schema.string().max(100),
|
|
63
|
+
message: {
|
|
64
|
+
max: 'Phone number must have a maximum of 100 characters',
|
|
65
|
+
},
|
|
66
|
+
},
|
|
67
|
+
factory: faker => faker.phone.number(),
|
|
68
|
+
},
|
|
69
|
+
|
|
70
|
+
partySize: {
|
|
71
|
+
order: 4,
|
|
72
|
+
fillable: true,
|
|
73
|
+
validation: {
|
|
74
|
+
rule: schema.number().required().min(1),
|
|
75
|
+
message: {
|
|
76
|
+
min: 'Party size must be at least 1',
|
|
77
|
+
},
|
|
78
|
+
},
|
|
79
|
+
factory: faker => faker.number.int({ min: 1, max: 20 }),
|
|
80
|
+
},
|
|
81
|
+
|
|
82
|
+
checkInTime: {
|
|
83
|
+
order: 5,
|
|
84
|
+
fillable: true,
|
|
85
|
+
validation: {
|
|
86
|
+
rule: schema.timestamp().required(),
|
|
87
|
+
},
|
|
88
|
+
factory: (faker) => {
|
|
89
|
+
const date = faker.date.future()
|
|
90
|
+
return date.toISOString().slice(0, 19).replace('T', ' ')
|
|
91
|
+
},
|
|
92
|
+
},
|
|
93
|
+
|
|
94
|
+
tablePreference: {
|
|
95
|
+
order: 6,
|
|
96
|
+
fillable: true,
|
|
97
|
+
validation: {
|
|
98
|
+
rule: schema.enum(['indoor', 'bar', 'booth', 'no_preference']).required(),
|
|
99
|
+
},
|
|
100
|
+
factory: faker => faker.helpers.arrayElement(['indoor', 'bar', 'booth', 'no_preference']),
|
|
101
|
+
},
|
|
102
|
+
|
|
103
|
+
status: {
|
|
104
|
+
default: 'waiting',
|
|
105
|
+
order: 7,
|
|
106
|
+
fillable: true,
|
|
107
|
+
validation: {
|
|
108
|
+
rule: schema.enum(['waiting', 'seated', 'cancelled', 'no_show']).required(),
|
|
109
|
+
},
|
|
110
|
+
factory: faker => faker.helpers.arrayElement(['waiting', 'seated', 'cancelled', 'no_show']),
|
|
111
|
+
},
|
|
112
|
+
|
|
113
|
+
quoted_wait_time: {
|
|
114
|
+
order: 8,
|
|
115
|
+
fillable: true,
|
|
116
|
+
validation: {
|
|
117
|
+
rule: schema.number().required().min(0),
|
|
118
|
+
message: {
|
|
119
|
+
min: 'Quoted wait time must be at least 0 minutes',
|
|
120
|
+
},
|
|
121
|
+
},
|
|
122
|
+
factory: faker => faker.number.int({ min: 0, max: 120 }),
|
|
123
|
+
},
|
|
124
|
+
|
|
125
|
+
actual_wait_time: {
|
|
126
|
+
order: 9,
|
|
127
|
+
fillable: true,
|
|
128
|
+
validation: {
|
|
129
|
+
rule: schema.number().min(0),
|
|
130
|
+
message: {
|
|
131
|
+
min: 'Actual wait time must be at least 0 minutes',
|
|
132
|
+
},
|
|
133
|
+
},
|
|
134
|
+
factory: faker => faker.helpers.maybe(() => faker.number.int({ min: 0, max: 180 }), { probability: 0.7 }),
|
|
135
|
+
},
|
|
136
|
+
|
|
137
|
+
queue_position: {
|
|
138
|
+
order: 10,
|
|
139
|
+
fillable: true,
|
|
140
|
+
validation: {
|
|
141
|
+
rule: schema.number().min(1),
|
|
142
|
+
message: {
|
|
143
|
+
min: 'Queue position must be at least 1',
|
|
144
|
+
},
|
|
145
|
+
},
|
|
146
|
+
factory: faker => faker.helpers.maybe(() => faker.number.int({ min: 1, max: 50 }), { probability: 0.7 }),
|
|
147
|
+
},
|
|
148
|
+
|
|
149
|
+
seatedAt: {
|
|
150
|
+
order: 11,
|
|
151
|
+
fillable: true,
|
|
152
|
+
validation: {
|
|
153
|
+
rule: schema.timestamp(),
|
|
154
|
+
},
|
|
155
|
+
factory: (faker) => {
|
|
156
|
+
const date = faker.date.future()
|
|
157
|
+
return date.toISOString().slice(0, 19).replace('T', ' ')
|
|
158
|
+
},
|
|
159
|
+
},
|
|
160
|
+
|
|
161
|
+
noShowAt: {
|
|
162
|
+
order: 12,
|
|
163
|
+
fillable: true,
|
|
164
|
+
validation: {
|
|
165
|
+
rule: schema.timestamp(),
|
|
166
|
+
},
|
|
167
|
+
factory: (faker) => {
|
|
168
|
+
const date = faker.date.future()
|
|
169
|
+
return date.toISOString().slice(0, 19).replace('T', ' ')
|
|
170
|
+
},
|
|
171
|
+
},
|
|
172
|
+
|
|
173
|
+
cancelledAt: {
|
|
174
|
+
order: 13,
|
|
175
|
+
fillable: true,
|
|
176
|
+
validation: {
|
|
177
|
+
rule: schema.timestamp(),
|
|
178
|
+
},
|
|
179
|
+
factory: (faker) => {
|
|
180
|
+
const date = faker.date.future()
|
|
181
|
+
return date.toISOString().slice(0, 19).replace('T', ' ')
|
|
182
|
+
},
|
|
183
|
+
},
|
|
184
|
+
},
|
|
185
|
+
|
|
186
|
+
dashboard: {
|
|
187
|
+
highlight: true,
|
|
188
|
+
},
|
|
189
|
+
} as const)
|
|
@@ -0,0 +1,78 @@
|
|
|
1
|
+
import { defineModel } from '@stacksjs/orm'
|
|
2
|
+
import { schema } from '@stacksjs/validation'
|
|
3
|
+
|
|
4
|
+
export default defineModel({
|
|
5
|
+
name: 'Websocket',
|
|
6
|
+
table: 'websockets',
|
|
7
|
+
primaryKey: 'id',
|
|
8
|
+
autoIncrement: true,
|
|
9
|
+
|
|
10
|
+
traits: {
|
|
11
|
+
useTimestamps: true,
|
|
12
|
+
useSeeder: {
|
|
13
|
+
count: 20,
|
|
14
|
+
},
|
|
15
|
+
useApi: {
|
|
16
|
+
uri: 'websockets',
|
|
17
|
+
routes: ['index', 'store', 'show'],
|
|
18
|
+
middleware: ['auth'],
|
|
19
|
+
},
|
|
20
|
+
observe: true,
|
|
21
|
+
},
|
|
22
|
+
|
|
23
|
+
attributes: {
|
|
24
|
+
type: {
|
|
25
|
+
required: true,
|
|
26
|
+
order: 1,
|
|
27
|
+
fillable: true,
|
|
28
|
+
validation: {
|
|
29
|
+
rule: schema.enum(['disconnection', 'error', 'success']),
|
|
30
|
+
message: {
|
|
31
|
+
in: 'Type must be one of: disconnection, error, success',
|
|
32
|
+
},
|
|
33
|
+
},
|
|
34
|
+
factory: faker => faker.helpers.arrayElement(['success', 'success', 'success', 'disconnection', 'error']),
|
|
35
|
+
},
|
|
36
|
+
|
|
37
|
+
socket: {
|
|
38
|
+
required: true,
|
|
39
|
+
order: 2,
|
|
40
|
+
fillable: true,
|
|
41
|
+
validation: {
|
|
42
|
+
rule: schema.string().min(1).max(255),
|
|
43
|
+
message: {
|
|
44
|
+
min: 'Socket identifier must be provided',
|
|
45
|
+
max: 'Socket identifier must not exceed 255 characters',
|
|
46
|
+
},
|
|
47
|
+
},
|
|
48
|
+
factory: faker => faker.string.alphanumeric(20),
|
|
49
|
+
},
|
|
50
|
+
|
|
51
|
+
details: {
|
|
52
|
+
required: true,
|
|
53
|
+
order: 3,
|
|
54
|
+
fillable: true,
|
|
55
|
+
validation: {
|
|
56
|
+
rule: schema.string().min(1).max(1000),
|
|
57
|
+
message: {
|
|
58
|
+
min: 'Details must be provided',
|
|
59
|
+
max: 'Details must not exceed 1000 characters',
|
|
60
|
+
},
|
|
61
|
+
},
|
|
62
|
+
factory: faker => faker.lorem.sentence(),
|
|
63
|
+
},
|
|
64
|
+
|
|
65
|
+
time: {
|
|
66
|
+
required: true,
|
|
67
|
+
order: 4,
|
|
68
|
+
fillable: true,
|
|
69
|
+
validation: {
|
|
70
|
+
rule: schema.number(),
|
|
71
|
+
message: {
|
|
72
|
+
date: 'Time must be a valid timestamp',
|
|
73
|
+
},
|
|
74
|
+
},
|
|
75
|
+
factory: faker => faker.date.recent().getTime(),
|
|
76
|
+
},
|
|
77
|
+
},
|
|
78
|
+
} as const)
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* One password policy, in one place (stacksjs/stacks#2226).
|
|
3
|
+
*
|
|
4
|
+
* The framework shipped three numbers for one product concept: `RegisterAction`
|
|
5
|
+
* and `LoginAction` accepted six characters, the `User` model declared six, and
|
|
6
|
+
* `PasswordResetAction` hand-checked eight with `password.length < 8` — not in a
|
|
7
|
+
* `validations:` block at all, so it could not even be read by the machinery
|
|
8
|
+
* that reads the others.
|
|
9
|
+
*
|
|
10
|
+
* Apps then retyped the rule again in the browser, because an Action's
|
|
11
|
+
* `validations:` was unreachable from a template. That is how a real app ended
|
|
12
|
+
* up refusing a 7-character password in the browser that `POST /register` would
|
|
13
|
+
* have accepted.
|
|
14
|
+
*
|
|
15
|
+
* Change the policy here and every declaration follows. An app that wants a
|
|
16
|
+
* different one edits this file, which is scaffolded into it.
|
|
17
|
+
*/
|
|
18
|
+
|
|
19
|
+
/**
|
|
20
|
+
* Minimum length for a NEW password.
|
|
21
|
+
*
|
|
22
|
+
* Eight, because that is what the password-reset path already enforced and it
|
|
23
|
+
* is the weaker of the two that was actually protecting anything. Raising the
|
|
24
|
+
* registration minimum only affects accounts created from now on.
|
|
25
|
+
*/
|
|
26
|
+
export const PASSWORD_MIN_LENGTH = 8
|
|
27
|
+
|
|
28
|
+
/**
|
|
29
|
+
* Maximum length. Also the `varchar` width the User model's column derives
|
|
30
|
+
* from, so lowering it is a migration, not just a rule change.
|
|
31
|
+
*/
|
|
32
|
+
export const PASSWORD_MAX_LENGTH = 255
|
|
33
|
+
|
|
34
|
+
export const PASSWORD_POLICY_MESSAGE
|
|
35
|
+
= `Password must be between ${PASSWORD_MIN_LENGTH} and ${PASSWORD_MAX_LENGTH} characters.`
|
|
36
|
+
|
|
37
|
+
/**
|
|
38
|
+
* What a sign-in must require: that a password was supplied, and nothing more.
|
|
39
|
+
*
|
|
40
|
+
* Deliberately NOT the policy above. Applying a creation rule to authentication
|
|
41
|
+
* locks out every account created under a previous, shorter policy — they would
|
|
42
|
+
* get a 422 before their credentials were ever checked, with a message telling
|
|
43
|
+
* them their own password is too short. The policy belongs on the paths that
|
|
44
|
+
* SET a password.
|
|
45
|
+
*/
|
|
46
|
+
export const PASSWORD_PRESENCE_MESSAGE = 'Password is required.'
|
package/package.json
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
"name": "@stacksjs/orm",
|
|
3
3
|
"type": "module",
|
|
4
4
|
"sideEffects": false,
|
|
5
|
-
"version": "0.72.
|
|
5
|
+
"version": "0.72.18",
|
|
6
6
|
"description": "The Stacks ORM integration",
|
|
7
7
|
"author": "Chris Breuer",
|
|
8
8
|
"contributors": [
|
|
@@ -67,9 +67,9 @@
|
|
|
67
67
|
"bun-query-builder": "^0.2.44"
|
|
68
68
|
},
|
|
69
69
|
"devDependencies": {
|
|
70
|
-
"@stacksjs/config": "0.72.
|
|
70
|
+
"@stacksjs/config": "0.72.18",
|
|
71
71
|
"better-dx": "^0.2.23",
|
|
72
|
-
"@stacksjs/query-builder": "0.72.
|
|
73
|
-
"@stacksjs/types": "0.72.
|
|
72
|
+
"@stacksjs/query-builder": "0.72.18",
|
|
73
|
+
"@stacksjs/types": "0.72.18"
|
|
74
74
|
}
|
|
75
75
|
}
|