@vertz/create-vertz-app 0.2.18 → 0.2.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.
@@ -1 +1 @@
1
- {"version":3,"file":"scaffold.d.ts","sourceRoot":"","sources":["../src/scaffold.ts"],"names":[],"mappings":"AAyBA,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,YAAY,CAAC;AAElD;;GAEG;AACH,qBAAa,oBAAqB,SAAQ,KAAK;gBACjC,WAAW,EAAE,MAAM;CAIhC;AAED;;;;GAIG;AACH,wBAAsB,QAAQ,CAAC,SAAS,EAAE,MAAM,EAAE,OAAO,EAAE,eAAe,GAAG,OAAO,CAAC,IAAI,CAAC,CA6DzF"}
1
+ {"version":3,"file":"scaffold.d.ts","sourceRoot":"","sources":["../src/scaffold.ts"],"names":[],"mappings":"AA0BA,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,YAAY,CAAC;AAElD;;GAEG;AACH,qBAAa,oBAAqB,SAAQ,KAAK;gBACjC,WAAW,EAAE,MAAM;CAIhC;AAED;;;;GAIG;AACH,wBAAsB,QAAQ,CAAC,SAAS,EAAE,MAAM,EAAE,OAAO,EAAE,eAAe,GAAG,OAAO,CAAC,IAAI,CAAC,CAkEzF"}
package/dist/scaffold.js CHANGED
@@ -1,6 +1,6 @@
1
1
  import { promises as fs } from 'node:fs';
2
2
  import path from 'node:path';
3
- import { apiDevelopmentRuleTemplate, appComponentTemplate, bunfigTemplate, bunPluginShimTemplate, claudeMdTemplate, clientTemplate, dbTemplate, entryClientTemplate, envExampleTemplate, envModuleTemplate, envTemplate, gitignoreTemplate, homePageTemplate, packageJsonTemplate, schemaTemplate, serverTemplate, tasksEntityTemplate, themeTemplate, tsconfigTemplate, uiDevelopmentRuleTemplate, vertzConfigTemplate, } from './templates/index.js';
3
+ import { apiDevelopmentRuleTemplate, appComponentTemplate, bunfigTemplate, bunPluginShimTemplate, claudeMdTemplate, clientTemplate, dbTemplate, entryClientTemplate, envExampleTemplate, envModuleTemplate, envTemplate, faviconTemplate, gitignoreTemplate, homePageTemplate, packageJsonTemplate, schemaTemplate, serverTemplate, tasksEntityTemplate, themeTemplate, tsconfigTemplate, uiDevelopmentRuleTemplate, vertzConfigTemplate, } from './templates/index.js';
4
4
  /**
5
5
  * Error thrown when the project directory already exists
6
6
  */
@@ -36,11 +36,13 @@ export async function scaffold(parentDir, options) {
36
36
  const pagesDir = path.join(srcDir, 'pages');
37
37
  const stylesDir = path.join(srcDir, 'styles');
38
38
  const claudeRulesDir = path.join(projectDir, '.claude', 'rules');
39
+ const publicDir = path.join(projectDir, 'public');
39
40
  await Promise.all([
40
41
  fs.mkdir(entitiesDir, { recursive: true }),
41
42
  fs.mkdir(pagesDir, { recursive: true }),
42
43
  fs.mkdir(stylesDir, { recursive: true }),
43
44
  fs.mkdir(claudeRulesDir, { recursive: true }),
45
+ fs.mkdir(publicDir, { recursive: true }),
44
46
  ]);
45
47
  // Write all files in parallel
46
48
  await Promise.all([
@@ -65,6 +67,8 @@ export async function scaffold(parentDir, options) {
65
67
  writeFile(srcDir, 'entry-client.ts', entryClientTemplate()),
66
68
  writeFile(pagesDir, 'home.tsx', homePageTemplate()),
67
69
  writeFile(stylesDir, 'theme.ts', themeTemplate()),
70
+ // Static assets
71
+ writeFile(publicDir, 'favicon.svg', faviconTemplate()),
68
72
  // LLM rules
69
73
  writeFile(projectDir, 'CLAUDE.md', claudeMdTemplate(projectName)),
70
74
  writeFile(claudeRulesDir, 'api-development.md', apiDevelopmentRuleTemplate()),
@@ -10,6 +10,10 @@ export declare function apiDevelopmentRuleTemplate(): string;
10
10
  * .claude/rules/ui-development.md — UI conventions for LLMs
11
11
  */
12
12
  export declare function uiDevelopmentRuleTemplate(): string;
13
+ /**
14
+ * public/favicon.svg — Vertz logo on dark background
15
+ */
16
+ export declare function faviconTemplate(): string;
13
17
  /**
14
18
  * Package.json template — full-stack deps + #generated imports map
15
19
  */
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/templates/index.ts"],"names":[],"mappings":"AAEA;;GAEG;AACH,wBAAgB,gBAAgB,CAAC,WAAW,EAAE,MAAM,GAAG,MAAM,CA6B5D;AAED;;GAEG;AACH,wBAAgB,0BAA0B,IAAI,MAAM,CAyJnD;AAED;;GAEG;AACH,wBAAgB,yBAAyB,IAAI,MAAM,CA0NlD;AAID;;GAEG;AACH,wBAAgB,mBAAmB,CAAC,WAAW,EAAE,MAAM,GAAG,MAAM,CA6B/D;AAED;;GAEG;AACH,wBAAgB,gBAAgB,IAAI,MAAM,CAoBzC;AAED;;GAEG;AACH,wBAAgB,mBAAmB,IAAI,MAAM,CAa5C;AAED;;GAEG;AACH,wBAAgB,WAAW,IAAI,MAAM,CAIpC;AAED;;GAEG;AACH,wBAAgB,kBAAkB,IAAI,MAAM,CAI3C;AAED;;GAEG;AACH,wBAAgB,cAAc,IAAI,MAAM,CAIvC;AAED;;GAEG;AACH,wBAAgB,qBAAqB,IAAI,MAAM,CAc9C;AAED;;GAEG;AACH,wBAAgB,iBAAiB,IAAI,MAAM,CA6B1C;AAID;;GAEG;AACH,wBAAgB,iBAAiB,IAAI,MAAM,CAW1C;AAED;;GAEG;AACH,wBAAgB,cAAc,IAAI,MAAM,CAoBvC;AAED;;GAEG;AACH,wBAAgB,cAAc,IAAI,MAAM,CAavC;AAED;;GAEG;AACH,wBAAgB,UAAU,IAAI,MAAM,CASnC;AAED;;GAEG;AACH,wBAAgB,mBAAmB,IAAI,MAAM,CAe5C;AAED;;GAEG;AACH,wBAAgB,cAAc,IAAI,MAAM,CAOvC;AAED;;GAEG;AACH,wBAAgB,oBAAoB,IAAI,MAAM,CAgD7C;AAED;;GAEG;AACH,wBAAgB,mBAAmB,IAAI,MAAM,CAW5C;AAED;;GAEG;AACH,wBAAgB,aAAa,IAAI,MAAM,CAWtC;AAED;;GAEG;AACH,wBAAgB,gBAAgB,IAAI,MAAM,CAkIzC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/templates/index.ts"],"names":[],"mappings":"AAEA;;GAEG;AACH,wBAAgB,gBAAgB,CAAC,WAAW,EAAE,MAAM,GAAG,MAAM,CA6B5D;AAED;;GAEG;AACH,wBAAgB,0BAA0B,IAAI,MAAM,CAyJnD;AAED;;GAEG;AACH,wBAAgB,yBAAyB,IAAI,MAAM,CA0NlD;AAID;;GAEG;AACH,wBAAgB,eAAe,IAAI,MAAM,CAGxC;AAID;;GAEG;AACH,wBAAgB,mBAAmB,CAAC,WAAW,EAAE,MAAM,GAAG,MAAM,CA6B/D;AAED;;GAEG;AACH,wBAAgB,gBAAgB,IAAI,MAAM,CAoBzC;AAED;;GAEG;AACH,wBAAgB,mBAAmB,IAAI,MAAM,CAa5C;AAED;;GAEG;AACH,wBAAgB,WAAW,IAAI,MAAM,CAIpC;AAED;;GAEG;AACH,wBAAgB,kBAAkB,IAAI,MAAM,CAI3C;AAED;;GAEG;AACH,wBAAgB,cAAc,IAAI,MAAM,CAIvC;AAED;;GAEG;AACH,wBAAgB,qBAAqB,IAAI,MAAM,CAc9C;AAED;;GAEG;AACH,wBAAgB,iBAAiB,IAAI,MAAM,CA6B1C;AAID;;GAEG;AACH,wBAAgB,iBAAiB,IAAI,MAAM,CAW1C;AAED;;GAEG;AACH,wBAAgB,cAAc,IAAI,MAAM,CAoBvC;AAED;;GAEG;AACH,wBAAgB,cAAc,IAAI,MAAM,CAavC;AAED;;GAEG;AACH,wBAAgB,UAAU,IAAI,MAAM,CASnC;AAED;;GAEG;AACH,wBAAgB,mBAAmB,IAAI,MAAM,CAe5C;AAED;;GAEG;AACH,wBAAgB,cAAc,IAAI,MAAM,CAOvC;AAED;;GAEG;AACH,wBAAgB,oBAAoB,IAAI,MAAM,CAgD7C;AAED;;GAEG;AACH,wBAAgB,mBAAmB,IAAI,MAAM,CAW5C;AAED;;GAEG;AACH,wBAAgB,aAAa,IAAI,MAAM,CAWtC;AAED;;GAEG;AACH,wBAAgB,gBAAgB,IAAI,MAAM,CA0IzC"}
@@ -411,6 +411,14 @@ export function TaskDetailPage() {
411
411
  \`\`\`
412
412
  `;
413
413
  }
414
+ // ── Static asset templates ─────────────────────────────────
415
+ /**
416
+ * public/favicon.svg — Vertz logo on dark background
417
+ */
418
+ export function faviconTemplate() {
419
+ return `<svg width="32" height="32" viewBox="0 0 298 298" fill="none" xmlns="http://www.w3.org/2000/svg"><rect width="298" height="298" rx="60" fill="#0a0a0b"/><path d="M120.277 77H26L106.5 185.5L151.365 124.67L120.277 77Z" fill="white"/><path d="M147.986 243L125.5 210.5L190.467 124.67L160.731 77H272L147.986 243Z" fill="white"/></svg>
420
+ `;
421
+ }
414
422
  // ── Config file templates ──────────────────────────────────
415
423
  /**
416
424
  * Package.json template — full-stack deps + #generated imports map
@@ -751,6 +759,7 @@ export function homePageTemplate() {
751
759
  ListTransition,
752
760
  css,
753
761
  fadeOut,
762
+ form,
754
763
  globalCss,
755
764
  query,
756
765
  queryMatch,
@@ -772,9 +781,10 @@ void globalCss({
772
781
  const pageStyles = css({
773
782
  container: ['py:2', 'w:full'],
774
783
  heading: ['font:xl', 'font:bold', 'text:foreground', 'mb:4'],
775
- form: ['flex', 'gap:2', 'mb:6'],
784
+ form: ['flex', 'gap:2', 'items:start', 'mb:6'],
785
+ inputWrap: ['flex-1'],
776
786
  input: [
777
- 'flex-1',
787
+ 'w:full',
778
788
  'px:3',
779
789
  'py:2',
780
790
  'rounded:md',
@@ -783,12 +793,13 @@ const pageStyles = css({
783
793
  'bg:background',
784
794
  'text:foreground',
785
795
  ],
796
+ fieldError: ['text:destructive', 'font:xs', 'mt:1'],
786
797
  button: [
787
798
  'px:4',
788
799
  'py:2',
789
800
  'rounded:md',
790
- 'bg:primary.600',
791
- 'text:white',
801
+ 'bg:primary',
802
+ 'text:primary-foreground',
792
803
  'font:medium',
793
804
  'cursor:pointer',
794
805
  ],
@@ -812,31 +823,36 @@ const pageStyles = css({
812
823
  export function HomePage() {
813
824
  const tasksQuery = query(api.tasks.list());
814
825
 
815
- const handleSubmit = async (e: SubmitEvent) => {
816
- e.preventDefault();
817
- const form = e.target as HTMLFormElement;
818
- const data = new FormData(form);
819
- const title = data.get('title') as string;
820
- if (!title.trim()) return;
821
-
822
- await api.tasks.create({ title });
823
- form.reset();
824
- tasksQuery.refetch();
825
- };
826
+ const taskForm = form(api.tasks.create, {
827
+ resetOnSuccess: true,
828
+ });
826
829
 
827
830
  return (
828
831
  <div class={pageStyles.container} data-testid="home-page">
829
832
  <h1 class={pageStyles.heading}>Tasks</h1>
830
833
 
831
- <form class={pageStyles.form} onSubmit={handleSubmit}>
832
- <input
833
- name="title"
834
- class={pageStyles.input}
835
- placeholder="What needs to be done?"
836
- required
837
- />
838
- <button type="submit" class={pageStyles.button}>
839
- Add
834
+ <form
835
+ class={pageStyles.form}
836
+ action={taskForm.action}
837
+ method={taskForm.method}
838
+ onSubmit={taskForm.onSubmit}
839
+ >
840
+ <div class={pageStyles.inputWrap}>
841
+ <input
842
+ name={taskForm.fields.title}
843
+ class={pageStyles.input}
844
+ placeholder="What needs to be done?"
845
+ />
846
+ <span class={pageStyles.fieldError}>
847
+ {taskForm.title.error}
848
+ </span>
849
+ </div>
850
+ <button
851
+ type="submit"
852
+ class={pageStyles.button}
853
+ disabled={taskForm.submitting}
854
+ >
855
+ {taskForm.submitting.value ? 'Adding...' : 'Add'}
840
856
  </button>
841
857
  </form>
842
858
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@vertz/create-vertz-app",
3
- "version": "0.2.18",
3
+ "version": "0.2.20",
4
4
  "type": "module",
5
5
  "license": "MIT",
6
6
  "description": "Create a new Vertz application",