@papit/server 1.0.5 β 1.0.7
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/README.md +82 -59
- package/lib/bin.js +2 -2
- package/lib/bundle.d.ts +33 -0
- package/lib/bundle.js +2 -2
- package/package.json +5 -5
package/README.md
CHANGED
|
@@ -1,90 +1,113 @@
|
|
|
1
1
|
# @papit/server
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
Development server for papit workspaces that serves a package together with its workspace dependencies through an import map, bundles TypeScript on request and reloads the page when files change.
|
|
4
4
|
|
|
5
5
|

|
|
6
6
|
|
|
7
|
-
`@papit/server` can serve your **local assets, package files, dependency assets**, and automatically handle **live updates, bundling, and caching**. Itβs ideal for developers who want a **fast, flexible dev environment** with **asset localization, HTML/JS bundling, import maps, and dependency-aware serving**.
|
|
8
|
-
|
|
9
|
-
**Key features:**
|
|
10
|
-
|
|
11
|
-
- π¦ Serves local project files and assets
|
|
12
|
-
- π Handles package and dependency assets automatically
|
|
13
|
-
- β‘ Supports live-reload updates for JavaScript/TypeScript
|
|
14
|
-
- π Efficient caching mechanism for files, HTML, and bundles
|
|
15
|
-
- πΌ Automatic handling of images, fonts, audio, video, and other binary assets
|
|
16
|
-
- π Dev-friendly HTTP error handling (`404`, `500`, `405`)
|
|
17
|
-
- π Optional bundling via `@papit/build` for `.ts`/`.tsx` files
|
|
18
|
-
- π§© Importmap support for module resolution across packages
|
|
19
|
-
|
|
20
7
|
---
|
|
21
8
|
|
|
22
|
-

|
|
23
10
|
[](https://github.com/onkelhoy/papit/actions/workflows/pull-request.yml)
|
|
24
11
|
[](https://www.npmjs.com/package/@papit/server)
|
|
25
12
|
|
|
26
13
|
---
|
|
27
14
|
|
|
28
|
-
|
|
15
|
+
# Installation
|
|
29
16
|
|
|
30
17
|
```bash
|
|
31
18
|
npm install @papit/server
|
|
32
19
|
```
|
|
33
20
|
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
## Usage
|
|
21
|
+
# Usage
|
|
37
22
|
|
|
38
|
-
|
|
23
|
+
Run it from a package folder (or the workspace root) and open the printed port:
|
|
39
24
|
|
|
40
25
|
```bash
|
|
41
26
|
npx @papit/server
|
|
42
27
|
```
|
|
43
28
|
|
|
44
|
-
|
|
45
|
-
- Serves your project assets, HTML, and bundled JavaScript/TypeScript
|
|
46
|
-
- Supports **live reload** for client updates
|
|
47
|
-
- Automatically handles caching and streaming for large assets
|
|
29
|
+
Rebuild and reload while you edit, as every web package's `npm start` does:
|
|
48
30
|
|
|
49
|
-
|
|
31
|
+
```bash
|
|
32
|
+
npx @papit/server --info --live
|
|
33
|
+
```
|
|
50
34
|
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
All runtime flags are centralized here for easy reference. Flags can be passed via CLI or environment variables.
|
|
54
|
-
|
|
55
|
-
| Flag | Type | Default | Description |
|
|
56
|
-
| ---------------- | --------------- | ----------------------------- | ------------------------------------- |
|
|
57
|
-
| `--port` | number | 3000 | Set the server port |
|
|
58
|
-
| `--live` | boolean | false | Enable live updates (hot reload) |
|
|
59
|
-
| `--no-bundle` | boolean | false | Skip bundling of JS/TS files |
|
|
60
|
-
| `--asset` | string or array | `["asset","assets","public"]` | Custom asset folder(s) to serve |
|
|
61
|
-
| `--cache-file` | number (MB) | 50 | Max cache size for individual files |
|
|
62
|
-
| `--cache-html` | number (MB) | 50 | Max cache size for HTML files |
|
|
63
|
-
| `--cache-bundle` | number (MB) | 150 | Max cache size for bundled JS files |
|
|
64
|
-
| `--verbose` | boolean | false | Enable verbose logging |
|
|
65
|
-
| `--info` | boolean | false | Show info logs |
|
|
66
|
-
| `--error` | boolean | false | Show error traces |
|
|
67
|
-
| `--silent` | boolean | false | Suppress console output |
|
|
68
|
-
| `--no-cache` | boolean | false | Disable caching entirely |
|
|
69
|
-
| `--location` | string | - | Override project root location |
|
|
70
|
-
| `--mode` | string | "dev" | Server mode (`dev`/`prod`) |
|
|
71
|
-
| `--buildMode` | string | "ancestors" | Build mode (`ancestors`/`workspaces`) |
|
|
72
|
-
|
|
73
|
-
> **Note:** Some flags (like `--prod`, `--watch`, `--callback`) are inherited from [@papit/build](https://github.com/onkelhoy/papit/tree/main/packages/runtime/build/README.md). Please check the build README for advanced options.
|
|
35
|
+
Serve a fixed port for Playwright, as the test configs do:
|
|
74
36
|
|
|
75
|
-
|
|
37
|
+
```bash
|
|
38
|
+
npx @papit/server --serve --port=3500
|
|
39
|
+
```
|
|
40
|
+
|
|
41
|
+
Open the browser on a sub folder:
|
|
76
42
|
|
|
77
|
-
|
|
43
|
+
```bash
|
|
44
|
+
npx @papit/server --open=views/showcase
|
|
45
|
+
```
|
|
78
46
|
|
|
79
|
-
|
|
47
|
+
# CLI flags
|
|
80
48
|
|
|
81
|
-
|
|
49
|
+
| Flag | Type | Default | Description |
|
|
50
|
+
| --- | --- | --- | --- |
|
|
51
|
+
| `--port` | number | `3000` | first port to try; the next free one is used, up to 20 tries |
|
|
52
|
+
| `--live` | boolean | `false` | watch the workspace, rebuild changed packages and reload open pages |
|
|
53
|
+
| `--serve` | boolean | `false` | only serve; skip the build settings applied when run inside another package |
|
|
54
|
+
| `--open` | string | - | open the browser, optionally on this path |
|
|
55
|
+
| `--folder` | string | - | sub folder every request path is resolved under |
|
|
56
|
+
| `--asset` | string (repeatable) | - | extra asset folder names, on top of `asset`, `assets` and `public` |
|
|
57
|
+
| `--include-node` | boolean | `false` | also collect assets from `node` type packages |
|
|
58
|
+
| `--import-map` | string | `.temp/dependencies` | working folder created at startup; removed on shutdown unless this flag is given |
|
|
59
|
+
| `--prod` | boolean | `false` | drop the `Cache-Control: no-store` header on HTML |
|
|
60
|
+
| `--no-cache` | boolean | `false` | disable the in-memory caches |
|
|
61
|
+
| `--cache-file` | number (MB) | `50` | file cache size |
|
|
62
|
+
| `--cache-html` | number (MB) | `50` | HTML cache size |
|
|
63
|
+
| `--cache-bundle` | number (MB) | `150` | on-the-fly bundle cache size |
|
|
64
|
+
| `--MAX_FILE_SIZE_TO_CACHE` | number (bytes) | `1048576` | larger files are streamed, not cached |
|
|
65
|
+
| `--explorer-spritesheet` | string | built-in | spritesheet for the folder explorer icons |
|
|
66
|
+
| `--silent`, `--error`, `--info`, `--verbose`, `--debug` | boolean | - | log level, from `@papit/arguments` |
|
|
67
|
+
|
|
68
|
+
Other flags are passed on to `@papit/build` when `--live` rebuilds a package.
|
|
82
69
|
|
|
83
|
-
|
|
70
|
+
# What it serves
|
|
84
71
|
|
|
85
|
-
|
|
72
|
+
A GET request is answered by the first of these that matches. Other methods get `405`, and a path that matches nothing currently gets `500`.
|
|
86
73
|
|
|
87
|
-
**
|
|
74
|
+
1. **Translations**: JSON files in a folder whose name starts with `transl`, `locale` or `i18`, merged per language across the workspace.
|
|
75
|
+
2. **Assets**: files in asset folders of the served package, its workspace dependencies and the server itself, reachable by any trailing part of their path, so `/icons/x.svg` finds `asset/icons/x.svg`. A package's asset wins over the server's default of the same name.
|
|
76
|
+
3. **Themes**: a URL containing the name of a `theme` package serves that theme's built file.
|
|
77
|
+
4. **Files**: an absolute path inside the workspace that exists on disk, else the path resolved against the current folder, the package, then the workspace root. A path that resolves outside the workspace root (e.g. through `../`) gets `403`, before anything is read.
|
|
78
|
+
5. **Folders**: `index.html` if present, otherwise a file explorer page.
|
|
79
|
+
6. **HTML**: merged into the server's page template, which adds the import map and the live reload client. A request with an `x-router` header gets the raw file instead.
|
|
80
|
+
7. **TypeScript**: a `.ts` file requested as a script is bundled in memory with `@papit/bundle-js`.
|
|
81
|
+
|
|
82
|
+
Responses carry `X-Cache: HIT` or `MISS`. `/favicon.ico` falls back to the server's `favicon.svg`.
|
|
83
|
+
|
|
84
|
+
# Import resolution
|
|
85
|
+
|
|
86
|
+
At startup the server walks the workspace graph from `@papit/information` and builds one import map:
|
|
87
|
+
|
|
88
|
+
- every workspace package maps its package.json `exports` (import condition) and `main` to the file on disk
|
|
89
|
+
- third-party `dependencies` and `devDependencies` are added the same way from the root `node_modules`, except the build tools (`esbuild`, `typescript`, `chokidar`, `@microsoft/api-extractor`, `playwright`)
|
|
90
|
+
- the first mapping for a name wins, and an import map already in the page is merged in, not replaced
|
|
91
|
+
|
|
92
|
+
So `import "@papit/switch"` in a demo page loads the built `lib/bundle.js` of the workspace package, without a publish or install.
|
|
93
|
+
|
|
94
|
+
# Live reload
|
|
95
|
+
|
|
96
|
+
With `--live`, file changes in the workspace (outside `node_modules`, `lib`, `.temp`, `.git` and test folders) are handled per package:
|
|
97
|
+
|
|
98
|
+
- a change inside the package's source folder rebuilds that package with `@papit/build`, then reloads the pages
|
|
99
|
+
- any other change reloads the pages straight away
|
|
100
|
+
|
|
101
|
+
The pages reloaded are those of the changed package and of every package that depends on it.
|
|
102
|
+
|
|
103
|
+
Pages register over a WebSocket on the same port.
|
|
104
|
+
|
|
105
|
+
# License
|
|
106
|
+
|
|
107
|
+
Licensed under the **@Papit License 1.0**
|
|
108
|
+
Copyright (c) 2024 Henry Pap (@onkelhoy)
|
|
109
|
+
|
|
110
|
+
**Key points**
|
|
88
111
|
|
|
89
112
|
- β
Free to use in commercial projects
|
|
90
113
|
- β
Free to modify and distribute
|
|
@@ -93,8 +116,8 @@ Licensed under the **@Papit License 1.0** β Copyright (c) 2024 Henry Pap (@onk
|
|
|
93
116
|
|
|
94
117
|
See the [LICENSE](https://github.com/onkelhoy/papit/blob/main/LICENSE) file for full details.
|
|
95
118
|
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
## Support
|
|
119
|
+
# Related
|
|
99
120
|
|
|
100
|
-
|
|
121
|
+
- [@papit/build](https://github.com/onkelhoy/papit/tree/main/packages/runtime/cli/build) - rebuilds packages on change
|
|
122
|
+
- [@papit/bundle-js](https://github.com/onkelhoy/papit/tree/main/packages/runtime/cli/bundle-js) - bundles TypeScript requested by the page
|
|
123
|
+
- [@papit/information](https://github.com/onkelhoy/papit/tree/main/packages/runtime/cli/information) - the workspace graph the import map is built from
|
package/lib/bin.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
-
import re from"node:path";import ne from"node:fs";import{Arguments as O}from"@papit/arguments";import{Terminal as ze}from"@papit/terminal";import{Information as S,PackageGraph as wt}from"@papit/information";import Z from"node:path";import X from"node:fs";import He from"node:fs";import M from"node:path";import{deepMergeTwo as Pe}from"@papit/deep-merge";function ie(e,t,o){let i=JSON.parse(He.readFileSync(t,{encoding:"utf-8"})),r=i?.meta?.language??M.basename(t,".json");o.data[r]||(o.data[r]={meta:i.meta}),o.data[r]=Pe(o.data[r],i,["meta"]);let s=M.relative(e,t).split(M.sep);for(;s.length>0;){let a="/"+s.join("/");o.map[a]=r,s.shift()}}function se(e){if(!e.endsWith(".json"))return!1;let t=M.basename(M.dirname(e));return/^(transl|locale|i18)/i.test(t)}import R from"node:path";var A=class extends Error{constructor(t,o){super(t,o),this.name="http-error"}},z=class extends A{constructor(t,o){super(t??"internal server error",o),this.name="Internal Server Error",this.status=500}},x=class extends A{constructor(t,o){super(t??"not found",o),this.name="Not Found",this.status=404}},D=class extends A{constructor(t,o){super(t??"method not allowed",o),this.name="Method not allowed",this.status=405}};import J from"node:fs";import De from"node:path";import{Arguments as $e}from"@papit/arguments";import{Arguments as ae}from"@papit/arguments";var y=class{static{this.MimeTypes={".html":"text/html",".htm":"text/html",".css":"text/css",".js":"text/javascript",".mjs":"text/javascript",".ts":"text/typescript",".tsx":"text/typescript",".jsx":"text/javascript",".json":"application/json",".xml":"application/xml",".txt":"text/plain",".md":"text/markdown",".markdown":"text/markdown",".csv":"text/csv",".pdf":"application/pdf",".doc":"application/msword",".docx":"application/vnd.openxmlformats-officedocument.wordprocessingml.document",".xls":"application/vnd.ms-excel",".xlsx":"application/vnd.openxmlformats-officedocument.spreadsheetml.sheet",".ppt":"application/vnd.ms-powerpoint",".pptx":"application/vnd.openxmlformats-officedocument.presentationml.presentation",".png":"image/png",".jpg":"image/jpeg",".jpeg":"image/jpeg",".gif":"image/gif",".svg":"image/svg+xml",".webp":"image/webp",".ico":"image/x-icon",".bmp":"image/bmp",".tiff":"image/tiff",".tif":"image/tiff",".woff":"font/woff",".woff2":"font/woff2",".ttf":"font/ttf",".otf":"font/otf",".eot":"application/vnd.ms-fontobject",".mp3":"audio/mpeg",".wav":"audio/wav",".ogg":"audio/ogg",".m4a":"audio/mp4",".mp4":"video/mp4",".webm":"video/webm",".ogv":"video/ogg",".avi":"video/x-msvideo",".mov":"video/quicktime",".zip":"application/zip",".tar":"application/x-tar",".gz":"application/gzip",".7z":"application/x-7z-compressed",".rar":"application/vnd.rar"}}static{this._MAX_CACHE_SIZE=50*1024*1024}static{this._MAX_FILE_SIZE_TO_CACHE=1024*1024}static{this.BinaryExtensions=new Set([".png",".jpg",".jpeg",".gif",".ico",".webp",".bmp",".tiff",".tif",".woff",".woff2",".ttf",".otf",".eot",".mp3",".wav",".ogg",".m4a",".mp4",".webm",".ogv",".avi",".mov",".zip",".tar",".gz",".7z",".rar",".pdf",".doc",".docx",".xls",".xlsx",".ppt",".pptx"])}static get MAX_CACHE_SIZE(){return ae.number("MAX_CACHE_SIZE")??this._MAX_CACHE_SIZE}static get MAX_FILE_SIZE_TO_CACHE(){return ae.number("MAX_FILE_SIZE_TO_CACHE")??this._MAX_FILE_SIZE_TO_CACHE}};import Ue from"node:path";import ce from"node:fs";import{Arguments as me}from"@papit/arguments";import{Terminal as Oe}from"@papit/terminal";async function pe(e,t,o){return new Promise((i,r)=>{let s=y.BinaryExtensions.has(Ue.extname(e))?ce.createReadStream(e,{signal:o}):ce.createReadStream(e,{signal:o,encoding:"utf-8"});s.pipe(t),s.on("error",a=>{me.error&&Oe.error("streaming error",e),me.verbose&&console.trace(a),r(new x(a.message))}),s.on("close",i)})}function B(e,t,o,i){if(!J.existsSync(e.absolute))throw new x(`${e.relative} not found`);let r=De.extname(e.absolute),n=J.statSync(e.absolute);if(!t.isCacheable(n.size,r))return pe(e.absolute,o,i),"streamed";let s=y.MimeTypes[r]??"text/plain",a=J.readFileSync(e.absolute),m={mimeType:s,buffer:a,mtime:n.mtimeMs};return $e.has("no-cache")&&t.add(e,a,s,m.mtime),m}function le(e,t,o){let r=R.relative(e,t).split(R.sep);for(;r.length>0;){let n=R.join(R.sep+r.join(R.sep));o[n]||(o[n]=[]),o[n].push(t),r.shift()}}async function fe(e,t,o,i,r,n){let s=R.normalize(e);if(t.map[s]){let m=t.map[s];if(m)return{mimeType:"application/json",buffer:Buffer.from(JSON.stringify(t.data[m]))}}let a=[...o[s]];for(;a.length>0;){let m=a.pop();try{return B({absolute:R.normalize(m),relative:s},i,r,n)}catch{}}throw new x(`asset "${s}" not found`)}import{Arguments as ue}from"@papit/arguments";function de(){let e=["asset","assets","public"];if(ue.has("asset")){let t=ue.get("asset");e.push(...t)}return e}var We=new Set(["node_modules",".git",".temp","lib","dist","src","explorer-icons"]);async function K(e,t,o,i){let r=ge(e,(n,s,a)=>{if(We.has(n))return!1;if(!a){if(Z.dirname(s)===e)return!1;let m=s.split(Z.sep);if(!i.some(p=>m.includes(p)))return!1}return!0});for(let n of r)se(n)?ie(e,n,t):le(e,n,o)}function ge(e,t,o=0){if(!X.existsSync(e)||o>10)return[];let i=[],r=X.readdirSync(e);for(let n of r){let s=Z.join(e,n),m=X.statSync(s).isDirectory();t&&!t(n,s,m)||(m?i.push(...ge(s,t,o+1)):i.push(s))}return i}import gt from"node:http";import oe from"node:fs";import v from"node:path";import ht from"chokidar";import{Information as C}from"@papit/information";import{Arguments as f}from"@papit/arguments";import{Terminal as d}from"@papit/terminal";import Te from"node:path";import Q from"node:fs";import W from"node:path";import ye from"node:fs";import{Document as Ze}from"@papit/html";import{Arguments as Ke}from"@papit/arguments";import{Terminal as Ve}from"@papit/terminal";import{Document as Ge}from"@papit/html";import Je from"node:path";import V from"node:fs";import{Arguments as he}from"@papit/arguments";import{Terminal as Xe}from"@papit/terminal";function $(e,t){let o=new Ge,i=`${e}-template`,r=Je.join(t,"asset","templates",e,"index.html"),n=he.string(i);if(n&&V.existsSync(n)&&(r=n),!V.existsSync(r))return he.error&&Xe.error(`could not find ${e} template html file`),o.innerHTML='<!doctype html><html lang="en"><head><meta charset="utf-8" /><meta name="viewport" content="width=device-width, initial-scale=1" /><title>@papit/server</title><meta name="description" content="Development server" /><meta name="color-scheme" content="light dark" /></head><body>Llama Trauma Baby Mama</body></html>',o;let s=V.readFileSync(r,{encoding:"utf-8"});return o.innerHTML=s,o}function be(e,t,o,i){let r=$("explorer",i);r.title=e.packageJSON.name;let n=Ke.string("explorer-spritesheet")??W.join(i,"asset/icons/explorer-spritesheet.svg"),s=ye.readFileSync(n,{encoding:"utf-8"}),a=new Ze;a.innerHTML=s,a.documentElement||(Ve.error("something went wrong loading explorer icon spritesheet"),process.exit(1)),a.documentElement.setAttribute("style","display:none"),r.body?.appendChild(a.documentElement);let m=r.querySelector("[data-location]"),p=W.relative(e.location,o.absolute);p?m.innerHTML=p:m.parentElement?.removeChild(m);let c=r.querySelector("ul[data-folders]"),u=r.querySelector("ul[data-files]");return o.relative!==""&&(c.innerHTML='<li class="hidden"><a href=".."><svg><use href="#folder" /></svg><span class="name">..</span></a></li>'),t.sort((l,b)=>l.localeCompare(b)).forEach(l=>{let b=W.join(o.absolute,l),_=ye.statSync(b),w=r.createElement("li");w.innerHTML=`<a href="${l}"><svg><use href="" /></svg><span class="name">${l}</span></a>`;let g=w.querySelector("a"),T=g.querySelector("use");if(!l.startsWith(".env")&&!l.startsWith(".git")&&l.startsWith(".")&&w.classList.add("hidden"),_.isFile()){T?.setAttribute("href","#"+Qe(b,r)),u.appendChild(w);return}_.isDirectory()&&(T?.setAttribute("href","#"+Ye(b,r)),g.setAttribute("href",l+"/"),c.appendChild(w))}),r}function Qe(e,t){let o=W.basename(e),i=o.split(".");o.startsWith(".")&&i.shift();let r=i.at(0)??o,n;if(o.startsWith(".git")||/\.git/.test(e))n="git";else if(o==="package.json")n="package";else if(o.startsWith("tsconfig"))n="tsconfig";else if(r.startsWith("eslint"))n="eslint";else if(/translation/.test(e)){if(t.querySelector("symbol#"+r))return r;n="language"}else/\.vscode/.test(e)&&(n="vscode");if(t.querySelector("symbol#"+n))return n;let s=i.slice(i.length-2).join("_");if(t.querySelector("symbol#"+s))return s;let a=i.pop()??o;return t.querySelector("symbol#"+a)?a:"file"}function Ye(e,t){return"folder"}import qe from"node:fs";import{Document as et,Element as tt}from"@papit/html";import{Terminal as xe}from"@papit/terminal";function ve(e,t,o,i){let r=$("live",i);r.body||(xe.error("live document template is missing body"),process.exit(1)),r.head||(xe.error("live document template is missing head"),process.exit(1));let n=new et,s=qe.readFileSync(t.absolute,{encoding:"utf-8"});if(n.innerHTML=s,n.head&&[...n.head.childNodes].forEach(c=>ot(c,r.head)),n.body&&[...n.body.childNodes].forEach(c=>r.body?.appendChild(c)),n.body?.classList)for(let c of n.body?.classList)r.body.classList.add(c);if(n.body?.attributes)for(let c in n.body?.attributes){if(c==="class"||n.body.hasAttribute(c))continue;let u=n.body.getAttribute(c);u===!0?n.body.toggleAttribute(c):n.body.setAttribute(c,u)}let a=r.head.querySelector("script"),m=r.head.querySelector('script[type="importmap"]');m||(m=r.createElement("script"),m.setAttribute("type","importmap"));let p=JSON.parse(m.textContent||"{}");return p.imports||(p.imports={}),p.imports={...p.imports,...o.imports},m.textContent=JSON.stringify(p),a?a!==m&&r.head.insertBefore(m,a):r.head.appendChild(m),r}function ot(e,t){if(e instanceof tt){let o=`${e.tagName}${e.className?"."+e.className:""}${e.id?"#"+e.id:""}${Array.from(e.attributes).map(([r,n])=>`[${r}${typeof n=="string"?`="${n}"`:""}]`).join("")}`,i=t.querySelector(o);if(i){t.replaceChild(e,i);return}}t.appendChild(e)}import{fileURLToPath as rt}from"node:url";import h from"node:path";import H from"node:fs";import{Information as L,PackageGraph as nt}from"@papit/information";import{Arguments as it}from"@papit/arguments";function we(e){process.platform==="win32"&&e.url&&/^\/[A-Za-z]:/.test(e.url)&&(e.url=e.url.slice(1).replace(/\//g,"\\"));let o=(()=>{if(e.url&&H.existsSync(e.url)&&H.statSync(e.url).isFile())return{absolute:e.url,relative:h.relative(e.url,L.package.location)};let i=[it.string("folder"),e.url].filter(n=>n!==void 0),r=[L.local,L.package.location,L.root.location];for(let n of r){let s=h.join(n,...i);if(H.existsSync(s))return{absolute:s,relative:h.relative(n,s)||h.relative(L.package.location,L.local)||h.sep}}return{absolute:h.join(L.package.location,e.url??h.sep),relative:e.url??h.sep}})();return o.absolute.endsWith(h.sep)&&(o.absolute=o.absolute.slice(0,o.absolute.length-1)),{absolute:h.normalize(o.absolute),relative:h.normalize(o.relative)}}function Se(e){let o=rt(e);for(let i=0;i<5;i++)if(o=h.dirname(o),!!H.existsSync(h.join(o,"package.json")))return o;return null}function st(e){let t=e;for(;t!=="/"&&!H.existsSync(h.join(t,"package.json"));)t=h.dirname(t);return t}function E(e){let t=st(e.absolute);if(!t)throw new z(`could not find package at 1: ${t}`);let o=nt.search(t);if(!o)throw new z(`could not find package at 2: ${t}`);return o}async function Ee(e,t,o,i,r){let n=E(e),s=e.absolute.endsWith(".html")?e:{absolute:Te.join(e.absolute,"index.html"),relative:Te.join(e.relative,"index.html")},a,m=null;if(Q.existsSync(s.absolute))m=Q.statSync(s.absolute).mtimeMs,a=ve(n,s,o,i);else{let p=Q.readdirSync(e.absolute);a=be(n,p,e,i)}return r.add(e,Buffer.from(a.innerHTML,"utf8"),y.MimeTypes[".html"],m),a}import at from"node:fs";import{jsBundle as ct}from"@papit/bundle-js";import{Arguments as mt}from"@papit/arguments";async function ke(e,t){let o=E(e),i;if(await ct(mt.instance,o.location,{entryPointArray:[{input:e.absolute,output:void 0}],tsconfig:o?.tsconfig,externals:o?.externals,packageJSON:o?.packageJSON,esoptions:{write:!1}},r=>{r.type==="build"&&(i=r.result.outputFiles?.at(0)?.text)}),!i)throw new x("file not found: "+e.relative);return t.add(e,Buffer.from(i,"utf8"),y.MimeTypes[".js"],at.statSync(e.absolute)?.mtimeMs??null),i}import Y from"node:fs";import{Arguments as q}from"@papit/arguments";import{Terminal as I}from"@papit/terminal";var F=class{constructor(t){this.map=new Map;this._size=0;this.name="cache";this._maxSize=y.MAX_FILE_SIZE_TO_CACHE;t&&(this.name=t)}get size(){return this._size}get maxSize(){return this._maxSize}set maxSize(t){this._maxSize=t*1024*1024}get(t){let o=this.map.get(t.absolute);return!o||!Y.existsSync(t.absolute)?null:o.mtime===null||Y.statSync(t.absolute).mtimeMs===o.mtime?o:(this.delete(t),null)}delete(t,o=!1){let i=this.map.get(t.absolute);i&&(q.verbose&&!o&&I.write(I.yellow(t.relative),"removed from cache:"+I.blue(this.name)),this._size-=i.buffer.length,this.map.delete(t.absolute))}clear(){this.map.clear(),this._size=0}add(t,o,i,r){q.has("no-cache")||(this.delete(t,!0),this._size+=o.length,q.verbose&&I.write(I.yellow(t.relative),"added to cache:"+I.blue(this.name)),this.map.set(t.absolute,{mimeType:i??y.MimeTypes[t.absolute]??"text/plain",buffer:o,mtime:r===void 0?Y.statSync(t.absolute).mtimeMs:r}))}isCacheable(t,o){return!(t>this.maxSize||[".mp4",".webm",".ogv",".avi",".mov"].includes(o))}};import{createHash as pt}from"node:crypto";import Ce from"node:path";import{Arguments as ee}from"@papit/arguments";import{Terminal as P}from"@papit/terminal";import{Information as G}from"@papit/information";var j=new Map;function Ae(e,t,o){let i=e.headers["sec-websocket-key"],n=["HTTP/1.1 101 Switching Protocols","Upgrade: websocket","Connection: Upgrade",`Sec-WebSocket-Accept: ${pt("sha1").update(i+"258EAFA5-E914-47DA-95CA-C5AB0DC85B11").digest("base64")}`];t.write(n.join(`\r
|
|
2
|
+
import me from"node:path";import pe from"node:fs";import{Arguments as K}from"@papit/arguments";import{Terminal as He}from"@papit/terminal";import{Information as w}from"@papit/information";import Y from"node:path";import Q from"node:fs";import Ue from"node:fs";import B from"node:path";import{deepMergeTwo as Oe}from"@papit/deep-merge";function le(e,t,o){let i=JSON.parse(Ue.readFileSync(t,{encoding:"utf-8"})),r=i?.meta?.language??B.basename(t,".json");o.data[r]||(o.data[r]={meta:i.meta}),o.data[r]=Oe(o.data[r],i,["meta"]);let s=B.relative(e,t).split(B.sep);for(;s.length>0;){let a="/"+s.join("/");o.map[a]=r,s.shift()}}function fe(e){if(!e.endsWith(".json"))return!1;let t=B.basename(B.dirname(e));return/^(transl|locale|i18)/i.test(t)}import L from"node:path";var k=class extends Error{constructor(t,o){super(t,o),this.name="http-error"}},z=class extends k{constructor(t,o){super(t??"internal server error",o),this.name="Internal Server Error",this.status=500}},b=class extends k{constructor(t,o){super(t??"not found",o),this.name="Not Found",this.status=404}},D=class extends k{constructor(t,o){super(t??"method not allowed",o),this.name="Method not allowed",this.status=405}},$=class extends k{constructor(t,o){super(t??"forbidden",o),this.name="Forbidden",this.status=403}};import V from"node:fs";import We from"node:path";import{Arguments as Je}from"@papit/arguments";import{Arguments as ue}from"@papit/arguments";var y=class{static{this.MimeTypes={".html":"text/html",".htm":"text/html",".css":"text/css",".js":"text/javascript",".mjs":"text/javascript",".ts":"text/typescript",".tsx":"text/typescript",".jsx":"text/javascript",".json":"application/json",".xml":"application/xml",".txt":"text/plain",".md":"text/markdown",".markdown":"text/markdown",".csv":"text/csv",".pdf":"application/pdf",".doc":"application/msword",".docx":"application/vnd.openxmlformats-officedocument.wordprocessingml.document",".xls":"application/vnd.ms-excel",".xlsx":"application/vnd.openxmlformats-officedocument.spreadsheetml.sheet",".ppt":"application/vnd.ms-powerpoint",".pptx":"application/vnd.openxmlformats-officedocument.presentationml.presentation",".png":"image/png",".jpg":"image/jpeg",".jpeg":"image/jpeg",".gif":"image/gif",".svg":"image/svg+xml",".webp":"image/webp",".ico":"image/x-icon",".bmp":"image/bmp",".tiff":"image/tiff",".tif":"image/tiff",".woff":"font/woff",".woff2":"font/woff2",".ttf":"font/ttf",".otf":"font/otf",".eot":"application/vnd.ms-fontobject",".mp3":"audio/mpeg",".wav":"audio/wav",".ogg":"audio/ogg",".m4a":"audio/mp4",".mp4":"video/mp4",".webm":"video/webm",".ogv":"video/ogg",".avi":"video/x-msvideo",".mov":"video/quicktime",".zip":"application/zip",".tar":"application/x-tar",".gz":"application/gzip",".7z":"application/x-7z-compressed",".rar":"application/vnd.rar"}}static{this._MAX_CACHE_SIZE=50*1024*1024}static{this._MAX_FILE_SIZE_TO_CACHE=1024*1024}static{this.BinaryExtensions=new Set([".png",".jpg",".jpeg",".gif",".ico",".webp",".bmp",".tiff",".tif",".woff",".woff2",".ttf",".otf",".eot",".mp3",".wav",".ogg",".m4a",".mp4",".webm",".ogv",".avi",".mov",".zip",".tar",".gz",".7z",".rar",".pdf",".doc",".docx",".xls",".xlsx",".ppt",".pptx"])}static get MAX_CACHE_SIZE(){return ue.number("MAX_CACHE_SIZE")??this._MAX_CACHE_SIZE}static get MAX_FILE_SIZE_TO_CACHE(){return ue.number("MAX_FILE_SIZE_TO_CACHE")??this._MAX_FILE_SIZE_TO_CACHE}};import De from"node:path";import de from"node:fs";import{Arguments as ge}from"@papit/arguments";import{Terminal as $e}from"@papit/terminal";async function he(e,t,o){return new Promise((i,r)=>{let s=y.BinaryExtensions.has(De.extname(e))?de.createReadStream(e,{signal:o}):de.createReadStream(e,{signal:o,encoding:"utf-8"});s.pipe(t),s.on("error",a=>{ge.error&&$e.error("streaming error",e),ge.verbose&&console.trace(a),r(new b(a.message))}),s.on("close",i)})}function H(e,t,o,i){if(!V.existsSync(e.absolute))throw new b(`${e.relative} not found`);let r=We.extname(e.absolute),n=V.statSync(e.absolute);if(!t.isCacheable(n.size,r))return he(e.absolute,o,i),"streamed";let s=y.MimeTypes[r]??"text/plain",a=V.readFileSync(e.absolute),m={mimeType:s,buffer:a,mtime:n.mtimeMs};return Je.has("no-cache")&&t.add(e,a,s,m.mtime),m}function ye(e,t,o){let r=L.relative(e,t).split(L.sep);for(;r.length>0;){let n=L.join(L.sep+r.join(L.sep));o[n]||(o[n]=[]),o[n].push(t),r.shift()}}async function be(e,t,o,i,r,n){let s=L.normalize(e);if(t.map[s]){let m=t.map[s];if(m)return{mimeType:"application/json",buffer:Buffer.from(JSON.stringify(t.data[m]))}}let a=[...o[s]];for(;a.length>0;){let m=a.pop();try{return H({absolute:L.normalize(m),relative:s},i,r,n)}catch{}}throw new b(`asset "${s}" not found`)}import{Arguments as xe}from"@papit/arguments";function ve(){let e=["asset","assets","public"];if(xe.has("asset")){let t=xe.get("asset");e.push(...t)}return e}var Ge=new Set(["node_modules",".git",".temp","lib","dist","src","explorer-icons"]);async function q(e,t,o,i){let r=we(e,(n,s,a)=>{if(Ge.has(n))return!1;if(!a){if(Y.dirname(s)===e)return!1;let m=s.split(Y.sep);if(!i.some(p=>m.includes(p)))return!1}return!0});for(let n of r)fe(n)?le(e,n,t):ye(e,n,o)}function we(e,t,o=0){if(!Q.existsSync(e)||o>10)return[];let i=[],r=Q.readdirSync(e);for(let n of r){let s=Y.join(e,n),m=Q.statSync(s).isDirectory();t&&!t(n,s,m)||(m?i.push(...we(s,t,o+1)):i.push(s))}return i}import bt from"node:http";import ae from"node:fs";import x from"node:path";import xt from"chokidar";import{Information as R}from"@papit/information";import{Arguments as f}from"@papit/arguments";import{Terminal as d}from"@papit/terminal";import Re from"node:path";import oe from"node:fs";import J from"node:path";import Te from"node:fs";import{Document as Ve}from"@papit/html";import{Arguments as Qe}from"@papit/arguments";import{Terminal as Ye}from"@papit/terminal";import{Document as Xe}from"@papit/html";import Ze from"node:path";import ee from"node:fs";import{Arguments as Se}from"@papit/arguments";import{Terminal as Ke}from"@papit/terminal";function W(e,t){let o=new Xe,i=`${e}-template`,r=Ze.join(t,"asset","templates",e,"index.html"),n=Se.string(i);if(n&&ee.existsSync(n)&&(r=n),!ee.existsSync(r))return Se.error&&Ke.error(`could not find ${e} template html file`),o.innerHTML='<!doctype html><html lang="en"><head><meta charset="utf-8" /><meta name="viewport" content="width=device-width, initial-scale=1" /><title>@papit/server</title><meta name="description" content="Development server" /><meta name="color-scheme" content="light dark" /></head><body>Llama Trauma Baby Mama</body></html>',o;let s=ee.readFileSync(r,{encoding:"utf-8"});return o.innerHTML=s,o}function ke(e,t,o,i){let r=W("explorer",i);r.title=e.packageJSON.name;let n=Qe.string("explorer-spritesheet")??J.join(i,"asset/icons/explorer-spritesheet.svg"),s=Te.readFileSync(n,{encoding:"utf-8"}),a=new Ve;a.innerHTML=s,a.documentElement||(Ye.error("something went wrong loading explorer icon spritesheet"),process.exit(1)),a.documentElement.setAttribute("style","display:none"),r.body?.appendChild(a.documentElement);let m=r.querySelector("[data-location]"),p=J.relative(e.location,o.absolute);p?m.innerHTML=p:m.parentElement?.removeChild(m);let c=r.querySelector("ul[data-folders]"),u=r.querySelector("ul[data-files]");return o.relative!==""&&(c.innerHTML='<li class="hidden"><a href=".."><svg><use href="#folder" /></svg><span class="name">..</span></a></li>'),t.sort((l,S)=>l.localeCompare(S)).forEach(l=>{let S=J.join(o.absolute,l),_=Te.statSync(S),v=r.createElement("li");v.innerHTML=`<a href="${l}"><svg><use href="" /></svg><span class="name">${l}</span></a>`;let h=v.querySelector("a"),T=h.querySelector("use");if(!l.startsWith(".env")&&!l.startsWith(".git")&&l.startsWith(".")&&v.classList.add("hidden"),_.isFile()){T?.setAttribute("href","#"+qe(S,r)),u.appendChild(v);return}_.isDirectory()&&(T?.setAttribute("href","#"+et(S,r)),h.setAttribute("href",l+"/"),c.appendChild(v))}),r}function qe(e,t){let o=J.basename(e),i=o.split(".");o.startsWith(".")&&i.shift();let r=i.at(0)??o,n;if(o.startsWith(".git")||/\.git/.test(e))n="git";else if(o==="package.json")n="package";else if(o.startsWith("tsconfig"))n="tsconfig";else if(r.startsWith("eslint"))n="eslint";else if(/translation/.test(e)){if(t.querySelector("symbol#"+r))return r;n="language"}else/\.vscode/.test(e)&&(n="vscode");if(t.querySelector("symbol#"+n))return n;let s=i.slice(i.length-2).join("_");if(t.querySelector("symbol#"+s))return s;let a=i.pop()??o;return t.querySelector("symbol#"+a)?a:"file"}function et(e,t){return"folder"}import tt from"node:fs";import{Document as ot,Element as rt}from"@papit/html";import{Terminal as Ee}from"@papit/terminal";function Ce(e,t,o,i){let r=W("live",i);r.body||(Ee.error("live document template is missing body"),process.exit(1)),r.head||(Ee.error("live document template is missing head"),process.exit(1));let n=new ot,s=tt.readFileSync(t.absolute,{encoding:"utf-8"});if(n.innerHTML=s,n.head&&[...n.head.childNodes].forEach(c=>nt(c,r.head)),n.body&&[...n.body.childNodes].forEach(c=>r.body?.appendChild(c)),n.body?.classList)for(let c of n.body?.classList)r.body.classList.add(c);if(n.body?.attributes)for(let c in n.body?.attributes){if(c==="class"||n.body.hasAttribute(c))continue;let u=n.body.getAttribute(c);u===!0?n.body.toggleAttribute(c):n.body.setAttribute(c,u)}let a=r.head.querySelector("script"),m=r.head.querySelector('script[type="importmap"]');m||(m=r.createElement("script"),m.setAttribute("type","importmap"));let p=JSON.parse(m.textContent||"{}");return p.imports||(p.imports={}),p.imports={...p.imports,...o.imports},m.textContent=JSON.stringify(p),a?a!==m&&r.head.insertBefore(m,a):r.head.appendChild(m),r}function nt(e,t){if(e instanceof rt){let o=`${e.tagName}${e.className?"."+e.className:""}${e.id?"#"+e.id:""}${Array.from(e.attributes).map(([r,n])=>`[${r}${typeof n=="string"?`="${n}"`:""}]`).join("")}`,i=t.querySelector(o);if(i){t.replaceChild(e,i);return}}t.appendChild(e)}import{fileURLToPath as it}from"node:url";import g from"node:path";import P from"node:fs";import{Information as E,PackageGraph as st}from"@papit/information";import{Arguments as at}from"@papit/arguments";function U(e){let t=g.relative(E.root.location,g.resolve(e));return t===""||t!==".."&&!t.startsWith(".."+g.sep)&&!g.isAbsolute(t)}function te(e){process.platform==="win32"&&e.url&&/^\/[A-Za-z]:/.test(e.url)&&(e.url=e.url.slice(1).replace(/\//g,"\\"));let o=(()=>{if(e.url&&U(e.url)&&P.existsSync(e.url)&&P.statSync(e.url).isFile())return{absolute:e.url,relative:g.relative(e.url,E.package.location)};let i=[at.string("folder"),e.url].filter(s=>s!==void 0),r=[E.local,E.package.location,E.root.location];for(let s of r){let a=g.join(s,...i);if(U(a)&&P.existsSync(a))return{absolute:a,relative:g.relative(s,a)||g.relative(E.package.location,E.local)||g.sep}}let n=g.join(E.package.location,e.url??g.sep);if(!U(n))throw new $(`"${e.url}" is outside the served root`);return{absolute:n,relative:e.url??g.sep}})();return o.absolute.endsWith(g.sep)&&(o.absolute=o.absolute.slice(0,o.absolute.length-1)),{absolute:g.normalize(o.absolute),relative:g.normalize(o.relative)}}function Ae(e){let o=it(e);for(let i=0;i<5;i++)if(o=g.dirname(o),!!P.existsSync(g.join(o,"package.json")))return o;return null}function ct(e){let t=e;for(;t!=="/"&&!P.existsSync(g.join(t,"package.json"));)t=g.dirname(t);return t}function C(e){let t=ct(e.absolute);if(!t)throw new z(`could not find package at 1: ${t}`);let o=st.search(t);if(!o)throw new z(`could not find package at 2: ${t}`);return o}async function Le(e,t,o,i,r){let n=C(e),s=e.absolute.endsWith(".html")?e:{absolute:Re.join(e.absolute,"index.html"),relative:Re.join(e.relative,"index.html")},a,m=null;if(oe.existsSync(s.absolute))m=oe.statSync(s.absolute).mtimeMs,a=Ce(n,s,o,i);else{let p=oe.readdirSync(e.absolute);a=ke(n,p,e,i)}return r.add(e,Buffer.from(a.innerHTML,"utf8"),y.MimeTypes[".html"],m),a}import mt from"node:fs";import{jsBundle as pt}from"@papit/bundle-js";import{Arguments as lt}from"@papit/arguments";async function je(e,t){let o=C(e),i;if(await pt(lt.instance,o.location,{entryPointArray:[{input:e.absolute,output:void 0}],tsconfig:o?.tsconfig,externals:o?.externals,packageJSON:o?.packageJSON,esoptions:{write:!1}},r=>{r.type==="build"&&(i=r.result.outputFiles?.at(0)?.text)}),!i)throw new b("file not found: "+e.relative);return t.add(e,Buffer.from(i,"utf8"),y.MimeTypes[".js"],mt.statSync(e.absolute)?.mtimeMs??null),i}import re from"node:fs";import{Arguments as ne}from"@papit/arguments";import{Terminal as F}from"@papit/terminal";var N=class{constructor(t){this.map=new Map;this._size=0;this.name="cache";this._maxSize=y.MAX_FILE_SIZE_TO_CACHE;t&&(this.name=t)}get size(){return this._size}get maxSize(){return this._maxSize}set maxSize(t){this._maxSize=t*1024*1024}get(t){let o=this.map.get(t.absolute);return!o||!re.existsSync(t.absolute)?null:o.mtime===null||re.statSync(t.absolute).mtimeMs===o.mtime?o:(this.delete(t),null)}delete(t,o=!1){let i=this.map.get(t.absolute);i&&(ne.verbose&&!o&&F.write(F.yellow(t.relative),"removed from cache:"+F.blue(this.name)),this._size-=i.buffer.length,this.map.delete(t.absolute))}clear(){this.map.clear(),this._size=0}add(t,o,i,r){ne.has("no-cache")||(this.delete(t,!0),this._size+=o.length,ne.verbose&&F.write(F.yellow(t.relative),"added to cache:"+F.blue(this.name)),this.map.set(t.absolute,{mimeType:i??y.MimeTypes[t.absolute]??"text/plain",buffer:o,mtime:r===void 0?re.statSync(t.absolute).mtimeMs:r}))}isCacheable(t,o){return!(t>this.maxSize||[".mp4",".webm",".ogv",".avi",".mov"].includes(o))}};import{createHash as ft}from"node:crypto";import Ie from"node:path";import{Arguments as ie}from"@papit/arguments";import{Terminal as O}from"@papit/terminal";import{Information as G,PackageGraph as ut}from"@papit/information";var j=new Map;function _e(e,t,o){let i=e.headers["sec-websocket-key"],n=["HTTP/1.1 101 Switching Protocols","Upgrade: websocket","Connection: Upgrade",`Sec-WebSocket-Accept: ${ft("sha1").update(i+"258EAFA5-E914-47DA-95CA-C5AB0DC85B11").digest("base64")}`];t.write(n.join(`\r
|
|
3
3
|
`)+`\r
|
|
4
4
|
\r
|
|
5
|
-
`),
|
|
5
|
+
`),ie.info&&O.write(O.blue("client connected")),t.on("end",()=>j.delete(t)),t.on("close",()=>j.delete(t)),t.on("error",s=>{s.code==="ECONNRESET"&&j.delete(t)}),t.on("data",s=>{try{let a=dt(s);switch(a.opcode){case 1:let m=a.payload.toString("utf8");try{let c=JSON.parse(m);switch(c.type){case"register":{let u=Ie.join(G.root.location,c.location);if(!U(u))break;let l=C({relative:c.location,absolute:u});l.name===G.root.name&&(l=G.package),j.set(t,l);break}}}catch{}break;case 8:t.end();break;case 9:let p=Fe({type:"pong"});t.write(p);break;default:console.log("Unknown opcode:",a.opcode)}}catch(a){console.error("Error parsing WebSocket frame:",a)}})}function se(e){try{if(j.size===0){ie.verbose&&O.write("No clients connected to send update!");return}let t=Fe({action:"update",filename:"/"+Ie.relative(G.root.location,e.location)});j.forEach((o,i)=>{if(!(o.name!==e.name&&!ut.getDescendants(e.name).some(n=>n.name===o.name))){if(!i||!i.writable){ie.verbose&&O.error(O.blue("socket"),"[error] could not find client"),j.delete(i);return}i.write(t)}})}catch(t){console.log("[socket error]",t)}}function Fe(e){let t=Buffer.from(JSON.stringify(e),"utf8"),o=t.length,i=2;o>125&&o<=65535?i+=2:o>65535&&(i+=8);let r=Buffer.alloc(i+o);r[0]=129;let n=2;return o<=125?r[1]=o:o<=65535?(r[1]=126,r.writeUInt16BE(o,n),n+=2):(r[1]=127,r.writeBigUInt64BE(BigInt(o),n),n+=8),t.copy(r,n),r}function dt(e){let t=e[0],o=e[1],i=(t&128)!==0,r=t&15,n=(o&128)!==0,s=o&127,a=2;if(s===126?(s=e.readUInt16BE(a),a+=2):s===127&&(s=Number(e.readBigUInt64BE(a)),a+=8),!n)throw new Error("Expected masked frame from client");let m=e.slice(a,a+4);a+=4;let p=e.slice(a,a+s),c=Buffer.alloc(s);for(let u=0;u<s;u++)c[u]=p[u]^m[u%4];return{opcode:r,payload:c}}import gt from"node:net";import{Terminal as ht}from"@papit/terminal";function yt(e,t="0.0.0.0"){return new Promise(o=>{let i=gt.createServer().once("error",()=>o(!1)).once("listening",()=>{i.close(()=>o(!0))}).listen(e,t)})}async function Ne(e,t=20){for(let o=0;o<t;o++){let i=e+o;if(await yt(i))return i}ht.error(`No free ports found in range [${e}, ${e+t}]`),process.exit(1)}import{build as vt}from"@papit/build";var A=f.number("port")||3e3,M=null;function Me(e,t,o,i,r){return A=f.number("port")||3e3,new Promise(async n=>{A=await Ne(A),M=bt.createServer();let s=new N("file");s.maxSize=f.number("cache-file")??50;let a=new N("html");a.maxSize=f.number("cache-html")??50;let m=new N("bundle");m.maxSize=f.number("cache-bundle")??150,f.has("live")&&St(),R.packageName!=="@papit/server"&&!f.has("serve")&&(f.info&&d.write(d.blue("listening to file changes"),R.package.name),f.set("no-bundle",!0),f.set("live",!0),f.set("location",R.package.location),f.set("mode","dev"),f.set("buildMode","ancestors")),M.listen(A,()=>{if(f.set("port",A),f.silent||d.write("server:",d.blue(A),d.yellow("- running")),f.has("open")){let p=x.join(`http://localhost:${A}`,x.relative(R.root.location,R.package.location)),c=x.join(p,f.string("open")??f.string("folder")??"");switch(process.platform){case"win32":d.execute(`start "${c}"`,p);break;case"darwin":d.execute(`open "${c}"`,p);break;case"linux":d.execute(`xdg-open "${c}"`,p);break}}n()}),M.on("request",async(p,c)=>{try{if(p.method!=="GET")throw c.setHeader("Allow","GET"),new D;if(p.url?.startsWith("/.well-known"))return c.end("ok");p.url?.endsWith("/favicon.ico")&&(p.url="/favicon.svg");try{let h=await be(p.url,t,o,s,c);if(h==="streamed")return;c.statusCode=200,c.setHeader("Content-Type",h.mimeType),c.end(h.buffer);return}catch{}let u=p.url?.split("@")?.at(1);if(u){let h=r.get("@"+u);if(h){let T=H({absolute:x.normalize(h),relative:x.normalize(x.relative(R.root.location,h))},s,c);if(T==="streamed")return;c.statusCode=200,c.setHeader("Content-Type",T.mimeType),c.end(T.buffer);return}}let l=te(p),S=ae.statSync(l.absolute);if(S.isDirectory()){let h=x.join(l.absolute,"index.html");ae.existsSync(h)&&(l.absolute=h,l.relative=x.join(l.relative,"index.html"))}let _=a.get(l)??m.get(l)??s.get(l);if(_)return f.info&&d.write(d.yellow(l.relative),"found in cache"),c.statusCode=200,c.setHeader("Content-Type",_.mimeType),c.setHeader("X-Cache","HIT"),c.end(_.buffer);if(c.setHeader("X-Cache","MISS"),S.isDirectory()||x.extname(l.absolute)===".html"){if(p.headers["x-router"]){let T=ae.readFileSync(l.absolute,{encoding:"utf-8"});c.statusCode=200,c.setHeader("Content-Type","text/html"),c.end(T);return}let h=await Le(l,o,i,e,a);c.statusCode=200,f.has("prod")||c.setHeader("Cache-Control","no-store"),c.end(h.outerHTML);return}if(/\.tsx?/.test(l.absolute)&&(p.headers.referer?.endsWith(".js")||p.headers["sec-fetch-dest"]==="script")){let h=await je(l,m);c.statusCode=200,c.setHeader("Content-Type","text/javascript"),c.end(h);return}let v=H(l,s,c);if(v==="streamed")return;c.statusCode=200,c.setHeader("Content-Type",v.mimeType),c.end(v.buffer)}catch(u){wt(u,c)}}),M.on("error",p=>{f.error&&d.error(p.name,p.message,p.stack??"")}),M.on("upgrade",_e)})}function Be(){M?.close(),f.silent||d.write("server:",d.blue(String(A)),d.yellow("- shutdown"))}function wt(e,t){f.error&&console.trace("[SERVER]",e),e instanceof k?t.statusCode=e.status:t.statusCode=500,typeof e=="string"?t.write(e):e&&typeof e=="object"&&"message"in e?t.write(e.message):t.write("something went wrong"),t.end()}function St(){let e=xt.watch(R.root.location,{ignored:r=>r.includes("/node_modules/")||r.includes("/.temp/")||r.includes("/.vscode/")||r.includes("/.github/")||r.includes("/.git/")||r.includes("/lib/")||/\/tests?\//.test(r),persistent:!0,followSymlinks:!1}),t=!1;e.on("ready",()=>{t=!0});let o=!1,i=async r=>{o=!0;try{await vt(f.instance,r,(n,s)=>{s==="success"?(f.info&&d.write(d.blue("rebuilt"),r.name),se(r)):s==="skipped"?f.info&&d.write(d.blue("skipped"),r.name):f.info&&d.error(r.name)})}catch(n){f.error&&d.error(n)}finally{o=!1}};e.on("all",(r,n,s)=>{if(!t||o)return;let a={absolute:n,relative:x.relative(R.root.location,n)},m=C(a);a.relative.includes(m.sourceFolder+"/")?i(m):se(m),f.debug&&console.log("SERVER LIVE RELOAD",{url:a,package:{name:m.name,location:m.location,src:m.sourceFolder},includes:a.relative.includes(m.sourceFolder+"/")})})}import X from"node:fs";import I from"node:path";import{Information as Z}from"@papit/information";import{pathToFileURL as Tt}from"node:url";function ze(e,t,o){ce(e.name,e.location,e.packageJSON,t);for(let i in e.packageJSON.dependencies){if(i.startsWith(Z.scope)||["chokidar","esbuild","@microsoft/api-extractor","typescript","playwright"].includes(i))continue;let r=I.join(Z.root.location,"node_modules",i),n=I.join(r,"package.json");if(!X.existsSync(n))continue;let s=JSON.parse(X.readFileSync(n,{encoding:"utf-8"}));ce(i,r,s,t,!0)}for(let i in e.packageJSON.devDependencies){if(i.startsWith(Z.scope)||["chokidar","esbuild","@microsoft/api-extractor","typescript","playwright"].includes(i))continue;let r=I.join(Z.root.location,"node_modules",i),n=I.join(r,"package.json");if(!X.existsSync(n))continue;let s=JSON.parse(X.readFileSync(n,{encoding:"utf-8"}));ce(i,r,s,t,!0)}}function ce(e,t,o,i,r=!1){let n=(s,a)=>{i.imports[s]||(i.imports[s]=Tt(a).pathname)};if(o.exports)if(typeof o.exports=="string")n(e,I.resolve(t,o.exports));else for(let s in o.exports){let a=o.name;s!=="."&&s!=="default"&&(a+="/"+s.replace(/^\.?\/?/,""));let m=typeof o.exports[s]=="string"?o.exports[s]:o.exports[s]?.import;m&&n(a,I.resolve(t,m))}o.main&&n(e,I.resolve(t,o.main))}async function kt(){let e=Ae(import.meta.url);e==null&&(He.error("script location of @papit/server is missing"),process.exit(1)),w.package.packageJSON||(He.error("location is not a package, missing package.json"),process.exit(1));let o={data:{},map:{}},i={},r=ve();await q(e,o,i,r);let n={imports:{}},s=new Map,a=null;w.root.location===w.package.location?a=me.join(w.root.location,"node_modules"):a=me.join(w.package.location,K.string("import-map")??".temp/dependencies");let m=!1;a&&!pe.existsSync(a)&&(m=!0,pe.mkdirSync(a,{recursive:!0})),w.package.location!==w.root.location&&K.set("ancestors",!0);let p=w.getBatches();for(let c of p)for(let u of c){if(u.packageJSON.papit.type==="theme"){let l=u.entrypoints.entries.theme?.import?.output??u.entrypoints.entries.bundle?.import?.output;l&&s.set(u.name,l);continue}a&&ze(u,n,a),!(!K.has("include-node")&&u.packageJSON.papit.type==="node")&&await q(u.location,o,i,r)}return{importmap:n,importmapFolder:a,createdImportMapFolder:m,serverPackageLocation:e,translations:o,assets:i,themes:s}}async function Pe(){let{importmap:e,importmapFolder:t,createdImportMapFolder:o,serverPackageLocation:i,translations:r,assets:n,themes:s}=await kt(),a=()=>{t&&o&&!K.has("import-map")&&pe.rmSync(me.join(w.package.location,".temp"),{force:!0,recursive:!0}),console.log(),Be(),process.exit(0)};process.on("SIGINT",a),process.on("SIGTERM",a),process.on("SIGHUP",a),await Me(i,r,n,e,s)}(async function(){Pe()})();
|
package/lib/bundle.d.ts
CHANGED
|
@@ -1,16 +1,47 @@
|
|
|
1
1
|
import { Duplex } from 'node:stream';
|
|
2
2
|
import http from 'node:http';
|
|
3
|
+
import { IncomingMessage } from 'node:http';
|
|
3
4
|
import { PackageNode } from '@papit/information';
|
|
4
5
|
|
|
6
|
+
/** Stops the http server. */
|
|
5
7
|
declare function close_2(): void;
|
|
6
8
|
export { close_2 as close }
|
|
7
9
|
|
|
8
10
|
export declare function error(filename: string, errors: any[]): void;
|
|
9
11
|
|
|
12
|
+
/**
|
|
13
|
+
* Resolves a request to a file or folder: an absolute path inside the workspace, else the path
|
|
14
|
+
* under the current folder, the package, then the workspace root.
|
|
15
|
+
* @throws ForbiddenError (403) when the path resolves outside the workspace root
|
|
16
|
+
*/
|
|
17
|
+
export declare function getURL(request: IncomingMessage): {
|
|
18
|
+
absolute: string;
|
|
19
|
+
relative: string;
|
|
20
|
+
};
|
|
21
|
+
|
|
22
|
+
declare type Importmap = {
|
|
23
|
+
imports: Record<string, string>;
|
|
24
|
+
};
|
|
25
|
+
|
|
26
|
+
export declare function meta(): Promise<{
|
|
27
|
+
importmap: Importmap;
|
|
28
|
+
importmapFolder: string;
|
|
29
|
+
createdImportMapFolder: boolean;
|
|
30
|
+
serverPackageLocation: string;
|
|
31
|
+
translations: Translations;
|
|
32
|
+
assets: Record<string, string[]>;
|
|
33
|
+
themes: Map<string, string>;
|
|
34
|
+
}>;
|
|
35
|
+
|
|
36
|
+
/** The running http server, `null` until `start` is called. */
|
|
10
37
|
export declare let server: null | http.Server;
|
|
11
38
|
|
|
12
39
|
export declare function setup(): Promise<void>;
|
|
13
40
|
|
|
41
|
+
/**
|
|
42
|
+
* Starts the http server on `--port` (default 3000, or the next free port) and resolves once it listens.
|
|
43
|
+
* With `--live` it also watches the workspace and rebuilds changed packages.
|
|
44
|
+
*/
|
|
14
45
|
export declare function start(serverPackageLocation: string, translations: Translations, assets: Record<string, string[]>, importmap: {
|
|
15
46
|
imports: Record<string, string>;
|
|
16
47
|
}, themes: Map<string, string>): Promise<void>;
|
|
@@ -28,8 +59,10 @@ declare type Translations = {
|
|
|
28
59
|
map: Record<string, string>;
|
|
29
60
|
};
|
|
30
61
|
|
|
62
|
+
/** Tells every page registered for `node`, or for a package depending on it, to reload. */
|
|
31
63
|
export declare function update(node: PackageNode): void;
|
|
32
64
|
|
|
65
|
+
/** WebSocket handshake for the live reload client; bound as the server's `upgrade` handler. */
|
|
33
66
|
export declare function upgrade(this: http.Server, req: http.IncomingMessage, socket: Duplex, head: Buffer): void;
|
|
34
67
|
|
|
35
68
|
export { }
|
package/lib/bundle.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import ne from"node:path";import ie from"node:fs";import{Arguments as D}from"@papit/arguments";import{Terminal as ze}from"@papit/terminal";import{Information as T,PackageGraph as wt}from"@papit/information";import K from"node:path";import Z from"node:fs";import Be from"node:fs";import z from"node:path";import{deepMergeTwo as He}from"@papit/deep-merge";function se(e,o,t){let i=JSON.parse(Be.readFileSync(o,{encoding:"utf-8"})),r=i?.meta?.language??z.basename(o,".json");t.data[r]||(t.data[r]={meta:i.meta}),t.data[r]=He(t.data[r],i,["meta"]);let s=z.relative(e,o).split(z.sep);for(;s.length>0;){let a="/"+s.join("/");t.map[a]=r,s.shift()}}function ae(e){if(!e.endsWith(".json"))return!1;let o=z.basename(z.dirname(e));return/^(transl|locale|i18)/i.test(o)}import j from"node:path";var L=class extends Error{constructor(o,t){super(o,t),this.name="http-error"}},B=class extends L{constructor(o,t){super(o??"internal server error",t),this.name="Internal Server Error",this.status=500}},x=class extends L{constructor(o,t){super(o??"not found",t),this.name="Not Found",this.status=404}},$=class extends L{constructor(o,t){super(o??"method not allowed",t),this.name="Method not allowed",this.status=405}};import X from"node:fs";import Oe from"node:path";import{Arguments as De}from"@papit/arguments";import{Arguments as ce}from"@papit/arguments";var y=class{static{this.MimeTypes={".html":"text/html",".htm":"text/html",".css":"text/css",".js":"text/javascript",".mjs":"text/javascript",".ts":"text/typescript",".tsx":"text/typescript",".jsx":"text/javascript",".json":"application/json",".xml":"application/xml",".txt":"text/plain",".md":"text/markdown",".markdown":"text/markdown",".csv":"text/csv",".pdf":"application/pdf",".doc":"application/msword",".docx":"application/vnd.openxmlformats-officedocument.wordprocessingml.document",".xls":"application/vnd.ms-excel",".xlsx":"application/vnd.openxmlformats-officedocument.spreadsheetml.sheet",".ppt":"application/vnd.ms-powerpoint",".pptx":"application/vnd.openxmlformats-officedocument.presentationml.presentation",".png":"image/png",".jpg":"image/jpeg",".jpeg":"image/jpeg",".gif":"image/gif",".svg":"image/svg+xml",".webp":"image/webp",".ico":"image/x-icon",".bmp":"image/bmp",".tiff":"image/tiff",".tif":"image/tiff",".woff":"font/woff",".woff2":"font/woff2",".ttf":"font/ttf",".otf":"font/otf",".eot":"application/vnd.ms-fontobject",".mp3":"audio/mpeg",".wav":"audio/wav",".ogg":"audio/ogg",".m4a":"audio/mp4",".mp4":"video/mp4",".webm":"video/webm",".ogv":"video/ogg",".avi":"video/x-msvideo",".mov":"video/quicktime",".zip":"application/zip",".tar":"application/x-tar",".gz":"application/gzip",".7z":"application/x-7z-compressed",".rar":"application/vnd.rar"}}static{this._MAX_CACHE_SIZE=50*1024*1024}static{this._MAX_FILE_SIZE_TO_CACHE=1024*1024}static{this.BinaryExtensions=new Set([".png",".jpg",".jpeg",".gif",".ico",".webp",".bmp",".tiff",".tif",".woff",".woff2",".ttf",".otf",".eot",".mp3",".wav",".ogg",".m4a",".mp4",".webm",".ogv",".avi",".mov",".zip",".tar",".gz",".7z",".rar",".pdf",".doc",".docx",".xls",".xlsx",".ppt",".pptx"])}static get MAX_CACHE_SIZE(){return ce.number("MAX_CACHE_SIZE")??this._MAX_CACHE_SIZE}static get MAX_FILE_SIZE_TO_CACHE(){return ce.number("MAX_FILE_SIZE_TO_CACHE")??this._MAX_FILE_SIZE_TO_CACHE}};import Pe from"node:path";import me from"node:fs";import{Arguments as pe}from"@papit/arguments";import{Terminal as Ue}from"@papit/terminal";async function le(e,o,t){return new Promise((i,r)=>{let s=y.BinaryExtensions.has(Pe.extname(e))?me.createReadStream(e,{signal:t}):me.createReadStream(e,{signal:t,encoding:"utf-8"});s.pipe(o),s.on("error",a=>{pe.error&&Ue.error("streaming error",e),pe.verbose&&console.trace(a),r(new x(a.message))}),s.on("close",i)})}function H(e,o,t,i){if(!X.existsSync(e.absolute))throw new x(`${e.relative} not found`);let r=Oe.extname(e.absolute),n=X.statSync(e.absolute);if(!o.isCacheable(n.size,r))return le(e.absolute,t,i),"streamed";let s=y.MimeTypes[r]??"text/plain",a=X.readFileSync(e.absolute),m={mimeType:s,buffer:a,mtime:n.mtimeMs};return De.has("no-cache")&&o.add(e,a,s,m.mtime),m}function fe(e,o,t){let r=j.relative(e,o).split(j.sep);for(;r.length>0;){let n=j.join(j.sep+r.join(j.sep));t[n]||(t[n]=[]),t[n].push(o),r.shift()}}async function ue(e,o,t,i,r,n){let s=j.normalize(e);if(o.map[s]){let m=o.map[s];if(m)return{mimeType:"application/json",buffer:Buffer.from(JSON.stringify(o.data[m]))}}let a=[...t[s]];for(;a.length>0;){let m=a.pop();try{return H({absolute:j.normalize(m),relative:s},i,r,n)}catch{}}throw new x(`asset "${s}" not found`)}import{Arguments as de}from"@papit/arguments";function ge(){let e=["asset","assets","public"];if(de.has("asset")){let o=de.get("asset");e.push(...o)}return e}var $e=new Set(["node_modules",".git",".temp","lib","dist","src","explorer-icons"]);async function V(e,o,t,i){let r=he(e,(n,s,a)=>{if($e.has(n))return!1;if(!a){if(K.dirname(s)===e)return!1;let m=s.split(K.sep);if(!i.some(p=>m.includes(p)))return!1}return!0});for(let n of r)ae(n)?se(e,n,o):fe(e,n,t)}function he(e,o,t=0){if(!Z.existsSync(e)||t>10)return[];let i=[],r=Z.readdirSync(e);for(let n of r){let s=K.join(e,n),m=Z.statSync(s).isDirectory();o&&!o(n,s,m)||(m?i.push(...he(s,o,t+1)):i.push(s))}return i}import gt from"node:http";import re from"node:fs";import w from"node:path";import ht from"chokidar";import{Information as R}from"@papit/information";import{Arguments as f}from"@papit/arguments";import{Terminal as d}from"@papit/terminal";import Ee from"node:path";import Y from"node:fs";import G from"node:path";import be from"node:fs";import{Document as Xe}from"@papit/html";import{Arguments as Ze}from"@papit/arguments";import{Terminal as Ke}from"@papit/terminal";import{Document as We}from"@papit/html";import Ge from"node:path";import Q from"node:fs";import{Arguments as ye}from"@papit/arguments";import{Terminal as Je}from"@papit/terminal";function W(e,o){let t=new We,i=`${e}-template`,r=Ge.join(o,"asset","templates",e,"index.html"),n=ye.string(i);if(n&&Q.existsSync(n)&&(r=n),!Q.existsSync(r))return ye.error&&Je.error(`could not find ${e} template html file`),t.innerHTML='<!doctype html><html lang="en"><head><meta charset="utf-8" /><meta name="viewport" content="width=device-width, initial-scale=1" /><title>@papit/server</title><meta name="description" content="Development server" /><meta name="color-scheme" content="light dark" /></head><body>Llama Trauma Baby Mama</body></html>',t;let s=Q.readFileSync(r,{encoding:"utf-8"});return t.innerHTML=s,t}function xe(e,o,t,i){let r=W("explorer",i);r.title=e.packageJSON.name;let n=Ze.string("explorer-spritesheet")??G.join(i,"asset/icons/explorer-spritesheet.svg"),s=be.readFileSync(n,{encoding:"utf-8"}),a=new Xe;a.innerHTML=s,a.documentElement||(Ke.error("something went wrong loading explorer icon spritesheet"),process.exit(1)),a.documentElement.setAttribute("style","display:none"),r.body?.appendChild(a.documentElement);let m=r.querySelector("[data-location]"),p=G.relative(e.location,t.absolute);p?m.innerHTML=p:m.parentElement?.removeChild(m);let c=r.querySelector("ul[data-folders]"),u=r.querySelector("ul[data-files]");return t.relative!==""&&(c.innerHTML='<li class="hidden"><a href=".."><svg><use href="#folder" /></svg><span class="name">..</span></a></li>'),o.sort((l,b)=>l.localeCompare(b)).forEach(l=>{let b=G.join(t.absolute,l),I=be.statSync(b),S=r.createElement("li");S.innerHTML=`<a href="${l}"><svg><use href="" /></svg><span class="name">${l}</span></a>`;let g=S.querySelector("a"),E=g.querySelector("use");if(!l.startsWith(".env")&&!l.startsWith(".git")&&l.startsWith(".")&&S.classList.add("hidden"),I.isFile()){E?.setAttribute("href","#"+Ve(b,r)),u.appendChild(S);return}I.isDirectory()&&(E?.setAttribute("href","#"+Qe(b,r)),g.setAttribute("href",l+"/"),c.appendChild(S))}),r}function Ve(e,o){let t=G.basename(e),i=t.split(".");t.startsWith(".")&&i.shift();let r=i.at(0)??t,n;if(t.startsWith(".git")||/\.git/.test(e))n="git";else if(t==="package.json")n="package";else if(t.startsWith("tsconfig"))n="tsconfig";else if(r.startsWith("eslint"))n="eslint";else if(/translation/.test(e)){if(o.querySelector("symbol#"+r))return r;n="language"}else/\.vscode/.test(e)&&(n="vscode");if(o.querySelector("symbol#"+n))return n;let s=i.slice(i.length-2).join("_");if(o.querySelector("symbol#"+s))return s;let a=i.pop()??t;return o.querySelector("symbol#"+a)?a:"file"}function Qe(e,o){return"folder"}import Ye from"node:fs";import{Document as qe,Element as et}from"@papit/html";import{Terminal as ve}from"@papit/terminal";function we(e,o,t,i){let r=W("live",i);r.body||(ve.error("live document template is missing body"),process.exit(1)),r.head||(ve.error("live document template is missing head"),process.exit(1));let n=new qe,s=Ye.readFileSync(o.absolute,{encoding:"utf-8"});if(n.innerHTML=s,n.head&&[...n.head.childNodes].forEach(c=>tt(c,r.head)),n.body&&[...n.body.childNodes].forEach(c=>r.body?.appendChild(c)),n.body?.classList)for(let c of n.body?.classList)r.body.classList.add(c);if(n.body?.attributes)for(let c in n.body?.attributes){if(c==="class"||n.body.hasAttribute(c))continue;let u=n.body.getAttribute(c);u===!0?n.body.toggleAttribute(c):n.body.setAttribute(c,u)}let a=r.head.querySelector("script"),m=r.head.querySelector('script[type="importmap"]');m||(m=r.createElement("script"),m.setAttribute("type","importmap"));let p=JSON.parse(m.textContent||"{}");return p.imports||(p.imports={}),p.imports={...p.imports,...t.imports},m.textContent=JSON.stringify(p),a?a!==m&&r.head.insertBefore(m,a):r.head.appendChild(m),r}function tt(e,o){if(e instanceof et){let t=`${e.tagName}${e.className?"."+e.className:""}${e.id?"#"+e.id:""}${Array.from(e.attributes).map(([r,n])=>`[${r}${typeof n=="string"?`="${n}"`:""}]`).join("")}`,i=o.querySelector(t);if(i){o.replaceChild(e,i);return}}o.appendChild(e)}import{fileURLToPath as ot}from"node:url";import h from"node:path";import P from"node:fs";import{Information as _,PackageGraph as rt}from"@papit/information";import{Arguments as nt}from"@papit/arguments";function Se(e){process.platform==="win32"&&e.url&&/^\/[A-Za-z]:/.test(e.url)&&(e.url=e.url.slice(1).replace(/\//g,"\\"));let t=(()=>{if(e.url&&P.existsSync(e.url)&&P.statSync(e.url).isFile())return{absolute:e.url,relative:h.relative(e.url,_.package.location)};let i=[nt.string("folder"),e.url].filter(n=>n!==void 0),r=[_.local,_.package.location,_.root.location];for(let n of r){let s=h.join(n,...i);if(P.existsSync(s))return{absolute:s,relative:h.relative(n,s)||h.relative(_.package.location,_.local)||h.sep}}return{absolute:h.join(_.package.location,e.url??h.sep),relative:e.url??h.sep}})();return t.absolute.endsWith(h.sep)&&(t.absolute=t.absolute.slice(0,t.absolute.length-1)),{absolute:h.normalize(t.absolute),relative:h.normalize(t.relative)}}function Te(e){let t=ot(e);for(let i=0;i<5;i++)if(t=h.dirname(t),!!P.existsSync(h.join(t,"package.json")))return t;return null}function it(e){let o=e;for(;o!=="/"&&!P.existsSync(h.join(o,"package.json"));)o=h.dirname(o);return o}function k(e){let o=it(e.absolute);if(!o)throw new B(`could not find package at 1: ${o}`);let t=rt.search(o);if(!t)throw new B(`could not find package at 2: ${o}`);return t}async function ke(e,o,t,i,r){let n=k(e),s=e.absolute.endsWith(".html")?e:{absolute:Ee.join(e.absolute,"index.html"),relative:Ee.join(e.relative,"index.html")},a,m=null;if(Y.existsSync(s.absolute))m=Y.statSync(s.absolute).mtimeMs,a=we(n,s,t,i);else{let p=Y.readdirSync(e.absolute);a=xe(n,p,e,i)}return r.add(e,Buffer.from(a.innerHTML,"utf8"),y.MimeTypes[".html"],m),a}import st from"node:fs";import{jsBundle as at}from"@papit/bundle-js";import{Arguments as ct}from"@papit/arguments";async function Ce(e,o){let t=k(e),i;if(await at(ct.instance,t.location,{entryPointArray:[{input:e.absolute,output:void 0}],tsconfig:t?.tsconfig,externals:t?.externals,packageJSON:t?.packageJSON,esoptions:{write:!1}},r=>{r.type==="build"&&(i=r.result.outputFiles?.at(0)?.text)}),!i)throw new x("file not found: "+e.relative);return o.add(e,Buffer.from(i,"utf8"),y.MimeTypes[".js"],st.statSync(e.absolute)?.mtimeMs??null),i}import q from"node:fs";import{Arguments as ee}from"@papit/arguments";import{Terminal as F}from"@papit/terminal";var N=class{constructor(o){this.map=new Map;this._size=0;this.name="cache";this._maxSize=y.MAX_FILE_SIZE_TO_CACHE;o&&(this.name=o)}get size(){return this._size}get maxSize(){return this._maxSize}set maxSize(o){this._maxSize=o*1024*1024}get(o){let t=this.map.get(o.absolute);return!t||!q.existsSync(o.absolute)?null:t.mtime===null||q.statSync(o.absolute).mtimeMs===t.mtime?t:(this.delete(o),null)}delete(o,t=!1){let i=this.map.get(o.absolute);i&&(ee.verbose&&!t&&F.write(F.yellow(o.relative),"removed from cache:"+F.blue(this.name)),this._size-=i.buffer.length,this.map.delete(o.absolute))}clear(){this.map.clear(),this._size=0}add(o,t,i,r){ee.has("no-cache")||(this.delete(o,!0),this._size+=t.length,ee.verbose&&F.write(F.yellow(o.relative),"added to cache:"+F.blue(this.name)),this.map.set(o.absolute,{mimeType:i??y.MimeTypes[o.absolute]??"text/plain",buffer:t,mtime:r===void 0?q.statSync(o.absolute).mtimeMs:r}))}isCacheable(o,t){return!(o>this.maxSize||[".mp4",".webm",".ogv",".avi",".mov"].includes(t))}};import{createHash as mt}from"node:crypto";import Ae from"node:path";import{Arguments as U}from"@papit/arguments";import{Terminal as C}from"@papit/terminal";import{Information as J}from"@papit/information";var v=new Map;function Re(e,o,t){let i=e.headers["sec-websocket-key"],n=["HTTP/1.1 101 Switching Protocols","Upgrade: websocket","Connection: Upgrade",`Sec-WebSocket-Accept: ${mt("sha1").update(i+"258EAFA5-E914-47DA-95CA-C5AB0DC85B11").digest("base64")}`];o.write(n.join(`\r
|
|
1
|
+
import pe from"node:path";import le from"node:fs";import{Arguments as V}from"@papit/arguments";import{Terminal as He}from"@papit/terminal";import{Information as S}from"@papit/information";import q from"node:path";import Y from"node:fs";import Pe from"node:fs";import z from"node:path";import{deepMergeTwo as Ue}from"@papit/deep-merge";function fe(e,t,o){let i=JSON.parse(Pe.readFileSync(t,{encoding:"utf-8"})),r=i?.meta?.language??z.basename(t,".json");o.data[r]||(o.data[r]={meta:i.meta}),o.data[r]=Ue(o.data[r],i,["meta"]);let s=z.relative(e,t).split(z.sep);for(;s.length>0;){let a="/"+s.join("/");o.map[a]=r,s.shift()}}function ue(e){if(!e.endsWith(".json"))return!1;let t=z.basename(z.dirname(e));return/^(transl|locale|i18)/i.test(t)}import I from"node:path";var E=class extends Error{constructor(t,o){super(t,o),this.name="http-error"}},H=class extends E{constructor(t,o){super(t??"internal server error",o),this.name="Internal Server Error",this.status=500}},b=class extends E{constructor(t,o){super(t??"not found",o),this.name="Not Found",this.status=404}},$=class extends E{constructor(t,o){super(t??"method not allowed",o),this.name="Method not allowed",this.status=405}},W=class extends E{constructor(t,o){super(t??"forbidden",o),this.name="Forbidden",this.status=403}};import Q from"node:fs";import $e from"node:path";import{Arguments as We}from"@papit/arguments";import{Arguments as de}from"@papit/arguments";var y=class{static{this.MimeTypes={".html":"text/html",".htm":"text/html",".css":"text/css",".js":"text/javascript",".mjs":"text/javascript",".ts":"text/typescript",".tsx":"text/typescript",".jsx":"text/javascript",".json":"application/json",".xml":"application/xml",".txt":"text/plain",".md":"text/markdown",".markdown":"text/markdown",".csv":"text/csv",".pdf":"application/pdf",".doc":"application/msword",".docx":"application/vnd.openxmlformats-officedocument.wordprocessingml.document",".xls":"application/vnd.ms-excel",".xlsx":"application/vnd.openxmlformats-officedocument.spreadsheetml.sheet",".ppt":"application/vnd.ms-powerpoint",".pptx":"application/vnd.openxmlformats-officedocument.presentationml.presentation",".png":"image/png",".jpg":"image/jpeg",".jpeg":"image/jpeg",".gif":"image/gif",".svg":"image/svg+xml",".webp":"image/webp",".ico":"image/x-icon",".bmp":"image/bmp",".tiff":"image/tiff",".tif":"image/tiff",".woff":"font/woff",".woff2":"font/woff2",".ttf":"font/ttf",".otf":"font/otf",".eot":"application/vnd.ms-fontobject",".mp3":"audio/mpeg",".wav":"audio/wav",".ogg":"audio/ogg",".m4a":"audio/mp4",".mp4":"video/mp4",".webm":"video/webm",".ogv":"video/ogg",".avi":"video/x-msvideo",".mov":"video/quicktime",".zip":"application/zip",".tar":"application/x-tar",".gz":"application/gzip",".7z":"application/x-7z-compressed",".rar":"application/vnd.rar"}}static{this._MAX_CACHE_SIZE=50*1024*1024}static{this._MAX_FILE_SIZE_TO_CACHE=1024*1024}static{this.BinaryExtensions=new Set([".png",".jpg",".jpeg",".gif",".ico",".webp",".bmp",".tiff",".tif",".woff",".woff2",".ttf",".otf",".eot",".mp3",".wav",".ogg",".m4a",".mp4",".webm",".ogv",".avi",".mov",".zip",".tar",".gz",".7z",".rar",".pdf",".doc",".docx",".xls",".xlsx",".ppt",".pptx"])}static get MAX_CACHE_SIZE(){return de.number("MAX_CACHE_SIZE")??this._MAX_CACHE_SIZE}static get MAX_FILE_SIZE_TO_CACHE(){return de.number("MAX_FILE_SIZE_TO_CACHE")??this._MAX_FILE_SIZE_TO_CACHE}};import Oe from"node:path";import ge from"node:fs";import{Arguments as he}from"@papit/arguments";import{Terminal as De}from"@papit/terminal";async function ye(e,t,o){return new Promise((i,r)=>{let s=y.BinaryExtensions.has(Oe.extname(e))?ge.createReadStream(e,{signal:o}):ge.createReadStream(e,{signal:o,encoding:"utf-8"});s.pipe(t),s.on("error",a=>{he.error&&De.error("streaming error",e),he.verbose&&console.trace(a),r(new b(a.message))}),s.on("close",i)})}function P(e,t,o,i){if(!Q.existsSync(e.absolute))throw new b(`${e.relative} not found`);let r=$e.extname(e.absolute),n=Q.statSync(e.absolute);if(!t.isCacheable(n.size,r))return ye(e.absolute,o,i),"streamed";let s=y.MimeTypes[r]??"text/plain",a=Q.readFileSync(e.absolute),m={mimeType:s,buffer:a,mtime:n.mtimeMs};return We.has("no-cache")&&t.add(e,a,s,m.mtime),m}function be(e,t,o){let r=I.relative(e,t).split(I.sep);for(;r.length>0;){let n=I.join(I.sep+r.join(I.sep));o[n]||(o[n]=[]),o[n].push(t),r.shift()}}async function xe(e,t,o,i,r,n){let s=I.normalize(e);if(t.map[s]){let m=t.map[s];if(m)return{mimeType:"application/json",buffer:Buffer.from(JSON.stringify(t.data[m]))}}let a=[...o[s]];for(;a.length>0;){let m=a.pop();try{return P({absolute:I.normalize(m),relative:s},i,r,n)}catch{}}throw new b(`asset "${s}" not found`)}import{Arguments as ve}from"@papit/arguments";function we(){let e=["asset","assets","public"];if(ve.has("asset")){let t=ve.get("asset");e.push(...t)}return e}var Je=new Set(["node_modules",".git",".temp","lib","dist","src","explorer-icons"]);async function ee(e,t,o,i){let r=Se(e,(n,s,a)=>{if(Je.has(n))return!1;if(!a){if(q.dirname(s)===e)return!1;let m=s.split(q.sep);if(!i.some(p=>m.includes(p)))return!1}return!0});for(let n of r)ue(n)?fe(e,n,t):be(e,n,o)}function Se(e,t,o=0){if(!Y.existsSync(e)||o>10)return[];let i=[],r=Y.readdirSync(e);for(let n of r){let s=q.join(e,n),m=Y.statSync(s).isDirectory();t&&!t(n,s,m)||(m?i.push(...Se(s,t,o+1)):i.push(s))}return i}import bt from"node:http";import ce from"node:fs";import v from"node:path";import xt from"chokidar";import{Information as j}from"@papit/information";import{Arguments as f}from"@papit/arguments";import{Terminal as d}from"@papit/terminal";import Le from"node:path";import re from"node:fs";import G from"node:path";import ke from"node:fs";import{Document as Ke}from"@papit/html";import{Arguments as Ve}from"@papit/arguments";import{Terminal as Qe}from"@papit/terminal";import{Document as Ge}from"@papit/html";import Xe from"node:path";import te from"node:fs";import{Arguments as Te}from"@papit/arguments";import{Terminal as Ze}from"@papit/terminal";function J(e,t){let o=new Ge,i=`${e}-template`,r=Xe.join(t,"asset","templates",e,"index.html"),n=Te.string(i);if(n&&te.existsSync(n)&&(r=n),!te.existsSync(r))return Te.error&&Ze.error(`could not find ${e} template html file`),o.innerHTML='<!doctype html><html lang="en"><head><meta charset="utf-8" /><meta name="viewport" content="width=device-width, initial-scale=1" /><title>@papit/server</title><meta name="description" content="Development server" /><meta name="color-scheme" content="light dark" /></head><body>Llama Trauma Baby Mama</body></html>',o;let s=te.readFileSync(r,{encoding:"utf-8"});return o.innerHTML=s,o}function Ee(e,t,o,i){let r=J("explorer",i);r.title=e.packageJSON.name;let n=Ve.string("explorer-spritesheet")??G.join(i,"asset/icons/explorer-spritesheet.svg"),s=ke.readFileSync(n,{encoding:"utf-8"}),a=new Ke;a.innerHTML=s,a.documentElement||(Qe.error("something went wrong loading explorer icon spritesheet"),process.exit(1)),a.documentElement.setAttribute("style","display:none"),r.body?.appendChild(a.documentElement);let m=r.querySelector("[data-location]"),p=G.relative(e.location,o.absolute);p?m.innerHTML=p:m.parentElement?.removeChild(m);let c=r.querySelector("ul[data-folders]"),u=r.querySelector("ul[data-files]");return o.relative!==""&&(c.innerHTML='<li class="hidden"><a href=".."><svg><use href="#folder" /></svg><span class="name">..</span></a></li>'),t.sort((l,T)=>l.localeCompare(T)).forEach(l=>{let T=G.join(o.absolute,l),F=ke.statSync(T),w=r.createElement("li");w.innerHTML=`<a href="${l}"><svg><use href="" /></svg><span class="name">${l}</span></a>`;let h=w.querySelector("a"),k=h.querySelector("use");if(!l.startsWith(".env")&&!l.startsWith(".git")&&l.startsWith(".")&&w.classList.add("hidden"),F.isFile()){k?.setAttribute("href","#"+Ye(T,r)),u.appendChild(w);return}F.isDirectory()&&(k?.setAttribute("href","#"+qe(T,r)),h.setAttribute("href",l+"/"),c.appendChild(w))}),r}function Ye(e,t){let o=G.basename(e),i=o.split(".");o.startsWith(".")&&i.shift();let r=i.at(0)??o,n;if(o.startsWith(".git")||/\.git/.test(e))n="git";else if(o==="package.json")n="package";else if(o.startsWith("tsconfig"))n="tsconfig";else if(r.startsWith("eslint"))n="eslint";else if(/translation/.test(e)){if(t.querySelector("symbol#"+r))return r;n="language"}else/\.vscode/.test(e)&&(n="vscode");if(t.querySelector("symbol#"+n))return n;let s=i.slice(i.length-2).join("_");if(t.querySelector("symbol#"+s))return s;let a=i.pop()??o;return t.querySelector("symbol#"+a)?a:"file"}function qe(e,t){return"folder"}import et from"node:fs";import{Document as tt,Element as ot}from"@papit/html";import{Terminal as Ce}from"@papit/terminal";function Ae(e,t,o,i){let r=J("live",i);r.body||(Ce.error("live document template is missing body"),process.exit(1)),r.head||(Ce.error("live document template is missing head"),process.exit(1));let n=new tt,s=et.readFileSync(t.absolute,{encoding:"utf-8"});if(n.innerHTML=s,n.head&&[...n.head.childNodes].forEach(c=>rt(c,r.head)),n.body&&[...n.body.childNodes].forEach(c=>r.body?.appendChild(c)),n.body?.classList)for(let c of n.body?.classList)r.body.classList.add(c);if(n.body?.attributes)for(let c in n.body?.attributes){if(c==="class"||n.body.hasAttribute(c))continue;let u=n.body.getAttribute(c);u===!0?n.body.toggleAttribute(c):n.body.setAttribute(c,u)}let a=r.head.querySelector("script"),m=r.head.querySelector('script[type="importmap"]');m||(m=r.createElement("script"),m.setAttribute("type","importmap"));let p=JSON.parse(m.textContent||"{}");return p.imports||(p.imports={}),p.imports={...p.imports,...o.imports},m.textContent=JSON.stringify(p),a?a!==m&&r.head.insertBefore(m,a):r.head.appendChild(m),r}function rt(e,t){if(e instanceof ot){let o=`${e.tagName}${e.className?"."+e.className:""}${e.id?"#"+e.id:""}${Array.from(e.attributes).map(([r,n])=>`[${r}${typeof n=="string"?`="${n}"`:""}]`).join("")}`,i=t.querySelector(o);if(i){t.replaceChild(e,i);return}}t.appendChild(e)}import{fileURLToPath as nt}from"node:url";import g from"node:path";import U from"node:fs";import{Information as C,PackageGraph as it}from"@papit/information";import{Arguments as st}from"@papit/arguments";function O(e){let t=g.relative(C.root.location,g.resolve(e));return t===""||t!==".."&&!t.startsWith(".."+g.sep)&&!g.isAbsolute(t)}function oe(e){process.platform==="win32"&&e.url&&/^\/[A-Za-z]:/.test(e.url)&&(e.url=e.url.slice(1).replace(/\//g,"\\"));let o=(()=>{if(e.url&&O(e.url)&&U.existsSync(e.url)&&U.statSync(e.url).isFile())return{absolute:e.url,relative:g.relative(e.url,C.package.location)};let i=[st.string("folder"),e.url].filter(s=>s!==void 0),r=[C.local,C.package.location,C.root.location];for(let s of r){let a=g.join(s,...i);if(O(a)&&U.existsSync(a))return{absolute:a,relative:g.relative(s,a)||g.relative(C.package.location,C.local)||g.sep}}let n=g.join(C.package.location,e.url??g.sep);if(!O(n))throw new W(`"${e.url}" is outside the served root`);return{absolute:n,relative:e.url??g.sep}})();return o.absolute.endsWith(g.sep)&&(o.absolute=o.absolute.slice(0,o.absolute.length-1)),{absolute:g.normalize(o.absolute),relative:g.normalize(o.relative)}}function Re(e){let o=nt(e);for(let i=0;i<5;i++)if(o=g.dirname(o),!!U.existsSync(g.join(o,"package.json")))return o;return null}function at(e){let t=e;for(;t!=="/"&&!U.existsSync(g.join(t,"package.json"));)t=g.dirname(t);return t}function A(e){let t=at(e.absolute);if(!t)throw new H(`could not find package at 1: ${t}`);let o=it.search(t);if(!o)throw new H(`could not find package at 2: ${t}`);return o}async function je(e,t,o,i,r){let n=A(e),s=e.absolute.endsWith(".html")?e:{absolute:Le.join(e.absolute,"index.html"),relative:Le.join(e.relative,"index.html")},a,m=null;if(re.existsSync(s.absolute))m=re.statSync(s.absolute).mtimeMs,a=Ae(n,s,o,i);else{let p=re.readdirSync(e.absolute);a=Ee(n,p,e,i)}return r.add(e,Buffer.from(a.innerHTML,"utf8"),y.MimeTypes[".html"],m),a}import ct from"node:fs";import{jsBundle as mt}from"@papit/bundle-js";import{Arguments as pt}from"@papit/arguments";async function Ie(e,t){let o=A(e),i;if(await mt(pt.instance,o.location,{entryPointArray:[{input:e.absolute,output:void 0}],tsconfig:o?.tsconfig,externals:o?.externals,packageJSON:o?.packageJSON,esoptions:{write:!1}},r=>{r.type==="build"&&(i=r.result.outputFiles?.at(0)?.text)}),!i)throw new b("file not found: "+e.relative);return t.add(e,Buffer.from(i,"utf8"),y.MimeTypes[".js"],ct.statSync(e.absolute)?.mtimeMs??null),i}import ne from"node:fs";import{Arguments as ie}from"@papit/arguments";import{Terminal as N}from"@papit/terminal";var M=class{constructor(t){this.map=new Map;this._size=0;this.name="cache";this._maxSize=y.MAX_FILE_SIZE_TO_CACHE;t&&(this.name=t)}get size(){return this._size}get maxSize(){return this._maxSize}set maxSize(t){this._maxSize=t*1024*1024}get(t){let o=this.map.get(t.absolute);return!o||!ne.existsSync(t.absolute)?null:o.mtime===null||ne.statSync(t.absolute).mtimeMs===o.mtime?o:(this.delete(t),null)}delete(t,o=!1){let i=this.map.get(t.absolute);i&&(ie.verbose&&!o&&N.write(N.yellow(t.relative),"removed from cache:"+N.blue(this.name)),this._size-=i.buffer.length,this.map.delete(t.absolute))}clear(){this.map.clear(),this._size=0}add(t,o,i,r){ie.has("no-cache")||(this.delete(t,!0),this._size+=o.length,ie.verbose&&N.write(N.yellow(t.relative),"added to cache:"+N.blue(this.name)),this.map.set(t.absolute,{mimeType:i??y.MimeTypes[t.absolute]??"text/plain",buffer:o,mtime:r===void 0?ne.statSync(t.absolute).mtimeMs:r}))}isCacheable(t,o){return!(t>this.maxSize||[".mp4",".webm",".ogv",".avi",".mov"].includes(o))}};import{createHash as lt}from"node:crypto";import _e from"node:path";import{Arguments as D}from"@papit/arguments";import{Terminal as R}from"@papit/terminal";import{Information as X,PackageGraph as ft}from"@papit/information";var x=new Map;function Fe(e,t,o){let i=e.headers["sec-websocket-key"],n=["HTTP/1.1 101 Switching Protocols","Upgrade: websocket","Connection: Upgrade",`Sec-WebSocket-Accept: ${lt("sha1").update(i+"258EAFA5-E914-47DA-95CA-C5AB0DC85B11").digest("base64")}`];t.write(n.join(`\r
|
|
2
2
|
`)+`\r
|
|
3
3
|
\r
|
|
4
|
-
`),
|
|
4
|
+
`),D.info&&R.write(R.blue("client connected")),t.on("end",()=>x.delete(t)),t.on("close",()=>x.delete(t)),t.on("error",s=>{s.code==="ECONNRESET"&&x.delete(t)}),t.on("data",s=>{try{let a=dt(s);switch(a.opcode){case 1:let m=a.payload.toString("utf8");try{let c=JSON.parse(m);switch(c.type){case"register":{let u=_e.join(X.root.location,c.location);if(!O(u))break;let l=A({relative:c.location,absolute:u});l.name===X.root.name&&(l=X.package),x.set(t,l);break}}}catch{}break;case 8:t.end();break;case 9:let p=ae({type:"pong"});t.write(p);break;default:console.log("Unknown opcode:",a.opcode)}}catch(a){console.error("Error parsing WebSocket frame:",a)}})}function se(e){try{if(x.size===0){D.verbose&&R.write("No clients connected to send update!");return}let t=ae({action:"update",filename:"/"+_e.relative(X.root.location,e.location)});x.forEach((o,i)=>{if(!(o.name!==e.name&&!ft.getDescendants(e.name).some(n=>n.name===o.name))){if(!i||!i.writable){D.verbose&&R.error(R.blue("socket"),"[error] could not find client"),x.delete(i);return}i.write(t)}})}catch(t){console.log("[socket error]",t)}}function ar(e,t){x.size===0&&D.verbose&&R.write("No clients connected to send error!");let o=ae({action:"error",filename:e,error:t});ut(o)}function ut(e){x.forEach((t,o)=>{if(!o||!o.writable){D.verbose&&R.error(R.blue("socket"),"[error] could not find client"),x.delete(o);return}o.write(e)})}function ae(e){let t=Buffer.from(JSON.stringify(e),"utf8"),o=t.length,i=2;o>125&&o<=65535?i+=2:o>65535&&(i+=8);let r=Buffer.alloc(i+o);r[0]=129;let n=2;return o<=125?r[1]=o:o<=65535?(r[1]=126,r.writeUInt16BE(o,n),n+=2):(r[1]=127,r.writeBigUInt64BE(BigInt(o),n),n+=8),t.copy(r,n),r}function dt(e){let t=e[0],o=e[1],i=(t&128)!==0,r=t&15,n=(o&128)!==0,s=o&127,a=2;if(s===126?(s=e.readUInt16BE(a),a+=2):s===127&&(s=Number(e.readBigUInt64BE(a)),a+=8),!n)throw new Error("Expected masked frame from client");let m=e.slice(a,a+4);a+=4;let p=e.slice(a,a+s),c=Buffer.alloc(s);for(let u=0;u<s;u++)c[u]=p[u]^m[u%4];return{opcode:r,payload:c}}import gt from"node:net";import{Terminal as ht}from"@papit/terminal";function yt(e,t="0.0.0.0"){return new Promise(o=>{let i=gt.createServer().once("error",()=>o(!1)).once("listening",()=>{i.close(()=>o(!0))}).listen(e,t)})}async function Ne(e,t=20){for(let o=0;o<t;o++){let i=e+o;if(await yt(i))return i}ht.error(`No free ports found in range [${e}, ${e+t}]`),process.exit(1)}import{build as vt}from"@papit/build";var L=f.number("port")||3e3,B=null;function Me(e,t,o,i,r){return L=f.number("port")||3e3,new Promise(async n=>{L=await Ne(L),B=bt.createServer();let s=new M("file");s.maxSize=f.number("cache-file")??50;let a=new M("html");a.maxSize=f.number("cache-html")??50;let m=new M("bundle");m.maxSize=f.number("cache-bundle")??150,f.has("live")&&St(),j.packageName!=="@papit/server"&&!f.has("serve")&&(f.info&&d.write(d.blue("listening to file changes"),j.package.name),f.set("no-bundle",!0),f.set("live",!0),f.set("location",j.package.location),f.set("mode","dev"),f.set("buildMode","ancestors")),B.listen(L,()=>{if(f.set("port",L),f.silent||d.write("server:",d.blue(L),d.yellow("- running")),f.has("open")){let p=v.join(`http://localhost:${L}`,v.relative(j.root.location,j.package.location)),c=v.join(p,f.string("open")??f.string("folder")??"");switch(process.platform){case"win32":d.execute(`start "${c}"`,p);break;case"darwin":d.execute(`open "${c}"`,p);break;case"linux":d.execute(`xdg-open "${c}"`,p);break}}n()}),B.on("request",async(p,c)=>{try{if(p.method!=="GET")throw c.setHeader("Allow","GET"),new $;if(p.url?.startsWith("/.well-known"))return c.end("ok");p.url?.endsWith("/favicon.ico")&&(p.url="/favicon.svg");try{let h=await xe(p.url,t,o,s,c);if(h==="streamed")return;c.statusCode=200,c.setHeader("Content-Type",h.mimeType),c.end(h.buffer);return}catch{}let u=p.url?.split("@")?.at(1);if(u){let h=r.get("@"+u);if(h){let k=P({absolute:v.normalize(h),relative:v.normalize(v.relative(j.root.location,h))},s,c);if(k==="streamed")return;c.statusCode=200,c.setHeader("Content-Type",k.mimeType),c.end(k.buffer);return}}let l=oe(p),T=ce.statSync(l.absolute);if(T.isDirectory()){let h=v.join(l.absolute,"index.html");ce.existsSync(h)&&(l.absolute=h,l.relative=v.join(l.relative,"index.html"))}let F=a.get(l)??m.get(l)??s.get(l);if(F)return f.info&&d.write(d.yellow(l.relative),"found in cache"),c.statusCode=200,c.setHeader("Content-Type",F.mimeType),c.setHeader("X-Cache","HIT"),c.end(F.buffer);if(c.setHeader("X-Cache","MISS"),T.isDirectory()||v.extname(l.absolute)===".html"){if(p.headers["x-router"]){let k=ce.readFileSync(l.absolute,{encoding:"utf-8"});c.statusCode=200,c.setHeader("Content-Type","text/html"),c.end(k);return}let h=await je(l,o,i,e,a);c.statusCode=200,f.has("prod")||c.setHeader("Cache-Control","no-store"),c.end(h.outerHTML);return}if(/\.tsx?/.test(l.absolute)&&(p.headers.referer?.endsWith(".js")||p.headers["sec-fetch-dest"]==="script")){let h=await Ie(l,m);c.statusCode=200,c.setHeader("Content-Type","text/javascript"),c.end(h);return}let w=P(l,s,c);if(w==="streamed")return;c.statusCode=200,c.setHeader("Content-Type",w.mimeType),c.end(w.buffer)}catch(u){wt(u,c)}}),B.on("error",p=>{f.error&&d.error(p.name,p.message,p.stack??"")}),B.on("upgrade",Fe)})}function Be(){B?.close(),f.silent||d.write("server:",d.blue(String(L)),d.yellow("- shutdown"))}function wt(e,t){f.error&&console.trace("[SERVER]",e),e instanceof E?t.statusCode=e.status:t.statusCode=500,typeof e=="string"?t.write(e):e&&typeof e=="object"&&"message"in e?t.write(e.message):t.write("something went wrong"),t.end()}function St(){let e=xt.watch(j.root.location,{ignored:r=>r.includes("/node_modules/")||r.includes("/.temp/")||r.includes("/.vscode/")||r.includes("/.github/")||r.includes("/.git/")||r.includes("/lib/")||/\/tests?\//.test(r),persistent:!0,followSymlinks:!1}),t=!1;e.on("ready",()=>{t=!0});let o=!1,i=async r=>{o=!0;try{await vt(f.instance,r,(n,s)=>{s==="success"?(f.info&&d.write(d.blue("rebuilt"),r.name),se(r)):s==="skipped"?f.info&&d.write(d.blue("skipped"),r.name):f.info&&d.error(r.name)})}catch(n){f.error&&d.error(n)}finally{o=!1}};e.on("all",(r,n,s)=>{if(!t||o)return;let a={absolute:n,relative:v.relative(j.root.location,n)},m=A(a);a.relative.includes(m.sourceFolder+"/")?i(m):se(m),f.debug&&console.log("SERVER LIVE RELOAD",{url:a,package:{name:m.name,location:m.location,src:m.sourceFolder},includes:a.relative.includes(m.sourceFolder+"/")})})}import Z from"node:fs";import _ from"node:path";import{Information as K}from"@papit/information";import{pathToFileURL as Tt}from"node:url";function ze(e,t,o){me(e.name,e.location,e.packageJSON,t);for(let i in e.packageJSON.dependencies){if(i.startsWith(K.scope)||["chokidar","esbuild","@microsoft/api-extractor","typescript","playwright"].includes(i))continue;let r=_.join(K.root.location,"node_modules",i),n=_.join(r,"package.json");if(!Z.existsSync(n))continue;let s=JSON.parse(Z.readFileSync(n,{encoding:"utf-8"}));me(i,r,s,t,!0)}for(let i in e.packageJSON.devDependencies){if(i.startsWith(K.scope)||["chokidar","esbuild","@microsoft/api-extractor","typescript","playwright"].includes(i))continue;let r=_.join(K.root.location,"node_modules",i),n=_.join(r,"package.json");if(!Z.existsSync(n))continue;let s=JSON.parse(Z.readFileSync(n,{encoding:"utf-8"}));me(i,r,s,t,!0)}}function me(e,t,o,i,r=!1){let n=(s,a)=>{i.imports[s]||(i.imports[s]=Tt(a).pathname)};if(o.exports)if(typeof o.exports=="string")n(e,_.resolve(t,o.exports));else for(let s in o.exports){let a=o.name;s!=="."&&s!=="default"&&(a+="/"+s.replace(/^\.?\/?/,""));let m=typeof o.exports[s]=="string"?o.exports[s]:o.exports[s]?.import;m&&n(a,_.resolve(t,m))}o.main&&n(e,_.resolve(t,o.main))}async function kt(){let e=Re(import.meta.url);e==null&&(He.error("script location of @papit/server is missing"),process.exit(1)),S.package.packageJSON||(He.error("location is not a package, missing package.json"),process.exit(1));let o={data:{},map:{}},i={},r=we();await ee(e,o,i,r);let n={imports:{}},s=new Map,a=null;S.root.location===S.package.location?a=pe.join(S.root.location,"node_modules"):a=pe.join(S.package.location,V.string("import-map")??".temp/dependencies");let m=!1;a&&!le.existsSync(a)&&(m=!0,le.mkdirSync(a,{recursive:!0})),S.package.location!==S.root.location&&V.set("ancestors",!0);let p=S.getBatches();for(let c of p)for(let u of c){if(u.packageJSON.papit.type==="theme"){let l=u.entrypoints.entries.theme?.import?.output??u.entrypoints.entries.bundle?.import?.output;l&&s.set(u.name,l);continue}a&&ze(u,n,a),!(!V.has("include-node")&&u.packageJSON.papit.type==="node")&&await ee(u.location,o,i,r)}return{importmap:n,importmapFolder:a,createdImportMapFolder:m,serverPackageLocation:e,translations:o,assets:i,themes:s}}async function Qr(){let{importmap:e,importmapFolder:t,createdImportMapFolder:o,serverPackageLocation:i,translations:r,assets:n,themes:s}=await kt(),a=()=>{t&&o&&!V.has("import-map")&&le.rmSync(pe.join(S.package.location,".temp"),{force:!0,recursive:!0}),console.log(),Be(),process.exit(0)};process.on("SIGINT",a),process.on("SIGTERM",a),process.on("SIGHUP",a),await Me(i,r,n,e,s)}export{Be as close,ar as error,oe as getURL,kt as meta,B as server,Qr as setup,Me as start,se as update,Fe as upgrade};
|
package/package.json
CHANGED
|
@@ -7,7 +7,7 @@
|
|
|
7
7
|
"typescript",
|
|
8
8
|
"dev-server"
|
|
9
9
|
],
|
|
10
|
-
"version": "1.0.
|
|
10
|
+
"version": "1.0.7",
|
|
11
11
|
"scripts": {
|
|
12
12
|
"build": "npx @papit/build -- --error --ancestors",
|
|
13
13
|
"watch": "tsc -w",
|
|
@@ -56,11 +56,11 @@
|
|
|
56
56
|
},
|
|
57
57
|
"dependencies": {
|
|
58
58
|
"@papit/arguments": "0.0.1",
|
|
59
|
-
"@papit/build": "0.0.
|
|
60
|
-
"@papit/bundle-js": "0.0.
|
|
59
|
+
"@papit/build": "0.0.7",
|
|
60
|
+
"@papit/bundle-js": "0.0.3",
|
|
61
61
|
"@papit/deep-merge": "0.0.1",
|
|
62
62
|
"@papit/html": "0.0.1",
|
|
63
|
-
"@papit/information": "0.0.
|
|
63
|
+
"@papit/information": "0.0.8",
|
|
64
64
|
"@papit/terminal": "0.0.2",
|
|
65
65
|
"chokidar": "^5.0.0",
|
|
66
66
|
"esbuild": "0.27.2"
|
|
@@ -97,5 +97,5 @@
|
|
|
97
97
|
}
|
|
98
98
|
}
|
|
99
99
|
},
|
|
100
|
-
"remoteVersion": "1.0.
|
|
100
|
+
"remoteVersion": "1.0.6"
|
|
101
101
|
}
|