@stacksjs/actions 0.61.18 → 0.61.20

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.js CHANGED
@@ -611,20 +611,24 @@ export default {
611
611
  class Action3 {
612
612
  name;
613
613
  description;
614
- fields;
615
614
  rate;
616
615
  tries;
617
616
  backoff;
618
617
  enabled;
618
+ path;
619
+ method;
620
+ validations;
619
621
  handle;
620
- constructor({ name, description, fields, handle, rate, tries, backoff, enabled }) {
622
+ constructor({ name, description, validations, handle, rate, tries, backoff, enabled, path: path4, method }) {
621
623
  this.name = name;
622
624
  this.description = description;
623
- this.fields = fields;
625
+ this.validations = validations;
624
626
  this.rate = rate;
625
627
  this.tries = tries;
626
628
  this.backoff = backoff;
627
629
  this.enabled = enabled;
630
+ this.path = path4;
631
+ this.method = method;
628
632
  this.handle = handle;
629
633
  }
630
634
  }
package/dist/lint/fix.js CHANGED
@@ -1,12 +1,6 @@
1
1
  // @bun
2
2
  // src/lint/fix.ts
3
- import {log, parseOptions, runCommand} from "@stacksjs/cli";
4
- import {NpmScript} from "@stacksjs/enums";
5
- import {projectPath} from "@stacksjs/path";
3
+ import {log, parseOptions} from "@stacksjs/cli";
6
4
  log.info("Ensuring Code Style...");
7
5
  var options = parseOptions();
8
- var result = await runCommand(NpmScript.LintFix, {
9
- cwd: projectPath(),
10
- ...options
11
- });
12
6
  log.success("Linted");
@@ -1,16 +1,5 @@
1
1
  // @bun
2
2
  // src/lint/index.ts
3
- import process from "process";
4
- import {log, runCommands} from "@stacksjs/cli";
5
- import {NpmScript} from "@stacksjs/enums";
6
- import {projectPath} from "@stacksjs/path";
7
- import {ExitCode} from "@stacksjs/types";
3
+ import {log} from "@stacksjs/cli";
8
4
  log.info("Ensuring Code Style...");
9
- var result = await runCommands([NpmScript.Lint, NpmScript.LintPackageJson], {
10
- cwd: projectPath()
11
- });
12
- if (Array.isArray(result)) {
13
- if (result.map((r) => r.isErr()).includes(true))
14
- process.exit(ExitCode.FatalError);
15
- }
16
5
  log.success("Linted");
package/dist/release.js CHANGED
@@ -613,20 +613,24 @@ export default {
613
613
  class Action3 {
614
614
  name;
615
615
  description;
616
- fields;
617
616
  rate;
618
617
  tries;
619
618
  backoff;
620
619
  enabled;
620
+ path;
621
+ method;
622
+ validations;
621
623
  handle;
622
- constructor({ name, description, fields, handle, rate, tries, backoff, enabled }) {
624
+ constructor({ name, description, validations, handle, rate, tries, backoff, enabled, path: path4, method }) {
623
625
  this.name = name;
624
626
  this.description = description;
625
- this.fields = fields;
627
+ this.validations = validations;
626
628
  this.rate = rate;
627
629
  this.tries = tries;
628
630
  this.backoff = backoff;
629
631
  this.enabled = enabled;
632
+ this.path = path4;
633
+ this.method = method;
630
634
  this.handle = handle;
631
635
  }
632
636
  }
package/dist/upgrade.js CHANGED
@@ -7,7 +7,7 @@ import {log} from "@stacksjs/logging";
7
7
  import {projectPath} from "@stacksjs/path";
8
8
  import * as storage from "@stacksjs/storage";
9
9
  // package.json
10
- var version = "0.61.18";
10
+ var version = "0.61.20";
11
11
 
12
12
  // src/upgrade.ts
13
13
  function checkForUncommittedChanges(options) {
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@stacksjs/actions",
3
3
  "type": "module",
4
- "version": "0.61.18",
4
+ "version": "0.61.20",
5
5
  "description": "The Stacks actions.",
6
6
  "author": "Chris Breuer",
7
7
  "license": "MIT",
package/src/action.ts CHANGED
@@ -1,12 +1,10 @@
1
1
  import type { JobOptions, Nullable } from '@stacksjs/types'
2
2
  import type { ValidationBoolean, ValidationNumber, ValidationString } from '@stacksjs/validation'
3
3
 
4
- type FieldKey = string
5
- interface FieldValue {
4
+ type ValidationKey = string
5
+ interface ValidationValue {
6
6
  rule: ValidationString | ValidationNumber | ValidationBoolean | Date | Nullable<any>
7
7
  message: string
8
- factory?: any
9
- unique?: boolean
10
8
  }
11
9
 
12
10
  // TODO: this is temporary and will get auto generated based on ./app/Actions/*
@@ -19,8 +17,9 @@ interface ActionOptions {
19
17
  name?: string
20
18
  description?: string
21
19
  apiResponse?: boolean
22
- fields?: Record<FieldKey, FieldValue>
20
+ validations?: Record<ValidationKey, ValidationValue>
23
21
  path?: string
22
+ method?: 'GET' | 'POST' | 'PUT' | 'PATCH' | 'DELETE'
24
23
  rate?: JobOptions['rate']
25
24
  tries?: JobOptions['tries']
26
25
  backoff?: JobOptions['backoff']
@@ -31,23 +30,27 @@ interface ActionOptions {
31
30
  export class Action {
32
31
  name?: string
33
32
  description?: string
34
- fields?: Record<FieldKey, FieldValue>
35
- rate?: JobOptions['rate']
36
- tries?: JobOptions['tries']
37
- backoff?: JobOptions['backoff']
38
- enabled?: boolean
33
+ rate?: ActionOptions['rate']
34
+ tries?: ActionOptions['tries']
35
+ backoff?: ActionOptions['backoff']
36
+ enabled?: ActionOptions['enabled']
37
+ path?: ActionOptions['path']
38
+ method?: ActionOptions['method']
39
+ validations?: Record<ValidationKey, ValidationValue>
39
40
  handle: (request?: Request) => Promise<any> | object | string
40
41
 
41
- constructor({ name, description, fields, handle, rate, tries, backoff, enabled }: ActionOptions) {
42
+ constructor({ name, description, validations, handle, rate, tries, backoff, enabled, path, method }: ActionOptions) {
42
43
  // log.debug(`Action ${name} created`) // TODO: this does not yet work because the cloud does not yet have proper file system (efs) access
43
44
 
44
45
  this.name = name
45
46
  this.description = description
46
- this.fields = fields
47
+ this.validations = validations
47
48
  this.rate = rate
48
49
  this.tries = tries
49
50
  this.backoff = backoff
50
51
  this.enabled = enabled
52
+ this.path = path
53
+ this.method = method
51
54
  this.handle = handle
52
55
  }
53
56
  }
package/src/bump.ts CHANGED
@@ -3,11 +3,6 @@ import { path as p } from '@stacksjs/path'
3
3
 
4
4
  const options = parseOptions()
5
5
  const changelogCommand = options?.dryRun ? 'buddy changelog --quiet --dry-run' : 'buddy changelog --quiet'
6
-
7
- // await runCommand(changelogCommand, {
8
- // cwd: p.projectPath(),
9
- // })
10
-
11
6
  const bumpCommand = options?.dryRun
12
7
  ? `bunx bumpp ./package.json ./**/package.json ../ide/vscode/package.json --no-push --execute "../scripts/lint"`
13
8
  : `bunx bumpp ./package.json ./**/package.json ../ide/vscode/package.json --all --execute "../scripts/lint"`
package/src/lint/fix.ts CHANGED
@@ -8,10 +8,10 @@ log.info('Ensuring Code Style...')
8
8
 
9
9
  const options = parseOptions()
10
10
 
11
- const result = await runCommand(NpmScript.LintFix, {
12
- cwd: projectPath(),
13
- ...options,
14
- })
11
+ // const result = await runCommand(NpmScript.LintFix, {
12
+ // cwd: projectPath(),
13
+ // ...options,
14
+ // })
15
15
 
16
16
  // console.log('rs', result.error)
17
17
  // if (result.isErr()) {
package/src/lint/index.ts CHANGED
@@ -12,12 +12,12 @@ log.info('Ensuring Code Style...')
12
12
  // await $`${NpmScript.Lint}`
13
13
  // await $`${NpmScript.LintPackageJson}`
14
14
 
15
- const result = await runCommands([NpmScript.Lint, NpmScript.LintPackageJson], {
16
- cwd: projectPath(),
17
- })
15
+ // const result = await runCommands([NpmScript.Lint, NpmScript.LintPackageJson], {
16
+ // cwd: projectPath(),
17
+ // })
18
18
 
19
- if (Array.isArray(result)) {
20
- if (result.map((r) => r.isErr()).includes(true)) process.exit(ExitCode.FatalError)
21
- }
19
+ // if (Array.isArray(result)) {
20
+ // if (result.map((r) => r.isErr()).includes(true)) process.exit(ExitCode.FatalError)
21
+ // }
22
22
 
23
23
  log.success('Linted')
@@ -22,23 +22,58 @@ export interface ModelElement {
22
22
  await initiateModelGeneration()
23
23
  await setKyselyTypes()
24
24
 
25
- async function generateApiRoutes(model: Model) {
26
- if (model.traits?.useApi) {
27
- let routeString = `import { route } from '@stacksjs/router'\n\n\n`
28
- const apiRoutes = model.traits?.useApi?.routes
29
-
30
- if (apiRoutes?.length) {
31
- for (const apiRoute of apiRoutes) {
32
- await writeOrmActions(apiRoute, model)
33
- routeString += await writeApiRoutes(apiRoute, model)
25
+ async function generateApiRoutes(modelFiles: string[]) {
26
+ const file = Bun.file(path.projectStoragePath(`framework/orm/routes.ts`))
27
+ const writer = file.writer()
28
+ let routeString = `import { route } from '@stacksjs/router'\n\n\n`
29
+
30
+ for (const modelFile of modelFiles) {
31
+ log.debug(`Processing model file: ${modelFile}`)
32
+
33
+ const model = (await import(modelFile)).default as Model
34
+
35
+ if (model.traits?.useApi) {
36
+ const apiRoutes = model.traits?.useApi?.routes
37
+ const middlewares = model.traits.useApi?.middleware
38
+ let middlewareString = `.middleware([`
39
+
40
+ if (middlewares.length) {
41
+ for (let i = 0; i < middlewares.length; i++) {
42
+ middlewareString += `'${middlewares[i]}'`
43
+
44
+ if (i < middlewares.length - 1) {
45
+ middlewareString += ','
46
+ }
47
+ }
34
48
  }
35
- }
36
49
 
37
- const file = Bun.file(path.projectStoragePath(`framework/orm/routes.ts`))
38
- const writer = file.writer()
39
- writer.write(routeString)
40
- await writer.end()
50
+ middlewareString += `])`
51
+
52
+ if (apiRoutes?.length) {
53
+ for (const apiRoute of apiRoutes) {
54
+ await writeOrmActions(apiRoute, model)
55
+
56
+ if (apiRoute === 'index')
57
+ routeString += `await route.get('${model.table}', 'Actions/${model.name}IndexOrmAction')${middlewareString}\n\n`
58
+
59
+ if (apiRoute === 'store')
60
+ routeString += `await route.post('${model.table}', 'Actions/${model.name}StoreOrmAction')${middlewareString}\n\n`
61
+
62
+ if (apiRoute === 'update')
63
+ routeString += `await route.patch('${model.table}/{id}', 'Actions/${model.name}UpdateOrmAction')${middlewareString}\n\n`
64
+
65
+ if (apiRoute === 'show')
66
+ routeString += `await route.get('${model.table}/{id}', 'Actions/${model.name}ShowOrmAction')${middlewareString}\n\n`
67
+
68
+ if (apiRoute === 'destroy')
69
+ routeString += `await route.delete('${model.table}/{id}', 'Actions/${model.name}DestroyOrmAction')${middlewareString}\n\n`
70
+ }
71
+ }
72
+ }
41
73
  }
74
+
75
+ writer.write(routeString)
76
+ await writer.end()
42
77
  }
43
78
 
44
79
  async function writeModelNames() {
@@ -68,57 +103,71 @@ async function writeModelNames() {
68
103
  async function writeOrmActions(apiRoute: string, model: Model): Promise<void> {
69
104
  const modelName = model.name
70
105
  const formattedApiRoute = apiRoute.charAt(0).toUpperCase() + apiRoute.slice(1)
71
-
106
+ let method = 'GET'
72
107
  let actionString = `import { Action } from '@stacksjs/actions'\n`
73
- actionString += `import ${modelName} from '../src/${modelName}'\n\n`
108
+ actionString += `import ${modelName} from '../src/models/${modelName}'\n\n`
74
109
  actionString += `import { request } from '@stacksjs/router'\n\n`
75
110
 
76
111
  let handleString = ``
77
112
 
78
113
  if (apiRoute === 'index') {
79
- handleString += `handle() {
80
- return ${modelName}.all()
114
+ handleString += `async handle() {
115
+ return await ${modelName}.all()
81
116
  },`
117
+
118
+ method = 'GET'
82
119
  }
83
120
 
84
121
  if (apiRoute === 'show') {
85
- handleString += `handle() {
86
- return ${modelName}.find(1)
122
+ handleString += `async handle() {
123
+ const id = await request.getParam('id')
124
+
125
+ return ${modelName}.findOrFail(Number(id))
87
126
  },`
127
+
128
+ method = 'GET'
88
129
  }
89
130
 
90
131
  if (apiRoute === 'destroy') {
91
- handleString += `handle() {
92
- const model = ${modelName}.find(1)
132
+ handleString += `async handle() {
133
+ const id = request.getParam('id')
134
+
135
+ const model = await ${modelName}.findOrFail(Number(id))
93
136
 
94
137
  model.delete()
95
138
 
96
139
  return 'Model deleted!'
97
140
  },`
141
+
142
+ method = 'DELETE'
98
143
  }
99
144
 
100
145
  if (apiRoute === 'store') {
101
- handleString += `handle() {
102
- const model = ${modelName}.create(request.all())
146
+ handleString += `async handle() {
147
+ const model = await ${modelName}.create(request.all())
103
148
 
104
149
  return model
105
150
  },`
151
+
152
+ method = 'POST'
106
153
  }
107
154
 
108
155
  if (apiRoute === 'update') {
109
- handleString += `handle() {
110
- const id = request.get(req.params.id)
156
+ handleString += `async handle() {
157
+ const id = request.getParam('id')
111
158
 
112
- const model = ${modelName}.find(req.params.id)
159
+ const model = await ${modelName}.findOrFail(Number(id))
113
160
 
114
- return model.update(req.all())
161
+ return model.update(request.all())
115
162
  },`
163
+
164
+ method = 'PATCH'
116
165
  }
117
166
 
118
167
  actionString += `export default new Action({
119
168
  name: '${modelName} ${formattedApiRoute}',
120
169
  description: '${modelName} ${formattedApiRoute} ORM Action',
121
-
170
+ method: '${method}',
122
171
  ${handleString}
123
172
  })
124
173
  `
@@ -159,6 +208,8 @@ async function initiateModelGeneration(): Promise<void> {
159
208
 
160
209
  const modelFiles = glob.sync(path.userModelsPath('*.ts'))
161
210
 
211
+ await generateApiRoutes(modelFiles)
212
+
162
213
  for (const modelFile of modelFiles) {
163
214
  log.debug(`Processing model file: ${modelFile}`)
164
215
 
@@ -166,8 +217,6 @@ async function initiateModelGeneration(): Promise<void> {
166
217
  const tableName = await modelTableName(model)
167
218
  const modelName = path.basename(modelFile, '.ts')
168
219
 
169
- await generateApiRoutes(model)
170
-
171
220
  const file = Bun.file(path.projectStoragePath(`framework/orm/src/models/${modelName}.ts`))
172
221
  const fields = await extractFields(model, modelFile)
173
222
  const classString = await generateModelString(tableName, model, fields)
@@ -220,7 +269,7 @@ function hasRelations(obj: any, key: string): boolean {
220
269
  }
221
270
 
222
271
  async function deleteExistingModels() {
223
- const modelPaths = glob.sync(path.projectStoragePath(`framework/orm/src/models*.ts`))
272
+ const modelPaths = glob.sync(path.projectStoragePath(`framework/orm/src/models/*.ts`))
224
273
 
225
274
  for (const modelPath of modelPaths) {
226
275
  if (fs.existsSync(modelPath)) await Bun.$`rm ${modelPath}`
@@ -233,10 +282,13 @@ async function deleteExistingModels() {
233
282
 
234
283
  async function deleteExistingOrmActions() {
235
284
  const ormPaths = glob.sync(path.projectStoragePath(`framework/orm/Actions/*.ts`))
285
+ const routes = path.projectStoragePath(`framework/orm/routes`)
236
286
 
237
287
  for (const ormPath of ormPaths) {
238
288
  if (fs.existsSync(ormPath)) await Bun.$`rm ${ormPath}`
239
289
  }
290
+
291
+ if (fs.existsSync(routes)) await Bun.$`rm ${routes}`
240
292
  }
241
293
 
242
294
  async function deleteExistingModelNameTypes() {
@@ -586,7 +638,7 @@ async function generateModelString(tableName: string, model: Model, attributes:
586
638
 
587
639
  const otherModelRelations = await fetchOtherModelRelations(model)
588
640
 
589
- for (const otherModelRelation of otherModelRelations) fieldString += ` ${otherModelRelation.foreignKey}: number`
641
+ for (const otherModelRelation of otherModelRelations) fieldString += ` ${otherModelRelation.foreignKey}: number \n`
590
642
 
591
643
  return `import type { ColumnType, Generated, Insertable, Selectable, Updateable } from 'kysely'
592
644
  import type { Result } from '@stacksjs/error-handling'
@@ -643,7 +695,7 @@ async function generateModelString(tableName: string, model: Model, attributes:
643
695
  }
644
696
 
645
697
  // Method to find a ${formattedModelName} by ID
646
- static async find(id: number, fields?: (keyof ${modelName}Type)[]) {
698
+ static async find(id: number, fields?: (keyof ${modelName}Type)[]): Promise<${modelName}Model> {
647
699
  let query = db.selectFrom('${tableName}').where('id', '=', id)
648
700
 
649
701
  if (fields)
@@ -659,7 +711,23 @@ async function generateModelString(tableName: string, model: Model, attributes:
659
711
  return new ${modelName}Model(model)
660
712
  }
661
713
 
662
- static async findMany(ids: number[], fields?: (keyof ${modelName}Type)[]) {
714
+ static async findOrFail(id: number, fields?: (keyof ${modelName}Type)[]): Promise<${modelName}Model> {
715
+ let query = db.selectFrom('${tableName}').where('id', '=', id)
716
+
717
+ if (fields)
718
+ query = query.select(fields)
719
+ else
720
+ query = query.selectAll()
721
+
722
+ const model = await query.executeTakeFirst()
723
+
724
+ if (!model)
725
+ throw(\`No model results found for \${id}\ \`)
726
+
727
+ return new ${modelName}Model(model)
728
+ }
729
+
730
+ static async findMany(ids: number[], fields?: (keyof ${modelName}Type)[]): Promise<${modelName}Model[]> {
663
731
  let query = db.selectFrom('${tableName}').where('id', 'in', ids)
664
732
 
665
733
  if (fields)
@@ -724,36 +792,23 @@ async function generateModelString(tableName: string, model: Model, attributes:
724
792
 
725
793
  // Method to create a new ${formattedModelName}
726
794
  static async create(new${modelName}: New${modelName}): Promise<${modelName}Model> {
727
- const model = await db.insertInto('${tableName}')
795
+ const result = await db.insertInto('${tableName}')
728
796
  .values(new${modelName})
729
- .returningAll()
730
- .executeTakeFirstOrThrow()
731
-
732
- return new ${modelName}Model(model)
733
- }
734
-
735
- // Method to update a ${formattedModelName}
736
- static async update(id: number, ${formattedModelName}Update: ${modelName}Update): Promise<${modelName}Model> {
737
- const model = await db.updateTable('${tableName}')
738
- .set(${formattedModelName}Update)
739
- .where('id', '=', id)
740
- .returningAll()
741
797
  .executeTakeFirstOrThrow()
742
798
 
743
- return new ${modelName}Model(model)
799
+ return await find(Number(result.insertId)) as ${modelName}Model
744
800
  }
745
801
 
746
802
  // Method to remove a ${formattedModelName}
747
803
  static async remove(id: number): Promise<${modelName}Model> {
748
804
  const model = await db.deleteFrom('${tableName}')
749
805
  .where('id', '=', id)
750
- .returningAll()
751
806
  .executeTakeFirstOrThrow()
752
807
 
753
808
  return new ${modelName}Model(model)
754
809
  }
755
810
 
756
- async where(column: string, operator = '=', value: any) {
811
+ async where(column: string, operator = '=', value: any): Promise<${modelName}Type[]> {
757
812
  let query = db.selectFrom('${tableName}')
758
813
 
759
814
  query = query.where(column, operator, value)
@@ -805,7 +860,7 @@ async function generateModelString(tableName: string, model: Model, attributes:
805
860
  return await query.selectAll().execute()
806
861
  }
807
862
 
808
- async whereIn(column: keyof ${modelName}Type, values: any[], options: QueryOptions = {}) {
863
+ async whereIn(column: keyof ${modelName}Type, values: any[], options: QueryOptions = {}): Promise<${modelName}Type[]> {
809
864
  let query = db.selectFrom('${tableName}')
810
865
 
811
866
  query = query.where(column, 'in', values)
@@ -824,34 +879,34 @@ async function generateModelString(tableName: string, model: Model, attributes:
824
879
  return await query.selectAll().execute()
825
880
  }
826
881
 
827
- async first() {
882
+ async first(): Promise<${modelName}Type> {
828
883
  return await db.selectFrom('${tableName}')
829
884
  .selectAll()
830
885
  .executeTakeFirst()
831
886
  }
832
887
 
833
- async last() {
888
+ async last(): Promise<${modelName}Type> {
834
889
  return await db.selectFrom('${tableName}')
835
890
  .selectAll()
836
891
  .orderBy('id', 'desc')
837
892
  .executeTakeFirst()
838
893
  }
839
894
 
840
- async orderBy(column: keyof ${modelName}Type, order: 'asc' | 'desc') {
895
+ async orderBy(column: keyof ${modelName}Type, order: 'asc' | 'desc'): Promise<${modelName}Type[]> {
841
896
  return await db.selectFrom('${tableName}')
842
897
  .selectAll()
843
898
  .orderBy(column, order)
844
899
  .execute()
845
900
  }
846
901
 
847
- async orderByDesc(column: keyof ${modelName}Type) {
902
+ async orderByDesc(column: keyof ${modelName}Type): Promise<${modelName}Type[]> {
848
903
  return await db.selectFrom('${tableName}')
849
904
  .selectAll()
850
905
  .orderBy(column, 'desc')
851
906
  .execute()
852
907
  }
853
908
 
854
- async orderByAsc(column: keyof ${modelName}Type) {
909
+ async orderByAsc(column: keyof ${modelName}Type): Promise<${modelName}Type[]> {
855
910
  return await db.selectFrom('${tableName}')
856
911
  .selectAll()
857
912
  .orderBy(column, 'asc')
@@ -859,7 +914,7 @@ async function generateModelString(tableName: string, model: Model, attributes:
859
914
  }
860
915
 
861
916
  // Method to get the ${formattedModelName} instance itself
862
- self() {
917
+ self(): ${modelName}Model {
863
918
  return this
864
919
  }
865
920
 
@@ -876,14 +931,11 @@ async function generateModelString(tableName: string, model: Model, attributes:
876
931
  const updatedModel = await db.updateTable('${tableName}')
877
932
  .set(${formattedModelName})
878
933
  .where('id', '=', this.${formattedModelName}.id)
879
- .returningAll()
880
934
  .executeTakeFirst()
881
935
 
882
936
  if (!updatedModel)
883
937
  return err(handleError('${modelName} not found'))
884
938
 
885
- this.${formattedModelName} = updatedModel
886
-
887
939
  return ok(updatedModel)
888
940
  }
889
941
 
@@ -896,9 +948,7 @@ async function generateModelString(tableName: string, model: Model, attributes:
896
948
  // Insert new ${formattedModelName}
897
949
  const newModel = await db.insertInto('${tableName}')
898
950
  .values(this.${formattedModelName} as New${modelName})
899
- .returningAll()
900
951
  .executeTakeFirstOrThrow()
901
- this.${formattedModelName} = newModel
902
952
  }
903
953
  else {
904
954
  // Update existing ${formattedModelName}
@@ -969,6 +1019,22 @@ async function generateModelString(tableName: string, model: Model, attributes:
969
1019
  return new ${modelName}Model(model)
970
1020
  }
971
1021
 
1022
+ export async function findOrFail(id: number, fields?: (keyof ${modelName}Type)[]) {
1023
+ let query = db.selectFrom('${tableName}').where('id', '=', id)
1024
+
1025
+ if (fields)
1026
+ query = query.select(fields)
1027
+ else
1028
+ query = query.selectAll()
1029
+
1030
+ const model = await query.executeTakeFirst()
1031
+
1032
+ if (!model)
1033
+ throw(\`No model results found for \${id}\ \`)
1034
+
1035
+ return new ${modelName}Model(model)
1036
+ }
1037
+
972
1038
  export async function findMany(ids: number[], fields?: (keyof ${modelName}Type)[]) {
973
1039
  let query = db.selectFrom('${tableName}').where('id', 'in', ids)
974
1040
 
@@ -982,7 +1048,7 @@ async function generateModelString(tableName: string, model: Model, attributes:
982
1048
  return model.map(modelItem => new ${modelName}Model(modelItem))
983
1049
  }
984
1050
 
985
- export async function count() {
1051
+ export async function count(): Number {
986
1052
  const results = await db.selectFrom('${tableName}')
987
1053
  .selectAll()
988
1054
  .execute()
@@ -1025,7 +1091,7 @@ async function generateModelString(tableName: string, model: Model, attributes:
1025
1091
  return await query.selectAll().execute()
1026
1092
  }
1027
1093
 
1028
- export async function all(limit: number = 10, offset: number = 0) {
1094
+ export async function all(limit: number = 10, offset: number = 0): Promise<${modelName}Type[]> {
1029
1095
  return await db.selectFrom('${tableName}')
1030
1096
  .selectAll()
1031
1097
  .orderBy('created_at', 'desc')
@@ -1034,27 +1100,28 @@ async function generateModelString(tableName: string, model: Model, attributes:
1034
1100
  .execute()
1035
1101
  }
1036
1102
 
1037
- export async function create(new${modelName}: New${modelName}) {
1038
- return await db.insertInto('${tableName}')
1039
- .values(new${modelName})
1040
- .returningAll()
1041
- .executeTakeFirstOrThrow()
1103
+ export async function create(new${modelName}: New${modelName}): Promise<${modelName}Model> {
1104
+ const result = await db.insertInto('${tableName}')
1105
+ .values(new${modelName})
1106
+ .executeTakeFirstOrThrow()
1107
+
1108
+ return await find(Number(result.insertId))
1042
1109
  }
1043
1110
 
1044
- export async function first() {
1111
+ export async function first(): Promise<${modelName}Model> {
1045
1112
  return await db.selectFrom('${tableName}')
1046
1113
  .selectAll()
1047
1114
  .executeTakeFirst()
1048
1115
  }
1049
1116
 
1050
- export async function recent(limit: number) {
1117
+ export async function recent(limit: number): Promise<${modelName}Model[]> {
1051
1118
  return await db.selectFrom('${tableName}')
1052
1119
  .selectAll()
1053
1120
  .limit(limit)
1054
1121
  .execute()
1055
1122
  }
1056
1123
 
1057
- export async function last(limit: number) {
1124
+ export async function last(limit: number): Promise<${modelName}Type> {
1058
1125
  return await db.selectFrom('${tableName}')
1059
1126
  .selectAll()
1060
1127
  .orderBy('id', 'desc')
@@ -1072,7 +1139,6 @@ async function generateModelString(tableName: string, model: Model, attributes:
1072
1139
  export async function remove(id: number) {
1073
1140
  return await db.deleteFrom('${tableName}')
1074
1141
  .where('id', '=', id)
1075
- .returningAll()
1076
1142
  .executeTakeFirst()
1077
1143
  }
1078
1144
 
@@ -1156,6 +1222,7 @@ async function generateModelString(tableName: string, model: Model, attributes:
1156
1222
 
1157
1223
  export const ${modelName} = {
1158
1224
  find,
1225
+ findOrFail,
1159
1226
  findMany,
1160
1227
  get,
1161
1228
  count,
@@ -0,0 +1,14 @@
1
+ import process from 'node:process'
2
+ import { log } from '@stacksjs/logging'
3
+ import { listRoutes } from '@stacksjs/router'
4
+
5
+ // first, reset the database, if it exists
6
+ const result = await listRoutes()
7
+
8
+ if (result?.isErr()) {
9
+ console.error(result.error)
10
+ log.error('Route lists failed', result.error)
11
+ process.exit(1)
12
+ }
13
+
14
+ process.exit(0)