tw-framework 1.0.0

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/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 TW Framework Team
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/README.md ADDED
@@ -0,0 +1,67 @@
1
+ # TW Framework
2
+
3
+ Full-stack web framework for building sites and apps with `.tw` pages, `.twm` server modules and `.tss` styles — compiled by the TW Compiler, hydrated by TW VDOM 1, served anywhere.
4
+
5
+ ## Install
6
+
7
+ ```bash
8
+ bun add -d tw-framework
9
+ ```
10
+
11
+ The CLI runs on Node 18+ for `tw create`, `tw build`, `tw test` and `tw adapter`. `tw dev` and `tw serve` use the Bun runtime.
12
+
13
+ ## Quickstart
14
+
15
+ ```bash
16
+ # scaffold an app
17
+ npx create-tw-framework@latest my-site
18
+ cd my-site
19
+
20
+ # develop (http://localhost:3000)
21
+ bunx tw-framework dev
22
+
23
+ # production build -> .tw/
24
+ bunx tw-framework build
25
+
26
+ # production server (Bun)
27
+ bunx tw-framework serve
28
+ ```
29
+
30
+ ## Commands
31
+
32
+ | Command | What it does |
33
+ | --- | --- |
34
+ | `tw create <name>` | Scaffold a new app (pages, API routes, layout, config) |
35
+ | `tw dev` | Dev server with on-demand compilation |
36
+ | `tw build` | Production build to `.tw/` (pages, client chunks, route-split CSS) |
37
+ | `tw serve` | Production server (Bun) — pages, `.twm` APIs, middleware |
38
+ | `tw test` | Run the app test suite (Bun and Node) |
39
+ | `tw check` | Diagnostics for the current project |
40
+ | `tw ship` | Generate deployment configs (Vercel, Netlify, Cloudflare, Docker) |
41
+ | `tw adapter <name>` | Deployment adapters: `node`, `bun`, `docker`, `vercel` |
42
+ | `tw plugin` | Manage project plugins |
43
+
44
+ ## Deployment adapters
45
+
46
+ ```bash
47
+ # zero-dependency Node server for the build output (static sites)
48
+ bunx tw-framework adapter node && node server.mjs
49
+
50
+ # full server (pages + APIs) on Bun
51
+ bunx tw-framework adapter bun && bun server.ts
52
+
53
+ # Docker (full + static Dockerfiles, compose file)
54
+ bunx tw-framework adapter docker
55
+
56
+ # Vercel
57
+ bunx tw-framework adapter vercel
58
+ ```
59
+
60
+ ## Learn more
61
+
62
+ - [Full documentation](https://github.com/tw-origin/tw-framework/blob/main/docs/framework-overview.md) — 183 guides and references
63
+ - [Setup guide](https://github.com/tw-origin/tw-framework/blob/main/docs/setup-guide.md) — templates, editors, first app
64
+ - [Deployment guides](https://github.com/tw-origin/tw-framework/blob/main/docs/guide-vercel.md) — Vercel, Netlify, Docker, AWS and more
65
+ - [Repository](https://github.com/tw-origin/tw-framework)
66
+
67
+ MIT licensed.
@@ -0,0 +1,37 @@
1
+ # Deploying TW Framework to AWS
2
+
3
+ Generated by `tw adapter aws`. Two paths, depending on what you built:
4
+
5
+ ## A. Static output → S3 + CloudFront
6
+
7
+ For static and pre-rendered output (no `.twm` APIs served per request):
8
+
9
+ 1. Create an S3 bucket (block public access off for static hosting, or keep it
10
+ private and front it with CloudFront — recommended).
11
+ 2. Create a CloudFront distribution with the bucket as origin, default root
12
+ object `index.html`.
13
+ 3. Deploy:
14
+
15
+ ```bash
16
+ tw build
17
+ BUCKET=my-bucket DISTRIBUTION_ID=E123ABC bash deploy-s3.sh
18
+ ```
19
+
20
+ `deploy-s3.sh` uploads `/assets/*` and `/js/*` with immutable cache headers
21
+ and everything else with `no-cache`, then invalidates CloudFront.
22
+
23
+ ## B. Full server (pages + APIs + middleware) → containers
24
+
25
+ The full TW server runs in a container. Use the Docker adapter and deploy to
26
+ any container service:
27
+
28
+ ```bash
29
+ tw adapter docker
30
+ ```
31
+
32
+ - **App Runner**: point a service at the repo (or ECR image) — `PORT` is
33
+ injected and honoured.
34
+ - **ECS / Fargate**: use the same image; the task port maps to `PORT`.
35
+ - **Lightsail containers**: same image, same port handling.
36
+
37
+ The image listens on `PORT` (default 8000) and serves the complete app.
@@ -0,0 +1,39 @@
1
+ #!/usr/bin/env bash
2
+ # Deploy the .tw/ build output to AWS S3 + CloudFront.
3
+ # Generated by `tw adapter aws`.
4
+ #
5
+ # Usage:
6
+ # tw build
7
+ # BUCKET=my-bucket DISTRIBUTION_ID=E123ABC bash deploy-s3.sh
8
+ #
9
+ # Requires the AWS CLI configured with permissions for the bucket
10
+ # (and the distribution, when DISTRIBUTION_ID is set).
11
+ set -euo pipefail
12
+
13
+ BUCKET="${BUCKET:?set BUCKET=<your-bucket>}"
14
+ DISTRIBUTION_ID="${DISTRIBUTION_ID:-}"
15
+
16
+ if [ ! -d .tw ]; then
17
+ echo "Run 'tw build' first — .tw/ not found."
18
+ exit 1
19
+ fi
20
+
21
+ # Hashed assets never change — cache them forever.
22
+ aws s3 sync .tw/assets "s3://$BUCKET/assets" \
23
+ --cache-control "public, max-age=31536000, immutable" --delete
24
+
25
+ aws s3 sync .tw/js "s3://$BUCKET/js" \
26
+ --cache-control "public, max-age=31536000, immutable" --delete
27
+
28
+ # HTML revalidates on every request.
29
+ aws s3 sync .tw "s3://$BUCKET" \
30
+ --exclude "assets/*" --exclude "js/*" \
31
+ --cache-control "no-cache" --delete
32
+
33
+ # Invalidate CloudFront so new HTML is live immediately.
34
+ if [ -n "$DISTRIBUTION_ID" ]; then
35
+ aws cloudfront create-invalidation \
36
+ --distribution-id "$DISTRIBUTION_ID" --paths "/*"
37
+ fi
38
+
39
+ echo "Deployed to s3://$BUCKET"
@@ -0,0 +1,30 @@
1
+ /**
2
+ * TW Framework — Bun deployment adapter (full server).
3
+ *
4
+ * Runs the production TWServer (pages + .twm APIs + middleware + config)
5
+ * on Bun's native HTTP server. Copy this file next to your app (or generate
6
+ * it with `tw adapter bun`) and run:
7
+ *
8
+ * bun server.ts
9
+ *
10
+ * Env: PORT (default 3000) HOST (default 0.0.0.0) TW_ROOT (default .tw)
11
+ */
12
+
13
+ import { TWServer } from "@tw/server";
14
+ import { join } from "node:path";
15
+
16
+ const rootDir = process.cwd();
17
+ const port = Number(process.env.PORT ?? 3000);
18
+ const host = process.env.HOST ?? "0.0.0.0";
19
+ const staticDir = process.env.TW_ROOT ?? join(rootDir, ".tw");
20
+
21
+ const server = new TWServer({
22
+ rootDir,
23
+ port,
24
+ host,
25
+ staticDir,
26
+ } as any);
27
+
28
+ try { server.loadRoutes(); } catch { /* optional */ }
29
+ try { server.loadMiddleware(); } catch { /* optional */ }
30
+ await server.start();
@@ -0,0 +1,25 @@
1
+ # Caddyfile for TW Framework
2
+ # Generated by `tw adapter caddy`.
3
+ #
4
+ # Replace example.com with your domain. Caddy issues and renews HTTPS
5
+ # certificates automatically.
6
+ #
7
+ # Static output only (pages + pre-rendered routes). For the full server,
8
+ # run `tw serve` (or the node/bun adapter) and proxy to it instead:
9
+ #
10
+ # example.com {
11
+ # reverse_proxy 127.0.0.1:8000
12
+ # }
13
+
14
+ example.com {
15
+ root * .tw
16
+ encode gzip
17
+
18
+ # Hashed assets never change — cache them forever.
19
+ @immutable path /assets/* /js/*
20
+ header @immutable Cache-Control "public, max-age=31536000, immutable"
21
+
22
+ # Clean URLs: /about serves about/index.html
23
+ try_files {path} {path}/ /{path}.html
24
+ file_server
25
+ }
@@ -0,0 +1,12 @@
1
+ # Cloudflare Pages headers
2
+ # Hashed assets never change — cache them forever.
3
+ /assets/*
4
+ Cache-Control: public, max-age=31536000, immutable
5
+
6
+ /js/*
7
+ Cache-Control: public, max-age=31536000, immutable
8
+
9
+ /*
10
+ X-Content-Type-Options: nosniff
11
+ X-Frame-Options: DENY
12
+ Referrer-Policy: strict-origin-when-cross-origin
@@ -0,0 +1,4 @@
1
+ # Cloudflare Pages redirects — one per line:
2
+ # /old-path /new-path 301
3
+ #
4
+ # Netlify-style syntax: source, destination, status code.
@@ -0,0 +1,13 @@
1
+ # Cloudflare Pages deployment for TW Framework
2
+ # Generated by `tw adapter cloudflare`.
3
+ #
4
+ # Build configuration (also settable in the Cloudflare dashboard):
5
+ # Build command: tw build
6
+ # Build output dir: .tw
7
+ #
8
+ # Deploy with git integration (push to deploy) or:
9
+ # npx wrangler pages deploy .tw
10
+
11
+ name = "tw-app"
12
+ compatibility_date = "2024-11-01"
13
+ pages_build_output_dir = ".tw"
@@ -0,0 +1,15 @@
1
+ # DigitalOcean App Platform spec for TW Framework
2
+ # Generated by `tw adapter digitalocean`.
3
+ #
4
+ # Connect the repo in the DigitalOcean control panel (Apps → Create App),
5
+ # pick the repository and branch — this spec configures the service.
6
+ #
7
+ # Static output (pages + pre-rendered routes). For the full server
8
+ # (.twm APIs + middleware), run `tw adapter docker` instead and change
9
+ # the service below to a dockerfile build.
10
+
11
+ name: tw-app
12
+ static_sites:
13
+ - name: web
14
+ build_command: npm install && npx tw build
15
+ output_dir: .tw
@@ -0,0 +1,7 @@
1
+ node_modules
2
+ .tw
3
+ .git
4
+ .env
5
+ .env.*
6
+ dist
7
+ *.log
@@ -0,0 +1,35 @@
1
+ # TW Framework — production Docker image (full server: pages + .twm APIs).
2
+ #
3
+ # docker build -t tw-app .
4
+ # docker run -p 8000:8000 tw-app
5
+ #
6
+ # Static site (no .twm API routes)? Use Dockerfile.static instead —
7
+ # its runtime is a tiny zero-dependency Node alpine image.
8
+
9
+ # ---- Stage 1: install + build ----
10
+ FROM oven/bun:1 AS build
11
+ WORKDIR /app
12
+
13
+ # Install dependencies first (layer cache)
14
+ COPY package.json bun.lock* ./
15
+ RUN bun install
16
+
17
+ # The TW CLI (published as tw-framework on npm)
18
+ RUN bun add -d tw-framework
19
+
20
+ # Build the app
21
+ COPY . .
22
+ RUN bunx tw build
23
+
24
+ # ---- Stage 2: runtime ----
25
+ FROM oven/bun:1
26
+ WORKDIR /app
27
+
28
+ ENV NODE_ENV=production
29
+ ENV PORT=8000
30
+ ENV HOST=0.0.0.0
31
+
32
+ COPY --from=build /app ./
33
+
34
+ EXPOSE 8000
35
+ CMD ["bunx", "tw", "serve"]
@@ -0,0 +1,27 @@
1
+ # TW Framework — static-site Docker image (no .twm API routes).
2
+ # Runtime is zero-dependency Node 20 alpine serving the compiled .tw/ output.
3
+
4
+ # ---- Stage 1: build ----
5
+ FROM oven/bun:1 AS build
6
+ WORKDIR /app
7
+
8
+ COPY package.json bun.lock* ./
9
+ RUN bun install
10
+ RUN bun add -d tw-framework
11
+
12
+ COPY . .
13
+ RUN bunx tw build
14
+
15
+ # ---- Stage 2: run (tiny) ----
16
+ FROM node:20-alpine
17
+ WORKDIR /app
18
+
19
+ ENV NODE_ENV=production
20
+ ENV PORT=8000
21
+ ENV HOST=0.0.0.0
22
+
23
+ COPY --from=build /app/.tw ./.tw
24
+ COPY server.mjs ./server.mjs
25
+
26
+ EXPOSE 8000
27
+ CMD ["node", "server.mjs"]
@@ -0,0 +1,8 @@
1
+ services:
2
+ web:
3
+ build: .
4
+ ports:
5
+ - "8000:8000"
6
+ environment:
7
+ - NODE_ENV=production
8
+ restart: unless-stopped
@@ -0,0 +1,31 @@
1
+ {
2
+ "hosting": {
3
+ "public": ".tw",
4
+ "ignore": [
5
+ "firebase.json",
6
+ "**/.*",
7
+ "**/node_modules/**"
8
+ ],
9
+ "cleanUrls": true,
10
+ "headers": [
11
+ {
12
+ "source": "/assets/**",
13
+ "headers": [
14
+ {
15
+ "key": "Cache-Control",
16
+ "value": "public, max-age=31536000, immutable"
17
+ }
18
+ ]
19
+ },
20
+ {
21
+ "source": "/js/**",
22
+ "headers": [
23
+ {
24
+ "key": "Cache-Control",
25
+ "value": "public, max-age=31536000, immutable"
26
+ }
27
+ ]
28
+ }
29
+ ]
30
+ }
31
+ }
@@ -0,0 +1,32 @@
1
+ # Fly.io deployment for TW Framework
2
+ # Generated by `tw adapter fly`.
3
+ #
4
+ # 1. Run `tw adapter docker` first — fly deploys the container image.
5
+ # 2. fly launch (first time — picks a region, creates the app)
6
+ # 3. fly deploy
7
+ #
8
+ # The container listens on PORT (default 8000), which matches
9
+ # internal_port below. The full server (pages + .twm APIs + middleware)
10
+ # runs on every machine.
11
+
12
+ app = "tw-app"
13
+ primary_region = "bom"
14
+
15
+ [build]
16
+
17
+ [http_service]
18
+ internal_port = 8000
19
+ force_https = true
20
+ auto_stop_machines = true
21
+ auto_start_machines = true
22
+ min_machines_running = 1
23
+
24
+ [http_service.concurrency]
25
+ type = "requests"
26
+ soft_limit = 200
27
+ hard_limit = 250
28
+
29
+ [[http_service.checks]]
30
+ interval = "10s"
31
+ timeout = "2s"
32
+ grace_period = "5s"
@@ -0,0 +1,41 @@
1
+ name: Deploy to GitHub Pages
2
+
3
+ on:
4
+ push:
5
+ branches: [main]
6
+ workflow_dispatch:
7
+
8
+ permissions:
9
+ contents: read
10
+ pages: write
11
+ id-token: write
12
+
13
+ concurrency:
14
+ group: pages
15
+ cancel-in-progress: true
16
+
17
+ jobs:
18
+ build:
19
+ runs-on: ubuntu-latest
20
+ steps:
21
+ - uses: actions/checkout@v4
22
+
23
+ - uses: oven-sh/setup-bun@v2
24
+
25
+ - run: bun install
26
+
27
+ - run: bunx tw build
28
+
29
+ - uses: actions/upload-pages-artifact@v3
30
+ with:
31
+ path: .tw
32
+
33
+ deploy:
34
+ needs: build
35
+ runs-on: ubuntu-latest
36
+ environment:
37
+ name: github-pages
38
+ url: ${{ steps.deployment.outputs.page_url }}
39
+ steps:
40
+ - id: deployment
41
+ uses: actions/deploy-pages@v4
@@ -0,0 +1 @@
1
+ # GitHub Pages must not run Jekyll processing on the .tw/ output.