asterflow 0.0.1 → 0.0.3

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.
@@ -1,36 +1,35 @@
1
1
  "use strict";
2
- var y = Object.defineProperty;
3
- var f = Object.getOwnPropertyDescriptor;
2
+ var c = Object.defineProperty;
3
+ var g = Object.getOwnPropertyDescriptor;
4
4
  var P = Object.getOwnPropertyNames;
5
5
  var w = Object.prototype.hasOwnProperty;
6
- var A = (r, e) => {
6
+ var A = (d, e) => {
7
7
  for (var t in e)
8
- y(r, t, { get: e[t], enumerable: !0 });
9
- }, M = (r, e, t, s) => {
8
+ c(d, t, { get: e[t], enumerable: !0 });
9
+ }, M = (d, e, t, s) => {
10
10
  if (e && typeof e == "object" || typeof e == "function")
11
11
  for (let n of P(e))
12
- !w.call(r, n) && n !== t && y(r, n, { get: () => e[n], enumerable: !(s = f(e, n)) || s.enumerable });
13
- return r;
12
+ !w.call(d, n) && n !== t && c(d, n, { get: () => e[n], enumerable: !(s = g(e, n)) || s.enumerable });
13
+ return d;
14
14
  };
15
- var I = (r) => M(y({}, "__esModule", { value: !0 }), r);
15
+ var I = (d) => M(c({}, "__esModule", { value: !0 }), d);
16
16
  // core/src/index.ts
17
17
  var C = {};
18
18
  A(C, {
19
19
  AsterFlow: () => v,
20
- AsterFlowInstance: () => h,
21
- joinPaths: () => R
20
+ AsterFlowInstance: () => h
22
21
  });
23
22
  module.exports = I(C);
24
23
  // core/src/controllers/Asterflow.ts
25
- var m = require("@asterflow/adapter"), p = require("@asterflow/response"), a = require("@asterflow/router"), l = require("@asterflow/url-parser"), x = require("reminist");
24
+ var p = require("@asterflow/adapter"), m = require("@asterflow/response"), u = require("@asterflow/router"), l = require("@asterflow/url-parser"), x = require("reminist");
26
25
  // core/src/utils/parser.ts
27
- function R(r, e) {
28
- return `${r}${e}`.replace(/\/{2,}/g, "/");
26
+ function y(d, e) {
27
+ return `${d}${e}`.replace(/\/{2,}/g, "/");
29
28
  }
30
29
  // core/src/controllers/Asterflow.ts
31
30
  var h = class {
32
31
  driver;
33
- reminist = new x.Reminist({ keys: Object.keys(a.MethodType) });
32
+ reminist = new x.Reminist({ keys: Object.keys(u.MethodType) });
34
33
  middlewares = [];
35
34
  plugins = {};
36
35
  onRequestPlugins = [];
@@ -38,40 +37,41 @@ var h = class {
38
37
  beforeInitializePlugins = [];
39
38
  afterInitializePlugins = [];
40
39
  constructor(e) {
41
- this.driver = e?.driver ?? m.adapters.node, this.driver.onRequest = this.handleRequest.bind(this);
40
+ this.driver = e?.driver ?? p.adapters.node, this.driver.onRequest = this.handleRequest.bind(this);
42
41
  }
43
42
  async handleRequest(e, t) {
44
- t = t ?? new p.AsterResponse(), await this.runHooks("onRequest", e, t);
45
- let s = () => t.notFound({
43
+ t = t ?? new m.AsterResponse();
44
+ let s = await this.runHooks("onRequest", e, t);
45
+ if (s) return s;
46
+ let n = () => t.notFound({
46
47
  statusCode: 404,
47
48
  code: "NOT_FOUND",
48
49
  message: `Unable to find route: ${e.getPathname()}`
49
- }), n = e.getMethod().toLowerCase();
50
- if (!n) return s();
51
- let o = this.reminist.find(n, e.url.getPathname());
52
- if (!o?.node?.store) return s();
53
- let i = o.node.store;
54
- e.url = e.url.withParser(i.url);
50
+ }), o = e.getMethod().toLowerCase();
51
+ if (!o) return n();
52
+ let r = this.reminist.find(o, e.url.getPathname());
53
+ if (!r?.node?.store) return n();
54
+ let i = r.node.store;
55
+ (i.url.ast.expressions.has(l.InternalExpression.Variable) || i.url.ast.expressions.has(l.InternalExpression.Slug)) && (e.url = e.url.withParser(i.url));
55
56
  try {
56
57
  return await this.runHandler(i, e, t), await this.runHooks("onResponse", e, t), t;
57
- } catch (d) {
58
- let c = {
58
+ } catch (a) {
59
+ return t.badRequest({
59
60
  statusCode: 400,
60
- message: d instanceof l.ErrorLog ? "AST_ERROR" : "ERROR",
61
- error: d instanceof l.ErrorLog ? d.message : d
62
- };
63
- return t.badRequest(c);
61
+ message: a instanceof l.ErrorLog ? "AST_ERROR" : "ERROR",
62
+ error: a instanceof l.ErrorLog ? a.message : a
63
+ });
64
64
  }
65
65
  }
66
66
  middleware(e) {
67
67
  for (let t of e.controllers) {
68
- let s = R(e.basePath, t.path);
68
+ let s = y(e.basePath, t.path);
69
69
  this.addEntry(t, s);
70
70
  }
71
71
  return this;
72
72
  }
73
73
  controller(e) {
74
- let t = R("/", e.path);
74
+ let t = y("/", e.path);
75
75
  return this.addEntry(e, t), this;
76
76
  }
77
77
  use(e, t) {
@@ -83,10 +83,10 @@ var h = class {
83
83
  return this;
84
84
  }
85
85
  router(e) {
86
- return this.controller(new a.Router(e)), this;
86
+ return this.controller(new u.Router(e)), this;
87
87
  }
88
88
  method(e) {
89
- return this.controller(new a.Method(e)), this;
89
+ return this.controller(new u.Method(e)), this;
90
90
  }
91
91
  async resolvePluginContexts() {
92
92
  for (let e in this.plugins) {
@@ -102,7 +102,7 @@ var h = class {
102
102
  await this.resolvePluginContexts(), await this.runHooks("beforeInitialize"), await this.driver.listen(...e), await this.runHooks("afterInitialize");
103
103
  }
104
104
  addEntry(e, t) {
105
- let s = e instanceof a.Method ? [e.method] : Object.keys(e.methods), n = { path: t, route: e, methods: s, url: new l.Analyze(t) };
105
+ let s = e instanceof u.Method ? [e.method] : Object.keys(e.methods), n = { path: t, route: e, methods: s, url: new l.Analyze(t) };
106
106
  for (let o of s)
107
107
  this.reminist.add(o, t, n);
108
108
  }
@@ -113,47 +113,61 @@ var h = class {
113
113
  case "beforeInitialize":
114
114
  case "afterInitialize":
115
115
  {
116
- let i = o.hooks[e];
117
- if (i)
118
- for (let d of i)
119
- await d(this, o.context);
116
+ let r = o.hooks[e];
117
+ if (r)
118
+ for (let i of r)
119
+ await i(this, o.context);
120
120
  }
121
121
  break;
122
122
  case "onRequest":
123
- case "onResponse": {
124
- if (!t || !s) return;
125
- for (let i of o.hooks.onRequest)
126
- await i({ request: t, response: s, context: o.context });
127
- }
123
+ {
124
+ if (!t || !s) return;
125
+ let r = o.hooks.onRequest;
126
+ if (r)
127
+ for (let i of r) {
128
+ let a = await i({ request: t, response: s, context: o.context });
129
+ if (a && typeof a == "object" && a.constructor?.name === "AsterResponse")
130
+ return a;
131
+ }
132
+ }
133
+ break;
134
+ case "onResponse":
135
+ {
136
+ if (!t || !s) return;
137
+ let r = o.hooks.onResponse;
138
+ if (r)
139
+ for (let i of r)
140
+ await i({ request: t, response: s, context: o.context });
141
+ }
142
+ break;
128
143
  }
129
144
  }
130
145
  async runHandler({ route: e }, t, s) {
131
- let n = t.getMethod().toLowerCase(), o = e instanceof a.Method ? e.handler : e.methods[n], i = e instanceof a.Method ? e.schema : e.schema?.[n];
146
+ let n = t.getMethod().toLowerCase(), o = e instanceof u.Method ? e.handler : e.methods[n], r = e instanceof u.Method ? e.schema : e.schema?.[n];
132
147
  if (!o) return null;
133
- if (i) {
134
- let u = i.safeParse(t.getBody());
135
- if (!u.success)
148
+ if (r) {
149
+ let R = r.safeParse(await t.getBody());
150
+ if (!R.success)
136
151
  return s.validationError({
137
152
  statusCode: 422,
138
153
  message: "VALIDATION_ERROR",
139
- error: u.error
154
+ error: R.error
140
155
  });
141
- s.send(u.data);
156
+ s.send(R.data);
142
157
  }
143
- let d = Object.values(this.plugins).reduce((u, g) => ({ ...u, ...g.context }), {}), c = {
158
+ let i = Object.values(this.plugins).reduce((R, f) => ({ ...R, ...f.context }), {}), a = {
144
159
  instance: this,
145
160
  request: t,
146
161
  response: s,
147
162
  url: t.url,
148
163
  schema: t.getBody(),
149
164
  middleware: {},
150
- plugins: d
165
+ plugins: i
151
166
  };
152
- return o(c);
167
+ return o(a);
153
168
  }
154
169
  }, v = h;
155
170
  0 && (module.exports = {
156
171
  AsterFlow,
157
- AsterFlowInstance,
158
- joinPaths
172
+ AsterFlowInstance
159
173
  });
package/dist/mjs/index.js CHANGED
@@ -1,13 +1,13 @@
1
1
  // core/src/controllers/Asterflow.ts
2
2
  import { adapters as m } from "@asterflow/adapter";
3
- import { AsterResponse as p } from "@asterflow/response";
3
+ import { AsterResponse as x } from "@asterflow/response";
4
4
  import {
5
- Method as d,
6
- MethodType as x,
5
+ Method as u,
6
+ MethodType as f,
7
7
  Router as g
8
8
  } from "@asterflow/router";
9
- import { Analyze as f, ErrorLog as c } from "@asterflow/url-parser";
10
- import { Reminist as P } from "reminist";
9
+ import { Analyze as P, ErrorLog as c, InternalExpression as y } from "@asterflow/url-parser";
10
+ import { Reminist as w } from "reminist";
11
11
  // core/src/utils/parser.ts
12
12
  function l(h, e) {
13
13
  return `${h}${e}`.replace(/\/{2,}/g, "/");
@@ -15,7 +15,7 @@ function l(h, e) {
15
15
  // core/src/controllers/Asterflow.ts
16
16
  var R = class {
17
17
  driver;
18
- reminist = new P({ keys: Object.keys(x) });
18
+ reminist = new w({ keys: Object.keys(f) });
19
19
  middlewares = [];
20
20
  plugins = {};
21
21
  onRequestPlugins = [];
@@ -26,26 +26,27 @@ var R = class {
26
26
  this.driver = e?.driver ?? m.node, this.driver.onRequest = this.handleRequest.bind(this);
27
27
  }
28
28
  async handleRequest(e, t) {
29
- t = t ?? new p(), await this.runHooks("onRequest", e, t);
30
- let s = () => t.notFound({
29
+ t = t ?? new x();
30
+ let s = await this.runHooks("onRequest", e, t);
31
+ if (s) return s;
32
+ let n = () => t.notFound({
31
33
  statusCode: 404,
32
34
  code: "NOT_FOUND",
33
35
  message: `Unable to find route: ${e.getPathname()}`
34
- }), n = e.getMethod().toLowerCase();
35
- if (!n) return s();
36
- let o = this.reminist.find(n, e.url.getPathname());
37
- if (!o?.node?.store) return s();
38
- let r = o.node.store;
39
- e.url = e.url.withParser(r.url);
36
+ }), o = e.getMethod().toLowerCase();
37
+ if (!o) return n();
38
+ let r = this.reminist.find(o, e.url.getPathname());
39
+ if (!r?.node?.store) return n();
40
+ let i = r.node.store;
41
+ (i.url.ast.expressions.has(y.Variable) || i.url.ast.expressions.has(y.Slug)) && (e.url = e.url.withParser(i.url));
40
42
  try {
41
- return await this.runHandler(r, e, t), await this.runHooks("onResponse", e, t), t;
42
- } catch (i) {
43
- let u = {
43
+ return await this.runHandler(i, e, t), await this.runHooks("onResponse", e, t), t;
44
+ } catch (a) {
45
+ return t.badRequest({
44
46
  statusCode: 400,
45
- message: i instanceof c ? "AST_ERROR" : "ERROR",
46
- error: i instanceof c ? i.message : i
47
- };
48
- return t.badRequest(u);
47
+ message: a instanceof c ? "AST_ERROR" : "ERROR",
48
+ error: a instanceof c ? a.message : a
49
+ });
49
50
  }
50
51
  }
51
52
  middleware(e) {
@@ -71,7 +72,7 @@ var R = class {
71
72
  return this.controller(new g(e)), this;
72
73
  }
73
74
  method(e) {
74
- return this.controller(new d(e)), this;
75
+ return this.controller(new u(e)), this;
75
76
  }
76
77
  async resolvePluginContexts() {
77
78
  for (let e in this.plugins) {
@@ -87,7 +88,7 @@ var R = class {
87
88
  await this.resolvePluginContexts(), await this.runHooks("beforeInitialize"), await this.driver.listen(...e), await this.runHooks("afterInitialize");
88
89
  }
89
90
  addEntry(e, t) {
90
- let s = e instanceof d ? [e.method] : Object.keys(e.methods), n = { path: t, route: e, methods: s, url: new f(t) };
91
+ let s = e instanceof u ? [e.method] : Object.keys(e.methods), n = { path: t, route: e, methods: s, url: new P(t) };
91
92
  for (let o of s)
92
93
  this.reminist.add(o, t, n);
93
94
  }
@@ -105,27 +106,42 @@ var R = class {
105
106
  }
106
107
  break;
107
108
  case "onRequest":
108
- case "onResponse": {
109
- if (!t || !s) return;
110
- for (let r of o.hooks.onRequest)
111
- await r({ request: t, response: s, context: o.context });
112
- }
109
+ {
110
+ if (!t || !s) return;
111
+ let r = o.hooks.onRequest;
112
+ if (r)
113
+ for (let i of r) {
114
+ let a = await i({ request: t, response: s, context: o.context });
115
+ if (a && typeof a == "object" && a.constructor?.name === "AsterResponse")
116
+ return a;
117
+ }
118
+ }
119
+ break;
120
+ case "onResponse":
121
+ {
122
+ if (!t || !s) return;
123
+ let r = o.hooks.onResponse;
124
+ if (r)
125
+ for (let i of r)
126
+ await i({ request: t, response: s, context: o.context });
127
+ }
128
+ break;
113
129
  }
114
130
  }
115
131
  async runHandler({ route: e }, t, s) {
116
- let n = t.getMethod().toLowerCase(), o = e instanceof d ? e.handler : e.methods[n], r = e instanceof d ? e.schema : e.schema?.[n];
132
+ let n = t.getMethod().toLowerCase(), o = e instanceof u ? e.handler : e.methods[n], r = e instanceof u ? e.schema : e.schema?.[n];
117
133
  if (!o) return null;
118
134
  if (r) {
119
- let a = r.safeParse(t.getBody());
120
- if (!a.success)
135
+ let d = r.safeParse(await t.getBody());
136
+ if (!d.success)
121
137
  return s.validationError({
122
138
  statusCode: 422,
123
139
  message: "VALIDATION_ERROR",
124
- error: a.error
140
+ error: d.error
125
141
  });
126
- s.send(a.data);
142
+ s.send(d.data);
127
143
  }
128
- let i = Object.values(this.plugins).reduce((a, y) => ({ ...a, ...y.context }), {}), u = {
144
+ let i = Object.values(this.plugins).reduce((d, p) => ({ ...d, ...p.context }), {}), a = {
129
145
  instance: this,
130
146
  request: t,
131
147
  response: s,
@@ -134,11 +150,10 @@ var R = class {
134
150
  middleware: {},
135
151
  plugins: i
136
152
  };
137
- return o(u);
153
+ return o(a);
138
154
  }
139
- }, O = R;
155
+ }, k = R;
140
156
  export {
141
- O as AsterFlow,
142
- R as AsterFlowInstance,
143
- l as joinPaths
157
+ k as AsterFlow,
158
+ R as AsterFlowInstance
144
159
  };
@@ -2,9 +2,10 @@ import { Runtime, type Adapter, type AnyAdapter } from '@asterflow/adapter';
2
2
  import type { AnyPlugins, InferConfigArgument, InferPluginExtension, Plugin, ResolvedPlugin } from '@asterflow/plugin';
3
3
  import { type Responders } from '@asterflow/response';
4
4
  import { Method, Router, type AnyMiddleware, type AnyMiddlewares, type AnyRouter, type AnySchema, type MethodHandler, type MethodKeys, type MethodOptions, type Middleware, type MiddlewareOutput, type RouteHandler, type RouterOptions, type SchemaDynamic } from '@asterflow/router';
5
+ import { type NormalizePath } from '@asterflow/url-parser';
5
6
  import { Reminist } from 'reminist';
6
7
  import type { AsterFlowOptions } from '../types/asterflow';
7
- import type { ExtractPaths, InferPath, NormalizePath } from '../types/paths';
8
+ import type { ExtractPaths, InferPath } from '../types/paths';
8
9
  import type { AnyReminist, InferReministContext, InferReministPath } from '../types/reminist';
9
10
  import type { BuildRouteContext, BuildRoutesContext, RouteEntry } from '../types/routes';
10
11
  import type { AnyRecord } from '../types/utils';
@@ -71,6 +72,7 @@ export declare class AsterFlowInstance<const Drive extends AnyAdapter = Adapter<
71
72
  private addEntry;
72
73
  /**
73
74
  * Executes the hook handlers for a specific hook name.
75
+ * For onRequest hooks, returns the response if any plugin returns one (to stop execution flow).
74
76
  */
75
77
  private runHooks;
76
78
  /**
@@ -5,4 +5,3 @@ export * from './types/plugin';
5
5
  export * from './types/reminist';
6
6
  export * from './types/routes';
7
7
  export * from './types/utils';
8
- export * from './utils/parser';
@@ -1,33 +1,5 @@
1
1
  import type { AnyRouter, Method, Router } from '@asterflow/router';
2
- /**
3
- * Removes the fragment identifier from a URL path.
4
- * @example
5
- * // '/page#about' -> '/page'
6
- */
7
- type RemoveFragment<Path extends string> = Path extends `${infer CleanPath}#${string}` ? CleanPath : Path;
8
- /**
9
- * Removes the query string from a URL path.
10
- * @example
11
- * // '/users?data=1' -> '/users'
12
- */
13
- type RemoveQueryString<Path extends string> = Path extends `${infer CleanPath}?${string}` ? CleanPath : Path;
14
- /**
15
- * Removes type definitions from path segments.
16
- * Recursively processes the path to clean parts like '=number'.
17
- * @example
18
- * // '/users/:id=number' -> '/users/:id'
19
- */
20
- type SanitizeSegments<Path extends string> = Path extends `/${infer Rest}` ? `/${SanitizeSegments<Rest>}` : Path extends `${infer Segment}/${infer Rest}` ? `${(Segment extends `${infer Name}=${string}` ? Name : Segment)}/${SanitizeSegments<Rest>}` : Path extends `${infer Name}=${string}` ? Name : Path;
21
- /**
22
- * Normalizes a URL path by performing several cleaning operations:
23
- * 1. Replaces double slashes ('//') with a single slash.
24
- * 2. Removes the URL fragment (e.g., '#about').
25
- * 3. Removes the query string (e.g., '?data=1').
26
- * 4. Removes type definitions from path segments (e.g., ':id=number' -> ':id').
27
- * @example
28
- * // '/users//:id=number?data=1#profile' -> '/users/:id'
29
- */
30
- export type NormalizePath<Path extends string> = Path extends `${infer Head}//${infer Tail}` ? NormalizePath<`${Head}/${Tail}`> : SanitizeSegments<RemoveQueryString<RemoveFragment<Path>>>;
2
+ import type { NormalizePath } from '@asterflow/url-parser';
31
3
  /**
32
4
  * Combines a base path with a relative path and normalizes the result.
33
5
  */
@@ -43,4 +15,3 @@ export type InferPath<T> = T extends Router<any, infer P, any, any, any, any> ?
43
15
  export type ExtractPaths<Base extends string, Routes extends readonly AnyRouter[]> = {
44
16
  [K in keyof Routes]: Routes[K] extends infer R extends AnyRouter ? CombinePaths<Base, InferPath<R>> : never;
45
17
  };
46
- export {};
@@ -1,7 +1,7 @@
1
1
  import type { AnyRouter, MethodKeys } from '@asterflow/router';
2
- import type { CombinePaths, InferPath, NormalizePath } from './paths';
2
+ import type { CombinePaths, InferPath } from './paths';
3
3
  import type { UnionToIntersection } from './utils';
4
- import type { Analyze } from '@asterflow/url-parser';
4
+ import type { Analyze, NormalizePath } from '@asterflow/url-parser';
5
5
  /**
6
6
  * Builds the context for a single route, inferring the path and associating the route entry.
7
7
  */
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "asterflow",
3
- "version": "0.0.1",
3
+ "version": "0.0.3",
4
4
  "main": "dist/cjs/index.cjs",
5
5
  "module": "dist/mjs/index.js",
6
6
  "types": "dist/types/index.d.ts",
@@ -27,19 +27,18 @@
27
27
  "node": ">=20"
28
28
  },
29
29
  "scripts": {
30
- "dev": "bun run --inspect=ws://localhost:6499 src/index.ts",
31
- "exemple": "bun run --inspect-brk=ws://localhost:6499 src/exemple.ts"
30
+ "dev": "bun run --inspect=ws://localhost:6499 src/index.ts"
32
31
  },
33
32
  "peerDependencies": {
34
- "zod": "^3.25.63",
33
+ "zod": "^3.25.67",
35
34
  "typescript": "^5.8.3"
36
35
  },
37
36
  "dependencies": {
38
- "@asterflow/adapter": "1.0.9",
39
- "@asterflow/plugin": "1.0.5",
40
- "@asterflow/response": "1.0.6",
41
- "@asterflow/router": "1.0.9",
42
- "@asterflow/url-parser": "^2.0.1",
37
+ "@asterflow/adapter": "1.0.11",
38
+ "@asterflow/plugin": "1.0.7",
39
+ "@asterflow/response": "1.0.8",
40
+ "@asterflow/router": "1.0.11",
41
+ "@asterflow/url-parser": "^2.0.3",
43
42
  "reminist": "^1.0.5"
44
43
  }
45
44
  }