@webjsdev/cli 0.10.33 → 0.10.34

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/lib/create.js CHANGED
@@ -542,9 +542,12 @@ export async function scaffoldApp(name, cwd, opts = {}) {
542
542
  // Environment variables
543
543
  '.env.example',
544
544
  // Project-level gitignore (node_modules, .webjs, .env, OS junk).
545
- // The SQLite dev.db rule is appended programmatically below so it
546
- // only appears for the sqlite dialect.
547
- '.gitignore',
545
+ // Shipped as `gitignore` (no dot) and renamed to `.gitignore` on copy:
546
+ // npm STRIPS a `.gitignore` from a published tarball, so a dotfile name
547
+ // would arrive missing and the app would ship without a `.env` ignore
548
+ // (dogfood #845). The SQLite dev.db rule is appended programmatically
549
+ // below so it only appears for the sqlite dialect.
550
+ 'gitignore',
548
551
  // Git hooks (blocks commits on main)
549
552
  '.hooks/pre-commit',
550
553
  // Claude Code config + hooks
@@ -617,14 +620,17 @@ export async function scaffoldApp(name, cwd, opts = {}) {
617
620
  for (const f of templateFiles) {
618
621
  const src = join(TEMPLATES, f);
619
622
  if (existsSync(src)) {
620
- await mkdir(dirname(join(appDir, f)), { recursive: true });
623
+ // `gitignore` ships without a dot (npm strips a published `.gitignore`)
624
+ // and is written to `.gitignore` in the generated app.
625
+ const dest = f === 'gitignore' ? '.gitignore' : f;
626
+ await mkdir(dirname(join(appDir, dest)), { recursive: true });
621
627
  let content = await readFile(src, 'utf8');
622
628
  content = content.replace(/\{\{APP_NAME\}\}/g, name);
623
629
  if (isBun) {
624
630
  if (PROSE_REWRITE.has(f)) content = bunifyProse(content);
625
631
  else if (FILE_REWRITE[f]) content = FILE_REWRITE[f](content);
626
632
  }
627
- await writeFile(join(appDir, f), content);
633
+ await writeFile(join(appDir, dest), content);
628
634
  }
629
635
  }
630
636
 
@@ -837,7 +843,9 @@ export default defineConfig({
837
843
  const cur = await readFile(gitignore, 'utf8');
838
844
  if (!cur.includes('db/dev.db')) await writeFile(gitignore, cur + gitignoreExtra);
839
845
  } else {
840
- await writeFile(gitignore, 'node_modules\n.webjs\n' + gitignoreExtra);
846
+ // Defense in depth: if the template gitignore is ever absent, still
847
+ // never leave a real `.env` trackable (dogfood #845).
848
+ await writeFile(gitignore, 'node_modules\n.webjs\n.env\n.env.*\n!.env.example\n' + gitignoreExtra);
841
849
  }
842
850
  }
843
851
 
@@ -1093,6 +1101,15 @@ export default function RootLayout({ children }: { children: unknown }) {
1093
1101
  const nonce = cspNonce();
1094
1102
  return html\`
1095
1103
  <script nonce="\${nonce}">
1104
+ // ===== OPTIONAL: light/dark theme apparatus (remove as one unit) =====
1105
+ // This IIFE reads the saved or OS theme and toggles the data-theme
1106
+ // attribute plus the dark class the ui kit reads, so the token VALUES in
1107
+ // the root, dark, and data-theme style blocks below switch. It is what
1108
+ // makes the app theme-aware. Building a SINGLE-theme app of your own?
1109
+ // Delete this IIFE, delete the dark and light style blocks below, and set
1110
+ // your palette once on the root selector. That removes the wiring so it
1111
+ // cannot fight your own colours (it will not override a plain root
1112
+ // palette). The header-measure IIFE that follows is unrelated, keep it.
1096
1113
  (function(){
1097
1114
  try {
1098
1115
  var mq = window.matchMedia('(prefers-color-scheme: light)');
@@ -1112,6 +1129,7 @@ export default function RootLayout({ children }: { children: unknown }) {
1112
1129
  mq.addEventListener('change', apply);
1113
1130
  } catch (_) {}
1114
1131
  })();
1132
+ // ===== end optional theme apparatus =====
1115
1133
  // The header is position:fixed (not sticky): a sticky header flickers on
1116
1134
  // iOS WebKit during a client-router nav. fixed leaves normal flow, so
1117
1135
  // --header-h reserves its height for the content below. Measured here so
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@webjsdev/cli",
3
- "version": "0.10.33",
3
+ "version": "0.10.34",
4
4
  "type": "module",
5
5
  "description": "webjs CLI - dev, start, create, db",
6
6
  "bin": {
@@ -928,7 +928,11 @@ global light-DOM namespace.
928
928
 
929
929
  Every page wraps its output in `<div class="page-<route>">`. Every
930
930
  layout wraps in `<div class="layout-<name>">`. Components scope via
931
- their tag. Styles colocate as `const STYLES = css\`…\`` + `<style>${'$'}{STYLES.text}</style>`.
931
+ their tag. In a PAGE or LAYOUT (which render server-only and never
932
+ hydrate) styles colocate as `const STYLES = css\`…\`` + `<style>${'$'}{STYLES.text}</style>`.
933
+ In a COMPONENT, do NOT interpolate into `<style>` (the client drops the
934
+ raw-text hole on hydrate, so the styles vanish); use `static styles =
935
+ css\`…\`` or Tailwind classes instead.
932
936
 
933
937
  ```ts
934
938
  // app/dashboard/page.ts
@@ -0,0 +1,68 @@
1
+ # deps
2
+ node_modules/
3
+
4
+ # webjs / framework caches.
5
+ # `.webjs/routes.d.ts` (the generated route-types overlay, regenerated per
6
+ # machine by `webjs types` / `webjs dev`) is correctly ignored by `**/.webjs/*`.
7
+ # `.webjs/vendor/` is the EXCEPTION: it holds the committed importmap
8
+ # manifest (.webjs/vendor/importmap.json) and optionally the vendored
9
+ # bundle files (after `webjs vendor pin --download`). Both ship to
10
+ # production via source control so the server doesn't need
11
+ # api.jspm.io reachable at boot. Pattern is `**/.webjs/*` ignored,
12
+ # `.webjs/vendor/` un-ignored, mirroring Rails' config/importmap.rb
13
+ # + vendor/javascript/ being committed.
14
+ #
15
+ # DO NOT "simplify" the three lines below to `.webjs/`. Git's
16
+ # gitignore semantics excludes the parent first; once the parent is
17
+ # excluded, no `!**/.webjs/vendor/` negation can ever re-include children
18
+ # (the failure is silent: `webjs vendor pin` runs, writes files, and
19
+ # git ignores them with no warning). The `gitignore-vendor-not-ignored`
20
+ # lint rule (run via `webjs check`) verifies this with
21
+ # `git check-ignore` and will fail CI if the pattern regresses.
22
+ #
23
+ # The `**/` prefix matches `.webjs/` at ANY depth, not just this app's
24
+ # root. A slash-bearing `.webjs/*` anchors to this file's directory, so
25
+ # an app nested below its repo root (a monorepo package) would leak its
26
+ # generated `.webjs/routes.d.ts` into `git status`. `**/.webjs/*` covers
27
+ # the nested case while the negations still re-include vendor at each
28
+ # depth (a re-included parent dir permits a child negation).
29
+ **/.webjs/*
30
+ !**/.webjs/vendor/
31
+ !**/.webjs/vendor/**
32
+
33
+ # generated Tailwind CSS, built from public/input.css via npm run dev / start
34
+ public/tailwind.css
35
+
36
+ # env (.env.example stays tracked; the real .env never is)
37
+ .env
38
+ .env.*
39
+ !.env.example
40
+
41
+ # logs
42
+ *.log
43
+ npm-debug.log*
44
+
45
+ # OS
46
+ .DS_Store
47
+ Thumbs.db
48
+
49
+ # editors
50
+ # `.vscode/*` ignored, but `.vscode/settings.json` (the webjs-config JSON
51
+ # Schema association, #259) is committed so the editor validates package.json's
52
+ # webjs block out of the box. Same gitignore shape as `.webjs/*` above: a bare
53
+ # `.vscode/` would exclude the directory and no negation could re-include a
54
+ # child, so the settings file would silently never ship.
55
+ .vscode/*
56
+ !.vscode/settings.json
57
+ .idea/
58
+
59
+ # test artifacts
60
+ coverage/
61
+
62
+ # AI assistants: local session state, scheduled-task locks, etc.
63
+ # Repo-shared config (settings.json + hooks scripts) stays tracked so
64
+ # every contributor and agent gets the same PreToolUse rules.
65
+ .claude/*
66
+ !.claude/settings.json
67
+ !.claude/hooks/
68
+ !.claude/hooks/**