@stacksjs/actions 0.70.87 → 0.70.90

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 (159) hide show
  1. package/dist/action.js +78 -2
  2. package/dist/actions.js +2 -2
  3. package/dist/add.js +20 -2
  4. package/dist/ai/request-model-access.js +10 -2
  5. package/dist/auth/client.js +44 -3
  6. package/dist/auth/prune.js +35 -2
  7. package/dist/auth/setup.js +152 -36
  8. package/dist/auth/token.js +10 -2
  9. package/dist/blog-admin.d.ts +55 -0
  10. package/dist/blog-admin.js +156 -0
  11. package/dist/blog.d.ts +11 -0
  12. package/dist/blog.js +306 -56
  13. package/dist/build/cli.js +6 -2
  14. package/dist/build/component-libs.js +7 -2
  15. package/dist/build/core.js +55 -2
  16. package/dist/build/desktop.js +5 -2
  17. package/dist/build/docs.js +5 -2
  18. package/dist/build/frontend-static.js +123 -8
  19. package/dist/build/server.js +6 -2
  20. package/dist/build/stacks.js +8 -2
  21. package/dist/build/views.js +11 -2
  22. package/dist/build.js +64 -2
  23. package/dist/bump.js +162 -7
  24. package/dist/cdn/invalidate-cache.js +0 -1
  25. package/dist/changelog.js +27 -3
  26. package/dist/check/ports.js +16 -2
  27. package/dist/clean.js +4 -2
  28. package/dist/commit.js +12 -2
  29. package/dist/copy-types.js +10 -3
  30. package/dist/database/seed.js +26 -2
  31. package/dist/deploy/create-receipt-rule.js +36 -2
  32. package/dist/deploy/index.js +1318 -44
  33. package/dist/dev/api.js +94 -6
  34. package/dist/dev/components.js +7 -2
  35. package/dist/dev/dashboard-globals.js +89 -3
  36. package/dist/dev/dashboard-utils.js +380 -2
  37. package/dist/dev/dashboard.js +435 -8
  38. package/dist/dev/desktop.js +5 -2
  39. package/dist/dev/docs.js +24 -2
  40. package/dist/dev/index.js +29 -2
  41. package/dist/dev/migrate-watcher.js +74 -2
  42. package/dist/dev/system-tray.js +5 -2
  43. package/dist/dev/views.js +147 -2
  44. package/dist/discover-packages.js +32 -2
  45. package/dist/domains/add.js +61 -2
  46. package/dist/domains/purchase.js +66 -2
  47. package/dist/domains/remove.js +24 -2
  48. package/dist/examples.js +34 -2
  49. package/dist/find-projects.js +16 -2
  50. package/dist/fresh.js +17 -2
  51. package/dist/generate/action-types.js +9 -4
  52. package/dist/generate/component-meta.js +9 -3
  53. package/dist/generate/custom-cli-file.js +20 -3
  54. package/dist/generate/env-files.js +46 -6
  55. package/dist/generate/ide-helpers.js +8 -3
  56. package/dist/generate/index.js +158 -2
  57. package/dist/generate/lib-entries.js +16 -3
  58. package/dist/generate/pantry-file.js +46 -2
  59. package/dist/generate/symlink-core.js +2 -2
  60. package/dist/generate/types.js +3 -2
  61. package/dist/generate/vscode-custom-data.js +9 -3
  62. package/dist/generate/web-types.js +0 -1
  63. package/dist/helpers/component-meta.js +295 -2
  64. package/dist/helpers/index.js +1 -2
  65. package/dist/helpers/lib-entries.js +73 -2
  66. package/dist/helpers/package-json.js +45 -14
  67. package/dist/helpers/utils.js +105 -2
  68. package/dist/helpers/vscode-custom-data.js +30 -2
  69. package/dist/index.d.ts +13 -0
  70. package/dist/index.js +50 -2
  71. package/dist/key-generate.js +24 -2
  72. package/dist/lint/fix.js +4 -3
  73. package/dist/lint/index.js +4 -3
  74. package/dist/lint/lint.js +34 -2
  75. package/dist/make-command.js +64 -14
  76. package/dist/make-job.js +41 -16
  77. package/dist/make-policy.js +74 -26
  78. package/dist/make-resource.js +50 -21
  79. package/dist/make.js +328 -2
  80. package/dist/migrate/database.js +16 -2
  81. package/dist/migrate/fresh.js +31 -2
  82. package/dist/orm/base.js +0 -2
  83. package/dist/orm/test.js +0 -1
  84. package/dist/prepublish.js +16 -2
  85. package/dist/queue/clear.js +42 -2
  86. package/dist/queue/dlq-purge.js +28 -2
  87. package/dist/queue/dlq-retry.js +35 -2
  88. package/dist/queue/dlq.js +55 -5
  89. package/dist/queue/failed.js +69 -5
  90. package/dist/queue/flush.js +49 -3
  91. package/dist/queue/inspect.js +154 -8
  92. package/dist/queue/list.js +69 -5
  93. package/dist/queue/monitor.js +94 -6
  94. package/dist/queue/pause.js +28 -2
  95. package/dist/queue/quarantine.js +42 -3
  96. package/dist/queue/resume.js +27 -2
  97. package/dist/queue/retry.js +41 -2
  98. package/dist/queue/schedule-list.js +33 -5
  99. package/dist/queue/schedule.js +12 -2
  100. package/dist/queue/status.js +68 -5
  101. package/dist/queue/table.js +10 -2
  102. package/dist/queue/unquarantine.js +27 -2
  103. package/dist/queue/work.js +57 -2
  104. package/dist/release.js +21 -3
  105. package/dist/route/list.js +78 -3
  106. package/dist/run-action.js +1 -2
  107. package/dist/saas/setup.js +9 -2
  108. package/dist/scaffold-crud.js +164 -40
  109. package/dist/schedule/run.js +7 -2
  110. package/dist/search/flush.js +10 -2
  111. package/dist/search/import.js +10 -2
  112. package/dist/search/settings-list.js +10 -2
  113. package/dist/search/settings.js +9 -2
  114. package/dist/serve/api.js +35 -2
  115. package/dist/setup/index.js +1 -2
  116. package/dist/setup/ssl.js +271 -2
  117. package/dist/stacks.js +265 -2
  118. package/dist/templates.js +301 -2
  119. package/dist/test/feature.js +11 -2
  120. package/dist/test/index.js +11 -2
  121. package/dist/test/ui.js +4 -2
  122. package/dist/test/unit.js +11 -2
  123. package/dist/typecheck.js +4 -2
  124. package/dist/types.js +16 -2
  125. package/dist/upgrade/binary.js +29 -2
  126. package/dist/upgrade/bun.js +0 -1
  127. package/dist/upgrade/dependencies.js +0 -2
  128. package/dist/upgrade/framework-utils.js +193 -2
  129. package/dist/upgrade/framework.js +310 -7
  130. package/dist/upgrade/index.js +17 -2
  131. package/dist/upgrade/packages.js +99 -12
  132. package/dist/upgrade/shell.js +40 -4
  133. package/dist/upgrade.js +38 -2
  134. package/package.json +16 -16
  135. package/dist/chunk-0c8sd1t6.js +0 -2
  136. package/dist/chunk-0g2nzhx9.js +0 -240
  137. package/dist/chunk-0gadhvn7.js +0 -3
  138. package/dist/chunk-0h27aa4r.js +0 -93
  139. package/dist/chunk-3peh8kqs.js +0 -851
  140. package/dist/chunk-62gdfav8.js +0 -3
  141. package/dist/chunk-6bk53y02.js +0 -3
  142. package/dist/chunk-78c5n3s2.js +0 -3
  143. package/dist/chunk-c74qv38e.js +0 -17
  144. package/dist/chunk-cdk2r2jd.js +0 -1
  145. package/dist/chunk-dbz9dp2h.js +0 -3
  146. package/dist/chunk-e142dheq.js +0 -3
  147. package/dist/chunk-ec4gky40.js +0 -3
  148. package/dist/chunk-h3d81wrg.js +0 -3
  149. package/dist/chunk-m3q0x4h0.js +0 -688
  150. package/dist/chunk-mqgbyhph.js +0 -5
  151. package/dist/chunk-n24m8prb.js +0 -3
  152. package/dist/chunk-n5eqwhck.js +0 -7
  153. package/dist/chunk-nsvnqv8y.js +0 -5
  154. package/dist/chunk-nty6mmx4.js +0 -283
  155. package/dist/chunk-s735m9mg.js +0 -1
  156. package/dist/chunk-tpb8jgsk.js +0 -7
  157. package/dist/chunk-tsbk5vne.js +0 -3
  158. package/dist/chunk-xg9xscqz.js +0 -1
  159. package/dist/chunk-y6e448he.js +0 -7
@@ -1,3 +1,78 @@
1
- // @bun
2
- import m from"process";import{italic as l,log as c}from"@stacksjs/cli";import{route as g}from"@stacksjs/router";var f=["GET","HEAD","POST","PUT","PATCH","DELETE","OPTIONS"];function p(r){if(typeof r==="string")return r;if(typeof r==="function")return r.name?`[fn ${r.name}]`:"[fn]";return"[handler]"}function o(r,t){if(r.length>=t)return r;return r+" ".repeat(t-r.length)}function i(r){m.stdout.write(`${r}
3
- `)}async function w(){try{await g.importRoutes()}catch(e){return{isErr:!0,error:e}}let r=g.routes??[];if(r.length===0)return i(l("No routes registered.")),{};let t=r.map((e)=>({method:String(e.method||"GET").toUpperCase(),uri:String(e.path||e.uri||""),handler:p(e.handler??e.action??""),name:String(e.name||""),middleware:Array.isArray(e.middleware)?e.middleware.join(","):String(e.middleware||"")}));t.sort((e,h)=>{let s=f.indexOf(e.method),a=f.indexOf(h.method);if(s!==a)return(s===-1?99:s)-(a===-1?99:a);return e.uri.localeCompare(h.uri)});let n={method:Math.max(6,...t.map((e)=>e.method.length)),uri:Math.max(3,...t.map((e)=>e.uri.length)),handler:Math.max(7,...t.map((e)=>e.handler.length)),name:Math.max(4,...t.map((e)=>e.name.length))},d=[o("METHOD",n.method),o("URI",n.uri),o("HANDLER",n.handler),o("NAME",n.name),"MIDDLEWARE"].join(" ");i(""),i(d),i("-".repeat(d.length));for(let e of t)i([o(e.method,n.method),o(e.uri,n.uri),o(e.handler,n.handler),o(e.name||"-",n.name),e.middleware||"-"].join(" "));return i(""),i(l(`${t.length} route${t.length===1?"":"s"} registered.`)),{}}var u=await w();if(u?.isErr)console.error(u.error),c.error("Route lists failed",u.error),m.exit(1);m.exit(0);
1
+ import process from "node:process";
2
+ import { italic, log } from "@stacksjs/cli";
3
+ import { route } from "@stacksjs/router";
4
+ const METHOD_ORDER = ["GET", "HEAD", "POST", "PUT", "PATCH", "DELETE", "OPTIONS"];
5
+ function formatHandler(handler) {
6
+ if (typeof handler === "string")
7
+ return handler;
8
+ if (typeof handler === "function")
9
+ return handler.name ? `[fn ${handler.name}]` : "[fn]";
10
+ return "[handler]";
11
+ }
12
+ function pad(value, width) {
13
+ if (value.length >= width)
14
+ return value;
15
+ return value + " ".repeat(width - value.length);
16
+ }
17
+ function write(line) {
18
+ process.stdout.write(`${line}
19
+ `);
20
+ }
21
+ async function listRoutes() {
22
+ try {
23
+ await route.importRoutes();
24
+ } catch (error) {
25
+ return { isErr: !0, error };
26
+ }
27
+ const registered = route.routes ?? [];
28
+ if (registered.length === 0) {
29
+ write(italic("No routes registered."));
30
+ return {};
31
+ }
32
+ const rows = registered.map((r) => ({
33
+ method: String(r.method || "GET").toUpperCase(),
34
+ uri: String(r.path || r.uri || ""),
35
+ handler: formatHandler(r.handler ?? r.action ?? ""),
36
+ name: String(r.name || ""),
37
+ middleware: Array.isArray(r.middleware) ? r.middleware.join(",") : String(r.middleware || "")
38
+ }));
39
+ rows.sort((a, b) => {
40
+ const ai = METHOD_ORDER.indexOf(a.method), bi = METHOD_ORDER.indexOf(b.method);
41
+ if (ai !== bi)
42
+ return (ai === -1 ? 99 : ai) - (bi === -1 ? 99 : bi);
43
+ return a.uri.localeCompare(b.uri);
44
+ });
45
+ const widths = {
46
+ method: Math.max(6, ...rows.map((r) => r.method.length)),
47
+ uri: Math.max(3, ...rows.map((r) => r.uri.length)),
48
+ handler: Math.max(7, ...rows.map((r) => r.handler.length)),
49
+ name: Math.max(4, ...rows.map((r) => r.name.length))
50
+ }, header = [
51
+ pad("METHOD", widths.method),
52
+ pad("URI", widths.uri),
53
+ pad("HANDLER", widths.handler),
54
+ pad("NAME", widths.name),
55
+ "MIDDLEWARE"
56
+ ].join(" ");
57
+ write("");
58
+ write(header);
59
+ write("-".repeat(header.length));
60
+ for (const r of rows)
61
+ write([
62
+ pad(r.method, widths.method),
63
+ pad(r.uri, widths.uri),
64
+ pad(r.handler, widths.handler),
65
+ pad(r.name || "-", widths.name),
66
+ r.middleware || "-"
67
+ ].join(" "));
68
+ write("");
69
+ write(italic(`${rows.length} route${rows.length === 1 ? "" : "s"} registered.`));
70
+ return {};
71
+ }
72
+ const result = await listRoutes();
73
+ if (result?.isErr) {
74
+ console.error(result.error);
75
+ log.error("Route lists failed", result.error);
76
+ process.exit(1);
77
+ }
78
+ process.exit(0);
@@ -1,2 +1 @@
1
- // @bun
2
- import"./chunk-h3d81wrg.js";export{i as runAction};
1
+ export { runAction } from "./helpers/utils";
@@ -1,2 +1,9 @@
1
- // @bun
2
- import o from"process";import{log as e}from"@stacksjs/logging";import{createStripeProduct as t}from"@stacksjs/payments";var r=await t();if(r?.isErr)console.error(r.error),e.error("generateMigrations failed",r.error),o.exit(1);
1
+ import process from "node:process";
2
+ import { log } from "@stacksjs/logging";
3
+ import { createStripeProduct } from "@stacksjs/payments";
4
+ const result = await createStripeProduct();
5
+ if (result?.isErr) {
6
+ console.error(result.error);
7
+ log.error("generateMigrations failed", result.error);
8
+ process.exit(1);
9
+ }
@@ -1,87 +1,211 @@
1
- // @bun
2
- import{r as x}from"./chunk-c74qv38e.js";import"./chunk-nty6mmx4.js";import"./chunk-s735m9mg.js";import"./chunk-0gadhvn7.js";import"./chunk-h3d81wrg.js";import{italic as I}from"@stacksjs/cli";import{log as W}from"@stacksjs/logging";import{path as Z}from"@stacksjs/path";import{writeTextFile as L}from"@stacksjs/storage";var P={str:"string",string:"string",varchar:"string",text:"text",longtext:"text",int:"number",integer:"number",number:"number",num:"number",bool:"boolean",boolean:"boolean",date:"date",datetime:"date",json:"json"};function U(G){if(!G)return[];let H=G.split(",").map((q)=>q.trim()).filter(Boolean),J=[];for(let q of H){let[K,O="string"]=q.split(":"),Q=K?.trim();if(!Q)continue;let B=P[O.trim().toLowerCase()]??"string";J.push({name:Q,type:B})}return J}function V(G){if(!G)return G;let H=G.toLowerCase();if(H.endsWith("s")||H.endsWith("x")||H.endsWith("z")||H.endsWith("ch")||H.endsWith("sh"))return`${G}es`;if(H.endsWith("y")&&!/[aeiou]y$/.test(H))return`${G.slice(0,-1)}ies`;return`${G}s`}function v(G){return G.replace(/(^|[-_\s])(\w)/g,(H,J,q)=>String(q).toUpperCase())}function X(G){return G.replace(/([a-z0-9])([A-Z])/g,"$1_$2").replace(/[-\s]+/g,"_").toLowerCase()}function Y(G){if(G.length===0)return" title: { type: 'string', fillable: true, validation: { rule: schema.string().required() } },";return G.map((H)=>{let J=H.type,q=J==="number"?"schema.number()":J==="boolean"?"schema.boolean()":J==="date"?"schema.date()":J==="json"?"schema.object({})":"schema.string()",K=J==="number"?"number":J==="boolean"?"boolean":J==="date"?"date":J==="json"?"json":"string";return` ${H.name}: { type: '${K}', fillable: true, validation: { rule: ${q} } },`}).join(`
3
- `)}function _(G){if(G.length===0)return" .addColumn('title', 'varchar(255)', col => col.notNull())";return G.map((H)=>{switch(H.type){case"number":return` .addColumn('${H.name}', 'integer')`;case"boolean":return` .addColumn('${H.name}', 'boolean', col => col.defaultTo(false))`;case"text":return` .addColumn('${H.name}', 'text')`;case"date":return` .addColumn('${H.name}', 'timestamp')`;case"json":return` .addColumn('${H.name}', 'text')`;default:return` .addColumn('${H.name}', 'varchar(255)')`}}).join(`
4
- `)}function D(G,H,J){let q=v(G);switch(H){case"Index":return`import { Action } from '@stacksjs/actions'
5
- import ${q} from '~/app/Models/${q}'
1
+ import { italic } from "@stacksjs/cli";
2
+ import { log } from "@stacksjs/logging";
3
+ import { path as p } from "@stacksjs/path";
4
+ import { writeTextFile } from "@stacksjs/storage";
5
+ import { isDryRunActive } from "./make";
6
+ const TYPE_ALIASES = {
7
+ str: "string",
8
+ string: "string",
9
+ varchar: "string",
10
+ text: "text",
11
+ longtext: "text",
12
+ int: "number",
13
+ integer: "number",
14
+ number: "number",
15
+ num: "number",
16
+ bool: "boolean",
17
+ boolean: "boolean",
18
+ date: "date",
19
+ datetime: "date",
20
+ json: "json"
21
+ };
22
+ export function parseFields(input) {
23
+ if (!input)
24
+ return [];
25
+ const parts = input.split(",").map((p) => p.trim()).filter(Boolean), out = [];
26
+ for (const part of parts) {
27
+ const [rawName, rawType = "string"] = part.split(":"), name = rawName?.trim();
28
+ if (!name)
29
+ continue;
30
+ const type = TYPE_ALIASES[rawType.trim().toLowerCase()] ?? "string";
31
+ out.push({ name, type });
32
+ }
33
+ return out;
34
+ }
35
+ function pluralize(word) {
36
+ if (!word)
37
+ return word;
38
+ const lower = word.toLowerCase();
39
+ if (lower.endsWith("s") || lower.endsWith("x") || lower.endsWith("z") || lower.endsWith("ch") || lower.endsWith("sh"))
40
+ return `${word}es`;
41
+ if (lower.endsWith("y") && !/[aeiou]y$/.test(lower))
42
+ return `${word.slice(0, -1)}ies`;
43
+ return `${word}s`;
44
+ }
45
+ function pascalCase(name) {
46
+ return name.replace(/(^|[-_\s])(\w)/g, (_, __, c) => String(c).toUpperCase());
47
+ }
48
+ function snakeCase(name) {
49
+ return name.replace(/([a-z0-9])([A-Z])/g, "$1_$2").replace(/[-\s]+/g, "_").toLowerCase();
50
+ }
51
+ function attributeBlock(fields) {
52
+ if (fields.length === 0)
53
+ return " title: { type: 'string', fillable: true, validation: { rule: schema.string().required() } },";
54
+ return fields.map((f) => {
55
+ const t = f.type, rule = t === "number" ? "schema.number()" : t === "boolean" ? "schema.boolean()" : t === "date" ? "schema.date()" : t === "json" ? "schema.object({})" : "schema.string()", dbType = t === "number" ? "number" : t === "boolean" ? "boolean" : t === "date" ? "date" : t === "json" ? "json" : "string";
56
+ return ` ${f.name}: { type: '${dbType}', fillable: true, validation: { rule: ${rule} } },`;
57
+ }).join(`
58
+ `);
59
+ }
60
+ function migrationColumns(fields) {
61
+ if (fields.length === 0)
62
+ return " .addColumn('title', 'varchar(255)', col => col.notNull())";
63
+ return fields.map((f) => {
64
+ switch (f.type) {
65
+ case "number":
66
+ return ` .addColumn('${f.name}', 'integer')`;
67
+ case "boolean":
68
+ return ` .addColumn('${f.name}', 'boolean', col => col.defaultTo(false))`;
69
+ case "text":
70
+ return ` .addColumn('${f.name}', 'text')`;
71
+ case "date":
72
+ return ` .addColumn('${f.name}', 'timestamp')`;
73
+ case "json":
74
+ return ` .addColumn('${f.name}', 'text')`;
75
+ default:
76
+ return ` .addColumn('${f.name}', 'varchar(255)')`;
77
+ }
78
+ }).join(`
79
+ `);
80
+ }
81
+ function actionStub(name, kind, fields) {
82
+ const Model = pascalCase(name);
83
+ switch (kind) {
84
+ case "Index":
85
+ return `import { Action } from '@stacksjs/actions'
86
+ import ${Model} from '~/app/Models/${Model}'
6
87
 
7
88
  export default new Action({
8
- name: '${q}IndexAction',
9
- description: 'List ${V(q)}',
89
+ name: '${Model}IndexAction',
90
+ description: 'List ${pluralize(Model)}',
10
91
 
11
92
  async handle() {
12
- return await ${q}.all()
93
+ return await ${Model}.all()
13
94
  },
14
- })`;case"Show":return`import { Action } from '@stacksjs/actions'
15
- import ${q} from '~/app/Models/${q}'
95
+ })`;
96
+ case "Show":
97
+ return `import { Action } from '@stacksjs/actions'
98
+ import ${Model} from '~/app/Models/${Model}'
16
99
 
17
100
  export default new Action({
18
- name: '${q}ShowAction',
19
- description: 'Show a single ${q}',
101
+ name: '${Model}ShowAction',
102
+ description: 'Show a single ${Model}',
20
103
 
21
104
  async handle(request) {
22
105
  const id = Number(request.get('id'))
23
- return await ${q}.findOrFail(id)
106
+ return await ${Model}.findOrFail(id)
24
107
  },
25
- })`;case"Store":{let K=(J.length>0?J:[{name:"title",type:"string"}]).map((O)=>`'${O.name}'`).join(", ");return`import { Action } from '@stacksjs/actions'
26
- import ${q} from '~/app/Models/${q}'
108
+ })`;
109
+ case "Store": {
110
+ const keys = (fields.length > 0 ? fields : [{ name: "title", type: "string" }]).map((f) => `'${f.name}'`).join(", ");
111
+ return `import { Action } from '@stacksjs/actions'
112
+ import ${Model} from '~/app/Models/${Model}'
27
113
 
28
114
  export default new Action({
29
- name: '${q}StoreAction',
30
- description: 'Create a new ${q}',
115
+ name: '${Model}StoreAction',
116
+ description: 'Create a new ${Model}',
31
117
 
32
118
  async handle(request) {
33
- const data = request.only([${K}])
34
- return await ${q}.create(data)
119
+ const data = request.only([${keys}])
120
+ return await ${Model}.create(data)
35
121
  },
36
- })`}case"Update":{let K=(J.length>0?J:[{name:"title",type:"string"}]).map((O)=>`'${O.name}'`).join(", ");return`import { Action } from '@stacksjs/actions'
37
- import ${q} from '~/app/Models/${q}'
122
+ })`;
123
+ }
124
+ case "Update": {
125
+ const keys = (fields.length > 0 ? fields : [{ name: "title", type: "string" }]).map((f) => `'${f.name}'`).join(", ");
126
+ return `import { Action } from '@stacksjs/actions'
127
+ import ${Model} from '~/app/Models/${Model}'
38
128
 
39
129
  export default new Action({
40
- name: '${q}UpdateAction',
41
- description: 'Update an existing ${q}',
130
+ name: '${Model}UpdateAction',
131
+ description: 'Update an existing ${Model}',
42
132
 
43
133
  async handle(request) {
44
134
  const id = Number(request.get('id'))
45
- const data = request.only([${K}])
46
- return await ${q}.update(id, data)
135
+ const data = request.only([${keys}])
136
+ return await ${Model}.update(id, data)
47
137
  },
48
- })`}case"Destroy":return`import { Action } from '@stacksjs/actions'
49
- import ${q} from '~/app/Models/${q}'
138
+ })`;
139
+ }
140
+ case "Destroy":
141
+ return `import { Action } from '@stacksjs/actions'
142
+ import ${Model} from '~/app/Models/${Model}'
50
143
 
51
144
  export default new Action({
52
- name: '${q}DestroyAction',
53
- description: 'Delete a ${q}',
145
+ name: '${Model}DestroyAction',
146
+ description: 'Delete a ${Model}',
54
147
 
55
148
  async handle(request) {
56
149
  const id = Number(request.get('id'))
57
- const deleted = await ${q}.delete(id)
150
+ const deleted = await ${Model}.delete(id)
58
151
  return { deleted }
59
152
  },
60
- })`}}function E(G,H){return`import { defineModel } from '@stacksjs/orm'
153
+ })`;
154
+ }
155
+ }
156
+ function modelStub(name, fields) {
157
+ return `import { defineModel } from '@stacksjs/orm'
61
158
  import { schema } from '@stacksjs/validation'
62
159
 
63
160
  export default defineModel({
64
- name: '${v(G)}',
65
- table: '${V(X(G))}',
161
+ name: '${pascalCase(name)}',
162
+ table: '${pluralize(snakeCase(name))}',
66
163
  attributes: {
67
- ${Y(H)}
164
+ ${attributeBlock(fields)}
68
165
  },
69
166
  traits: { useTimestamps: true, useUuid: false },
70
167
  } as const)
71
- `}function N(G,H){return`import type { Database } from '@stacksjs/database'
168
+ `;
169
+ }
170
+ function migrationStub(name, fields) {
171
+ return `import type { Database } from '@stacksjs/database'
72
172
  import { sql } from '@stacksjs/database'
73
173
 
74
174
  export async function up(db: Database<any>) {
75
175
  await db.schema
76
- .createTable('${V(X(G))}')
176
+ .createTable('${pluralize(snakeCase(name))}')
77
177
  .addColumn('id', 'serial', col => col.primaryKey())
78
- ${_(H)}
178
+ ${migrationColumns(fields)}
79
179
  .addColumn('created_at', 'timestamp', col => col.notNull().defaultTo(sql.raw('CURRENT_TIMESTAMP')))
80
180
  .addColumn('updated_at', 'timestamp')
81
181
  .execute()
82
182
  }
83
- `}async function $(G,H){if(x()){let J=H.split(`
84
- `);W.info(`[dry-run] would write ${G} (${J.length} lines)`),process.stdout.write(`${J.slice(0,60).map((q)=>` ${q}`).join(`
183
+ `;
184
+ }
185
+ async function writeFile(path, contents) {
186
+ if (isDryRunActive()) {
187
+ const lines = contents.split(`
188
+ `);
189
+ log.info(`[dry-run] would write ${path} (${lines.length} lines)`);
190
+ process.stdout.write(`${lines.slice(0, 60).map((l) => ` ${l}`).join(`
85
191
  `)}
86
192
 
87
- `);return}await L({path:G,data:H})}async function h(G,H){let J=v(G);if(!J)throw Error("scaffold:crud requires a non-empty resource name");let q=U(H.fields);W.info(`Scaffolding CRUD for ${I(J)} (${q.length||"no"} fields)`),await $(Z.userModelsPath(`${J}.ts`),E(J,q));let O=`${Date.now().toString()}-create-${V(X(G))}-table.ts`;await $(Z.userMigrationsPath(O),N(G,q));for(let Q of["Index","Show","Store","Update","Destroy"])await $(Z.userActionsPath(`${J}${Q}Action.ts`),D(G,Q,q));W.success(`CRUD scaffold complete: model + migration + 5 actions for ${J}`),W.info(`Next: register \`route.resource('${V(X(G))}', '${J}')\` in routes/api.ts`)}export{h as scaffoldCrud,U as parseFields};
193
+ `);
194
+ return;
195
+ }
196
+ await writeTextFile({ path, data: contents });
197
+ }
198
+ export async function scaffoldCrud(name, options) {
199
+ const Model = pascalCase(name);
200
+ if (!Model)
201
+ throw Error("scaffold:crud requires a non-empty resource name");
202
+ const fields = parseFields(options.fields);
203
+ log.info(`Scaffolding CRUD for ${italic(Model)} (${fields.length || "no"} fields)`);
204
+ await writeFile(p.userModelsPath(`${Model}.ts`), modelStub(Model, fields));
205
+ const migrationName = `${Date.now().toString()}-create-${pluralize(snakeCase(name))}-table.ts`;
206
+ await writeFile(p.userMigrationsPath(migrationName), migrationStub(name, fields));
207
+ for (const kind of ["Index", "Show", "Store", "Update", "Destroy"])
208
+ await writeFile(p.userActionsPath(`${Model}${kind}Action.ts`), actionStub(name, kind, fields));
209
+ log.success(`CRUD scaffold complete: model + migration + 5 actions for ${Model}`);
210
+ log.info(`Next: register \`route.resource('${pluralize(snakeCase(name))}', '${Model}')\` in routes/api.ts`);
211
+ }
@@ -1,2 +1,7 @@
1
- // @bun
2
- import{log as o}from"@stacksjs/logging";import{runScheduler as e}from"@stacksjs/scheduler";var r=await e();if(r?.isErr)console.error(r.error),o.error("Schedule run failed",r.error);
1
+ import { log } from "@stacksjs/logging";
2
+ import { runScheduler } from "@stacksjs/scheduler";
3
+ const result = await runScheduler();
4
+ if (result?.isErr) {
5
+ console.error(result.error);
6
+ log.error("Schedule run failed", result.error);
7
+ }
@@ -1,2 +1,10 @@
1
- // @bun
2
- import r from"process";import{parseOptions as e}from"@stacksjs/cli";import{log as s}from"@stacksjs/logging";import{flushModelDocuments as i}from"@stacksjs/search-engine";var t=e(),n=t.model,o=await i(n);if(o?.isErr)console.error(o.error),s.error("Flushing search engine failed",o.error);r.exit(0);
1
+ import process from "node:process";
2
+ import { parseOptions } from "@stacksjs/cli";
3
+ import { log } from "@stacksjs/logging";
4
+ import { flushModelDocuments } from "@stacksjs/search-engine";
5
+ const options = parseOptions(), modelOption = options.model, result = await flushModelDocuments(modelOption);
6
+ if (result?.isErr) {
7
+ console.error(result.error);
8
+ log.error("Flushing search engine failed", result.error);
9
+ }
10
+ process.exit(0);
@@ -1,2 +1,10 @@
1
- // @bun
2
- import r from"process";import{parseOptions as t}from"@stacksjs/cli";import{log as e}from"@stacksjs/logging";import{importModelDocuments as i}from"@stacksjs/search-engine";var s=t(),m=s.model,o=await i(m);if(o?.isErr)console.error(o.error),e.error("Import to search engine failed",o.error);r.exit(0);
1
+ import process from "node:process";
2
+ import { parseOptions } from "@stacksjs/cli";
3
+ import { log } from "@stacksjs/logging";
4
+ import { importModelDocuments } from "@stacksjs/search-engine";
5
+ const options = parseOptions(), modelOption = options.model, result = await importModelDocuments(modelOption);
6
+ if (result?.isErr) {
7
+ console.error(result.error);
8
+ log.error("Import to search engine failed", result.error);
9
+ }
10
+ process.exit(0);
@@ -1,2 +1,10 @@
1
- // @bun
2
- import o from"process";import{parseOptions as t}from"@stacksjs/cli";import{log as i}from"@stacksjs/logging";import{listIndexSettings as s}from"@stacksjs/search-engine";var e=t(),n=e.model,r=await s(n);if(r?.isErr)console.error(r.error),i.error("Listing index settings failed",r.error);o.exit(0);
1
+ import process from "node:process";
2
+ import { parseOptions } from "@stacksjs/cli";
3
+ import { log } from "@stacksjs/logging";
4
+ import { listIndexSettings } from "@stacksjs/search-engine";
5
+ const options = parseOptions(), modelOption = options.model, result = await listIndexSettings(modelOption);
6
+ if (result?.isErr) {
7
+ console.error(result.error);
8
+ log.error("Listing index settings failed", result.error);
9
+ }
10
+ process.exit(0);
@@ -1,2 +1,9 @@
1
- // @bun
2
- import o from"process";import{log as e}from"@stacksjs/logging";import{updateIndexSettings as t}from"@stacksjs/search-engine";var r=await t();if(r?.isErr)console.error(r.error),e.error("generateMigrations failed",r.error);o.exit(0);
1
+ import process from "node:process";
2
+ import { log } from "@stacksjs/logging";
3
+ import { updateIndexSettings } from "@stacksjs/search-engine";
4
+ const result = await updateIndexSettings();
5
+ if (result?.isErr) {
6
+ console.error(result.error);
7
+ log.error("generateMigrations failed", result.error);
8
+ }
9
+ process.exit(0);
package/dist/serve/api.js CHANGED
@@ -1,2 +1,35 @@
1
- // @bun
2
- import{existsSync as O}from"fs";import{dirname as Q,join as R}from"path";import b from"process";import{config as T}from"@stacksjs/config";import{log as B}from"@stacksjs/logging";import{frameworkPath as U}from"@stacksjs/path";import{route as C}from"@stacksjs/router";function V(z){let A=U(`defaults/${z}`);if(O(A))return A;try{let N=Bun.resolveSync("@stacksjs/defaults/package.json",b.cwd());return R(Q(N),z)}catch{return A}}var W=b.env.APP_ENV==="production"||b.env.NODE_ENV==="production",E=Number(b.env.PORT)||T.ports?.api||3008,H=b.env.HOST||(W?"0.0.0.0":"127.0.0.1");B.info("[Stacks API] Starting server...");B.info(`[Stacks API] Environment: ${b.env.APP_ENV||"development"}`);var X=await import(V("app/Middleware/Cors.ts")),Y=X.default;C.use(Y.toRouterHandler());await C.importRoutes();var Z=["production","staging","development"].includes((b.env.APP_ENV||"").toLowerCase()),_=await C.serve({port:E,hostname:H,reusePort:Z});b.on("SIGTERM",()=>{let z=Number(b.env.SHUTDOWN_GRACE_MS)||15000;setTimeout(()=>b.exit(0),z).unref(),Promise.resolve(_?.stop()).then(()=>b.exit(0))});B.info(`[Stacks API] Server running at http://${H}:${E}`);
1
+ import { existsSync } from "node:fs";
2
+ import { dirname, join } from "node:path";
3
+ import process from "node:process";
4
+ import { config } from "@stacksjs/config";
5
+ import { log } from "@stacksjs/logging";
6
+ import { frameworkPath } from "@stacksjs/path";
7
+ import { route } from "@stacksjs/router";
8
+ function resolveDefaultsFile(rel) {
9
+ const vendored = frameworkPath(`defaults/${rel}`);
10
+ if (existsSync(vendored))
11
+ return vendored;
12
+ try {
13
+ const pkgJson = Bun.resolveSync("@stacksjs/defaults/package.json", process.cwd());
14
+ return join(dirname(pkgJson), rel);
15
+ } catch {
16
+ return vendored;
17
+ }
18
+ }
19
+ const isProduction = process.env.APP_ENV === "production" || process.env.NODE_ENV === "production", port = Number(process.env.PORT) || config.ports?.api || 3008, hostname = process.env.HOST || (isProduction ? "0.0.0.0" : "127.0.0.1");
20
+ log.info("[Stacks API] Starting server...");
21
+ log.info(`[Stacks API] Environment: ${process.env.APP_ENV || "development"}`);
22
+ const corsMod = await import(resolveDefaultsFile("app/Middleware/Cors.ts")), corsMiddleware = corsMod.default;
23
+ route.use(corsMiddleware.toRouterHandler());
24
+ await route.importRoutes();
25
+ const isDeployed = ["production", "staging", "development"].includes((process.env.APP_ENV || "").toLowerCase()), server = await route.serve({
26
+ port,
27
+ hostname,
28
+ reusePort: isDeployed
29
+ });
30
+ process.on("SIGTERM", () => {
31
+ const graceMs = Number(process.env.SHUTDOWN_GRACE_MS) || 15000;
32
+ setTimeout(() => process.exit(0), graceMs).unref();
33
+ Promise.resolve(server?.stop()).then(() => process.exit(0));
34
+ });
35
+ log.info(`[Stacks API] Server running at http://${hostname}:${port}`);
@@ -1,2 +1 @@
1
- // @bun
2
- import"../chunk-cdk2r2jd.js";import{Fa as a,Ga as b,Ha as c,Ia as d,Ja as e,Ka as f,La as g,Ma as h}from"../chunk-n5eqwhck.js";import"../chunk-h3d81wrg.js";export{e as trustCertificate,c as sslCertificatesExist,g as setupSSL,h as isSSLSetupComplete,a as isDomainInHosts,d as isCertificateTrusted,f as generateCertificates,b as addDomainToHosts};
1
+ export * from "./ssl";