@stacksjs/actions 0.58.48 → 0.58.49

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (90) hide show
  1. package/dist/src/generate/ide-helpers.js +1 -0
  2. package/dist/src/generate/lib-entries.js +4 -2
  3. package/dist/src/generate/vscode-custom-data.js +1 -0
  4. package/dist/src/helpers/lib-entries.js +1 -0
  5. package/dist/src/helpers/package-json.js +1 -0
  6. package/dist/src/helpers/vscode-custom-data.js +1 -0
  7. package/dist/src/upgrade.js +1 -1
  8. package/package.json +3 -2
  9. package/src/action.ts +11 -0
  10. package/src/actions.ts +2 -0
  11. package/src/add.ts +27 -0
  12. package/src/ai/request-model-access.ts +74 -0
  13. package/src/build/cli.ts +7 -0
  14. package/src/build/component-libs.ts +5 -0
  15. package/src/build/core.ts +34 -0
  16. package/src/build/desktop.ts +7 -0
  17. package/src/build/docs.ts +7 -0
  18. package/src/build/stacks.ts +7 -0
  19. package/src/build.ts +89 -0
  20. package/src/bump.ts +11 -0
  21. package/src/cdn/invalidate-cache.ts +27 -0
  22. package/src/changelog.ts +11 -0
  23. package/src/clean.ts +6 -0
  24. package/src/commit.ts +14 -0
  25. package/src/copy-types.ts +22 -0
  26. package/src/database/fields.ts +111 -0
  27. package/src/database/migration-mysql.ts +72 -0
  28. package/src/database/migration-sqlite.ts +67 -0
  29. package/src/database/migration.ts +10 -0
  30. package/src/database/mydb.sqlite +0 -0
  31. package/src/database/seed.ts +4 -0
  32. package/src/database/stacks.sqlite +0 -0
  33. package/src/database/user-migration.ts +20 -0
  34. package/src/deploy/create-receipt-rule.ts +55 -0
  35. package/src/deploy/index.ts +46 -0
  36. package/src/dev/api.ts +19 -0
  37. package/src/dev/components.ts +14 -0
  38. package/src/dev/dashboard.ts +7 -0
  39. package/src/dev/desktop.ts +7 -0
  40. package/src/dev/docs.ts +7 -0
  41. package/src/dev/index.ts +48 -0
  42. package/src/dev/system-tray.ts +6 -0
  43. package/src/dev/views.ts +7 -0
  44. package/src/domains/add.ts +82 -0
  45. package/src/domains/purchase.ts +76 -0
  46. package/src/domains/remove.ts +38 -0
  47. package/src/examples.ts +46 -0
  48. package/src/fresh.ts +20 -0
  49. package/src/generate/caddyfile.ts +1 -0
  50. package/src/generate/component-meta.ts +19 -0
  51. package/src/generate/env-files.ts +89 -0
  52. package/src/generate/ide-helpers.ts +18 -0
  53. package/src/generate/index.ts +132 -0
  54. package/src/generate/lib-entries.ts +18 -0
  55. package/src/generate/model-classes.ts +299 -0
  56. package/src/generate/model-generate.ts +12 -0
  57. package/src/generate/pkgx-file.ts +72 -0
  58. package/src/generate/types.ts +6 -0
  59. package/src/generate/vscode-custom-data.ts +19 -0
  60. package/src/generate/web-types.ts +2 -0
  61. package/src/helpers/component-meta.ts +93 -0
  62. package/src/helpers/index.ts +1 -0
  63. package/src/helpers/lib-entries.ts +139 -0
  64. package/src/helpers/package-json.ts +96 -0
  65. package/src/helpers/utils.ts +82 -0
  66. package/src/helpers/vscode-custom-data.ts +35 -0
  67. package/src/index.ts +29 -0
  68. package/src/key-generate.ts +10 -0
  69. package/src/lint/fix.ts +7 -0
  70. package/src/lint/index.ts +27 -0
  71. package/src/make.ts +322 -0
  72. package/src/migrate/database.ts +1 -0
  73. package/src/migrate/dns.ts +3 -0
  74. package/src/prepublish.ts +17 -0
  75. package/src/release.ts +15 -0
  76. package/src/start-caddy.ts +13 -0
  77. package/src/test/coverage.ts +5 -0
  78. package/src/test/feature.ts +5 -0
  79. package/src/test/ui.ts +5 -0
  80. package/src/test/unit.ts +5 -0
  81. package/src/test.ts +5 -0
  82. package/src/tinker.ts +10 -0
  83. package/src/typecheck.ts +5 -0
  84. package/src/types.ts +20 -0
  85. package/src/upgrade/bun.ts +4 -0
  86. package/src/upgrade/dependencies.ts +0 -0
  87. package/src/upgrade/framework.ts +30 -0
  88. package/src/upgrade/index.ts +21 -0
  89. package/src/upgrade.ts +65 -0
  90. package/src/zip/api.ts +22 -0
@@ -15,6 +15,7 @@ var library_default = {
15
15
  author: "Chris Breuer",
16
16
  contributors: ["Chris Breuer <chris@stacksjs.org>"],
17
17
  defaultLanguage: "en",
18
+ releaseable: true,
18
19
  vueComponents: {
19
20
  name: "hello-world-vue",
20
21
  description: "Your Vue component library description",
@@ -19,6 +19,7 @@ var library_default = {
19
19
  author: "Chris Breuer",
20
20
  contributors: ["Chris Breuer <chris@stacksjs.org>"],
21
21
  defaultLanguage: "en",
22
+ releaseable: true,
22
23
  vueComponents: {
23
24
  name: "hello-world-vue",
24
25
  description: "Your Vue component library description",
@@ -155,14 +156,15 @@ function generateEntryPointData(type) {
155
156
 
156
157
  // src/generate/lib-entries.ts
157
158
  import {log as log2} from "@stacksjs/logging";
159
+ import {library as library2} from "@stacksjs/config";
158
160
  import {hasComponents, hasFunctions} from "@stacksjs/storage";
159
- if (hasComponents()) {
161
+ if (library2.releaseable && hasComponents()) {
160
162
  await generateLibEntry("vue-components");
161
163
  await generateLibEntry("web-components");
162
164
  } else {
163
165
  log2.info("No components found. Skipping building component entry points.");
164
166
  }
165
- if (hasFunctions())
167
+ if (library2.releaseable && hasFunctions())
166
168
  await generateLibEntry("functions");
167
169
  else
168
170
  log2.info("No functions found. Skipping building function entry point.");
@@ -15,6 +15,7 @@ var library_default = {
15
15
  author: "Chris Breuer",
16
16
  contributors: ["Chris Breuer <chris@stacksjs.org>"],
17
17
  defaultLanguage: "en",
18
+ releaseable: true,
18
19
  vueComponents: {
19
20
  name: "hello-world-vue",
20
21
  description: "Your Vue component library description",
@@ -17,6 +17,7 @@ var library_default = {
17
17
  author: "Chris Breuer",
18
18
  contributors: ["Chris Breuer <chris@stacksjs.org>"],
19
19
  defaultLanguage: "en",
20
+ releaseable: true,
20
21
  vueComponents: {
21
22
  name: "hello-world-vue",
22
23
  description: "Your Vue component library description",
@@ -13,6 +13,7 @@ var library_default = {
13
13
  author: "Chris Breuer",
14
14
  contributors: ["Chris Breuer <chris@stacksjs.org>"],
15
15
  defaultLanguage: "en",
16
+ releaseable: true,
16
17
  vueComponents: {
17
18
  name: "hello-world-vue",
18
19
  description: "Your Vue component library description",
@@ -13,6 +13,7 @@ var library_default = {
13
13
  author: "Chris Breuer",
14
14
  contributors: ["Chris Breuer <chris@stacksjs.org>"],
15
15
  defaultLanguage: "en",
16
+ releaseable: true,
16
17
  vueComponents: {
17
18
  name: "hello-world-vue",
18
19
  description: "Your Vue component library description",
@@ -6,7 +6,7 @@ import {log} from "@stacksjs/logging";
6
6
  import {projectPath} from "@stacksjs/path";
7
7
  import * as storage from "@stacksjs/storage";
8
8
  // package.json
9
- var version = "0.58.48";
9
+ var version = "0.58.49";
10
10
 
11
11
  // src/upgrade.ts
12
12
  function checkForUncommittedChanges(options2) {
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@stacksjs/actions",
3
3
  "type": "module",
4
- "version": "0.58.48",
4
+ "version": "0.58.49",
5
5
  "description": "The Stacks actions.",
6
6
  "author": "Chris Breuer",
7
7
  "license": "MIT",
@@ -41,7 +41,8 @@
41
41
  ],
42
42
  "files": [
43
43
  "README.md",
44
- "dist"
44
+ "dist",
45
+ "src"
45
46
  ],
46
47
  "scripts": {
47
48
  "build": "bun --bun build.ts",
package/src/action.ts ADDED
@@ -0,0 +1,11 @@
1
+ export class Action {
2
+ name: string
3
+ description: string
4
+ handle: () => Promise<string>
5
+
6
+ constructor({ name, description, handle }: { name: string, description: string, handle: () => Promise<string> }) {
7
+ this.name = name
8
+ this.description = description
9
+ this.handle = handle
10
+ }
11
+ }
package/src/actions.ts ADDED
@@ -0,0 +1,2 @@
1
+ export * from './helpers'
2
+ export * as actions from './helpers'
package/src/add.ts ADDED
@@ -0,0 +1,27 @@
1
+ import { installPackage } from '@stacksjs/cli'
2
+ import type { AddOptions } from '@stacksjs/types'
3
+
4
+ export async function invoke(options: AddOptions) {
5
+ if (options?.table)
6
+ await addTable()
7
+
8
+ if (options?.calendar)
9
+ await addCalendar()
10
+ }
11
+
12
+ export async function add(options: AddOptions) {
13
+ return invoke(options)
14
+ }
15
+
16
+ export async function addTable() {
17
+ await installPackage('@stacksjs/table')
18
+ }
19
+
20
+ export async function addCalendar() {
21
+ await installPackage('@stacksjs/calendar')
22
+ }
23
+
24
+ export async function installPackages(names: string[]) {
25
+ for (const name of names)
26
+ await installPackage(name)
27
+ }
@@ -0,0 +1,74 @@
1
+ import process from 'node:process'
2
+ import * as AWS4 from 'aws4'
3
+
4
+ // todo: Remove axios and use the AWS SDK instead if possible, but I couldn't get it to work. At least, move to our own fetch wrapper
5
+ import axios from 'axios'
6
+ import { config } from 'aws-sdk'
7
+ import { log } from '@stacksjs/cli'
8
+ import { ai } from '@stacksjs/config'
9
+
10
+ // Specify the AWS profile
11
+ // process.env.AWS_PROFILE = 'your-profile-name' -> no need to define this because of our .env file
12
+ process.env.AWS_REGION = 'us-east-1'
13
+
14
+ config.getCredentials((err) => {
15
+ if (err) {
16
+ log.info(err.stack)
17
+ }
18
+ else if (config.credentials) {
19
+ const { accessKeyId, secretAccessKey, sessionToken } = config.credentials
20
+ log.info('AWS credentials are set', accessKeyId, secretAccessKey, sessionToken)
21
+
22
+ const endpoint = 'https://bedrock.us-east-1.amazonaws.com/foundation-model-entitlement'
23
+ const region = 'us-east-1'
24
+ const service = 'bedrock'
25
+
26
+ const models = ai.models
27
+
28
+ if (!models) {
29
+ log.error('No AI models found. Please set ./config/ai.ts values.')
30
+ return
31
+ }
32
+
33
+ for (const model of models) {
34
+ log.info(`Requesting access to model ${model}`)
35
+ const request = {
36
+ host: 'bedrock.us-east-1.amazonaws.com',
37
+ method: 'POST',
38
+ url: endpoint,
39
+ path: '/foundation-model-entitlement',
40
+ headers: {
41
+ 'Content-Type': 'application/json',
42
+ 'authority': 'http://bedrock.us-east-1.amazonaws.com',
43
+ },
44
+ body: JSON.stringify({ modelId: model }), // use the current model in the loop
45
+ service,
46
+ region,
47
+ }
48
+
49
+ // Sign the request
50
+ const signedRequest = AWS4.sign(request, { accessKeyId, secretAccessKey, sessionToken })
51
+
52
+ // Convert headers to the correct type
53
+ const axiosHeaders = Object.fromEntries(
54
+ Object.entries(signedRequest.headers || {}).map(([key, value]) => [key, String(value)]),
55
+ )
56
+
57
+ const url = `https://${signedRequest.host}${signedRequest.path}`
58
+
59
+ // Send the request
60
+ axios({
61
+ method: signedRequest.method,
62
+ url,
63
+ headers: axiosHeaders,
64
+ data: signedRequest.body,
65
+ })
66
+ .then((response) => {
67
+ log.info(response.data)
68
+ })
69
+ .catch((error) => {
70
+ log.error(error.data)
71
+ })
72
+ }
73
+ }
74
+ })
@@ -0,0 +1,7 @@
1
+ import { log } from '@stacksjs/cli'
2
+ import { buddyPath } from '@stacksjs/path'
3
+ import { $ } from 'bun'
4
+
5
+ log.info('Building CLI')
6
+
7
+ await $`bun ${buddyPath('compile.ts')}`
@@ -0,0 +1,5 @@
1
+ import { frameworkPath } from '@stacksjs/path'
2
+ import { runCommand } from '@stacksjs/cli'
3
+ import { NpmScript } from '@stacksjs/enums'
4
+
5
+ await runCommand(NpmScript.BuildComponents, { cwd: frameworkPath(), verbose: true })
@@ -0,0 +1,34 @@
1
+ import process from 'node:process'
2
+ import { glob } from '@stacksjs/storage'
3
+ import { dim, italic, log } from '@stacksjs/cli'
4
+ import { corePath } from '@stacksjs/path'
5
+ import { ExitCode } from '@stacksjs/types'
6
+ import { $ } from 'bun'
7
+
8
+ log.info('Building core packages')
9
+
10
+ const dirs = (await glob([corePath('*')], { onlyDirectories: true })).sort()
11
+
12
+ if (dirs.length === 0) {
13
+ log.info('No core packages found')
14
+ process.exit(ExitCode.FatalError)
15
+ }
16
+
17
+ for (const folder of dirs) {
18
+ log.info(`🏗️ Building ${italic(dim(folder))}`)
19
+
20
+ $.cwd(folder)
21
+ await $`bun run build`
22
+ log.success(`${italic(dim(folder))} built`)
23
+
24
+ // eslint-disable-next-line no-console
25
+ console.log(``)
26
+ }
27
+
28
+ // dirs.forEach(async (folder) => {
29
+ // log.info(`🏗️ Building ${italic(dim(folder))}`)
30
+
31
+ // $.cwd(folder)
32
+ // const text = await $`bun run build`.text()
33
+ // console.log(text)
34
+ // })
@@ -0,0 +1,7 @@
1
+ import { runCommand } from '@stacksjs/cli'
2
+ import { corePath } from '@stacksjs/path'
3
+
4
+ await runCommand('bun run build:app', {
5
+ // ...options,
6
+ cwd: corePath('desktop'),
7
+ })
@@ -0,0 +1,7 @@
1
+ import { runCommand } from '@stacksjs/cli'
2
+ import { frameworkPath } from '@stacksjs/path'
3
+
4
+ await runCommand('bun run build', {
5
+ // ...options,
6
+ cwd: frameworkPath('docs'),
7
+ })
@@ -0,0 +1,7 @@
1
+ import { frameworkPath } from '@stacksjs/path'
2
+ import { runCommands } from '@stacksjs/cli'
3
+
4
+ await runCommands([
5
+ 'bun build:cli', // command to build the Buddy CLI
6
+ 'bun build:core', // command to build the Stacks Core
7
+ ], { verbose: true, cwd: frameworkPath() })
package/src/build.ts ADDED
@@ -0,0 +1,89 @@
1
+ import { log } from '@stacksjs/logging'
2
+ import { hasComponents, hasFunctions } from '@stacksjs/storage'
3
+ import { runNpmScript } from '@stacksjs/utils'
4
+ import type { BuildOptions } from '@stacksjs/types'
5
+ import { NpmScript } from '@stacksjs/enums'
6
+ import { generateTypes } from './generate'
7
+
8
+ export async function invoke(options: BuildOptions) {
9
+ if (options.components)
10
+ await componentLibraries(options)
11
+
12
+ else if (options.vueComponents)
13
+ await vueComponentLibrary(options)
14
+
15
+ else if (options.webComponents || options.elements)
16
+ await webComponentLibrary(options)
17
+
18
+ else if (options.functions)
19
+ await functionsLibrary(options)
20
+
21
+ else if (options.docs)
22
+ await docs(options)
23
+
24
+ else if (options.stacks)
25
+ await stacks(options)
26
+
27
+ await generateTypes()
28
+ }
29
+
30
+ export async function build(options: BuildOptions) {
31
+ return invoke(options)
32
+ }
33
+
34
+ export async function componentLibraries(options: BuildOptions) {
35
+ await runNpmScript(NpmScript.GenerateEntries, options)
36
+ await vueComponentLibrary(options)
37
+ await webComponentLibrary(options)
38
+ }
39
+
40
+ export async function vueComponentLibrary(options: BuildOptions) {
41
+ if (hasComponents()) {
42
+ log.info('Building your component library...')
43
+ await runNpmScript(NpmScript.BuildComponents, options)
44
+ log.success('Your component library was built successfully')
45
+ }
46
+ else {
47
+ // todo: throw custom error here
48
+ log.warn('No components found.')
49
+ log.info('Before you can build components,')
50
+ log.info('you need to have created some in the ./components folder.')
51
+ }
52
+ }
53
+
54
+ export async function webComponentLibrary(options: BuildOptions) {
55
+ log.info('Building your component library for production use & npm/CDN distribution...')
56
+
57
+ if (hasComponents()) {
58
+ await runNpmScript(NpmScript.BuildWebComponents, options)
59
+ log.success('Your Web Component library was built successfully')
60
+ }
61
+ else {
62
+ // todo: throw custom error here
63
+ log.info('No components found.')
64
+ }
65
+ }
66
+
67
+ export async function docs(options: BuildOptions) {
68
+ log.info('Building the documentation site...')
69
+ await runNpmScript(NpmScript.BuildDocs, options)
70
+ log.success('Docs built successfully')
71
+ }
72
+
73
+ export async function stacks(options: BuildOptions) {
74
+ log.info('Building the Stacks Framework...')
75
+ await runNpmScript(NpmScript.BuildStacks, options)
76
+ log.success('Stacks built successfully')
77
+ }
78
+
79
+ export async function functionsLibrary(options: BuildOptions) {
80
+ if (hasFunctions()) {
81
+ log.info('Building your functions library for production usages...')
82
+ log.info('Production usages include: manual npm distribution and/or CDN distribution')
83
+ await runNpmScript(NpmScript.BuildFunctions, options)
84
+ log.success('Functions library built successfully')
85
+ }
86
+ else {
87
+ log.info('No functions found')
88
+ }
89
+ }
package/src/bump.ts ADDED
@@ -0,0 +1,11 @@
1
+ import { runCommand } from '@stacksjs/cli'
2
+ import { path as p } from '@stacksjs/path'
3
+
4
+ await runCommand('buddy changelog --quiet', {
5
+ cwd: p.projectPath(),
6
+ })
7
+
8
+ await runCommand(
9
+ 'bunx bumpp ./package.json ./core/**/package.json ./ide/vscode/package.json --all',
10
+ { cwd: p.frameworkPath(), stdin: 'inherit' },
11
+ )
@@ -0,0 +1,27 @@
1
+ // TODO: port over logic from meemalabs/cloudfront to invalidate cache
2
+ // buddy cloud invalidate-cache --paths /index.html /about.html
3
+
4
+ // import { CloudFrontClient, CreateInvalidationCommand } from '@aws-sdk/client-cloudfront'
5
+
6
+ // const cloudfront = new CloudFrontClient()
7
+
8
+ // const params = {
9
+ // DistributionId: 'YOUR_DISTRIBUTION_ID', /* required */
10
+ // InvalidationBatch: { /* required */
11
+ // CallerReference: `${Date.now()}`, /* required */
12
+ // Paths: { /* required */
13
+ // Quantity: 1, /* required */
14
+ // Items: [
15
+ // '/*',
16
+ // /* more items */
17
+ // ],
18
+ // },
19
+ // },
20
+ // }
21
+
22
+ // const command = new CreateInvalidationCommand(params)
23
+
24
+ // cloudfront.send(command).then(
25
+ // data => console.log(data),
26
+ // err => console.log(err, err.stack),
27
+ // )
@@ -0,0 +1,11 @@
1
+ import { execSync, runCommand } from '@stacksjs/cli'
2
+ import { projectPath } from '@stacksjs/path'
3
+
4
+ const fromRevision = await execSync('git describe --abbrev=0 --tags HEAD^')
5
+ // console.log('fromRevision', fromRevision)
6
+ const toRevision = await execSync('git describe')
7
+ // console.log('toRevision', toRevision)
8
+
9
+ await runCommand(`bunx changelogen --output CHANGELOG.md --from ${fromRevision} --to ${toRevision}`, {
10
+ cwd: projectPath(),
11
+ })
package/src/clean.ts ADDED
@@ -0,0 +1,6 @@
1
+ import { log } from '@stacksjs/logging'
2
+ import { clean } from '@stacksjs/utils'
3
+
4
+ log.info('Running clean command...')
5
+
6
+ await clean()
package/src/commit.ts ADDED
@@ -0,0 +1,14 @@
1
+ import { log } from '@stacksjs/logging'
2
+ import { runNpmScript } from '@stacksjs/utils'
3
+ import type { CleanOptions } from '@stacksjs/types'
4
+ import { NpmScript } from '@stacksjs/enums'
5
+
6
+ export async function invoke(options: CleanOptions) {
7
+ log.info('Committing...')
8
+ await runNpmScript(NpmScript.Commit, options)
9
+ log.success('Committed')
10
+ }
11
+
12
+ export async function commit(options: CleanOptions) {
13
+ return invoke(options)
14
+ }
@@ -0,0 +1,22 @@
1
+ #!/usr/bin/env bun
2
+
3
+ /**
4
+ * This action copies all the generated types.
5
+ */
6
+
7
+ import { frameworkPath } from '@stacksjs/path'
8
+ import { copyFolder } from '@stacksjs/storage'
9
+
10
+ // relative to scripts directory
11
+ const destinations = [
12
+ [frameworkPath('dist/types/components'), frameworkPath('components/vue/dist/types')],
13
+ [frameworkPath('dist/types/components'), frameworkPath('components/web/dist/types')],
14
+ [frameworkPath('dist/types/functions'), frameworkPath('functions/dist/types')],
15
+ ]
16
+
17
+ destinations.forEach(([src, dest]) => {
18
+ // const srcPath = resolve(__filename, '..', src)
19
+ // const destPath = resolve(__filename, '..', dest)
20
+
21
+ copyFolder(src, dest)
22
+ })
@@ -0,0 +1,111 @@
1
+ import User from '../../../../../../app/Models/User'
2
+
3
+ const fields = User.fields // Assuming you have a specific type for fields
4
+
5
+ export interface ModelElement {
6
+ field: string
7
+ default: string | number | boolean | Date | undefined | null
8
+ unique: boolean
9
+ fieldArray: FieldArrayElement[]
10
+ }
11
+
12
+ export interface FieldArrayElement {
13
+ entity: string
14
+ charValue?: string | null
15
+ // Add other properties as needed
16
+ }
17
+ const rules: string[] = []
18
+
19
+ async function extractModelRule() {
20
+ const modelFile = Bun.file('../../../../../app/Models/User.ts') // Assuming Bun is imported properly
21
+
22
+ const code = await modelFile.text()
23
+
24
+ const regex = /rule:.*$/gm
25
+
26
+ let match: RegExpExecArray | null
27
+ match = regex.exec(code)
28
+ while (match !== null) {
29
+ rules.push(match[0])
30
+ match = regex.exec(code)
31
+ }
32
+ }
33
+
34
+ await extractModelRule()
35
+
36
+ const fieldKeys = Object.keys(fields)
37
+
38
+ const input: ModelElement[] = fieldKeys.map((field, index) => {
39
+ const fieldExist = fields[field]
40
+ let defaultValue = null
41
+ let uniqueValue = false
42
+
43
+ if (fieldExist) {
44
+ defaultValue = fieldExist?.default || null
45
+ uniqueValue = fieldExist?.unique || false
46
+ }
47
+
48
+ return {
49
+ field,
50
+ default: defaultValue,
51
+ unique: uniqueValue,
52
+ fieldArray: parseRule(rules[index]),
53
+ }
54
+ })
55
+
56
+ function parseRule(rule: string): FieldArrayElement[] {
57
+ const parts = rule.split('rule: validator.')
58
+
59
+ if (parts.length !== 2)
60
+ return []
61
+
62
+ if (!parts[1])
63
+ parts[1] = ''
64
+
65
+ const extractedString = parts[1].replace(/,/g, '')
66
+
67
+ if (!extractedString)
68
+ return []
69
+
70
+ const extractedParts = extractedString.split('.')
71
+ const regex = /\(([^)]+)\)/
72
+
73
+ return extractedParts.map((input) => {
74
+ const match = regex.exec(input)
75
+ const value = match ? match[1] : null
76
+ const field = input.replace(regex, '').replace(/\(|\)/g, '')
77
+ return { entity: field, charValue: value }
78
+ })
79
+ }
80
+
81
+ const modelEntity: ModelElement[] = input
82
+
83
+ // You can now use the modelEntity array with type safety.
84
+
85
+ const fieldAssociation: { [key: string]: { [key: string]: string } } = {
86
+ mysql: {
87
+ string: 'varchar',
88
+ enum: 'varchar',
89
+ number: 'integer',
90
+ boolean: 'boolean',
91
+ text: 'text',
92
+ },
93
+ sqlite: {
94
+ string: 'text',
95
+ enum: 'text',
96
+ number: 'integer',
97
+ boolean: 'boolean',
98
+ text: 'text',
99
+ },
100
+ }
101
+
102
+ const fieldEntity = [
103
+ 'maxLength',
104
+ ]
105
+
106
+ const excludeFieldEntity = [
107
+ 'minLength',
108
+ 'enum',
109
+ ]
110
+
111
+ export { fieldEntity, fieldAssociation, modelEntity, excludeFieldEntity }
@@ -0,0 +1,72 @@
1
+ import User from '../../../../../../app/Models/User'
2
+ import { fieldAssociation, fieldEntity, modelEntity } from './fields'
3
+
4
+ const file = Bun.file('user-migration.ts')
5
+
6
+ const driver = 'mysql'
7
+
8
+ const writer = file.writer()
9
+
10
+ writer.write('import { Kysely, sql } from \'kysely\'\n')
11
+ writer.write('import { db } from \'@stacksjs/database\'\n')
12
+ writer.write('\n')
13
+ writer.write('export async function up(db: Kysely<any>): Promise<void> {\n')
14
+
15
+ writer.write(' await db.schema\n')
16
+ writer.write(` .createTable('${User.table}')\n`)
17
+
18
+ writer.write(' .addColumn(\'id\', \'integer\', (col) => col.primaryKey())\n')
19
+
20
+ for (let modelIndex = 0; modelIndex < modelEntity.length; modelIndex++) {
21
+ const modelElement = modelEntity[modelIndex]
22
+
23
+ if (!modelElement)
24
+ continue
25
+
26
+ let entity = ''
27
+ let characteristic = ''
28
+
29
+ const isNullablePresent = modelElement.fieldArray.some(item => item.entity === 'nullable')
30
+
31
+ if (modelElement.default)
32
+ characteristic += `.defaultTo('${modelElement.default.toString()}')`
33
+
34
+ if (modelElement.unique)
35
+ characteristic += '.unique()'
36
+
37
+ if (!isNullablePresent)
38
+ characteristic += '.notNull()'
39
+
40
+ for (let fieldIndex = 0; fieldIndex < modelElement.fieldArray.length; fieldIndex++) {
41
+ const fieldArrayElement = modelElement.fieldArray[fieldIndex]
42
+
43
+ if (!fieldArrayElement)
44
+ continue
45
+
46
+ if (!fieldAssociation[driver])
47
+ continue
48
+
49
+ if (fieldAssociation[driver][fieldArrayElement.entity])
50
+ entity += `${fieldAssociation[driver][fieldArrayElement.entity]}`
51
+
52
+ fieldEntity.forEach((entityField) => {
53
+ if (fieldArrayElement.entity === entityField)
54
+ entity += `(${fieldArrayElement.charValue})`
55
+ })
56
+
57
+ const isMaxLengthPresent = modelElement.fieldArray.some(item => item.entity === 'maxLength')
58
+
59
+ if (fieldAssociation[driver][fieldArrayElement.entity] === 'varchar' && !isMaxLengthPresent)
60
+ entity += '(255)'
61
+ }
62
+
63
+ writer.write(` .addColumn('${modelElement.field}', '${entity}', (col) => col${characteristic})\n`)
64
+ }
65
+
66
+ writer.write(' .addColumn(\'created_at\', \'timestamp\', (col) => col.defaultTo(sql`now()`).notNull())\n')
67
+ writer.write(' .execute()\n')
68
+ writer.write('}\n\n')
69
+
70
+ writer.write('process.exit(0)\n')
71
+
72
+ await writer.end()