@marko/run 0.0.1-beta1 → 0.0.1-beta3

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.
Files changed (41) hide show
  1. package/dist/adapter/default-entry.mjs +9 -3
  2. package/dist/adapter/dev-server.d.ts +1 -1
  3. package/dist/adapter/index.cjs +23 -8
  4. package/dist/adapter/index.js +22 -7
  5. package/dist/adapter/middleware.cjs +200 -0
  6. package/dist/adapter/middleware.d.ts +59 -0
  7. package/dist/adapter/middleware.js +169 -0
  8. package/dist/cli/default.config.mjs +1 -1
  9. package/dist/cli/index.mjs +45 -24
  10. package/dist/runtime/index.cjs +0 -16
  11. package/dist/runtime/index.d.ts +10 -2
  12. package/dist/runtime/index.js +0 -7
  13. package/dist/runtime/internal.cjs +148 -0
  14. package/dist/runtime/internal.d.ts +10 -0
  15. package/dist/runtime/internal.js +115 -0
  16. package/dist/runtime/router.cjs +6 -6
  17. package/dist/runtime/router.d.ts +4 -4
  18. package/dist/runtime/router.js +4 -4
  19. package/dist/runtime/types.d.ts +31 -16
  20. package/dist/runtime/utils.d.ts +3 -0
  21. package/dist/vite/codegen/index.d.ts +4 -3
  22. package/dist/vite/codegen/writer.d.ts +1 -1
  23. package/dist/vite/constants.d.ts +3 -2
  24. package/dist/vite/index.cjs +542 -275
  25. package/dist/vite/index.d.ts +4 -3
  26. package/dist/vite/index.js +539 -275
  27. package/dist/vite/types.d.ts +9 -7
  28. package/dist/vite/utils/config.d.ts +2 -2
  29. package/dist/vite/utils/server.d.ts +3 -1
  30. package/package.json +18 -6
  31. package/dist/adapter/server-old.d.ts +0 -3
  32. package/dist/adapter/server.d.ts +0 -6
  33. package/dist/adapters/node/index.d.ts +0 -5
  34. package/dist/adapters/node/server.d.ts +0 -3
  35. package/dist/adapters/static/crawler.d.ts +0 -9
  36. package/dist/adapters/static/default-entry.mjs +0 -1
  37. package/dist/adapters/static/index.cjs +0 -371
  38. package/dist/adapters/static/index.d.ts +0 -5
  39. package/dist/adapters/static/index.js +0 -341
  40. package/dist/adapters/static/server.d.ts +0 -3
  41. package/dist/runtime/request.d.ts +0 -4
@@ -8,18 +8,17 @@ export interface Adapter {
8
8
  pluginOptions?(options: Options): Promise<Options> | Options | undefined;
9
9
  viteConfig?(config: UserConfig): Promise<UserConfig> | UserConfig | undefined;
10
10
  getEntryFile?(): Promise<string> | string;
11
- startDev?(configFile: string, port: number): Promise<void> | void;
12
- startPreview?(dir: string, entry?: string, port?: number): Promise<void> | void;
11
+ startDev?(configFile: string, port: number, envFile?: string): Promise<void> | void;
12
+ startPreview?(dir: string, entry?: string, port?: number, envFile?: string): Promise<void> | void;
13
13
  buildEnd?(config: ResolvedConfig, routes: Route[], builtEntries: string[], sourceEntries: string[]): Promise<void> | void;
14
14
  }
15
- export interface MarkoServeOptions {
15
+ export interface RouterOptions {
16
+ trailingSlashes: 'Ignore' | 'RedirectWithout' | 'RedirectWith' | 'RewriteWithout' | 'RewriteWith';
17
+ }
18
+ export interface MarkoServeOptions extends Partial<RouterOptions> {
16
19
  routesDir?: string;
17
20
  emitRoutes?(routes: Route[]): void | Promise<void>;
18
21
  adapter?: Adapter;
19
- codegen?: CodegenOptions;
20
- }
21
- export interface CodegenOptions {
22
- trailingSlashes: 'Ignore' | 'RedirectWithout' | 'RedirectWith' | 'RewriteWithout' | 'RewriteWith';
23
22
  }
24
23
  export declare type Options = MarkoServeOptions & MarkoViteOptions;
25
24
  export interface Route {
@@ -43,9 +42,11 @@ export interface SpecialRoutes {
43
42
  [RoutableFileTypes.Error]?: Route;
44
43
  }
45
44
  export interface RoutableFile {
45
+ id: string;
46
46
  name: string;
47
47
  type: RoutableFileType;
48
48
  filePath: string;
49
+ relativePath: string;
49
50
  importPath: string;
50
51
  verbs?: HttpVerb[];
51
52
  }
@@ -59,4 +60,5 @@ export interface RouteTrie {
59
60
  export interface BuiltRoutes {
60
61
  list: Route[];
61
62
  special: SpecialRoutes;
63
+ middleware: RoutableFile[];
62
64
  }
@@ -1,3 +1,3 @@
1
1
  import type { Options } from '../types';
2
- export declare function getMarkoServeOptions<T extends Record<string, any>>(viteConfig: T): Readonly<Options> | undefined;
3
- export declare function setMarkoServeOptions<T extends Record<string, any>>(viteConfig: T, options: Options): T;
2
+ export declare function getMarkoRunOptions<T extends Record<string, any>>(viteConfig: T): Readonly<Options> | undefined;
3
+ export declare function setMarkoRunOptions<T extends Record<string, any>>(viteConfig: T, options: Options): T;
@@ -2,6 +2,8 @@ export interface SpawnedServer {
2
2
  port: number;
3
3
  close(): void;
4
4
  }
5
- export declare function spawnServer(cmd: string, port?: number, cwd?: string, wait?: number): Promise<SpawnedServer>;
5
+ export declare function parseEnv(envFile: string): Promise<import("dotenv").DotenvParseOutput | undefined>;
6
+ export declare function loadEnv(envFile: string): void;
7
+ export declare function spawnServer(cmd: string, port?: number, env?: string | Record<string, string>, cwd?: string, wait?: number): Promise<SpawnedServer>;
6
8
  export declare function isPortInUse(port: number): Promise<boolean>;
7
9
  export declare function getAvailablePort(): Promise<number>;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@marko/run",
3
- "version": "0.0.1-beta1",
3
+ "version": "0.0.1-beta3",
4
4
  "description": "File-based routing for Marko based on Vite",
5
5
  "keywords": [],
6
6
  "author": "Ryan Turnquist <rturnq@gmail.com>",
@@ -33,6 +33,11 @@
33
33
  "import": "./dist/vite/index.js",
34
34
  "require": "./dist/vite/index.cjs"
35
35
  },
36
+ "./adapter/middleware": {
37
+ "types": "./dist/adapter/middleware.d.ts",
38
+ "import": "./dist/adapter/middleware.js",
39
+ "require": "./dist/adapter/middleware.cjs"
40
+ },
36
41
  "./adapter": {
37
42
  "types": "./dist/adapter/index.d.ts",
38
43
  "import": "./dist/adapter/index.js",
@@ -50,6 +55,9 @@
50
55
  "vite": [
51
56
  "./src/vite/index.ts"
52
57
  ],
58
+ "adapter/middleware": [
59
+ "./src/adapter/middleware.ts"
60
+ ],
53
61
  "adapter": [
54
62
  "./src/adapter/index.ts"
55
63
  ]
@@ -66,8 +74,10 @@
66
74
  "devDependencies": {
67
75
  "@babel/types": "^7.19.0",
68
76
  "@marko/compiler": "^5.22.6",
77
+ "@types/glob": "^8.0.1",
78
+ "@types/human-format": "^1.0.0",
69
79
  "@types/mocha": "^9.1.1",
70
- "@types/node": "^18.7.6",
80
+ "@types/node": "^18.11.18",
71
81
  "acorn": "^8.8.0",
72
82
  "cross-env": "^7.0.3",
73
83
  "esbuild": "^0.15.7",
@@ -79,13 +89,15 @@
79
89
  "typescript": "^4.7.4"
80
90
  },
81
91
  "dependencies": {
82
- "@hattip/adapter-node": "^0.0.24",
83
- "@hattip/core": "^0.0.24",
84
- "@marko/vite": "^2.3.11",
92
+ "@hattip/polyfills": "^0.0.27",
93
+ "@marko/vite": "^2.3.9",
85
94
  "cli-table3": "^0.6.3",
95
+ "compression": "^1.7.4",
96
+ "dotenv": "^16.0.3",
97
+ "glob": "^8.1.0",
86
98
  "gzip-size": "^7.0.0",
99
+ "human-format": "^1.0.0",
87
100
  "kleur": "^4.1.5",
88
- "pretty-bytes": "^6.0.0",
89
101
  "sade": "^1.8.1",
90
102
  "serve-static": "^1.15.0",
91
103
  "vite": "^3.0.8"
@@ -1,3 +0,0 @@
1
- /// <reference types="node" />
2
- import type { Server } from "http";
3
- export default function (dir?: string): Promise<Server>;
@@ -1,6 +0,0 @@
1
- /// <reference types="node" />
2
- import { ViteDevServer } from "vite";
3
- import { type NodeMiddleware } from "@hattip/adapter-node";
4
- import type { Server } from "http";
5
- export declare function createViteDevMiddleware<T>(devServer: ViteDevServer, load: (prev: T | undefined) => Promise<T>, factory: (value: T) => NodeMiddleware): NodeMiddleware;
6
- export default function (entryFile?: string): Promise<Server>;
@@ -1,5 +0,0 @@
1
- import type { Adapter, Route } from "../../vite";
2
- export interface Options {
3
- urls?: string[] | ((routes: Route[]) => string[] | Promise<string[]>);
4
- }
5
- export default function staticAdapter(_options?: Options): Adapter;
@@ -1,3 +0,0 @@
1
- /// <reference types="node" />
2
- import type { Server } from "http";
3
- export default function (dir?: string): Promise<Server>;
@@ -1,9 +0,0 @@
1
- export interface Options {
2
- out?: string;
3
- origin?: string;
4
- notFoundPath?: string;
5
- }
6
- export interface Crawler {
7
- crawl(paths: string[]): Promise<void>;
8
- }
9
- export default function createCrawler(makeRequest: (request: Request) => Promise<Response>, opts?: Options): Crawler;
@@ -1 +0,0 @@
1
- export { router } from '@marko/run';
@@ -1,371 +0,0 @@
1
- "use strict";
2
- var __create = Object.create;
3
- var __defProp = Object.defineProperty;
4
- var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
5
- var __getOwnPropNames = Object.getOwnPropertyNames;
6
- var __getProtoOf = Object.getPrototypeOf;
7
- var __hasOwnProp = Object.prototype.hasOwnProperty;
8
- var __export = (target, all) => {
9
- for (var name in all)
10
- __defProp(target, name, { get: all[name], enumerable: true });
11
- };
12
- var __copyProps = (to, from, except, desc) => {
13
- if (from && typeof from === "object" || typeof from === "function") {
14
- for (let key of __getOwnPropNames(from))
15
- if (!__hasOwnProp.call(to, key) && key !== except)
16
- __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
17
- }
18
- return to;
19
- };
20
- var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
21
- isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
22
- mod
23
- ));
24
- var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
25
-
26
- // src/adapters/static/index.ts
27
- var static_exports = {};
28
- __export(static_exports, {
29
- default: () => staticAdapter
30
- });
31
- module.exports = __toCommonJS(static_exports);
32
- var import_path2 = __toESM(require("path"), 1);
33
- var import_url = require("url");
34
- var import_undici = require("undici");
35
-
36
- // src/adapters/static/crawler.ts
37
- var import_fs = __toESM(require("fs"), 1);
38
- var import_path = __toESM(require("path"), 1);
39
- var import_WritableStream = require("htmlparser2/lib/WritableStream");
40
- var noop = () => {
41
- };
42
- var ignoredRels = /* @__PURE__ */ new Set(["nofollow", "enclosure", "external"]);
43
- var contentType = "text/html";
44
- function createCrawler(makeRequest, opts = {}) {
45
- const origin = opts.origin || `http://localhost`;
46
- const out = import_path.default.resolve(opts.out || "dist");
47
- const notFoundPath = resolvePath(opts.notFoundPath || "/404/", origin);
48
- let seen;
49
- let queue;
50
- let pending;
51
- async function visit(path2) {
52
- var _a, _b;
53
- const parser = new import_WritableStream.WritableStream({
54
- onopentag(name, attrs) {
55
- const href = resolveHref(name, attrs);
56
- const path3 = href && resolvePath(href, origin);
57
- if (path3 !== void 0 && !seen.has(path3)) {
58
- seen.add(path3);
59
- queue.push(visit(path3));
60
- }
61
- }
62
- });
63
- const dirname = import_path.default.join(out, path2);
64
- const abortController = new AbortController();
65
- let fsWriter;
66
- try {
67
- const url = new URL(path2, origin);
68
- const req = new Request(url, {
69
- method: "GET",
70
- signal: abortController.signal,
71
- headers: { accept: contentType }
72
- });
73
- const res = await makeRequest(req);
74
- if (!((_a = res.headers.get("content-type")) == null ? void 0 : _a.includes(contentType))) {
75
- abortController.abort();
76
- return;
77
- }
78
- let redirect;
79
- switch (res.status) {
80
- case 200:
81
- break;
82
- case 404:
83
- if (path2 !== notFoundPath) {
84
- redirect = origin + notFoundPath;
85
- }
86
- break;
87
- case 301: {
88
- redirect = res.headers.get("location");
89
- const redirectPath = resolvePath(redirect, origin);
90
- if (redirectPath && !seen.has(redirectPath)) {
91
- seen.add(redirectPath);
92
- queue.push(visit(redirectPath));
93
- }
94
- break;
95
- }
96
- default: {
97
- abortController.abort();
98
- console.warn(`Status code ${res.status} was while crawling: '${path2}'`);
99
- return;
100
- }
101
- }
102
- await import_fs.default.promises.mkdir(dirname, { recursive: true }).catch(noop);
103
- fsWriter = import_fs.default.createWriteStream(import_path.default.join(dirname, "index.html"));
104
- if (redirect) {
105
- abortController.abort();
106
- fsWriter.write(
107
- `<!DOCTYPE html><meta http-equiv=Refresh content="0;url=${redirect.replace(
108
- /"/g,
109
- "&#40;"
110
- )}">`
111
- );
112
- } else {
113
- const writable = new WritableStream({
114
- write(data) {
115
- fsWriter.write(data);
116
- parser.write(data);
117
- }
118
- });
119
- await ((_b = res.body) == null ? void 0 : _b.pipeTo(writable));
120
- }
121
- } finally {
122
- fsWriter == null ? void 0 : fsWriter.end();
123
- parser.end();
124
- }
125
- }
126
- return {
127
- async crawl(paths = ["/"]) {
128
- if (pending) {
129
- await pending;
130
- }
131
- const startPaths = paths.map((path2) => resolvePath(path2, origin)).concat(notFoundPath);
132
- seen = new Set(startPaths);
133
- try {
134
- queue = startPaths.map(visit);
135
- while (queue.length) {
136
- pending = Promise.all(queue);
137
- queue = [];
138
- await pending;
139
- }
140
- } finally {
141
- pending = void 0;
142
- }
143
- }
144
- };
145
- }
146
- function resolveHref(tagName, attrs) {
147
- switch (tagName) {
148
- case "a":
149
- if (attrs.href && !(attrs.download || ignoredRels.has(attrs.rel))) {
150
- return attrs.href;
151
- }
152
- break;
153
- case "link":
154
- if (attrs.href) {
155
- switch (attrs.rel) {
156
- case "alternate":
157
- case "author":
158
- case "canonical":
159
- case "help":
160
- case "license":
161
- case "next":
162
- case "prefetch":
163
- case "prerender":
164
- case "prev":
165
- case "search":
166
- case "tag":
167
- return attrs.href;
168
- case "preload":
169
- if (attrs.as === "document") {
170
- return attrs.href;
171
- }
172
- break;
173
- }
174
- }
175
- break;
176
- case "iframe":
177
- return attrs.src;
178
- }
179
- }
180
- function resolvePath(href, origin) {
181
- const url = new URL(href, origin);
182
- if (url.origin === origin) {
183
- let { pathname } = url;
184
- const lastChar = pathname.length - 1;
185
- if (pathname[lastChar] !== "/") {
186
- pathname += "/";
187
- }
188
- return pathname + url.search;
189
- }
190
- }
191
-
192
- // src/adapters/static/index.ts
193
- var import_promises = __toESM(require("fs/promises"), 1);
194
-
195
- // src/vite/utils/server.ts
196
- var import_net = __toESM(require("net"), 1);
197
- var import_child_process = __toESM(require("child_process"), 1);
198
- async function spawnServer(cmd, port = 0, wait = 3e4) {
199
- if (port <= 0) {
200
- port = await getAvailablePort();
201
- }
202
- const proc = import_child_process.default.spawn(cmd, {
203
- shell: true,
204
- stdio: "inherit",
205
- windowsHide: true,
206
- env: { ...process.env, PORT: `${port}` }
207
- });
208
- const close = () => {
209
- proc.unref();
210
- proc.kill();
211
- };
212
- let remaining = wait > 0 ? wait : Infinity;
213
- while (!await isPortInUse(port)) {
214
- if (remaining >= 100) {
215
- remaining -= 100;
216
- await sleep(100);
217
- } else {
218
- close();
219
- throw new Error(
220
- `site-write: timeout while wating for server to start on port "${port}".`
221
- );
222
- }
223
- }
224
- return close;
225
- }
226
- async function isPortInUse(port) {
227
- return new Promise((resolve) => {
228
- const connection = import_net.default.connect(port).setNoDelay(true).setKeepAlive(false).on("error", () => done(false)).on("connect", () => done(true));
229
- function done(connected) {
230
- connection.end();
231
- resolve(connected);
232
- }
233
- });
234
- }
235
- async function getAvailablePort() {
236
- return new Promise((resolve) => {
237
- const server = import_net.default.createServer().listen(0, () => {
238
- const { port } = server.address();
239
- server.close(() => resolve(port));
240
- });
241
- });
242
- }
243
- function sleep(ms) {
244
- return new Promise((resolve) => setTimeout(resolve, ms));
245
- }
246
-
247
- // src/adapters/static/server.ts
248
- var import_serve_static = __toESM(require("serve-static"), 1);
249
- var import_http = require("http");
250
- var import_vite = require("vite");
251
- var import_adapter_node = require("@hattip/adapter-node");
252
- function noop2() {
253
- }
254
- async function server_default(dir) {
255
- if (dir) {
256
- const staticServe = (0, import_serve_static.default)(dir, {
257
- index: "index.html",
258
- immutable: true,
259
- maxAge: "365 days"
260
- });
261
- return await (0, import_http.createServer)((req, res) => staticServe(req, res, noop2));
262
- }
263
- const devServer = await (0, import_vite.createServer)({
264
- appType: "custom",
265
- server: { middlewareMode: true }
266
- });
267
- let handler;
268
- let middleware;
269
- return devServer.middlewares.use(async (req, res, next) => {
270
- try {
271
- const module2 = await devServer.ssrLoadModule("@marko/run");
272
- if (module2.handler !== handler) {
273
- handler = module2.handler;
274
- middleware = (0, import_adapter_node.createMiddleware)(handler);
275
- }
276
- await middleware(req, res, next);
277
- } catch (err) {
278
- if (err instanceof Error) {
279
- devServer.ssrFixStacktrace(err);
280
- }
281
- return next(err);
282
- }
283
- });
284
- }
285
-
286
- // src/adapters/static/index.ts
287
- var import_meta = {};
288
- var __dirname = (0, import_url.fileURLToPath)(new URL(".", import_meta.url));
289
- function staticAdapter(_options = {}) {
290
- return {
291
- name: "static-adapter",
292
- async config(_options2) {
293
- return {
294
- codegen: {
295
- trailingSlashes: "RedirectWith"
296
- }
297
- };
298
- },
299
- async getEntryFile() {
300
- return import_path2.default.join(__dirname, "default-entry");
301
- },
302
- async startServer(port, dir) {
303
- const server = await server_default(dir);
304
- server.on("error", (err) => {
305
- console.error(err);
306
- process.exit(1);
307
- });
308
- return new Promise((resolve) => {
309
- const listener = server.listen(port, () => {
310
- const address = listener.address();
311
- console.log(`Server started: http://localhost:${address.port}`);
312
- resolve();
313
- });
314
- });
315
- },
316
- async buildEnd(routes, builtEntries, sourceEntries) {
317
- var _a;
318
- const pathsToVisit = [];
319
- for (const route of routes) {
320
- if (!((_a = route.params) == null ? void 0 : _a.length)) {
321
- pathsToVisit.push(route.path);
322
- }
323
- }
324
- const defaultEntry = await this.getEntryFile();
325
- if (sourceEntries[0] === defaultEntry) {
326
- const { router } = await import(builtEntries[0]);
327
- const crawler = createCrawler(router, {});
328
- await crawler.crawl(pathsToVisit);
329
- } else {
330
- const port = await getAvailablePort();
331
- const origin = `http://localhost:${port}`;
332
- const client = new import_undici.Pool(origin);
333
- const closeServer = await spawnServer(`node ${builtEntries[0]}`, port);
334
- const crawler = createCrawler(
335
- async (request) => {
336
- const url = new URL(request.url);
337
- const headers = {};
338
- request.headers.forEach((value, key) => {
339
- headers[key] = value;
340
- });
341
- const responseData = await client.request({
342
- path: url.pathname + url.search,
343
- method: request.method,
344
- signal: request.signal,
345
- headers
346
- });
347
- return new Response(responseData.body, {
348
- status: responseData.statusCode,
349
- headers: responseData.headers
350
- });
351
- },
352
- {
353
- origin
354
- }
355
- );
356
- try {
357
- await crawler.crawl(pathsToVisit);
358
- } finally {
359
- await client.close();
360
- closeServer();
361
- }
362
- }
363
- for (const file of builtEntries) {
364
- await import_promises.default.rm(file, { maxRetries: 5 }).catch(() => {
365
- });
366
- }
367
- }
368
- };
369
- }
370
- // Annotate the CommonJS export names for ESM import in node:
371
- 0 && (module.exports = {});
@@ -1,5 +0,0 @@
1
- import type { Adapter, Route } from "../../vite";
2
- export interface Options {
3
- urls?: string[] | ((routes: Route[]) => string[] | Promise<string[]>);
4
- }
5
- export default function staticAdapter(_options?: Options): Adapter;