@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 +1 -1
- package/src/cli.ts +1 -1
- package/src/templates/shared/bin/strav.ts +1 -1
- package/src/templates/shared/bootstrap/providers.ts +7 -12
- package/src/templates/web/bootstrap/providers.ts +8 -11
- package/src/templates/web/config/view.ts +21 -2
- package/src/templates/web/resources/css/app.css +25 -34
- package/src/templates/web/resources/views/layouts/app.strav.tt +35 -4
- package/src/templates/web/resources/views/pages/index.strav.tt +39 -4
- package/src/version.ts +1 -1
- package/src/templates/web/resources/ts/islands/counter.vue +0 -11
- package/src/templates/web/resources/ts/islands/setup.ts +0 -13
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@strav/spring",
|
|
3
|
-
"version": "1.0.0-alpha.
|
|
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.
|
|
23
|
+
const SPRING_VERSION = '1.0.0-alpha.29'
|
|
24
24
|
|
|
25
25
|
function printUsage(): void {
|
|
26
26
|
process.stdout.write(`
|
|
@@ -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
|
-
*
|
|
14
|
-
*
|
|
15
|
-
*
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
8
|
-
|
|
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
|
-
/*
|
|
2
|
-
*
|
|
3
|
-
*
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
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
|
-
|
|
23
|
-
|
|
24
|
-
color: var(--fg);
|
|
11
|
+
background-color: #ffffff;
|
|
12
|
+
color: #000000;
|
|
25
13
|
}
|
|
26
14
|
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
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
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
font:
|
|
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
|
-
<
|
|
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
|
-
|
|
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
|
-
|
|
7
|
-
<
|
|
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
|
-
|
|
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
|
-
|
|
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
|
@@ -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
|
-
}
|