@strav/spring 1.0.0-alpha.28 → 1.0.0-alpha.29

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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@strav/spring",
3
- "version": "1.0.0-alpha.28",
3
+ "version": "1.0.0-alpha.29",
4
4
  "description": "Strav project scaffolder — `bunx @strav/spring my-app` writes a working app skeleton (bin/, bootstrap/, config/, routes/, …) per spec/directory-structure.md. Two templates: --api (headless REST) and --web (Vue islands + .strav views). Runtime-independent of the framework — no @strav/* runtime deps.",
5
5
  "type": "module",
6
6
  "main": "./src/index.ts",
package/src/cli.ts CHANGED
@@ -20,7 +20,7 @@ const green = (s: string): string => `\x1b[32m${s}\x1b[0m`
20
20
  const red = (s: string): string => `\x1b[31m${s}\x1b[0m`
21
21
  const cyan = (s: string): string => `\x1b[36m${s}\x1b[0m`
22
22
 
23
- const SPRING_VERSION = '1.0.0-alpha.28'
23
+ const SPRING_VERSION = '1.0.0-alpha.29'
24
24
 
25
25
  function printUsage(): void {
26
26
  process.stdout.write(`
@@ -14,7 +14,7 @@ import { providers } from '../bootstrap/providers.ts'
14
14
 
15
15
  const exitCode = await runCli({
16
16
  argv: process.argv.slice(2),
17
- defaultProviders: providers(),
17
+ defaultProviders: await providers(),
18
18
  app: createApp(),
19
19
  })
20
20
 
@@ -1,26 +1,21 @@
1
1
  import { HttpConsoleProvider, HttpProvider } from '@strav/http'
2
2
  import { ConfigProvider, LoggerProvider, type ServiceProvider } from '@strav/kernel'
3
3
  import { AppProvider } from '../app/providers/app_provider.ts'
4
- import appConfig from '../config/app.ts'
5
- import httpConfig from '../config/http.ts'
6
- import loggerConfig from '../config/logger.ts'
7
4
 
8
5
  /**
9
6
  * Default provider list. Order is not load-bearing — the container does a
10
7
  * dependency-aware topo sort at boot. Keep providers grouped by package
11
8
  * for readability.
12
9
  *
13
- * Adding more packages later (database, auth, queue, …)? Install the
14
- * package, add its config file under `config/`, register its `Config`
15
- * slot in `ConfigProvider` below, and append the provider to this list.
10
+ * `ConfigProvider.fromDirectory('config')` auto-discovers every
11
+ * `config/*.ts` file and keys them by basename `config/app.ts`
12
+ * `config('app.*')`, `config/http.ts` `config('http.*')`, etc. To add
13
+ * a new config slot, drop a file with a `default export` into
14
+ * `config/`. No edits to this list required.
16
15
  */
17
- export function providers(): ServiceProvider[] {
16
+ export async function providers(): Promise<ServiceProvider[]> {
18
17
  return [
19
- new ConfigProvider({
20
- app: appConfig,
21
- http: httpConfig,
22
- logger: loggerConfig,
23
- }),
18
+ await ConfigProvider.fromDirectory('config'),
24
19
  new LoggerProvider(),
25
20
  new HttpProvider(),
26
21
  new HttpConsoleProvider(),
@@ -2,28 +2,25 @@ import { HttpConsoleProvider, HttpProvider } from '@strav/http'
2
2
  import { ConfigProvider, LoggerProvider, type ServiceProvider } from '@strav/kernel'
3
3
  import { ViewConsoleProvider, ViewProvider } from '@strav/view'
4
4
  import { AppProvider } from '../app/providers/app_provider.ts'
5
- import appConfig from '../config/app.ts'
6
- import httpConfig from '../config/http.ts'
7
- import loggerConfig from '../config/logger.ts'
8
- import viewConfig from '../config/view.ts'
9
5
 
10
6
  /**
11
7
  * Default provider list. Order is not load-bearing — the container does a
12
8
  * dependency-aware topo sort at boot. Keep providers grouped by package
13
9
  * for readability.
14
10
  *
11
+ * `ConfigProvider.fromDirectory('config')` auto-discovers every
12
+ * `config/*.ts` file and keys them by basename — `config/view.ts` →
13
+ * `config('view.*')`, and so on. To add a new config slot, drop a file
14
+ * with a `default export` into `config/`. No edits to this list
15
+ * required.
16
+ *
15
17
  * `ViewProvider` discovers `.strav` files under `resources/views/pages/`
16
18
  * and registers a route for each at boot. `ViewConsoleProvider` adds the
17
19
  * `view:build` / `view:cache` / `view:clear` commands.
18
20
  */
19
- export function providers(): ServiceProvider[] {
21
+ export async function providers(): Promise<ServiceProvider[]> {
20
22
  return [
21
- new ConfigProvider({
22
- app: appConfig,
23
- http: httpConfig,
24
- logger: loggerConfig,
25
- view: viewConfig,
26
- }),
23
+ await ConfigProvider.fromDirectory('config'),
27
24
  new LoggerProvider(),
28
25
  new HttpProvider(),
29
26
  new HttpConsoleProvider(),
@@ -4,8 +4,27 @@ import type { ViewConfig } from '@strav/view'
4
4
  export default {
5
5
  directory: 'resources/views',
6
6
  cache: env('APP_ENV', 'local') === 'production',
7
- islandsDir: 'resources/ts/islands',
8
- islandsOut: 'public/assets/islands',
7
+
8
+ // CSS bundling — `view:build` reads each input, walks `@import`s
9
+ // via Bun's CSS bundler, and writes to `outputDir`. The layout's
10
+ // `@css` directive emits the matching `<link rel="stylesheet">`.
11
+ css: {
12
+ inputs: ['resources/css/app.css'],
13
+ outputDir: 'public/assets',
14
+ linkPath: 'app.css',
15
+ },
16
+
17
+ // Asset versioning for `@asset` / `@css`. `publicDir` mirrors the
18
+ // layout under `/assets/...` so `app.css` resolves to a file at
19
+ // `public/assets/app.css` and a URL at `/assets/app.css`.
20
+ // Versioning is mtime-based by default; drop a
21
+ // `public/assets/manifest.json` to switch to fingerprinted
22
+ // filenames.
23
+ assets: {
24
+ publicDir: 'public/assets',
25
+ prefix: '/assets/',
26
+ },
27
+
9
28
  pages: {
10
29
  autoRoute: true,
11
30
  },
@@ -1,41 +1,32 @@
1
- /* Bare-bones starter styles. Swap for Tailwind, vanilla-extract, or your
2
- * stylesheet of choice just point the <link rel="stylesheet"> in
3
- * `resources/views/layouts/app.strav` at the right built output. */
4
-
5
- :root {
6
- --bg: #ffffff;
7
- --fg: #111111;
8
- --accent: #3b82f6;
9
- font-family: system-ui, -apple-system, "Segoe UI", sans-serif;
10
- line-height: 1.5;
11
- color-scheme: light dark;
12
- }
13
-
14
- @media (prefers-color-scheme: dark) {
15
- :root {
16
- --bg: #0f0f10;
17
- --fg: #f5f5f5;
18
- }
19
- }
1
+ /* Spring `--web` starter vanilla CSS that pairs with the Tailwind
2
+ * CDN loaded by `resources/views/layouts/app.strav`. Everything below
3
+ * is what Tailwind doesn't cover: the body background grid, the
4
+ * fluid hero type, and the global text/background colour reset.
5
+ *
6
+ * Swap for your own stylesheet of choice — point the layout's `@css`
7
+ * directive (resolved via `config.view.css`) at whatever you build.
8
+ */
20
9
 
21
10
  body {
22
- margin: 0;
23
- background: var(--bg);
24
- color: var(--fg);
11
+ background-color: #ffffff;
12
+ color: #000000;
25
13
  }
26
14
 
27
- main {
28
- max-width: 48rem;
29
- margin: 0 auto;
30
- padding: 2rem 1.25rem;
15
+ /* Faint red grid overlay across the page. The 40px cells line up
16
+ * with the Tailwind 8/12-step spacing rhythm. */
17
+ .bg-grid-precision {
18
+ background-size: 40px 40px;
19
+ background-image:
20
+ linear-gradient(to right, rgba(255, 68, 51, 0.05) 1px, transparent 1px),
21
+ linear-gradient(to bottom, rgba(255, 68, 51, 0.05) 1px, transparent 1px);
31
22
  }
32
23
 
33
- button {
34
- cursor: pointer;
35
- border-radius: 0.375rem;
36
- border: 1px solid var(--accent);
37
- background: var(--accent);
38
- color: #fff;
39
- padding: 0.5rem 1rem;
40
- font: inherit;
24
+ /* Fluid display type for the hero — clamps between 3rem at narrow
25
+ * widths and 5.5rem at wide. Letter-spacing tightens at scale; the
26
+ * line-height is sub-1 so the two stacked lines hug. */
27
+ .text-huge {
28
+ font-size: clamp(3rem, 8vw, 5.5rem);
29
+ line-height: 0.95;
30
+ letter-spacing: -0.04em;
31
+ font-weight: 800;
41
32
  }
@@ -4,12 +4,43 @@
4
4
  <meta charset="utf-8" />
5
5
  <meta name="viewport" content="width=device-width, initial-scale=1" />
6
6
  <title>@yield('title', '{{projectName}}')</title>
7
- <link rel="stylesheet" href="/assets/app.css" />
7
+ <script src="https://cdn.tailwindcss.com?plugins=forms,container-queries"></script>
8
+ <script>
9
+ tailwind.config = {
10
+ theme: {
11
+ extend: {
12
+ colors: {
13
+ primary: '#ff4433',
14
+ 'on-surface': '#000000',
15
+ 'on-surface-variant': '#666666',
16
+ outline: '#e5e5e5',
17
+ surface: '#ffffff',
18
+ },
19
+ fontFamily: {
20
+ sans: ['system-ui', '-apple-system', 'sans-serif'],
21
+ mono: ['ui-monospace', 'SFMono-Regular', 'Menlo', 'Monaco', 'Consolas', 'monospace'],
22
+ },
23
+ },
24
+ },
25
+ }
26
+ </script>
27
+ @css
8
28
  </head>
9
- <body>
10
- <main>
29
+ <body class="min-h-screen flex flex-col selection:bg-primary selection:text-white bg-grid-precision">
30
+ <main class="flex-grow w-full mx-auto px-6 md:px-12 py-16 md:py-24 max-w-[800px]">
11
31
  @yield('content')
12
32
  </main>
13
- <script type="module" src="/assets/islands/islands.js" defer></script>
33
+
34
+ <footer class="border-t border-black bg-white py-12 px-6 md:px-12 mt-auto">
35
+ <div class="max-w-[1400px] mx-auto flex flex-col md:flex-row justify-between items-center gap-8">
36
+ <div class="text-[10px] font-mono tracking-[0.3em] uppercase text-on-surface-variant">
37
+ © 2026 Strav
38
+ </div>
39
+ <div class="flex gap-12">
40
+ <a class="text-sm font-bold uppercase tracking-tighter hover:text-primary transition-colors" href="https://strav.dev">Docs</a>
41
+ <a class="text-sm font-bold uppercase tracking-tighter hover:text-primary transition-colors" href="https://github.com/strav/strav">Repository</a>
42
+ </div>
43
+ </div>
44
+ </footer>
14
45
  </body>
15
46
  </html>
@@ -3,10 +3,45 @@
3
3
  @set('title', '{{projectName}}')
4
4
 
5
5
  @section('content')
6
- <h1>Welcome to {{projectName}}</h1>
7
- <p>You're looking at <code>resources/views/pages/index.strav</code>.</p>
6
+ {{-- Hero --}}
7
+ <div class="mb-24">
8
+ <div class="inline-block border border-primary px-3 py-1 mb-8 text-[11px] font-mono tracking-widest uppercase text-primary">
9
+ V1.0.0-AI • Local Environment Active
10
+ </div>
11
+ <h1 class="text-huge mb-8">
12
+ The Fast Path for<br>
13
+ <span class="text-primary">{{projectName}}</span>
14
+ </h1>
15
+ <p class="text-xl md:text-2xl text-on-surface-variant max-w-2xl leading-tight font-medium">
16
+ An industrial-grade architecture for modern web applications. Engineered for speed and the uncompromising developer.
17
+ </p>
18
+ </div>
8
19
 
9
- <p>The button below is a Vue 3 island — see <code>resources/ts/islands/counter.vue</code>. Run <code>bun strav view:build</code> to compile islands into <code>public/assets/islands/</code>.</p>
20
+ {{-- Edit these to get started --}}
21
+ <div class="grid gap-0 border border-black bg-white">
22
+ <div class="p-8 md:p-12">
23
+ <h2 class="text-3xl font-bold tracking-tighter mb-8 italic">Edit these to get started</h2>
10
24
 
11
- @island('Counter', { start: 0 })
25
+ <div class="flex flex-col divide-y divide-black/10 border-t border-black/10">
26
+ <div class="py-4 flex flex-col md:flex-row md:justify-between md:items-center gap-2 group">
27
+ <code class="font-mono text-primary group-hover:underline">resources/views/pages/index.strav</code>
28
+ <span class="text-[10px] font-mono uppercase text-on-surface-variant">This Page</span>
29
+ </div>
30
+ <div class="py-4 flex flex-col md:flex-row md:justify-between md:items-center gap-2">
31
+ <code class="font-mono text-black">resources/views/layouts/app.strav</code>
32
+ <span class="text-[10px] font-mono uppercase text-on-surface-variant">Layout Shell</span>
33
+ </div>
34
+ <div class="py-4 flex flex-col md:flex-row md:justify-between md:items-center gap-2">
35
+ <code class="font-mono text-black">resources/css/app.css</code>
36
+ <span class="text-[10px] font-mono uppercase text-on-surface-variant">Styles</span>
37
+ </div>
38
+ </div>
39
+
40
+ <div class="mt-12 flex flex-wrap gap-4">
41
+ <span class="text-[10px] font-mono font-bold px-2 py-1 border border-black">BUN</span>
42
+ <span class="text-[10px] font-mono font-bold px-2 py-1 border border-black">TYPESCRIPT</span>
43
+ <span class="text-[10px] font-mono font-bold px-2 py-1 border border-primary text-primary">POSTGRESQL</span>
44
+ </div>
45
+ </div>
46
+ </div>
12
47
  @endsection
package/src/version.ts CHANGED
@@ -6,4 +6,4 @@
6
6
  * but this constant is what *generated apps* depend on — keep them in sync
7
7
  * on each release until spring formally cuts independent versions.
8
8
  */
9
- export const STRAV_VERSION = '^1.0.0-alpha.28'
9
+ export const STRAV_VERSION = '^1.0.0-alpha.29'
@@ -1,11 +0,0 @@
1
- <script setup lang="ts">
2
- import { ref } from 'vue'
3
-
4
- const props = defineProps<{ start?: number }>()
5
- // biome-ignore lint/correctness/noUnusedVariables: bound by the <template> below
6
- const count = ref(props.start ?? 0)
7
- </script>
8
-
9
- <template>
10
- <button @click="count++">Count is {{ count }}</button>
11
- </template>
@@ -1,13 +0,0 @@
1
- import type { App } from 'vue'
2
-
3
- /**
4
- * Shared setup for every Vue island on the page. Runs once on the single
5
- * `createApp(Root)` that the `@strav/view` islands bundler produces, so
6
- * plugins (Pinia, vue-router, i18n, …) and global directives go here.
7
- *
8
- * Export a default function. The bundler invokes it with the app instance.
9
- */
10
- export default (app: App): void => {
11
- // Example: app.use(createPinia())
12
- void app
13
- }