diff --git a/ReadMe.md b/ReadMe.md
index 82733a8..0dc122a 100644
--- a/ReadMe.md
+++ b/ReadMe.md
@@ -1,5 +1,7 @@
**Welcome to Vixeny: Revolutionize Your Web Development**
+`Status : Currectly restructuring the project for the beta`
+
diff --git a/components/encode/test/b64toUrl.test.mjs b/components/encode/test/b64toUrl.test.mjs
deleted file mode 100644
index 07d3656..0000000
--- a/components/encode/test/b64toUrl.test.mjs
+++ /dev/null
@@ -1,12 +0,0 @@
-import convertBase64urlToBase64 from "../b64UrlTob64.mjs"; // Adjust this import to the name of your file
-const convert = convertBase64urlToBase64(); // Since it's a higher order function
-import test from "../../util/test.mjs";
-
-((test) => (describe) => (
- test("Converts valid base64url to base64", () =>
- describe(convert("SGVsbG8tV29ybGQ_")).toEqual("SGVsbG8tV29ybGQ/")),
- test("Adds padding for valid base64url strings", () =>
- describe(convert("U28")).toEqual("U28=")),
- test("Returns null for invalid base64url strings", () =>
- describe(convert("Invalid*String")).toEqual(null))
-))(test.test)(test.describe);
diff --git a/components/encode/test/stringify/composer/finder.test.mjs b/components/encode/test/stringify/composer/finder.test.mjs
deleted file mode 100644
index c1f000f..0000000
--- a/components/encode/test/stringify/composer/finder.test.mjs
+++ /dev/null
@@ -1,21 +0,0 @@
-import convert from "../../../src/stringify/composer/finder.mjs";
-import test from "../../../../util/test.mjs";
-
-((test) => (describe) => (
- test("hello - Test finder with nested object property", () =>
- describe(convert({
- type: "object",
- properties: {
- hello: {
- type: "object",
- properties: {
- hello: { type: "string" },
- },
- },
- },
- required: ["hello"],
- }))
- .toEqual(
- `"{" +'"hello":{' + '"hello":' + (typeof o.hello.hello === "string"?str(o.hello.hello):'null') + "}" + "}"`,
- ))
-))(test.test)(test.describe);
diff --git a/components/encode/test/stringify/composer/main.test.mjs b/components/encode/test/stringify/composer/main.test.mjs
deleted file mode 100644
index 3b735ca..0000000
--- a/components/encode/test/stringify/composer/main.test.mjs
+++ /dev/null
@@ -1,79 +0,0 @@
-import convert from "../../../src/stringify/safe.mjs"; // Adjust this import to the name of your file
-
-import test from "../../../../util/test.mjs";
-
-((test) => (describe) => (
- test("hello - Test composer with simple string property", () =>
- describe(JSON.parse(
- convert({
- type: "object",
- properties: {
- hello: { type: "string" },
- },
- required: ["hello"],
- })({ hello: 'wo"rld' }),
- ))
- .toEqual({ hello: 'wo"rld' })),
- test("hello - Test composer with nested object property", () =>
- describe(JSON.parse(
- convert({
- type: "object",
- properties: {
- hello: {
- type: "object",
- properties: {
- hello: { type: "string" },
- },
- required: ["hello"],
- },
- },
- required: ["hello"],
- })({ hello: { hello: "hi" } }),
- ))
- .toEqual({ hello: { hello: "hi" } })),
- test("hello - Test composer with deeply nested object property", () =>
- describe(JSON.parse(
- convert({
- type: "object",
- properties: {
- hello: {
- type: "object",
- properties: {
- hello: {
- type: "object",
- properties: {
- hello: { type: "string" },
- },
- required: ["hello"],
- },
- },
- required: ["hello"],
- },
- },
- required: ["hello"],
- })({ hello: { hello: { hello: "string" } } }),
- ))
- .toEqual({ hello: { hello: { hello: "string" } } })),
- test("hello - Test composer with number property and explicit value", () =>
- describe(JSON.parse(
- convert({
- type: "object",
- properties: {
- hello: { type: "number", default: 2 },
- },
- required: ["hello"],
- })({ hello: 1 }),
- ))
- .toEqual({ hello: 1 })),
- test("hello - Test composer with number property and default value", () =>
- describe(JSON.parse(
- convert({
- type: "object",
- properties: {
- hello: { type: "number", default: 2 },
- },
- required: ["hello"],
- })({}),
- ))
- .toEqual({ hello: 2 }))
-))(test.test)(test.describe);
diff --git a/components/encode/test/stringify/composer/sameMatch.test.mjs b/components/encode/test/stringify/composer/sameMatch.test.mjs
deleted file mode 100644
index b9c3f52..0000000
--- a/components/encode/test/stringify/composer/sameMatch.test.mjs
+++ /dev/null
@@ -1,95 +0,0 @@
-import convert from "../../../src/stringify/safe.mjs"; // Adjust this import to the name of your file
-import test from "../../../../util/test.mjs";
-
-((test) => (describe) => (
- test("hello - Test composer with simple string property", () =>
- describe(
- convert({
- type: "object",
- properties: {
- hello: { type: "string" },
- },
- required: ["hello"],
- })({ hello: 'wo"rld' }),
- )
- .toEqual(JSON.stringify({ hello: 'wo"rld' }))),
- test("hello - Test composer with nested object property", () =>
- describe(
- convert({
- type: "object",
- properties: {
- hello: {
- type: "object",
- properties: {
- hello: { type: "string" },
- },
- required: ["hello"],
- },
- },
- required: ["hello"],
- })({ hello: { hello: "hi" } }),
- )
- .toEqual(JSON.stringify({ hello: { hello: "hi" } }))),
- test("hello - Test composer with deeply nested object property", () =>
- describe(
- convert({
- type: "object",
- properties: {
- hello: {
- type: "object",
- properties: {
- hello: {
- type: "object",
- properties: {
- hello: { type: "string" },
- },
- required: ["hello"],
- },
- },
- required: ["hello"],
- },
- },
- required: ["hello"],
- })({ hello: { hello: { hello: "string" } } }),
- )
- .toEqual(JSON.stringify({ hello: { hello: { hello: "string" } } }))),
- test("hello - Test composer with number property and explicit value", () =>
- describe(
- convert({
- type: "object",
- properties: {
- hello: { type: "number", default: 2 },
- },
- required: ["hello"],
- })({ hello: 1 }),
- )
- .toEqual(JSON.stringify({ hello: 1 }))),
- test("hello - Test composer with number property and default value", () =>
- describe(
- convert({
- type: "object",
- properties: {
- hello: { type: "number", default: 2 },
- },
- required: ["hello"],
- })({}),
- )
- .toEqual(JSON.stringify({ hello: 2 }))),
- test("hello - Test composer with multiple properties including array", () =>
- describe(
- convert({
- type: "object",
- properties: {
- hello: { type: "number", default: 2 },
- string: { type: "string", default: "hello" },
- array: { type: "array" },
- },
- required: ["hello", "string", "array"],
- })({ array: ["hello", 2, ["hello", 2]] }),
- )
- .toEqual(JSON.stringify({
- hello: 2,
- string: "hello",
- array: ["hello", 2, ["hello", 2]],
- })))
-))(test.test)(test.describe);
diff --git a/components/encode/test/stringify/composer/selector.test.mjs b/components/encode/test/stringify/composer/selector.test.mjs
deleted file mode 100644
index f9af2ab..0000000
--- a/components/encode/test/stringify/composer/selector.test.mjs
+++ /dev/null
@@ -1,13 +0,0 @@
-import convert from "../../../src/stringify/composer/selector.mjs"; // Adjust this import to the name of your file
-import test from "../../../../util/test.mjs";
-
-((test) => (describe) => (
- test("hello - Test selector with string type and constant value", () =>
- describe(convert([{
- type: "string",
- name: "hello2",
- required: false,
- const: "world",
- }]))
- .toEqual(`'"hello2":"world"'`))
-))(test.test)(test.describe);
diff --git a/components/encode/test/stringify/methods/boolean.test.mjs b/components/encode/test/stringify/methods/boolean.test.mjs
deleted file mode 100644
index 905f11f..0000000
--- a/components/encode/test/stringify/methods/boolean.test.mjs
+++ /dev/null
@@ -1,47 +0,0 @@
-import convert from "../../../src/stringify/methods/json_boolean.mjs"; // Adjust this import to the name of your file
-
-import test from "../../../../util/test.mjs";
-
-((test) => (describe) => (
- test("hello - Handles boolean with constant value", () =>
- describe(convert({
- type: "boolean",
- name: "hello",
- required: true,
- const: true,
- path: ".hello",
- }))
- .toEqual(`'"hello":' + true`)),
- test("hello - Handles required boolean with name and path", () =>
- describe(convert({
- type: "boolean",
- name: "hello",
- required: true,
- path: ".hello",
- }))
- .toEqual(`'"hello":'+( typeof o.hello === "boolean"?o.hello:'null')`)),
- test("hello - Handles required boolean with default value", () =>
- describe(convert({
- type: "boolean",
- name: "hello",
- required: true,
- default: true,
- path: ".hello",
- }))
- .toEqual(`'"hello":'+( typeof o.hello === "boolean"?o.hello:'true')`)),
- test("hello - Compares required and optional boolean with default value", () =>
- describe(convert({
- type: "boolean",
- name: "hello",
- required: true,
- default: true,
- path: ".hello",
- }))
- .toEqual(convert({
- type: "boolean",
- name: "hello",
- required: false,
- default: true,
- path: ".hello",
- })))
-))(test.test)(test.describe);
diff --git a/components/encode/test/stringify/methods/number.test.mjs b/components/encode/test/stringify/methods/number.test.mjs
deleted file mode 100644
index 1ee44a0..0000000
--- a/components/encode/test/stringify/methods/number.test.mjs
+++ /dev/null
@@ -1,49 +0,0 @@
-import convert from "../../../src/stringify/methods/json_number.mjs"; // Adjust this import to the name of your file
-
-import test from "../../../../util/test.mjs";
-
-((test) => (describe) => (
- test("hello - Handles number with constant value", () =>
- describe(convert({
- type: "number",
- name: "hello",
- required: true,
- const: 1,
- path: ".hello",
- }))
- .toEqual(`'"hello":' + 1`)),
- test("hello - Handles required number with name and path", () =>
- describe(
- convert({
- type: "number",
- name: "hello",
- required: true,
- path: ".hello",
- }),
- )
- .toEqual(`'"hello":'+( typeof o.hello === "number"?o.hello:'null')`)),
- test("hello - Handles optional number with default value", () =>
- describe(convert({
- type: "number",
- name: "hello",
- required: false,
- default: 5,
- path: ".hello",
- }))
- .toEqual(`'"hello":'+( typeof o.hello === "number"?o.hello:'5')`)),
- test("hello - Compares required and optional number with default value", () =>
- describe(convert({
- type: "number",
- name: "hello",
- required: true,
- default: 5,
- path: ".hello",
- }))
- .toEqual(convert({
- type: "number",
- name: "hello",
- required: false,
- default: 5,
- path: ".hello",
- })))
-))(test.test)(test.describe);
diff --git a/components/encode/test/stringify/methods/strings.test.mjs b/components/encode/test/stringify/methods/strings.test.mjs
deleted file mode 100644
index e38cfa2..0000000
--- a/components/encode/test/stringify/methods/strings.test.mjs
+++ /dev/null
@@ -1,48 +0,0 @@
-import convert from "../../../src/stringify/methods/json_string.mjs";
-
-import test from "../../../../util/test.mjs";
-
-((test) => (describe) => (
- test("string - Handles required string with name and path", () =>
- describe(
- convert({
- type: "string",
- name: "hello",
- required: true,
- path: ".hello",
- }),
- )
- .toEqual(`'"hello":' + str(o.hello)`)),
- test("string - Handles optional string with name and path", () =>
- describe(convert({
- type: "string",
- name: "hello",
- required: false,
- path: ".hello",
- }))
- .toEqual(
- `'"hello":' + (typeof o.hello === "string"?str(o.hello):'null')`,
- )),
- test("string - Handles required string with constant value", () =>
- describe(
- convert({ type: "string", name: "hello", required: true, const: "hi" }),
- )
- .toEqual(`'"hello":"hi"'`)),
- test("string - Compares required and optional string with default value", () =>
- describe(
- convert({
- type: "string",
- name: "hello",
- required: true,
- default: "hi",
- }),
- )
- .toEqual(
- convert({
- type: "string",
- name: "hello",
- required: false,
- default: "hi",
- }),
- ))
-))(test.test)(test.describe);
diff --git a/components/http/src/framework/optimizer/branch/table.ts b/components/http/src/framework/optimizer/branch/table.ts
deleted file mode 100644
index 1a7f2c7..0000000
--- a/components/http/src/framework/optimizer/branch/table.ts
+++ /dev/null
@@ -1,27 +0,0 @@
-import aComposer, { specialOptions } from "../aComposer.ts";
-import isUsing from "../tools/isUsing.ts";
-import { BranchOptions } from "./types.ts";
-
-export default (o?: specialOptions) =>
-(path: string) =>
-(table: BranchOptions) =>
- table
- .map((x) => ({ ...x, path: path }))
- .map((x) => ({
- name: x.name,
- f: (
- (composed) =>
- x.f.constructor.name === "AsyncFunction" ||
- composed.constructor.name === "AsyncFunction"
- ? ((a) =>
- (k: (arg0: any) => any) =>
- (r: Request) =>
- async (b: unknown) => await k(a(r)(b)))(composed)(x.f)
- : ((a) => (k: (arg0: any) => any) => (r: Request) => (b: unknown) =>
- k(a(r)(b)))(composed)(x.f)
- )(
- aComposer(o ? { ...aComposer, branch: false } : { branch: false })(x)(
- isUsing(o)(x),
- ),
- ),
- }));
diff --git a/components/http/src/framework/optimizer/branch/types.ts b/components/http/src/framework/optimizer/branch/types.ts
deleted file mode 100644
index 7877ca1..0000000
--- a/components/http/src/framework/optimizer/branch/types.ts
+++ /dev/null
@@ -1,9 +0,0 @@
-import { AnyMorphism, PetitionOptions, RawCommonRequest } from "../types.ts";
-
-export type BranchOption = AnyMorphism & {
- name: string;
- options?: PetitionOptions;
-};
-export type BranchOptions = BranchOption[];
-
-export type ResponseResponse = (r: Request) => unknown;
diff --git a/components/http/src/framework/optimizer/checkAsync.ts b/components/http/src/framework/optimizer/checkAsync.ts
deleted file mode 100644
index 040f35d..0000000
--- a/components/http/src/framework/optimizer/checkAsync.ts
+++ /dev/null
@@ -1,15 +0,0 @@
-// deno-lint-ignore-file
-import { CommonRequestMorphism, RequestMorphism } from "./types.ts";
-
-type RecFunc = (f: CommonRequestMorphism | RequestMorphism) => boolean;
-
-export default (f: CommonRequestMorphism | RequestMorphism) =>
- f.f.constructor.name === "AsyncFunction"
- ? true
- : f.f.constructor.name === "Function" && typeof f.resolve == "undefined"
- ? false
- : "resolve" in f && f.resolve && Object.keys(f.resolve).some(
- (x) => f.resolve && f.resolve[x].f.constructor.name === "AsyncFunction",
- )
- ? true
- : false;
diff --git a/components/http/src/framework/optimizer/injectHtml.ts b/components/http/src/framework/optimizer/injectHtml.ts
deleted file mode 100644
index cc9c13d..0000000
--- a/components/http/src/framework/optimizer/injectHtml.ts
+++ /dev/null
@@ -1,34 +0,0 @@
-export default ((appendString: string) =>
-async (aResponse: Response | Promise) =>
- (
- (response) =>
- (response.headers.get("Content-Type") || "").includes("text/html")
- ? (async (clonedResponse) =>
- new Response(
- (await clonedResponse.text()) + appendString,
- {
- status: clonedResponse.status,
- statusText: clonedResponse.statusText,
- headers: new Headers(clonedResponse.headers),
- },
- ))(
- response.clone(),
- )
- : response
- )(
- await aResponse,
- ))(`
-
-
-`);
diff --git a/components/http/src/framework/optimizer/optimize.ts b/components/http/src/framework/optimizer/optimize.ts
deleted file mode 100644
index 6e74fcc..0000000
--- a/components/http/src/framework/optimizer/optimize.ts
+++ /dev/null
@@ -1,96 +0,0 @@
-import { FunRouterOptions } from "../../../types.ts";
-import { RouteTypes } from "../builder/types.ts";
-import {
- AnyMorphismMap,
- CommonRequestMorphism,
- CryptoOptions,
- MorphismMap,
- ObjectRawResponseReturn,
- ObjectRawResponseStatic,
- ParamOptions,
- QueryOptions,
- RequestMorphism,
-} from "./types.ts";
-import response from "./response.ts";
-import staticFiles from "./staticFiles/main.ts";
-import vixeny from "../../../serve.ts";
-import injectHtml from "./injectHtml.ts";
-
-export default (
- o?: FunRouterOptions,
-): <
- T extends MorphismMap,
- B extends AnyMorphismMap,
- Q extends QueryOptions,
- P extends ParamOptions,
- O extends FunRouterOptions,
- CR extends CryptoOptions,
->(routes: (
- | RequestMorphism
- | CommonRequestMorphism
- | ObjectRawResponseReturn
- | ObjectRawResponseStatic
-)[]) => RouteTypes[] =>
-(ar) =>
- ar
- .map(
- (x) =>
- "type" in x
- ? x.type === "response"
- ? [
- x?.method ? x.method : "GET",
- x.path,
- o && o.enableLiveReloading
- ? async (r: Request) => await injectHtml(x.r(r))
- : x.r,
- false,
- ] as RouteTypes
- : x.type === "fileServer"
- ? [
- "GET",
- x.name + "*",
- vixeny({
- ...o,
- stateFlags: {
- ...(o && o?.stateFlags ? o.stateFlags : {}),
- isFileServer: true,
- ...("slashIs" in x && typeof x.slashIs === "string"
- ? { slashIs: x.slashIs }
- : {}),
- },
- })(staticFiles(x)),
- "static",
- ] as RouteTypes
- : [
- x?.method ? x.method : "GET",
- x.path,
- o && o.enableLiveReloading
- ? async (r: Request) =>
- await injectHtml(
- response(o)(x as unknown as CommonRequestMorphism)(r),
- )
- : response(o)(x as unknown as CommonRequestMorphism),
-
- false,
- ] as unknown as RouteTypes
- : [
- x?.method ? x.method : "GET",
- x.path,
- o && o.enableLiveReloading
- ? async (r: Request) =>
- await injectHtml(
- response(o)(x as unknown as CommonRequestMorphism)(r),
- )
- : response(o)(x as unknown as CommonRequestMorphism),
- false,
- ] as unknown as RouteTypes,
- ).concat(
- o && o.enableLiveReloading
- ? [[
- "GET",
- "/timestamp-for-reload",
- ((t) => () => new Response(t))(Date.now().toString()),
- false,
- ]]
- : [],
- );
diff --git a/components/http/src/framework/optimizer/recursiveCheckAsync.ts b/components/http/src/framework/optimizer/recursiveCheckAsync.ts
deleted file mode 100644
index d85f9cb..0000000
--- a/components/http/src/framework/optimizer/recursiveCheckAsync.ts
+++ /dev/null
@@ -1,35 +0,0 @@
-import { CommonRequestMorphism, RequestMorphism } from "./types.ts";
-
-type RecFunc = (f: CommonRequestMorphism | RequestMorphism) => boolean;
-
-export default ((f: (x: RecFunc) => RecFunc) =>
- ((x: (arg: any) => any) => (v: any) => x(x)(v))(
- (x: (arg: any) => any) => (v: any) =>
- f((y: CommonRequestMorphism | RequestMorphism) => x(x)(y))(v),
- ))(
- (solver: RecFunc) => (f: CommonRequestMorphism | RequestMorphism) =>
- f.f.constructor.name === "AsyncFunction" || ("isAsync" in f && f.isAsync)
- ? true
- : f.f.constructor.name === "Function" &&
- typeof f.resolve === "undefined"
- ? false
- : ("resolve" in f && f.resolve &&
- Object.keys(f.resolve).some((ob) =>
- f.resolve &&
- solver(
- f.resolve[ob] as unknown as
- | CommonRequestMorphism
- | RequestMorphism,
- )
- )) ??
- ("branch" in f && f.branch &&
- Object.keys(f.branch).some((ob) =>
- f.branch &&
- solver(
- f.branch[ob] as unknown as
- | CommonRequestMorphism
- | RequestMorphism,
- )
- )) ??
- false,
- ) as unknown as (f: CommonRequestMorphism | RequestMorphism) => boolean;
diff --git a/components/http/src/framework/optimizer/resolve/table.ts b/components/http/src/framework/optimizer/resolve/table.ts
deleted file mode 100644
index cd7c12a..0000000
--- a/components/http/src/framework/optimizer/resolve/table.ts
+++ /dev/null
@@ -1,26 +0,0 @@
-import elements from "../../../util/elements.ts";
-import { FunRouterOptions } from "../../../../types.ts";
-import aComposer from "../aComposer.ts";
-import checker from "../checker.ts";
-import { CommonRequestMorphism } from "../types.ts";
-import { ResolveOptions } from "./types.ts";
-import isUsing from "../tools/isUsing.ts";
-
-export default (o?: FunRouterOptions) =>
-(path: string) =>
-(table: ResolveOptions) =>
- table
- .map((x) => ({ ...x, path: path }))
- .map((x) => ({
- name: x.name,
- f: (
- (composed) =>
- x.f.constructor.name === "AsyncFunction" ||
- composed.constructor.name === "AsyncFunction"
- ? ((a) => (k: (arg0: any) => any) => async (r: Request) =>
- await k(await a(r)))(composed)(x.f)
- : ((a) => (k: (arg0: any) => any) => (r: Request) => k(a(r)))(
- composed,
- )(x.f)
- )(aComposer(o)(x as CommonRequestMorphism)(isUsing(o)(x))),
- }));
diff --git a/components/http/src/framework/optimizer/staticFiles/getDir.ts b/components/http/src/framework/optimizer/staticFiles/getDir.ts
deleted file mode 100644
index 60ab930..0000000
--- a/components/http/src/framework/optimizer/staticFiles/getDir.ts
+++ /dev/null
@@ -1,16 +0,0 @@
-import syncCheckDir from "../syncCheckDir.ts";
-import bunSyncCheckDir from "../syncCheckDir_Bun.ts";
-import denoCheckRead from "../checkRead_Deno.ts";
-import joiner from "../../../../../util/joiner.mjs";
-
-export default (s: string) =>
- (
- (denoCheck) =>
- typeof denoCheck == "string"
- ? syncCheckDir(s).map((y) => y[0]).flat()
- : bunSyncCheckDir(joiner)(denoCheck.getFiles)(denoCheck.stats)(
- s,
- ).map((y) => y[0]).flat()
- )(
- denoCheckRead,
- );
diff --git a/components/http/src/framework/optimizer/staticFiles/mime.ts b/components/http/src/framework/optimizer/staticFiles/mime.ts
deleted file mode 100644
index 7c1e585..0000000
--- a/components/http/src/framework/optimizer/staticFiles/mime.ts
+++ /dev/null
@@ -1,10 +0,0 @@
-import mime from "../../../util/mime.ts";
-
-import { ObjectRawResponseStatic } from "../types.ts";
-
-export default (f: ObjectRawResponseStatic) =>
- "mime" in f && f.mime === false
- ? []
- : "extra" in f
- ? mime.concat(f.extra)
- : mime;
diff --git a/components/http/src/framework/optimizer/syncCheckDir.ts b/components/http/src/framework/optimizer/syncCheckDir.ts
deleted file mode 100644
index 00143b5..0000000
--- a/components/http/src/framework/optimizer/syncCheckDir.ts
+++ /dev/null
@@ -1,55 +0,0 @@
-// deno-lint-ignore-file
-
-// Default export function that takes a starting directory as a parameter and returns an array with all the names of the documents.
-export default ((start) =>
- (
- (Y) =>
- (
- (searcher) =>
- ((mapper) => Y(mapper)(searcher))(
- (f: (arg0: any) => any) => (m: any[]) =>
- m.some((x: boolean[]) => x[1] === true)
- ? f(m.reduce((acc: any[], x: string[]) =>
- !x[1] ? acc.concat([x]) : acc.concat(
- Y((f: (arg0: any) => ConcatArray) =>
- ((p) => (o: { next: () => any }) =>
- ((s) =>
- // Recursive call to the "Y" function with the next directory in the array.
- // It continues to concatenate the contents of all directories until there are no more directories.
- s.done === true
- ? []
- : [[p + s.value.name, s.value.isDirectory]]
- .concat(f(o)))(
- o.next(),
- ))(x[0] + "/")
- )(Deno.readDirSync(x[0] as string)),
- ), []))
- : m,
- )
- )(
- // Recursive call to the "Y" function with the starting directory.
- // Returns a new array that contains the names of all files and directories in the directory tree.
- Y((f: (arg0: any) => ConcatArray) =>
- ((p) => (o: { next: () => any }) =>
- ((s) =>
- // Recursive call to the "Y" function with the next directory in the array.
- // It continues to concatenate the contents of all directories until there are no more directories.
- s.done === true ? [] : [[
- (p.at(-2) === "/"
- ? p.slice(0, -1)
- : p.at(-1) === "/"
- ? p
- : p + "/") + s.value.name,
- s.value.isDirectory,
- ]].concat(f(o)))(
- o.next(),
- ))(start)
- )(Deno.readDirSync(start)),
- )
- )(
- // Setting up the Y combinator.
- (f: (arg0: (y: any) => any) => any) =>
- ((x) => x(x))((x: (arg0: any) => { (arg0: any): any; new (): any }) =>
- f((y: any) => x(x)(y))
- ),
- )) as (s: string) => string[];
diff --git a/components/http/src/framework/optimizer/syncCheckDir_Bun.mjs b/components/http/src/framework/optimizer/syncCheckDir_Bun.mjs
deleted file mode 100644
index 10bd38c..0000000
--- a/components/http/src/framework/optimizer/syncCheckDir_Bun.mjs
+++ /dev/null
@@ -1,28 +0,0 @@
-/**
- * Creates a function that searches through directories recursively and lists all files and directories along with a flag indicating if it's a directory.
- *
- * @param {Function} joiner - A function that takes a base path and a target path and returns the joined path.
- * @param {Function} readdir - A function that takes a directory path and returns an array of file and directory names within it.
- * @param {Function} stat - A function that takes a path and returns an object with an isDirectory method.
- * @returns {Function} A function that takes a directory path and returns an array of tuples, each containing a path and a boolean flag indicating if it's a directory.
- *
- * @example
- * const listFilesAndDirectories = myFunction(joinPathFunction, readDirectoryFunction, statsFunction);
- * const items = listFilesAndDirectories('/path/to/directory');
- */
-export default (joiner) => (readdir) => (stat) => (dir) =>
- (
- (Y) => (
- Y((f) => (
- (dir) =>
- readdir(dir).flatMap((item) =>
- stat(joiner(dir)(item)).isDirectory()
- ? [[joiner(dir)(item), true], ...f(joiner(dir)(item))]
- : [[joiner(dir)(item), false]]
- )
- ))(dir)
- )
- )(
- // Setting up the Y combinator.
- (f) => ((x) => x(x))((x) => f((y) => x(x)(y))),
- );
diff --git a/components/http/src/framework/optimizer/tools/isUsing.ts b/components/http/src/framework/optimizer/tools/isUsing.ts
deleted file mode 100644
index 873e3dd..0000000
--- a/components/http/src/framework/optimizer/tools/isUsing.ts
+++ /dev/null
@@ -1,21 +0,0 @@
-import { FunRouterOptions } from "../../../../types.ts";
-import elements from "../../../util/elements.ts";
-import checker from "../checker.ts";
-import { CommonRequestMorphism, RequestMorphism } from "../types.ts";
-
-export default (o?: FunRouterOptions) =>
-(f: CommonRequestMorphism | RequestMorphism) =>
- (
- f.options && typeof f.options?.only !== "undefined" &&
- f.options.only.length > 0
- )
- ? Object.keys(f.options.only)
- : checker(
- (f.options && f.options.remove) ? Object.keys(f.options.remove) : [],
- )([...elements(f), ...(Object.keys(o?.cyclePlugin || {}) || [])])(
- [
- ...((f.options && f.options.add) ? f.options.add : []),
- ],
- )(
- f.f.toString(),
- );
diff --git a/components/http/src/framework/optimizer/tools/parsingToHexa.ts b/components/http/src/framework/optimizer/tools/parsingToHexa.ts
deleted file mode 100644
index 628ae54..0000000
--- a/components/http/src/framework/optimizer/tools/parsingToHexa.ts
+++ /dev/null
@@ -1,10 +0,0 @@
-export default (crypto: { globalKey: string }) =>
- typeof crypto.globalKey === "string"
- // If it's a string, check if it's a valid hexadecimal
- ? /^[0-9a-fA-F]+$/g.test(crypto.globalKey)
- // If it's a valid hexadecimal, return it as is
- ? new Uint8Array([...crypto.globalKey].map((x) => x.charCodeAt(0)))
- // If it's not a valid hexadecimal, convert to Uint8Array
- : new Uint8Array([...crypto.globalKey].map((x) => x.charCodeAt(0)))
- // If not a string, return the value as is
- : crypto.globalKey;
diff --git a/components/http/src/framework/optimizer/types.ts b/components/http/src/framework/optimizer/types.ts
deleted file mode 100644
index 6fce3ac..0000000
--- a/components/http/src/framework/optimizer/types.ts
+++ /dev/null
@@ -1,995 +0,0 @@
-import { CyclePluginMap, FunRouterOptions } from "../../../types.ts";
-import { ParamsMethod } from "../builder/types.ts";
-
-// Modified ExtractPluginTypes
-type ExtractPluginTypes = O["cyclePlugin"] extends
- CyclePluginMap ? {
- [K in keyof O["cyclePlugin"]]?: O["cyclePlugin"][K] extends
- { type: infer T } ? T : never;
- }
- : {};
-
-export type Morphism<
- ResMap extends MorphismMap = MorphismMap,
- BraMap extends AnyMorphismMap = AnyMorphismMap,
- Query extends QueryOptions = QueryOptions,
- Param extends ParamOptions = ParamOptions,
- Options extends FunRouterOptions = FunRouterOptions,
- Crypto extends CryptoOptions = CryptoOptions,
- Mut extends MutableKey = MutableKey,
- Return = any,
-> = {
- readonly resolve?: ResMap;
- readonly branch?: BraMap;
- f: (
- ctx: WithPlugins<
- ResMap,
- BraMap,
- Query,
- Param,
- Options,
- Crypto,
- {},
- PetitionOptions<
- [Extract],
- Crypto
- >
- >,
- ) => Return;
- readonly query?: Query;
- readonly param?: Param;
- readonly options?: PetitionOptions<
- [Extract],
- Crypto
- >;
- readonly plugins?: ExtractPluginTypes;
- readonly crypto?: Crypto;
- readonly mutable?: Mut;
- readonly isAsync?: true;
-};
-
-type CryptoContext = CR extends
- { globalKey: any; token: infer Token } ? Token extends Record ? {
- token: { [K in keyof Token]: Record };
- } & SignerAndVarifier
- : {
- sign: any;
- verify: any;
- token: any;
- }
- : CR extends { globalKey: any } ? {
- token: Record | null>;
- } & SignerAndVarifier
- : {
- sign: any;
- verify: any;
- token: any;
- };
-
-type SignerAndVarifier = {
- verify: (s: string) => Record | null;
- sign: (key: Record) => string;
-};
-
-export type CryptoOptions = {
- globalKey: SupportedKeys;
- token?: {
- only?: {
- [key: string]: {};
- };
- };
-} | {};
-
-export type AnyMorphism<
- ResMap extends MorphismMap = MorphismMap,
- BraMap extends AnyMorphismMap = AnyMorphismMap,
- Query extends QueryOptions = QueryOptions,
- Param extends ParamOptions = ParamOptions,
- Options extends FunRouterOptions = FunRouterOptions,
- Crypto extends CryptoOptions = CryptoOptions,
- Mut extends MutableKey = MutableKey,
- Return = any,
-> = Omit, "f"> & {
- f: (
- ctx: WithPlugins<
- ResMap,
- BraMap,
- Query,
- Param,
- Options,
- Crypto,
- {},
- PetitionOptions<
- [Extract],
- Crypto
- >
- >,
- ) => Return;
-};
-export type MorphismMap = {
- [key: string]: Morphism;
-};
-export type AnyMorphismMap = {
- [key: string]: AnyMorphism;
-};
-
-type CyclePlugingFunctions = {
- [K in keyof CPM]: CPM[K] extends
- { isFunction: boolean; f: (...args: any) => any }
- ? ReturnType> // Direct function case
- : CPM[K] extends { f: (...args: any) => any }
- ? Awaited>>> // Nested function case
- : never; // Handle cases that do not match expected structure
-};
-
-type specialElements = {
- readonly hasHeaders?: true;
-} | {};
-
-type WithPlugins<
- R extends MorphismMap,
- B extends AnyMorphismMap,
- QS extends QueryOptions,
- PA extends ParamOptions,
- O extends FunRouterOptions,
- CR extends CryptoOptions,
- UNI extends specialElements,
- OPT extends PetitionOptions,
-> =
- & Ctx
- & (O extends { cyclePlugin: infer CPM } ? [keyof CPM] extends [never] ? {}
- : CPM extends CyclePluginMap ? CyclePlugingFunctions
- : never
- : {})
- & CryptoContext;
-
-export interface Ctx<
- R extends MorphismMap,
- B extends AnyMorphismMap,
- QS extends QueryOptions,
- PA extends ParamOptions,
- O extends FunRouterOptions,
- CR extends CryptoOptions,
- UNI extends specialElements,
- OPT extends PetitionOptions,
-> {
- /**
- * The `resolve` property is integral to ensuring that all necessary data is fetched or calculations are performed before the main function (`f`) of a morphism is executed. It consists of a map where each key corresponds to a resolve function that is executed prior to `f`. The results of these resolves are then made available in the `CTX` for use in the main function.
- *
- * **Key Features**:
- * - Ensures data dependencies are resolved beforehand.
- * - Supports both synchronous and asynchronous operations.
- * - Maintains the original state, allowing for clean and predictable code execution.
- * - Executes all resolves before integrating their outputs into the `CTX`.
- * - Supports an unlimited nesting of resolves and branches (using morphism), providing a flexible structure for complex data handling.
- *
- * **Examples**:
- * ---
- * Basic usage with synchronous data fetching:
- * ```js
- * wrap(options)()
- * .stdPetition({
- * path: "/withResolve",
- * resolve: {
- * hi: { f: () => "Hello world" },
- * },
- * f: (ctx) => ctx.resolve.hi,
- * });
- * ```
- * ---
- * Incorporating asynchronous functions:
- * ```js
- * wrap()()
- * .stdPetition({
- * path: "/withResolveAsync",
- * resolve: {
- * hi: { async f: () => await Promise.resolve("Hello world") }
- * },
- * f: (ctx) => ctx.resolve.hi,
- * })
- * ```
- * ---
- * Execution order and integration into `CTX`:
- * ```js
- * wrap(options)()
- * .stdPetition({
- * path: "/helloWorld",
- * resolve: {
- * hello: { async f: () => await Promise.resolve("Hello") },
- * world: { f: () => 'world' }
- * },
- * f: ctx => `${ctx.resolve.hello} ${ctx.resolve.world}`,
- * })
- * ```
- * ---
- * Using `morphism` with `resolve`:
- *
- * Suppose you need to fetch user data and perform some preprocessing on it before responding to a request. You can define a `morphism` for fetching and preprocessing the data, and then use it within the `resolve` to ensure the data is ready by the time you need to use it in `f`.
- *
- * ```js
- * // Define a morphism for fetching and preprocessing user data
- * const fetchAndProcessUserData = morphism({
- * resolve: {
- * userData: {
- * f: async (c) => {
- * // Imagine fetching user data asynchronously
- * const userData = await fetchUserData(c.param.userId);
- * // Preprocess the fetched data
- * const processedData = processData(userData);
- * return processedData;
- * }
- * }
- * },
- * f: (c) => c.resolve.userData, // This function simply returns the processed user data
- * });
- *
- * // Use the above morphism in a petition
- * wrap()()
- * .stdPetition({
- * path: "/user/:userId",
- * resolve: {
- * // Utilize the morphism to fetch and preprocess user data before executing the main function
- * processedUserData: fetchAndProcessUserData,
- * },
- * f: (c) => {
- * // Access the resolved and processed user data directly in the main function
- * const userData = c.resolve.processedUserData;
- * // Use the processed user data to construct the response
- * return new Response(JSON.stringify(userData));
- * }
- * });
- * ```
- */
- resolve: { [V in keyof R]: Awaited> };
- /**
- * The `branch` property allows for additional logic or operations to be executed alongside or within the main function (`f`) of a petition. Each key within the `branch` object maps to a branch function, executed with its context. The results of these branches are then accessible under the `branch` property of the `CTX`, complementing the main logic without overcrowding it.
- *
- * **Key Features**:
- * - Enables the execution of side operations or additional logic in parallel to the main function.
- * - Each branch operates with its own context, allowing for independent execution.
- * - Supports dynamic operations with parameters and asynchronous actions, enhancing flexibility.
- *
- * **Examples**:
- * ---
- * Defining a simple branch:
- * ```typescript
- * const helloBranch = morphism(options)({
- * f: (ctx) => "Hello from branch",
- * });
- *
- * wrap(options)()
- * .stdPetition({
- * path: "/helloBranch",
- * branch: {
- * hello: helloBranch,
- * },
- * f: (ctx) => new Response(ctx.branch.hello(null)),
- * });
- * ```
- * ---
- * Branch with parameters:
- * ```typescript
- * const greetUserBranch = morphism()({
- * f: (ctx) => `Hello, ${ctc.arguments.name}`,
- * });
- *
- * wrap(options)()
- * .stdPetition({
- * path: "/greet/:name",
- * branch: {
- * greetUser: greetUserBranch,
- * },
- * f: (ctx) => new Response(c.branch.greetUser({ name: ctx.param.name })),
- * });
- * ```
- * ---
- * Asynchronous branch example:
- * ```js
- * const fetchUserDataBranch = morphism(options)({
- * async f: (ctx) => {
- * const userId = ctc.arguments.userId;
- * return await fetch(`https://api.example.com/users/${userId}`).then(res => res.json());
- * },
- * });
- *
- * wrap(options)()
- * .stdPetition({
- * path: "/user/:userId",
- * branch: {
- * fetchUserData: fetchUserDataBranch,
- * },
- * f: async (ctx) => {
- * const userData = await ctx.branch.fetchUserData({ userId: ctx.param.userId });
- * return new Response(JSON.stringify(userData));
- * },
- * })
- * ```
- */
- branch: {
- [V in keyof B]: B[V]["options"] extends { arguments: infer Args }
- ? (ctx: Args) => ReturnType
- : (ctx: any) => ReturnType;
- };
-
- /**
- * Adds with query to the `context`
- *
- * ---
- * ```ts
- * {
- * path: "/path",
- * f: async ctx => await ctx.req.blob()
- * }
- * ---
- * {
- * path: '/path',
- * options: {add: ["req"]},
- * f: ctx => outOfContext(ctx)
- * };
- * ```
- */
- req: Request;
- /**
- * `query`: Facilitates access to URL query parameters within the petition's execution context.
- *
- * **Examples**:
- *
- * Accessing a simple query parameter:
- * ```typescript
- * {
- * path: '/query',
- * f: ctx => ctx.query.name ?? "NotFound"
- * };
- * ```
- * In this scenario, `ctx.query.name` directly accesses the `name` query parameter from the URL.
- *
- * ---
- *
- * Using query parameters with optimization for unique queries:
- * ```typescript
- * .stdPetition({
- * path: "/query",
- * query: {
- * unique: true,
- * name: "hello"
- * },
- * f: ctx => ctx.query ?? "NotFound"
- * })
- * ```
- */
- query: QS extends { unique: true } ? (string | null)
- : { [key: string]: string };
-
- /**
- * `param`: Enables the extraction of URL path parameters within the petition's execution context. This feature simplifies accessing dynamic segments of the URL path, allowing petitions to respond to varied requests efficiently.
- *
- * **Examples**:
- *
- * Accessing a path parameter:
- * ```typescript
- * {
- * path: '/user/:userId',
- * f: ctx => `User ID: ${ctx.param.userId}`
- * };
- * ```
- * In this example, `ctx.param.userId` retrieves the `userId` path parameter, enabling dynamic response content based on the URL.
- *
- * ---
- *
- * Using path parameters with optimization for unique paths:
- * ```typescript
- * .stdPetition({
- * path: "/user/:userId",
- * param: {
- * unique: true
- * },
- * f: ctx => `User ID: ${ctx.param}`
- * })
- * ```
- * Here, setting `unique: true` within the `param` configuration optimizes retrieval for a scenario where only one path parameter is expected, allowing direct access to the parameter value as `ctx.param`.
- */
- param: PA extends { unique: true } ? string : Record;
- /**
- * `headers`: Provides access to HTTP request headers within the petition's execution.
- *
- * **Examples**:
- *
- * Accessing request headers:
- * ```typescript
- * export const root = wrap({
- * cors: {
- * 'maxAge': 14556156
- * },
- * })()
- * .customPetition({
- * path: "/getHeaders",
- * f: c => new Response(
- * null, {
- * headers: c.headers
- * }
- * )
- * });
- *
- * const handles = root.handleRequest("/getHeaders")({});
- *
- * console.log(
- * await handles(
- * new Request("http://localhost/getHeaders")
- * )
- * );
- * ```
- */
- headers: UNI extends {
- readonly hasHeaders: true;
- } ? Record
- : null;
-
- /**
- * Adds a Date.now() returning the number of milliseconds elapsed since the epoch.
- *
- * ```ts
- * {
- * path: "/path"
- * f: ctx => ctx.date > Date.now()
- * ? "unreachable"
- * : "date is created before ctx is passed to f"
- * }
- * ```
- * ---
- * This behavior can be set for testing purpose
- * ```ts
- * {
- * path: "/",
- * options:{
- * setDate: 1694246953189
- * },
- * f: ctx => ctx.date === 1694246953189
- * ? "Date is bind to a state"
- * : "unreachable"
- * }
- * ```
- */
- date: number;
- randomNumber: number;
- /**
- * Generates a unique ID using `crypto.randomUUID()`.
- *
- * ```ts
- * {
- * path: "/path",
- * f: ctx => ctx.hash === "some-random-uuid"
- * ? "ID matches expected value"
- * : "Generated a unique ID"
- * }
- * ```
- * ---
- * This behavior can be set for testing purposes:
- * ```ts
- * {
- * path: "/",
- * options:{
- * setHash: "specified-uuid-value"
- * },
- * f: ctx => ctx.hash === "specified-uuid-value"
- * ? "UUID is bind to a state"
- * : "unreachable"
- * }
- * ```
- */
- hash: string;
- /**
- * Retrieves cookies sent with the request using `ctx.cookie`.
- *
- * ---
- * ```ts
- * {
- * path: '/path',
- * f: ctx => ctx.cookie?.sessionID
- * };
- * // If the `ctx` goes out of context
- * {
- * path: '/path',
- * options: {add: ["cookie"]},
- * f: ctx => outOfContext(ctx)
- * };
- * ```
- */
- cookie: null | { [key: string]: string | undefined };
-
- /**
- * `mutable`: A property designed to facilitate state mutation within the execution context of a petition. It enables the dynamic alteration of state across different parts of your application's flow, allowing for sophisticated state management strategies and interactions.
- *
- * **Caution**: Mutable state should be handled with care to prevent unintended side effects. It's recommended to use this feature judiciously, ensuring that state mutations are predictable and well-understood within your application's context.
- *
- * **Key Concept**:
- * - All morphisms composing a petition can share and mutate this state, providing a powerful mechanism for stateful logic and data management.
- * - This shared mutable state can be particularly useful for maintaining state across asynchronous operations, user authentication status, or other complex interaction patterns within a petition.
- *
- * **Example Usage**:
- * ```js
- * {
- * path: '/',
- * resolve: {
- * // Define a resolve function that mutates state within `mutable`
- * world: morphism()({
- * f: c => {
- * c.mutable.hello = "hello "; // Mutating state
- * return 'world';
- * }
- * })
- * },
- * // The main function leverages the mutated state for constructing the response
- * f: c => new Response(c.mutable.hello + c.resolve.world) // Accessing mutated state
- * }
- * ```
- * **Note**: The structure and usage of `mutable` enable developers to architect complex and dynamic data flows within their Vixeny applications, offering flexibility in handling stateful operations.
- */
- mutable: {
- [keys: string]: any;
- };
-
- /**
- * Interacts with the `arguments` property in `ctx.branch` to receive input for branch functions.
- *
- * ---
- * ```ts
- * {
- * path: '/path',
- * f: ctx => ctx.branch.hello("Greetings!"),
- * branch: {
- * hello: {
- * f: c => c.arguments
- * }
- * }
- * };
- * ```
- *
- * ---
- *
- * When invoking a branch function, any parameters passed are accessible as `arguments` within the branch function.
- *
- * ```ts
- * {
- * path: '/multipleArgs',
- * f: ctx => ctx.branch.greet("Hello", "world!"),
- * branch: {
- * greet: {
- * f: c => `${c.arguments[0]} ${c.arguments[1]}`
- * }
- * }
- * };
- * ```
- * In this example, multiple arguments are passed to the branch function, and they're accessed via index in the branch.
- */
- readonly arguments: OPT extends { arguments: infer A } ? A : any;
-}
-
-export type CommonRequestMorphism<
- ResMap extends MorphismMap = MorphismMap,
- BraMap extends AnyMorphismMap = AnyMorphismMap,
- Query extends QueryOptions = QueryOptions,
- Param extends ParamOptions = ParamOptions,
- Options extends FunRouterOptions = FunRouterOptions,
- Crypto extends CryptoOptions = CryptoOptions,
- Mut extends MutableKey = MutableKey,
- _Return = any,
-> =
- & Omit, "f">
- & RawCommonRequest
- & {
- headings?: PetitionHeader;
- f: (
- ctx: WithPlugins<
- ResMap,
- BraMap,
- Query,
- Param,
- Options,
- Crypto,
- {},
- PetitionOptions<
- [Extract],
- Crypto
- >
- >,
- ) => BodyInit | Promise;
- };
-
-export type RequestMorphism<
- ResMap extends MorphismMap = MorphismMap,
- BraMap extends AnyMorphismMap = AnyMorphismMap,
- Query extends QueryOptions = QueryOptions,
- Param extends ParamOptions = ParamOptions,
- Options extends FunRouterOptions = FunRouterOptions,
- Crypto extends CryptoOptions = CryptoOptions,
- Mut extends MutableKey = MutableKey,
- _Return = any,
-> =
- & Omit, "f">
- & ObjectRawCommonRequest
- & {
- f: (
- ctx: WithPlugins<
- ResMap,
- BraMap,
- Query,
- Param,
- Options,
- Crypto,
- { hasHeaders: true },
- PetitionOptions<
- [Extract],
- Crypto
- >
- >,
- ) => Response | Promise;
- };
-
-export type BodyNull = {
- [propName: string]: any;
-} | null;
-export type ObjectAndNullMorphism<
- ResMap extends MorphismMap = MorphismMap,
- BraMap extends AnyMorphismMap = AnyMorphismMap,
- Query extends QueryOptions = QueryOptions,
- Param extends ParamOptions = ParamOptions,
- Options extends FunRouterOptions = FunRouterOptions,
- Crypto extends CryptoOptions = CryptoOptions,
- Mut extends MutableKey = MutableKey,
- _Return = any,
-> =
- & Omit, "f">
- & {
- f: (
- ctx: WithPlugins<
- ResMap,
- BraMap,
- Query,
- Param,
- Options,
- Crypto,
- { hasHeaders: true },
- PetitionOptions<
- [Extract],
- Crypto
- >
- >,
- ) => Promise | BodyNull;
- };
-
-export type ObjectaAnyMorphism<
- ResMap extends MorphismMap = MorphismMap,
- BraMap extends AnyMorphismMap = AnyMorphismMap,
- Query extends QueryOptions = QueryOptions,
- Param extends ParamOptions = ParamOptions,
- Options extends FunRouterOptions = FunRouterOptions,
- Crypto extends CryptoOptions = CryptoOptions,
- Mut extends MutableKey = MutableKey,
- T = any, // Add generic type parameter T here
-> =
- & Omit, "f">
- & {
- f: (
- ctx: WithPlugins<
- ResMap,
- BraMap,
- Query,
- Param,
- Options,
- Crypto,
- { hasHeaders: true },
- PetitionOptions<
- [Extract],
- Crypto
- >
- >,
- ) => T;
- };
-
-export type Petition =
- | RequestMorphism
- | CommonRequestMorphism
- | ObjectRawResponseReturn
- | ObjectRawResponseStatic;
-
-/**
- * Object for raw response return.
- */
-export type ObjectRawResponseReturn = {
- /**
- * Direct interaction with Request and Response.
- *
- * ---
- * ```ts
- * {
- * path: "/response/hello",
- * type: "response",
- * r: r => new Response("Hello world!")
- * }
- * ```
- */
- type: "response";
- /**
- * `r` requires a functions which arguments contains the `Request` and need to return a `Response` or a `Promise`
- * ---
- *
- * ```ts
- * {
- * path: "/path",
- * r: () => new Response("hi")
- *
- * }
- *
- * ```
- */
- r: (r: Request) => Response | Promise;
- method?: ParamsMethod;
-} & PathKey;
-
-/**
- * Object for raw common request.
- */
-export type ObjectRawCommonRequest =
- & {
- /**
- * Route Method
- */
- method?: ParamsMethod;
- /**
- * Returns `Response` for custom statuses.
- *
- * ---
- * ```ts
- * {
- * path: "/response/who/:name",
- * type: "request",
- * f: context =>
- * context.param.name === "Bun"
- * ? new Response("Welcome")
- * : new Response("Only devs", {status: 400})
- * }
- * ```
- */
- type: "request";
- }
- & RawCommonRequest;
-
-/**
- * Common raw request object.
- */
-export type RawCommonRequest = {
- /**
- * Route Method
- */
- method?: ParamsMethod;
-} & PathKey;
-
-type ExtendedAddOption = "globalKey" extends keyof CR
- ? AddOption | "token" | "sign" | "verify"
- : AddOption;
-
-/**
- * Options for the petition.
- */
-export type PetitionOptions<
- T extends string[],
- CR extends CryptoOptions,
-> = {
- readonly add?: Array | T[number]>;
- readonly debug?: DebugOptions;
- readonly remove?: Array | T[number]>;
- readonly only?: Array | T[number]>;
- readonly setHash?: string;
- readonly setRandomNumber?: number;
- readonly setDate?: number;
- readonly arguments?: any;
-};
-
-/**
- * List of options for adding.
- */
-export type AddOptions = AddOption[];
-
-/**
- * Options for adding.
- */
-export type AddOption =
- | "req"
- | "query"
- | "param"
- | "date"
- | "randomNumber"
- | "hash"
- | "cookie"
- | "resolve"
- | "mutable"
- | "branch"
- | "arguments"
- | "headers";
-
-export type PathKey = {
- /**
- * Represents the endpoint path for a Vixeny petition.
- *
- * Remember that it have to start with `/`
- *
- * A "Hello World" example on `"/"`:
- * ```ts
- * {
- * path: "/",
- * f: () => "hello world",
- * }
- * ```
- *
- * Alongside other configurations, this path determines how the server responds to specific endpoints.
- */
- path: string;
-};
-
-/**
- * Options for debugging.
- */
-export type DebugOptions = {
- type: "list";
- name: string;
-};
-
-export type MutableKey = {
- mutable?: {
- readonly is: true;
- };
-} | {};
-
-/**
- * Headers for the petition.
- */
-export type PetitionHeader = {
- /**
- * The headers initialization.
- */
- headers?: HeadersInit | defaultMime;
- /**
- * The status text.
- */
- statusText?: string;
- /**
- * The status number.
- */
- status?: number;
-};
-
-export type QueryOptions = {
- unique?: true;
- name: string; // 'unique' is an optional boolean
-} | {
- only?: string[];
-} | {};
-
-export type ParamOptions = {
- readonly unique?: true; // 'unique' is an optional boolean
-} | {};
-
-type StaticFilePlugin = {
- checker: (path: string) => boolean;
- r: (options: {
- root: string;
- path: string;
- relativeName: string;
- }) => ObjectRawResponseReturn;
-};
-
-/**
- * Object for raw response static.
- */
-export type ObjectRawResponseStatic =
- & ({
- type: "fileServer";
- name: string;
- path: string;
- } | {
- type: "fileServer";
- name: string;
- path: string;
- mime?: true;
- extra: [string, string][];
- } | {
- type: "fileServer";
- name: string;
- path: string;
- mime: false;
- })
- & {
- template?: StaticFilePlugin[];
- removeExtensionOf?: defaultMime[];
- slashIs?: string;
- };
-
-export type SupportedKeys =
- | string
- | Uint8Array
- | Uint8ClampedArray
- | Uint16Array
- | Uint32Array
- | Int8Array
- | Int16Array
- | Int32Array
- | BigUint64Array
- | BigInt64Array
- | Float32Array
- | Float64Array;
-
-export type defaultMime =
- | ".aac"
- | ".abw"
- | ".arc"
- | ".avif"
- | ".avi"
- | ".azw"
- | ".azw"
- | ".bmp"
- | ".bz"
- | ".bz2"
- | ".cda"
- | ".csh"
- | ".css"
- | ".csv"
- | ".doc"
- | ".docx"
- | ".eot"
- | ".epub"
- | ".gz"
- | ".gif"
- | ".htm"
- | ".html"
- | ".ico"
- | ".ics"
- | ".jar"
- | ".jpeg"
- | ".js"
- | ".json"
- | ".jsonld"
- | ".mid"
- | ".mjs"
- | ".mp3"
- | ".mp4"
- | ".mpeg"
- | ".mpkg"
- | ".odp"
- | ".ods"
- | ".odt"
- | ".oga"
- | ".ogv"
- | ".ogx"
- | ".opus"
- | ".otf"
- | ".png"
- | ".pdf"
- | ".php"
- | ".ppt"
- | ".pptx"
- | ".rar"
- | ".rtf"
- | ".sh"
- | ".svg"
- | ".tar"
- | ".tif"
- | ".tiff"
- | ".ts"
- | ".ttf"
- | ".txt"
- | ".vsd"
- | ".wav"
- | ".weba"
- | ".webm"
- | ".webp"
- | ".woff"
- | ".woff2"
- | ".xhtml"
- | ".xls"
- | ".xlsx"
- | ".xml"
- | ".xul"
- | ".zip"
- | ".3gp"
- | ".3g2"
- | ".7z";
diff --git a/components/http/test/builder/atlas/main1.test.ts b/components/http/test/builder/atlas/main1.test.ts
deleted file mode 100644
index 57232a5..0000000
--- a/components/http/test/builder/atlas/main1.test.ts
+++ /dev/null
@@ -1,110 +0,0 @@
-import assert from "node:assert";
-import test from "node:test";
-
-import atlas from "../../../src/framework/builder/atlas/main1.ts";
-import optimize from "../../../src/framework/optimizer/optimize.ts";
-import paths from "../../util/paths.ts";
-import split from "../../../src/framework/builder/atlas/splitter.ts";
-
-test(
- "Atlas",
- (_) =>
- assert.deepStrictEqual(
- ((r) => [r[0], r[1], r[2]])(
- atlas()(split()(optimize()(paths))),
- ),
- [
- [
- "GET",
- "POST",
- "HEAD",
- "DELETE",
- ],
- [
- [
- 1,
- 2,
- 4,
- ],
- [
- 1,
- ],
- [
- 1,
- ],
- [
- 1,
- ],
- ],
- [
- [
- [
- "/",
- "/one",
- "/two",
- "/three",
- "/four",
- "/five",
- "/six",
- "/test",
- ],
- [
- "/test/",
- ],
- [
- "/test/:id/:name/",
- ],
- ],
- [
- [
- "/",
- ],
- ],
- [
- [
- "/",
- ],
- ],
- [
- [
- "/",
- ],
- ],
- ],
- ],
- ),
-);
-test(
- "Atlas",
- (_) =>
- assert.deepStrictEqual(
- atlas()(
- split()(
- optimize()([...paths, {
- path: "/hello/*",
- f: () => "wild",
- }, {
- path: "/hello/nested/*",
- f: () => "card",
- }, { type: "fileServer", path: "./misc/", name: "/static/" }]),
- ),
- )[4].slice(0, -2) as unknown as null,
- [
- [
- "GET",
- ],
- [
- [
- 2,
- 3,
- ],
- ],
- [
- [
- ["/hello/", "/static/"],
- ["/hello/nested/"],
- ],
- ],
- ],
- ),
-);
diff --git a/components/http/test/builder/atlas/position.test.ts b/components/http/test/builder/atlas/position.test.ts
deleted file mode 100644
index 4fd9808..0000000
--- a/components/http/test/builder/atlas/position.test.ts
+++ /dev/null
@@ -1,99 +0,0 @@
-import assert from "node:assert";
-import test from "node:test";
-import map from "../../../src/framework/builder/atlas/map.ts";
-
-test(
- "position",
- () =>
- assert.deepStrictEqual(
- map(
- [
- [
- ["/", "/test"],
- ["/test/"],
- ["/test/:id/:name/"],
- ],
- [
- ["/"],
- ],
- [
- ["/"],
- ],
- [
- ["/"],
- ],
- ],
- ),
- [
- [
- 0,
- 2,
- 3,
- ],
- [
- 4,
- ],
- [
- 5,
- ],
- [
- 6,
- ],
- ],
- ),
-);
-
-test("functionName basic test", () => {
- assert.deepStrictEqual(
- map([
- [
- ["a", "b"],
- ["c"],
- ],
- [
- ["d"],
- ["e", "f"],
- ],
- ]),
- [
- [0, 2],
- [3, 4],
- ],
- );
-});
-
-test("functionName edge case test", () => {
- assert.deepStrictEqual(
- map([
- [
- ["a"],
- ["b"],
- ],
- [
- ["c"],
- ["d"],
- ],
- ]),
- [
- [0, 1],
- [2, 3],
- ],
- );
-});
-
-test("functionName edge case test", () => {
- assert.deepStrictEqual(
- map([
- [
- ["/count", "/hello_world", "/random_number"],
- ],
- [
- ["/plus_1", "/minus_1"],
- ],
- ]),
- [
- [0],
- [3],
- ],
- );
-});
diff --git a/components/http/test/builder/atlas/splitter.test.ts b/components/http/test/builder/atlas/splitter.test.ts
deleted file mode 100644
index c4d03e1..0000000
--- a/components/http/test/builder/atlas/splitter.test.ts
+++ /dev/null
@@ -1,121 +0,0 @@
-import assert from "node:assert";
-import test from "node:test";
-import paths from "../../util/paths.ts";
-import optimize from "../../../src/framework/optimizer/optimize.ts";
-import split from "../../../src/framework/builder/atlas/splitter.ts";
-
-test(
- "arraySwap",
- (_) =>
- assert.deepStrictEqual(
- split({ hasName: "http://localhost:8080/" })(
- optimize({ hasName: "http://localhost:8080/" })(paths),
- )[0].map((x) => [x[0], x[1], x[2]]),
- [
- [1, "/", "GET"],
- [1, "/one", "GET"],
- [1, "/two", "GET"],
- [1, "/three", "GET"],
- [1, "/four", "GET"],
- [1, "/five", "GET"],
- [1, "/six", "GET"],
- [1, "/test", "GET"],
- [2, "/test/", "GET"],
- [4, "/test/:id/:name/", "GET"],
- [1, "/", "POST"],
- [1, "/", "HEAD"],
- [1, "/", "DELETE"],
- ],
- ),
-);
-
-test(
- "arraySwap",
- (_) =>
- assert.deepStrictEqual(
- split()(optimize()(paths))[0].map((x) => [x[0], x[1], x[2]]),
- [
- [1, "/", "GET"],
- [1, "/one", "GET"],
- [1, "/two", "GET"],
- [1, "/three", "GET"],
- [1, "/four", "GET"],
- [1, "/five", "GET"],
- [1, "/six", "GET"],
- [1, "/test", "GET"],
- [2, "/test/", "GET"],
- [4, "/test/:id/:name/", "GET"],
- [1, "/", "POST"],
- [1, "/", "HEAD"],
- [1, "/", "DELETE"],
- ],
- ),
-);
-
-test(
- "cheksplit",
- () => {
- assert.deepStrictEqual(
- split()(
- optimize()([{ path: "/", f: () => "hello" }, {
- path: "/hello/*",
- f: () => "wild",
- }, { path: "/hello/hello/*", f: () => "wild" }]),
- )[1][2],
- [
- [
- ["/hello/"],
- ["/hello/hello/"],
- ],
- ],
- );
- },
-);
-
-test(
- "cheksplit",
- () => {
- assert.deepStrictEqual(
- split()(
- optimize()([
- {
- path: "/",
- f: () => "hello",
- },
- { path: "/hello/*", f: () => "wild" },
- { path: "/hello/hello/*", f: () => "wild" },
- { type: "fileServer", path: "./components/", name: "/static/" },
- ]),
- )[1][2],
- [
- [
- ["/hello/", "/static/"],
- ["/hello/hello/"],
- ],
- ],
- );
- },
-);
-test(
- "cheksplit",
- () => {
- assert.deepStrictEqual(
- split({})(optimize()([{ path: "/", f: () => "hello" }]))[1][2],
- [],
- );
- },
-);
-
-test(
- "checkSlashIs",
- () => {
- assert.deepStrictEqual(
- split({
- stateFlags: {
- slashIs: "$root",
- },
- })(optimize()([{ path: "/$root", f: () => "hello" }]))[0][0][1],
- "/",
- );
- },
-);
diff --git a/components/http/test/builder/composer/map.test.ts b/components/http/test/builder/composer/map.test.ts
deleted file mode 100644
index 8edfd34..0000000
--- a/components/http/test/builder/composer/map.test.ts
+++ /dev/null
@@ -1,63 +0,0 @@
-import map from "../../../src/framework/builder/composer/map.ts";
-import assert from "node:assert";
-import test from "node:test";
-
-test(
- "only one parameter at the end",
- (_) =>
- assert.deepStrictEqual(
- map({})("/test/:id"),
- {
- elements: [
- ":id",
- ],
- endsInSlash: false,
- firstParam: 5,
- lastParam: 0,
- path: "/test/:id",
- hasName: undefined,
- list: [
- "test",
- ":id",
- ],
- map: [
- false,
- true,
- ],
- startsWith: ":",
- },
- ),
-);
-
-test(
- "only one parameter at the end",
- (_) =>
- assert.deepStrictEqual(
- map({})("/test/:id/:acc/:x/"),
- {
- elements: [
- ":id",
- ":acc",
- ":x",
- ],
- endsInSlash: true,
- firstParam: 5,
- lastParam: 0,
- path: "/test/:id/:acc/:x/",
- hasName: undefined,
- list: [
- "test",
- ":id",
- ":acc",
- ":x",
- ],
- map: [
- false,
- true,
- true,
- true,
- ],
- startsWith: ":",
- },
- ),
-);
diff --git a/components/http/test/builder/composer/methods1.test.ts b/components/http/test/builder/composer/methods1.test.ts
deleted file mode 100644
index 5b4a90f..0000000
--- a/components/http/test/builder/composer/methods1.test.ts
+++ /dev/null
@@ -1,199 +0,0 @@
-import assert from "node:assert";
-import test from "node:test";
-import methods from "../../../src/framework/builder/composer/methods1.ts";
-
-test(
- "composer",
- (_) =>
- ((f) =>
- assert.deepStrictEqual(
- [
- f[0]("http://localhost:8080/"),
- f[0]("http://localhost:8080/test"),
- f[0]("http://localhost:8080/test/"),
- f[0]("http://localhost:8080/notfound/"),
- ],
- [0, 1, 2, 10],
- ))(
- methods({ hasName: "http://localhost:8080/" })(
- [
- [
- "GET",
- ],
- [
- [
- 1,
- 2,
- 4,
- ],
- ],
- [
- [
- ["/", "/test"],
- ["/test/"],
- ["test/:id/:hi/"],
- ],
- ],
- [],
- [],
- ],
- )(0)(10)(6),
- ),
-);
-
-test(
- "composer",
- (_) =>
- ((f) =>
- assert.deepStrictEqual(
- [
- f[0]("http://localhost:8080/"),
- f[0]("http://localhost:8080/test"),
- f[0]("http://localhost:8080/test/"),
- f[0]("http://localhost:8080/notfound/"),
- ],
- [5, 6, 7, 10],
- ))(
- methods({ hasName: "http://localhost:8080/" })(
- [
- [
- "GET",
- ],
- [
- [
- 1,
- 2,
- 4,
- ],
- ],
- [
- [
- ["/", "/test"],
- ["/test/"],
- ["test/:id/:hi/"],
- ],
- ],
- [],
- [],
- ],
- )(5)(10)(6),
- ),
-);
-
-test(
- "composer",
- (_) =>
- ((f) =>
- assert.deepStrictEqual(
- [
- f[0]("http://localhost:8080/"),
- f[0]("http://localhost:8080/test"),
- f[0]("http://localhost:8080/test/"),
- f[0]("http://localhost:8080/notfound/"),
- ],
- [0, 1, 2, 10],
- ))(
- methods({ hasName: "http://localhost:8080/" })(
- [
- [
- "GET",
- ],
- [
- [
- 1,
- 2,
- 4,
- ],
- ],
- [
- [
- ["/", "/test"],
- ["/test/"],
- ["test/:id/:hi/"],
- ],
- ],
- [],
- [
- [
- "GET",
- ],
- [
- [
- 1,
- 2,
- 4,
- ],
- ],
- [
- [
- ["/", "/test"],
- ["/test/"],
- ["test/:id/:hi/"],
- ],
- ],
- [],
- [],
- ],
- ],
- )(0)(10)(6),
- ),
-);
-
-test(
- "composer",
- (_) =>
- ((f) =>
- assert.deepStrictEqual(
- [
- f[0]("http://localhost:8080/"),
- f[0]("http://localhost:8080/test"),
- f[0]("http://localhost:8080/test/"),
- f[0]("http://localhost:8080/notfound/"),
- ],
- [5, 6, 7, 10],
- ))(
- methods({ hasName: "http://localhost:8080/" })(
- [
- [
- "GET",
- ],
- [
- [
- 1,
- 2,
- 4,
- ],
- ],
- [
- [
- ["/", "/test"],
- ["/test/"],
- ["test/:id/:hi/"],
- ],
- ],
- [],
- [
- [
- "GET",
- ],
- [
- [
- 1,
- 2,
- 4,
- ],
- ],
- [
- [
- ["/", "/test"],
- ["/test/"],
- ["test/:id/:hi/"],
- ],
- ],
- [],
- [],
- ],
- ],
- )(5)(10)(6),
- ),
-);
diff --git a/components/http/test/builder/composer/parameters.test.ts b/components/http/test/builder/composer/parameters.test.ts
deleted file mode 100644
index 2e0bb03..0000000
--- a/components/http/test/builder/composer/parameters.test.ts
+++ /dev/null
@@ -1,31 +0,0 @@
-import map from "../../../src/framework/builder/composer/map.ts";
-import parameter from "../../../src/framework/builder/composer/parameters.ts";
-import assert from "node:assert";
-import test from "node:test";
-
-test(
- "composer",
- (_) =>
- assert.deepStrictEqual(
- parameter(0)(map()("/test/:id/hello/")),
- ' s.slice(1, a0 - 1) === "test" && s.slice(a1).indexOf("hello") === 0 ? 0 : ',
- ),
-);
-
-test(
- "composer",
- (_) =>
- assert.deepStrictEqual(
- parameter(0)(map()("/test/:id/hello")),
- ' s.slice(1, a0 - 1) === "test" && s.slice(a1).indexOf("hello") === 0 ? 0 : ',
- ),
-);
-
-test(
- "composer",
- (_) =>
- assert.deepStrictEqual(
- parameter(0)(map()("/test/:id/:hello/")),
- ' s.indexOf("test/") === 1 ? 0 : ',
- ),
-);
diff --git a/components/http/test/builder/composer/parser1.test.ts b/components/http/test/builder/composer/parser1.test.ts
deleted file mode 100644
index 14f1e0f..0000000
--- a/components/http/test/builder/composer/parser1.test.ts
+++ /dev/null
@@ -1,186 +0,0 @@
-import parser from "../../../src/framework/builder/composer/parser1.ts";
-import assert from "node:assert";
-import test from "node:test";
-
-test(
- "composer",
- (_) =>
- (
- (f) =>
- assert.deepStrictEqual(
- [f("/"), f("/notFound"), f("/outOfTheScope/")],
- [0, 50, 50],
- )
- )(
- parser({})([["/"]])([0])([1])(0)(50),
- ),
-);
-
-test(
- "composer",
- (_) =>
- (
- (f) =>
- assert.deepStrictEqual(
- [
- f("/hello"),
- f("/hello/hello"),
- f("/other/bla/bla"),
- f("/notFound"),
- f("/outOfTheScope/"),
- ],
- [0, 0, 1, -1, -1],
- )
- )(
- parser({
- stateFlags: {
- isWild: true,
- },
- })([["/hello", "/other"]])([0])([1])(0)(-1),
- ),
-);
-
-test(
- "composer",
- (_) =>
- (
- (f) =>
- assert.deepStrictEqual(
- [f("/"), f("/notFound"), f("/outOfTheScope/")],
- [1, 50, 50],
- )
- )(
- parser({})([["/"]])([0])([1])(1)(50),
- ),
-);
-test(
- "composer",
- (_) =>
- (
- (f) =>
- assert.deepStrictEqual(
- [
- f("/"),
- f("/hello"),
- f("/test"),
- f("/notFound"),
- f("/outOfTheScope/"),
- ],
- [0, 1, 2, 50, 50],
- )
- )(
- parser({})([["/", "/hello", "/test"]])([0])([1])(0)(50),
- ),
-);
-
-test(
- "composer",
- (_) =>
- (
- (f) =>
- assert.deepStrictEqual(
- [
- f("/"),
- f("/hello"),
- f("/test"),
- f("/hello/"),
- f("/test/hello"),
- f("/notFound"),
- f("/outOfTheScope/lol/"),
- ],
- [0, 1, 2, 3, 4, 50, 50],
- )
- )(
- parser({})([["/", "/hello", "/test"], ["/hello/", "/test/hello"]])([
- 0,
- 3,
- ])([1, 2])(0)(50),
- ),
-);
-
-test(
- "composer",
- (_) =>
- (
- (f) =>
- assert.deepStrictEqual(
- [
- f("/"),
- f("/hello"),
- f("/test"),
- f("/hello/"),
- f("/test/hello"),
- f("/hello/1/test"),
- f("/test/2/hello"),
- f("/hello/1/test/"),
- f("/test/2/hello/"),
- f("/notFound"),
- f("/outOfTheScope/1/2/3/4/5/"),
- ],
- [0, 1, 2, 3, 4, 5, 6, 7, 8, 50, 50],
- )
- )(
- parser({})([["/", "/hello", "/test"], ["/hello/", "/test/hello"], [
- "/hello/:id/test",
- "/test/:id/hello",
- ], ["/hello/:id/test/", "/test/:id/hello/"]])([0, 3, 5, 7])([1, 2, 3, 4])(
- 0,
- )(
- 50,
- ),
- ),
-);
-
-test(
- "composer",
- (_) =>
- (
- (f) =>
- assert.deepStrictEqual(
- [
- f("/"),
- f("/hello"),
- f("/test"),
- f("/hello/"),
- f("/test/hello"),
- f("/hello/1/test/"),
- f("/test/2/hello/"),
- f("/notFound"),
- f("/outOfTheScope/1/2/3/4/5/"),
- ],
- [0, 1, 2, 3, 4, 5, 6, 50, 50],
- )
- )(
- parser({})([["/", "/hello", "/test"], ["/hello/", "/test/hello"], [
- "/hello/:id/test/",
- "/test/:id/hello/",
- ]])([0, 3, 5])([1, 2, 4])(0)(50),
- ),
-);
-
-test(
- "composer",
- (_) =>
- (
- (f) =>
- assert.deepStrictEqual(
- [
- f("/"),
- f("/hello"),
- f("/test"),
- f("/hello/"),
- f("/test/hello"),
- f("/hello/1/test/"),
- f("/test/2/hello/"),
- f("/notFound"),
- f("/outOfTheScope/1/2/3/4/5/"),
- ],
- [1, 2, 3, 4, 5, 6, 7, 50, 50],
- )
- )(
- parser({})([["/", "/hello", "/test"], ["/hello/", "/test/hello"], [
- "/hello/:id/test/",
- "/test/:id/hello/",
- ]])([0, 3, 5])([1, 2, 4])(1)(50),
- ),
-);
diff --git a/components/http/test/builder/composer/specialString.test.ts b/components/http/test/builder/composer/specialString.test.ts
deleted file mode 100644
index 42f55ae..0000000
--- a/components/http/test/builder/composer/specialString.test.ts
+++ /dev/null
@@ -1,14 +0,0 @@
-import specialString from "../../../src/framework/builder/composer/specialString.ts";
-import assert from "node:assert";
-import test from "node:test";
-
-test(
- "hello",
- (_) =>
- assert.deepStrictEqual(
- specialString({ hasName: "http://localhost:8080/" })(12)([
- ["GET", "/", (_) => new Response(), false],
- ])("http://localhost:8080/"),
- 10,
- ),
-);
diff --git a/components/http/test/builder/composer/validator.test.ts b/components/http/test/builder/composer/validator.test.ts
deleted file mode 100644
index 8c26aa9..0000000
--- a/components/http/test/builder/composer/validator.test.ts
+++ /dev/null
@@ -1,30 +0,0 @@
-import validator from "../../../src/framework/builder/composer/validator.ts";
-import assert from "node:assert";
-import test from "node:test";
-
-test(
- "composer",
- (_) =>
- assert.deepStrictEqual(
- validator({})(1)(-1)(["/", "/hello", "/test"]),
- 's === "/" || s.indexOf("?") === 1 || s.indexOf("?") === 1 ? 1 : s === "/hello" || s.indexOf("hello?") === 1 ? 2 : s === "/test" || s.indexOf("test?") === 1 ? 3 : -1',
- ),
-);
-
-test(
- "composer",
- (_) =>
- assert.deepStrictEqual(
- validator({})(1)(-1)(["/hello/", "/test/"]),
- 's.indexOf("hello/") === 1 ? 1 : s.indexOf("test/") === 1 ? 2 : -1',
- ),
-);
-
-test(
- "composer",
- (_) =>
- assert.deepStrictEqual(
- validator({})(1)(-1)(["/hello/:id/hello", "/test/:id/:bar"]),
- 's.slice(1, a0 - 1) === "hello" && s.slice(a1).indexOf("hello") === 0 ? 1 : s.indexOf("test/") === 1 ? 2 : -1',
- ),
-);
diff --git a/components/http/test/builder/solver1.test.ts b/components/http/test/builder/solver1.test.ts
deleted file mode 100644
index 8af4e9c..0000000
--- a/components/http/test/builder/solver1.test.ts
+++ /dev/null
@@ -1,162 +0,0 @@
-import assert from "node:assert";
-import test from "node:test";
-import solver from "../../src/framework/builder/solver1.ts";
-import atlas from "../../src/framework/builder/atlas/main1.ts";
-import paths from "../util/paths.ts";
-import split from "../../src/framework/builder/atlas/splitter.ts";
-import optimize from "../../src/framework/optimizer/optimize.ts";
-
-test(
- "full routes",
- (_) =>
- (
- (a) =>
- assert.deepStrictEqual(
- [
- a(new Request("http://localhost:8080/")),
- a(new Request("http://localhost:8080/one")),
- a(new Request("http://localhost:8080/two")),
- a(new Request("http://localhost:8080/three")),
- a(new Request("http://localhost:8080/four")),
- a(new Request("http://localhost:8080/five")),
- a(new Request("http://localhost:8080/six")),
- a(new Request("http://localhost:8080/test")),
- a(new Request("http://localhost:8080/test/")),
- a(new Request("http://localhost:8080/test/1/2/")),
- a(new Request("http://localhost:8080/", { method: "POST" })),
- a(new Request("http://localhost:8080/", { method: "HEAD" })),
- a(new Request("http://localhost:8080/", { method: "DELETE" })),
- a(new Request("http://localhost:8080/hello/nested/hello/***")),
- a(new Request("http://localhost:8080/hello/nested/***")),
- a(new Request("http://localhost:8080/hello/***")),
- a(new Request("http://localhost:8080/NOTFOUND")),
- a(new Request("http://localhost:8080/", { method: "BAD" })),
- ],
- [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 15, 14, 13, 16, 17],
- )
- )(
- solver({ hasName: "http://localhost:8080/" })(
- atlas({ hasName: "http://localhost:8080/" })(
- split({ hasName: "http://localhost:8080/" })(
- optimize({ hasName: "http://localhost:8080/" })([
- ...paths,
- { path: "/hello/nested/hello/*", f: () => "card" },
- { path: "/hello/nested/*", f: () => "card" },
- { path: "/hello/*", f: () => "wild" },
- ]),
- ),
- ),
- ),
- ),
-);
-
-test(
- "resolver",
- (_) =>
- (
- (a) =>
- assert.deepStrictEqual(
- [
- a(new Request("http://localhost:8080/")),
- a(new Request("http://localhost:8080/one")),
- a(new Request("http://localhost:8080/two")),
- a(new Request("http://localhost:8080/three")),
- a(new Request("http://localhost:8080/four")),
- a(new Request("http://localhost:8080/five")),
- a(new Request("http://localhost:8080/six")),
- a(new Request("http://localhost:8080/test")),
- a(new Request("http://localhost:8080/test/")),
- a(new Request("http://localhost:8080/test/1/2/")),
- a(new Request("http://localhost:8080/", { method: "POST" })),
- a(new Request("http://localhost:8080/", { method: "HEAD" })),
- a(new Request("http://localhost:8080/", { method: "DELETE" })),
- a(new Request("http://localhost:8080/NOTFOUND")),
- a(new Request("http://localhost:8080/", { method: "BAD" })),
- ],
- [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14],
- )
- )(
- solver()(atlas()(split()(optimize()(paths)))),
- ),
-);
-
-test(
- "resolver",
- (_) =>
- (
- (a) =>
- assert.deepStrictEqual(
- [
- a(new Request("http://localhost:8080/")),
- a(new Request("http://localhost:8080/one")),
- a(new Request("http://localhost:8080/two")),
- a(new Request("http://localhost:8080/three")),
- a(new Request("http://localhost:8080/four")),
- a(new Request("http://localhost:8080/five")),
- a(new Request("http://localhost:8080/six")),
- a(new Request("http://localhost:8080/test")),
- a(new Request("http://localhost:8080/test/")),
- a(new Request("http://localhost:8080/test/1/2/")),
- a(new Request("http://localhost:8080/", { method: "POST" })),
- a(new Request("http://localhost:8080/", { method: "HEAD" })),
- a(new Request("http://localhost:8080/", { method: "DELETE" })),
- a(new Request("http://localhost:8080/NOTFOUND")),
- a(new Request("http://localhost:8080/", { method: "BAD" })),
- ],
- [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14],
- )
- )(
- solver()(atlas()(split()(optimize()(paths)))),
- ),
-);
-
-test(
- "resolver",
- (_) =>
- (
- (f) =>
- assert.deepStrictEqual(
- [
- f(new Request("http://localhost:8000/count")),
- f(new Request("http://localhost:8000/hello_world")),
- f(new Request("http://localhost:8000/random_number")),
- f(new Request("http://localhost:8000/plus_1", { method: "POST" })),
- f(new Request("http://localhost:8000/minus_1", { method: "POST" })),
- f(new Request("http://localhost:8000/NOTFOUND")),
- f(new Request("http://localhost:8000/", { method: "BAD" })),
- ],
- [0, 1, 2, 3, 4, 5, 6],
- )
- )(
- solver()(
- atlas()(
- split()(
- optimize()([
- {
- path: "/count",
- f: () => "1",
- },
- {
- path: "/hello_world",
- f: () => "2",
- },
- {
- path: "/random_number",
- f: () => "3",
- },
- {
- path: "/plus_1",
- f: () => "4",
- method: "POST",
- },
- {
- path: "/minus_1",
- f: () => "5",
- method: "POST",
- },
- ]),
- ),
- ),
- ),
- ),
-);
diff --git a/components/http/test/components/cookieToToken/main.test.ts b/components/http/test/components/cookieToToken/main.test.ts
deleted file mode 100644
index 7891586..0000000
--- a/components/http/test/components/cookieToToken/main.test.ts
+++ /dev/null
@@ -1,31 +0,0 @@
-import assert from "node:assert";
-import test from "node:test";
-
-import signSha256 from "../../../../jwt/signSha256.mjs";
-import cookieToTokenFilter from "../../../src/cookieToToken/cookieToTokenFilter.ts";
-
-const secret = new Uint8Array([1, 2, 3, 4, 5, 6]);
-const sign = signSha256()(secret);
-
-const request = new Request("http://localhost:3000/", {
- headers: new Headers(
- [[
- "cookie",
- `hello=${sign({ hi: 1 })}`,
- ]],
- ),
-});
-
-test("with element", () => {
- assert.deepStrictEqual(
- cookieToTokenFilter(["f.token.jwt.id"])("token"),
- ["jwt"],
- );
-});
-
-test("no element", () => {
- assert.deepStrictEqual(
- cookieToTokenFilter(["f.token.jwt"])("token"),
- ["jwt"],
- );
-});
diff --git a/components/http/test/components/tokens/main.test.ts b/components/http/test/components/tokens/main.test.ts
deleted file mode 100644
index 44271af..0000000
--- a/components/http/test/components/tokens/main.test.ts
+++ /dev/null
@@ -1,135 +0,0 @@
-import verifier from "../../../src/framework/tokens/verifier.ts";
-import signer from "../../../src/framework/tokens/signer.ts";
-import assert from "node:assert";
-import test from "node:test";
-import jSigner from "../../../src/framework/tokens/jSigner.ts";
-import jVerify from "../../../src/framework/tokens/jVerify.ts";
-
-test(
- "test",
- () =>
- (
- (sign) =>
- assert.deepStrictEqual(
- (verifier({ seed: "hello", size: 40 }))(sign(
- Array.from({ length: 40 }, (_, i) => String.fromCharCode(i + 30))
- .join(""),
- )),
- true,
- )
- )(
- signer(
- {
- seed: "hello",
- size: 40,
- },
- ),
- ),
-);
-
-test(
- "test",
- () =>
- (
- (sign) =>
- assert.deepStrictEqual(
- (verifier({ seed: "hello" }))(sign(
- Array.from({ length: 9 }, (_, i) => String.fromCharCode(i + 30))
- .join(""),
- )),
- true,
- )
- )(
- signer(
- {
- seed: "hello",
- },
- ),
- ),
-);
-
-test(
- "experies",
- () =>
- (
- (sign) =>
- assert.deepStrictEqual(
- verifier({ seed: "hello", expires: 1000 })(sign("01234567")),
- true,
- )
- )(
- signer({ seed: "hello", expires: 1000 }),
- ),
-);
-test(
- "experies",
- () =>
- (
- (sign) =>
- assert.deepStrictEqual(
- verifier({ seed: "hello", expires: 1000 })(sign("01234567")),
- true,
- )
- )(
- signer({ seed: "hello", expires: 1000, size: 21 }),
- ),
-);
-test(
- "experies",
- () =>
- (
- (sign) =>
- assert.deepStrictEqual(
- verifier({ seed: "hello", expires: 1000, size: 21 })(
- sign("01234567"),
- ),
- true,
- )
- )(
- signer({ seed: "hello", expires: 1000 }),
- ),
-);
-test(
- "experies",
- () =>
- (
- (sign) =>
- assert.deepStrictEqual(
- verifier({ seed: "hello", expires: 1000 })(sign("01234567")),
- false,
- )
- )(
- signer({ seed: "hello", expires: -1 }),
- ),
-);
-
-test(
- "test",
- () =>
- assert.deepStrictEqual(
- jVerify({ seed: "hello" })(
- jSigner({ seed: "hello" })({ hello: "world" }),
- ),
- { hello: "world" },
- ),
-);
-test(
- "test",
- () =>
- assert.deepStrictEqual(
- jVerify({ seed: "hello", expires: 1000 })(
- jSigner({ seed: "hello", expires: 1000 })({ hello: "world" }),
- ),
- { hello: "world" },
- ),
-);
-test(
- "test",
- () =>
- assert.deepStrictEqual(
- jVerify({ seed: "hello", expires: -1 })(
- jSigner({ seed: "hello", expires: -1 })({ hello: "world" }),
- ),
- null,
- ),
-);
diff --git a/components/http/test/optimizer/aComposer.test.ts b/components/http/test/optimizer/aComposer.test.ts
deleted file mode 100644
index f1cfbf9..0000000
--- a/components/http/test/optimizer/aComposer.test.ts
+++ /dev/null
@@ -1,128 +0,0 @@
-import signer from "../../src/framework/tokens/signer.ts";
-import aComposer from "../../src/framework/optimizer/aComposer.ts";
-import assert from "node:assert";
-import test from "node:test";
-//await ((hi: (arg0: any) => any)=> async (r: any)=>({hi:await hi(r)}))((hi=>async (f: any) =>({hi:await hi(f)})) (async (f: { blob: () => any; })=> await(await f.blob()).text()))(new Request("http://hi.com/", {method: "POST", body: "hello"})),
-test(
- "Query",
- (_) =>
- assert.deepStrictEqual(
- (aComposer({ hasName: "http://localhost:8080/" })({
- path: "/test",
- f: (r) => r.query.hello || "nothing",
- })(["query"]))(new Request("http://localhost:8080/test?hello=hi")).query
- .hello,
- "hi",
- ),
-);
-test(
- "Query",
- (_) =>
- assert.deepStrictEqual(
- (aComposer()({
- path: "/test",
- f: (r) => r.query.hello || "nothing",
- })(["query"]))(new Request("http://localhost:8080/test?hello=hi")).query
- .hello,
- "hi",
- ),
-);
-test(
- "Query",
- (_) =>
- assert.deepStrictEqual(
- (aComposer({ hasName: "http://localhost:8080/" })({
- path: "/test",
- f: (r) => r.query.hello || "nothing",
- })(["query", "req"]))(new Request("http://localhost:8080/test?hello=hi"))
- .query.hello,
- "hi",
- ),
-);
-test(
- "Params",
- (_) =>
- assert.deepStrictEqual(
- (aComposer({ hasName: "http://localhost:8080/" })({
- path: "/test/:id",
- f: (r) => (r.param as Record).id,
- })(["param"]))(new Request("http://localhost:8080/test/1")).param.id,
- "1",
- ),
-);
-
-test(
- "Params",
- (_) =>
- assert.deepStrictEqual(
- (aComposer({ hasName: "http://localhost:8080/" })({
- path: "/test/:a/:b/:c/",
- f: (r) => (r.param as Record).id,
- })(["param"]))(new Request("http://localhost:8080/test/1/2/3/")).param.b,
- "2",
- ),
-);
-test(
- "Params",
- (_) =>
- assert.deepStrictEqual(
- (aComposer()({
- path: "/test/:a/:b/:c/",
- f: (r) => (r.param as Record).id.toString(),
- })(["param"]))(new Request("http://localhost:8080/test/1/2/3/")).param.b,
- "2",
- ),
-);
-
-test(
- "Date",
- (_) =>
- assert.deepStrictEqual(
- typeof (aComposer()({
- path: "/test/",
- f: (r) => r.date.toString(),
- })(["date"]))(new Request("http://localhost:8080/test/")).date,
- "number",
- ),
-);
-test(
- "randomNumber",
- (_) =>
- assert.deepStrictEqual(
- typeof (aComposer()({
- path: "/test/",
- f: (r) => r.randomNumber.toString(),
- })(["randomNumber"]))(new Request("http://localhost:8080/test/"))
- .randomNumber,
- "number",
- ),
-);
-test(
- "Hash",
- (_) =>
- assert.deepStrictEqual(
- typeof (aComposer()({
- path: "/test/",
- f: (r) => r.hash,
- })(["hash"]))(new Request("http://localhost:8080/test/")).hash,
- "string",
- ),
-);
-test(
- "cookie",
- (_) =>
- assert.deepStrictEqual(
- (aComposer()({
- path: "/test/",
- f: (r) => r.cookie?.id ?? "not_found",
- })(["cookie"]))(
- new Request("http://localhost:8080/test/", {
- headers: {
- "Content-Type": "application/json",
- "Cookie": "id=user",
- },
- }),
- ).cookie,
- { id: "user" },
- ),
-);
diff --git a/components/http/test/optimizer/checkAsync.test.ts b/components/http/test/optimizer/checkAsync.test.ts
deleted file mode 100644
index 1fa0d80..0000000
--- a/components/http/test/optimizer/checkAsync.test.ts
+++ /dev/null
@@ -1,96 +0,0 @@
-import assert from "node:assert";
-import test from "node:test";
-import checkAsync from "../../src/framework/optimizer/checkAsync.ts";
-
-test(
- "check for async",
- () =>
- assert.deepStrictEqual(
- checkAsync({
- path: "/",
- f: async (f) => await f.req.blob(),
- }),
- true,
- ),
-);
-test(
- "check for sync",
- () =>
- assert.deepStrictEqual(
- checkAsync({
- path: "/",
- f: () => "hello",
- }),
- false,
- ),
-);
-test(
- "check for nested async",
- () =>
- assert.deepStrictEqual(
- checkAsync({
- path: "/",
- resolve: {
- hi: {
- f: async (f) => await f.req.blob(),
- },
- },
- f: () => "hi",
- }),
- true,
- ),
-);
-test(
- "check for nested async",
- () =>
- assert.deepStrictEqual(
- checkAsync({
- path: "/",
- resolve: {
- hi: {
- f: () => "hi",
- },
- },
- f: () => "hi",
- }),
- false,
- ),
-);
-test(
- "check for nested array async",
- () =>
- assert.deepStrictEqual(
- checkAsync({
- path: "/",
- resolve: {
- "hi": {
- f: () => "ji",
- },
- "hi2": {
- f: async (f) => await f.req.blob(),
- },
- },
- f: () => "hi",
- }),
- true,
- ),
-);
-test(
- "check for nested array async",
- () =>
- assert.deepStrictEqual(
- checkAsync({
- path: "/",
- resolve: {
- hi: {
- f: () => "ji",
- },
- hi2: {
- f: () => "hi",
- },
- },
- f: () => "hi",
- }),
- false,
- ),
-);
diff --git a/components/http/test/optimizer/cheker.test.ts b/components/http/test/optimizer/cheker.test.ts
deleted file mode 100644
index acd73b8..0000000
--- a/components/http/test/optimizer/cheker.test.ts
+++ /dev/null
@@ -1,12 +0,0 @@
-import assert from "node:assert";
-import test from "node:test";
-import checker from "../../src/framework/optimizer/checker.ts";
-
-test(
- "Params",
- (_) =>
- assert.deepStrictEqual(
- checker([])(["param"])([])("r=> r. param "),
- ["param"],
- ),
-);
diff --git a/components/http/test/optimizer/parameters/finder.test.ts b/components/http/test/optimizer/parameters/finder.test.ts
deleted file mode 100644
index f5b32b8..0000000
--- a/components/http/test/optimizer/parameters/finder.test.ts
+++ /dev/null
@@ -1,53 +0,0 @@
-import finder from "../../../src/parameters/finder.ts";
-import assert from "node:assert";
-import test from "node:test";
-import map from "../../../src/parameters/map.ts";
-
-test(
- "only one parameter at the end and query",
- (_) =>
- assert.deepStrictEqual(
- (new Function(
- ` return ${
- finder(map()({ f: (_) => "hello", path: "/test/:id/:hi" }))
- }`,
- ))()("456/hi"),
- {
- hi: "hi",
- id: "456",
- },
- ),
-);
-
-test(
- "only one parameter at the end and query",
- (_) =>
- assert.deepStrictEqual(
- (new Function(
- ` return ${
- finder(map()({ f: (_) => "hello", path: "/:test/:id/:hi" }))
- }`,
- ))()("test/456/hi"),
- {
- hi: "hi",
- id: "456",
- test: "test",
- },
- ),
-);
-
-test(
- "only one parameter at the end and query",
- (_) =>
- assert.deepStrictEqual(
- (new Function(
- ` return ${
- finder(map()({ f: (_) => "hello", path: "/:test/:id/hi" }))
- }`,
- ))()("test/456"),
- {
- id: "456",
- test: "test",
- },
- ),
-);
diff --git a/components/http/test/optimizer/parameters/map.test.ts b/components/http/test/optimizer/parameters/map.test.ts
deleted file mode 100644
index bc9a499..0000000
--- a/components/http/test/optimizer/parameters/map.test.ts
+++ /dev/null
@@ -1,170 +0,0 @@
-import map from "../../../src/parameters/map.ts";
-import assert from "node:assert";
-import test from "node:test";
-
-test(
- "only one parameter at the end",
- (_) =>
- assert.deepStrictEqual(
- map({})({ path: "/test/:id", f: (_) => "hello" }),
- {
- elements: [
- ":id",
- ],
- endsInSlash: false,
- firstParam: 5,
- lastParam: 0,
- hasName: undefined,
- list: [
- "test",
- ":id",
- ],
- map: [
- false,
- true,
- ],
- startsWith: ":",
- },
- ),
-);
-
-test(
- "only one parameter at the end",
- (_) =>
- assert.deepStrictEqual(
- map({})({ path: "/test/:id/", f: (_) => "hello" }),
- {
- elements: [
- ":id",
- ],
- endsInSlash: true,
- firstParam: 5,
- lastParam: 1,
- hasName: undefined,
- list: [
- "test",
- ":id",
- ],
- map: [
- false,
- true,
- ],
- startsWith: ":",
- },
- ),
-);
-
-test(
- "only one parameter at the end",
- (_) =>
- assert.deepStrictEqual(
- map({})({ path: "/test/:id/hi", f: (_) => "hello" }),
- {
- elements: [
- ":id",
- ],
- endsInSlash: false,
- firstParam: 5,
- lastParam: 3,
- hasName: undefined,
- list: [
- "test",
- ":id",
- "hi",
- ],
- map: [
- false,
- true,
- false,
- ],
- startsWith: ":",
- },
- ),
-);
-
-test(
- "only one parameter at the end",
- (_) =>
- assert.deepStrictEqual(
- map({})({ path: "/test/:id/hi/", f: (_) => "hello" }),
- {
- elements: [
- ":id",
- ],
- endsInSlash: true,
- firstParam: 5,
- lastParam: 4,
- hasName: undefined,
- list: [
- "test",
- ":id",
- "hi",
- ],
- map: [
- false,
- true,
- false,
- ],
- startsWith: ":",
- },
- ),
-);
-
-test(
- "only one parameter at the end",
- (_) =>
- assert.deepStrictEqual(
- map({})({ path: "/test/:id/:test", f: (_) => "hello" }),
- {
- elements: [
- ":id",
- ":test",
- ],
- endsInSlash: false,
- firstParam: 5,
- lastParam: 0,
- hasName: undefined,
- list: [
- "test",
- ":id",
- ":test",
- ],
- map: [
- false,
- true,
- true,
- ],
- startsWith: ":",
- },
- ),
-);
-
-test(
- "only one parameter at the end",
- (_) =>
- assert.deepStrictEqual(
- map({})({ path: "/:test/:id/:hi", f: (_) => "hello" }),
- {
- elements: [
- ":test",
- ":id",
- ":hi",
- ],
- endsInSlash: false,
- firstParam: 0,
- lastParam: 0,
- hasName: undefined,
- list: [
- ":test",
- ":id",
- ":hi",
- ],
- map: [
- true,
- true,
- true,
- ],
- startsWith: ":",
- },
- ),
-);
diff --git a/components/http/test/optimizer/parameters/multi.test.ts b/components/http/test/optimizer/parameters/multi.test.ts
deleted file mode 100644
index 11dfc6c..0000000
--- a/components/http/test/optimizer/parameters/multi.test.ts
+++ /dev/null
@@ -1,66 +0,0 @@
-import multi from "../../../src/parameters/multi.ts";
-import map from "../../../src/parameters/map.ts";
-import assert from "node:assert";
-import test from "node:test";
-
-test(
- "param",
- (_) =>
- assert.deepStrictEqual(
- new Function(
- ` return ${
- multi(
- map({ hasName: "http://localhost:8080/" })({
- path: "/test/:id/:hello",
- f: (_) => "hello",
- }),
- )
- }`,
- )()("http://localhost:8080/test/hello/world"),
- {
- hello: "world",
- id: "hello",
- },
- ),
-);
-test(
- "param",
- (_) =>
- assert.deepStrictEqual(
- new Function(
- ` return ${
- multi(
- map({ hasName: "http://localhost:8080/" })({
- path: "/:test/:id/:hello",
- f: (_) => "hello",
- }),
- )
- }`,
- )()("http://localhost:8080/test/hello/world"),
- {
- hello: "world",
- id: "hello",
- test: "test",
- },
- ),
-);
-test(
- "param",
- (_) =>
- assert.deepStrictEqual(
- new Function(
- ` return ${
- multi(
- map({ hasName: "http://localhost:8080/" })({
- path: "/:test/:id/hello",
- f: (_) => "hello",
- }),
- )
- }`,
- )()("http://localhost:8080/test/hello/world"),
- {
- id: "hello",
- test: "test",
- },
- ),
-);
diff --git a/components/http/test/optimizer/parameters/one.test.ts b/components/http/test/optimizer/parameters/one.test.ts
deleted file mode 100644
index 7f0fa36..0000000
--- a/components/http/test/optimizer/parameters/one.test.ts
+++ /dev/null
@@ -1,299 +0,0 @@
-import one from "../../../src/parameters/one.ts";
-import map from "../../../src/parameters/map.ts";
-import assert from "node:assert";
-import test from "node:test";
-
-// "/test/:id"
-test(
- "param",
- (_) =>
- assert.deepStrictEqual(
- new Function(
- ` return ${
- one(
- map({ hasName: "http://localhost:8080/" })({
- path: "/test/:id",
- f: (_) => "hello",
- }),
- )
- }`,
- )()("http://localhost:8080/test/hello").id,
- "hello",
- ),
-);
-test(
- "param",
- (_) =>
- assert.deepStrictEqual(
- new Function(
- ` return ${
- one(
- map({ hasName: "http://localhost:8080/" })({
- path: "/test/:id",
- f: (_) => "hello",
- }),
- )
- }`,
- )()("http://localhost:8080/test/hello?a=1").id,
- "hello",
- ),
-);
-
-test(
- "param",
- (_) =>
- (
- (f) =>
- assert.deepStrictEqual(
- [
- f("http://localhost:8080/test/hello").id,
- f("http://localhost:8080/test/hello").id,
- ],
- ["hello", "hello"],
- )
- )(
- new Function(
- ` return ${one(map()({ path: "/test/:id", f: (_) => "hello" }))}`,
- )(),
- ),
-);
-test(
- "param",
- (_) =>
- (
- (f) =>
- assert.deepStrictEqual(
- [
- f("http://localhost:8080/test/hello?a=1").id,
- f("http://localhost:8080/test/hello?a=1").id,
- ],
- ["hello", "hello"],
- )
- )(
- new Function(
- ` return ${one(map()({ path: "/test/:id", f: (_) => "hello" }))}`,
- )(),
- ),
-);
-
-// "/test/:id/"
-
-test(
- "param",
- (_) =>
- assert.deepStrictEqual(
- new Function(
- ` return ${
- one(
- map({ hasName: "http://localhost:8080/" })({
- path: "/test/:id/",
- f: (_) => "hello",
- }),
- )
- }`,
- )()("http://localhost:8080/test/hello/").id,
- "hello",
- ),
-);
-test(
- "param",
- (_) =>
- assert.deepStrictEqual(
- new Function(
- ` return ${
- one(
- map({ hasName: "http://localhost:8080/" })({
- path: "/test/:id/",
- f: (_) => "hello",
- }),
- )
- }`,
- )()("http://localhost:8080/test/hello/?a=1").id,
- "hello",
- ),
-);
-
-test(
- "param",
- (_) =>
- (
- (f) =>
- assert.deepStrictEqual(
- [
- f("http://localhost:8080/test/hello/").id,
- f("http://localhost:8080/test/hello/").id,
- ],
- ["hello", "hello"],
- )
- )(
- new Function(
- ` return ${one(map()({ path: "/test/:id/", f: (_) => "hello" }))}`,
- )(),
- ),
-);
-test(
- "param",
- (_) =>
- (
- (f) =>
- assert.deepStrictEqual(
- [
- f("http://localhost:8080/test/hello/?a=1").id,
- f("http://localhost:8080/test/hello/?a=1").id,
- ],
- ["hello", "hello"],
- )
- )(
- new Function(
- ` return ${one(map()({ path: "/test/:id/", f: (_) => "hello" }))}`,
- )(),
- ),
-);
-
-// "/test/:id/hi"
-
-test(
- "param",
- (_) =>
- assert.deepStrictEqual(
- new Function(
- ` return ${
- one(
- map({ hasName: "http://localhost:8080/" })({
- path: "/test/:id/hi",
- f: (_) => "hello",
- }),
- )
- }`,
- )()("http://localhost:8080/test/hello/hi").id,
- "hello",
- ),
-);
-test(
- "param",
- (_) =>
- assert.deepStrictEqual(
- new Function(
- ` return ${
- one(
- map({ hasName: "http://localhost:8080/" })({
- path: "/test/:id/hi",
- f: (_) => "hello",
- }),
- )
- }`,
- )()("http://localhost:8080/test/hello/hi?a=1").id,
- "hello",
- ),
-);
-
-test(
- "param",
- (_) =>
- (
- (f) =>
- assert.deepStrictEqual(
- [
- f("http://localhost:8080/test/hello/hi").id,
- f("http://localhost:8080/test/hello/hi").id,
- ],
- ["hello", "hello"],
- )
- )(
- new Function(
- ` return ${one(map()({ path: "/test/:id/hi", f: (_) => "hello" }))}`,
- )(),
- ),
-);
-test(
- "param",
- (_) =>
- (
- (f) =>
- assert.deepStrictEqual(
- [
- f("http://localhost:8080/test/hello/hi?a=1").id,
- f("http://localhost:8080/test/hello/hi?a=1").id,
- ],
- ["hello", "hello"],
- )
- )(
- new Function(
- ` return ${one(map()({ path: "/test/:id/hi", f: (_) => "hello" }))}`,
- )(),
- ),
-);
-
-// "/test/:id/hi/"
-
-test(
- "param",
- (_) =>
- assert.deepStrictEqual(
- new Function(
- ` return ${
- one(
- map({ hasName: "http://localhost:8080/" })({
- path: "/test/:id/hi/",
- f: (_) => "hello",
- }),
- )
- }`,
- )()("http://localhost:8080/test/hello/hi/").id,
- "hello",
- ),
-);
-test(
- "param",
- (_) =>
- assert.deepStrictEqual(
- new Function(
- ` return ${
- one(
- map({ hasName: "http://localhost:8080/" })({
- path: "/test/:id/hi/",
- f: (_) => "hello",
- }),
- )
- }`,
- )()("http://localhost:8080/test/hello/hi/?a=1").id,
- "hello",
- ),
-);
-
-test(
- "param",
- (_) =>
- (
- (f) =>
- assert.deepStrictEqual(
- [
- f("http://localhost:8080/test/hello/hi/").id,
- f("http://localhost:8080/test/hello/hi/").id,
- ],
- ["hello", "hello"],
- )
- )(
- new Function(
- ` return ${one(map()({ path: "/test/:id/hi/", f: (_) => "hello" }))}`,
- )(),
- ),
-);
-test(
- "param",
- (_) =>
- (
- (f) =>
- assert.deepStrictEqual(
- [
- f("http://localhost:8080/test/hello/hi/?a=1").id,
- f("http://localhost:8080/test/hello/hi/?a=1").id,
- ],
- ["hello", "hello"],
- )
- )(
- new Function(
- ` return ${one(map()({ path: "/test/:id/hi/", f: (_) => "hello" }))}`,
- )(),
- ),
-);
diff --git a/components/http/test/optimizer/parameters/slicer.test.ts b/components/http/test/optimizer/parameters/slicer.test.ts
deleted file mode 100644
index e4f819e..0000000
--- a/components/http/test/optimizer/parameters/slicer.test.ts
+++ /dev/null
@@ -1,337 +0,0 @@
-import slicer from "../../../src/parameters/slicer.ts";
-import map from "../../../src/parameters/map.ts";
-import assert from "node:assert";
-import test from "node:test";
-
-// "/test/:id"
-test(
- "param",
- (_) =>
- assert.deepStrictEqual(
- new Function(
- ` return ${
- slicer(
- map({ hasName: "http://localhost:8080/" })({
- path: "/test/:id",
- f: (_) => "hello",
- }),
- )
- }`,
- )()("http://localhost:8080/test/hello"),
- "hello",
- ),
-);
-
-test(
- "param",
- (_) =>
- assert.deepStrictEqual(
- new Function(
- ` return ${
- slicer(
- map({ hasName: "http://localhost:8080/" })({
- path: "/test/:id/",
- f: (_) => "hello",
- }),
- )
- }`,
- )()("http://localhost:8080/test/hello/?a=1"),
- "hello",
- ),
-);
-
-test(
- "param",
- (_) =>
- (
- (f) =>
- assert.deepStrictEqual(
- [
- f("http://localhost:8080/test/hello/"),
- f("http://localhost:8080/test/hello/"),
- ],
- ["hello", "hello"],
- )
- )(
- new Function(
- ` return ${slicer(map()({ path: "/test/:id/", f: (_) => "hello" }))}`,
- )(),
- ),
-);
-test(
- "param",
- (_) =>
- (
- (f) =>
- assert.deepStrictEqual(
- [
- f("http://localhost:8080/test/hello/?a=1"),
- f("http://localhost:8080/test/hello/?a=1"),
- ],
- ["hello", "hello"],
- )
- )(
- new Function(
- ` return ${slicer(map()({ path: "/test/:id/", f: (_) => "hello" }))}`,
- )(),
- ),
-);
-
-// "/test/:id/hi"
-
-test(
- "param",
- (_) =>
- assert.deepStrictEqual(
- new Function(
- ` return ${
- slicer(
- map({ hasName: "http://localhost:8080/" })({
- path: "/test/:id/hi",
- f: (_) => "hello",
- }),
- )
- }`,
- )()("http://localhost:8080/test/hello/hi"),
- "hello",
- ),
-);
-test(
- "param",
- (_) =>
- assert.deepStrictEqual(
- new Function(
- ` return ${
- slicer(
- map({ hasName: "http://localhost:8080/" })({
- path: "/test/:id/hi",
- f: (_) => "hello",
- }),
- )
- }`,
- )()("http://localhost:8080/test/hello/hi?a=1"),
- "hello",
- ),
-);
-
-test(
- "param",
- (_) =>
- (
- (f) =>
- assert.deepStrictEqual(
- [
- f("http://localhost:8080/test/hello/hi"),
- f("http://localhost:8080/test/hello/hi"),
- ],
- ["hello", "hello"],
- )
- )(
- new Function(` return ${
- slicer(
- map()({
- path: "/test/:id/hi",
- f: (_) => "hello",
- }),
- )
- }`)(),
- ),
-);
-test(
- "param",
- (_) =>
- (
- (f) =>
- assert.deepStrictEqual(
- [
- f("http://localhost:8080/test/hello/hi?a=1"),
- f("http://localhost:8080/test/hello/hi?a=1"),
- ],
- ["hello", "hello"],
- )
- )(
- new Function(` return ${
- slicer(
- map()({
- path: "/test/:id/hi",
- f: (_) => "hello",
- }),
- )
- }`)(),
- ),
-);
-
-// "/test/:id/hi/"
-
-test(
- "param",
- (_) =>
- assert.deepStrictEqual(
- new Function(
- ` return ${
- slicer(
- map({ hasName: "http://localhost:8080/" })({
- path: "/test/:id/hi/",
- f: (_) => "hello",
- }),
- )
- }`,
- )()("http://localhost:8080/test/hello/hi/"),
- "hello",
- ),
-);
-test(
- "param",
- (_) =>
- assert.deepStrictEqual(
- new Function(
- ` return ${
- slicer(
- map({ hasName: "http://localhost:8080/" })({
- path: "/test/:id/hi/",
- f: (_) => "hello",
- }),
- )
- }`,
- )()("http://localhost:8080/test/hello/hi/?a=1"),
- "hello",
- ),
-);
-
-test(
- "param",
- (_) =>
- (
- (f) =>
- assert.deepStrictEqual(
- [
- f("http://localhost:8080/test/hello/hi/"),
- f("http://localhost:8080/test/hello/hi/"),
- ],
- ["hello", "hello"],
- )
- )(
- new Function(
- ` return ${
- slicer(
- map()({
- path: "/test/:id/hi/",
- f: (_) => "hello",
- }),
- )
- }`,
- )(),
- ),
-);
-test(
- "param",
- (_) =>
- (
- (f) =>
- assert.deepStrictEqual(
- [
- f("http://localhost:8080/test/hello/hi/?a=1"),
- f("http://localhost:8080/test/hello/hi/?a=1"),
- ],
- ["hello", "hello"],
- )
- )(
- new Function(
- ` return ${
- slicer(
- map()({
- path: "/test/:id/hi/",
- f: (_) => "hello",
- }),
- )
- }`,
- )(),
- ),
-);
-
-// "/:test/:id/hi/"
-
-test(
- "param",
- (_) =>
- assert.deepStrictEqual(
- new Function(
- ` return ${
- slicer(
- map({ hasName: "http://localhost:8080/" })({
- path: "/:test/:id/hi/",
- f: (_) => "hello",
- }),
- )
- }`,
- )()("http://localhost:8080/hello/world/hi/"),
- "hello/world",
- ),
-);
-test(
- "param",
- (_) =>
- assert.deepStrictEqual(
- new Function(
- ` return ${
- slicer(
- map({ hasName: "http://localhost:8080/" })({
- path: "/:test/:id/hi/",
- f: (_) => "hello",
- }),
- )
- }`,
- )()("http://localhost:8080/hello/world/hi/?a=1"),
- "hello/world",
- ),
-);
-test(
- "param",
- (_) =>
- (
- (f) =>
- assert.deepStrictEqual(
- [
- f("http://localhost:8080/hello/world/hi/"),
- f("http://localhost:8080/hello/world/hi/"),
- ],
- ["hello/world", "hello/world"],
- )
- )(
- new Function(
- ` return ${
- slicer(
- map()({
- path: "/:test/:id/hi/",
- f: (_) => "hello",
- }),
- )
- }`,
- )(),
- ),
-);
-test(
- "param",
- (_) =>
- (
- (f) =>
- assert.deepStrictEqual(
- [
- f("http://localhost:8080/hello/world/hi/"),
- f("http://localhost:8080/hello/world/hi/?a=1"),
- ],
- ["hello/world", "hello/world"],
- )
- )(
- new Function(
- ` return ${
- slicer(
- map()({
- path: "/:test/:id/hi/",
- f: (_) => "hello",
- }),
- )
- }`,
- )(),
- ),
-);
diff --git a/components/http/test/optimizer/parameters/unique.test .ts b/components/http/test/optimizer/parameters/unique.test .ts
deleted file mode 100644
index e1869ee..0000000
--- a/components/http/test/optimizer/parameters/unique.test .ts
+++ /dev/null
@@ -1,303 +0,0 @@
-import one from "../../../src/parameters/unique.ts";
-import map from "../../../src/parameters/map.ts";
-import assert from "node:assert";
-import test from "node:test";
-
-// "/test/:id"
-console.log(
- one(map()({ path: "/test/:id", f: (_) => "hello" })),
-);
-
-test(
- "param",
- (_) =>
- assert.deepStrictEqual(
- new Function(
- ` return ${
- one(
- map({ hasName: "http://localhost:8080/" })({
- path: "/test/:id",
- f: (_) => "hello",
- }),
- )
- }`,
- )()("http://localhost:8080/test/hello"),
- "hello",
- ),
-);
-test(
- "param",
- (_) =>
- assert.deepStrictEqual(
- new Function(
- ` return ${
- one(
- map({ hasName: "http://localhost:8080/" })({
- path: "/test/:id",
- f: (_) => "hello",
- }),
- )
- }`,
- )()("http://localhost:8080/test/hello?a=1"),
- "hello",
- ),
-);
-
-test(
- "param",
- (_) =>
- (
- (f) =>
- assert.deepStrictEqual(
- [
- f("http://localhost:8080/test/hello"),
- f("http://localhost:8080/test/hello"),
- ],
- ["hello", "hello"],
- )
- )(
- new Function(
- ` return ${one(map()({ path: "/test/:id", f: (_) => "hello" }))}`,
- )(),
- ),
-);
-test(
- "param",
- (_) =>
- (
- (f) =>
- assert.deepStrictEqual(
- [
- f("http://localhost:8080/test/hello?a=1"),
- f("http://localhost:8080/test/hello?a=1"),
- ],
- ["hello", "hello"],
- )
- )(
- new Function(
- ` return ${one(map()({ path: "/test/:id", f: (_) => "hello" }))}`,
- )(),
- ),
-);
-
-// "/test/:id/"
-
-test(
- "param",
- (_) =>
- assert.deepStrictEqual(
- new Function(
- ` return ${
- one(
- map({ hasName: "http://localhost:8080/" })({
- path: "/test/:id/",
- f: (_) => "hello",
- }),
- )
- }`,
- )()("http://localhost:8080/test/hello/"),
- "hello",
- ),
-);
-test(
- "param",
- (_) =>
- assert.deepStrictEqual(
- new Function(
- ` return ${
- one(
- map({ hasName: "http://localhost:8080/" })({
- path: "/test/:id/",
- f: (_) => "hello",
- }),
- )
- }`,
- )()("http://localhost:8080/test/hello/?a=1"),
- "hello",
- ),
-);
-
-test(
- "param",
- (_) =>
- (
- (f) =>
- assert.deepStrictEqual(
- [
- f("http://localhost:8080/test/hello/"),
- f("http://localhost:8080/test/hello/"),
- ],
- ["hello", "hello"],
- )
- )(
- new Function(
- ` return ${one(map()({ path: "/test/:id/", f: (_) => "hello" }))}`,
- )(),
- ),
-);
-test(
- "param",
- (_) =>
- (
- (f) =>
- assert.deepStrictEqual(
- [
- f("http://localhost:8080/test/hello/?a=1"),
- f("http://localhost:8080/test/hello/?a=1"),
- ],
- ["hello", "hello"],
- )
- )(
- new Function(
- ` return ${one(map()({ path: "/test/:id/", f: (_) => "hello" }))}`,
- )(),
- ),
-);
-
-// "/test/:id/hi"
-
-test(
- "param",
- (_) =>
- assert.deepStrictEqual(
- new Function(
- ` return ${
- one(
- map({ hasName: "http://localhost:8080/" })({
- path: "/test/:id/hi",
- f: (_) => "hello",
- }),
- )
- }`,
- )()("http://localhost:8080/test/hello/hi"),
- "hello",
- ),
-);
-test(
- "param",
- (_) =>
- assert.deepStrictEqual(
- new Function(
- ` return ${
- one(
- map({ hasName: "http://localhost:8080/" })({
- path: "/test/:id/hi",
- f: (_) => "hello",
- }),
- )
- }`,
- )()("http://localhost:8080/test/hello/hi?a=1"),
- "hello",
- ),
-);
-
-test(
- "param",
- (_) =>
- (
- (f) =>
- assert.deepStrictEqual(
- [
- f("http://localhost:8080/test/hello/hi"),
- f("http://localhost:8080/test/hello/hi"),
- ],
- ["hello", "hello"],
- )
- )(
- new Function(
- ` return ${one(map()({ path: "/test/:id/hi", f: (_) => "hello" }))}`,
- )(),
- ),
-);
-test(
- "param",
- (_) =>
- (
- (f) =>
- assert.deepStrictEqual(
- [
- f("http://localhost:8080/test/hello/hi?a=1"),
- f("http://localhost:8080/test/hello/hi?a=1"),
- ],
- ["hello", "hello"],
- )
- )(
- new Function(
- ` return ${one(map()({ path: "/test/:id/hi", f: (_) => "hello" }))}`,
- )(),
- ),
-);
-
-// "/test/:id/hi/"
-
-test(
- "param",
- (_) =>
- assert.deepStrictEqual(
- new Function(
- ` return ${
- one(
- map({ hasName: "http://localhost:8080/" })({
- path: "/test/:id/hi/",
- f: (_) => "hello",
- }),
- )
- }`,
- )()("http://localhost:8080/test/hello/hi/"),
- "hello",
- ),
-);
-test(
- "param",
- (_) =>
- assert.deepStrictEqual(
- new Function(
- ` return ${
- one(
- map({ hasName: "http://localhost:8080/" })({
- path: "/test/:id/hi/",
- f: (_) => "hello",
- }),
- )
- }`,
- )()("http://localhost:8080/test/hello/hi/?a=1"),
- "hello",
- ),
-);
-
-test(
- "param",
- (_) =>
- (
- (f) =>
- assert.deepStrictEqual(
- [
- f("http://localhost:8080/test/hello/hi/"),
- f("http://localhost:8080/test/hello/hi/"),
- ],
- ["hello", "hello"],
- )
- )(
- new Function(
- ` return ${one(map()({ path: "/test/:id/hi/", f: (_) => "hello" }))}`,
- )(),
- ),
-);
-test(
- "param",
- (_) =>
- (
- (f) =>
- assert.deepStrictEqual(
- [
- f("http://localhost:8080/test/hello/hi/?a=1"),
- f("http://localhost:8080/test/hello/hi/?a=1"),
- ],
- ["hello", "hello"],
- )
- )(
- new Function(
- ` return ${one(map()({ path: "/test/:id/hi/", f: (_) => "hello" }))}`,
- )(),
- ),
-);
diff --git a/components/http/test/optimizer/queries/elements.test.ts b/components/http/test/optimizer/queries/elements.test.ts
deleted file mode 100644
index 106765d..0000000
--- a/components/http/test/optimizer/queries/elements.test.ts
+++ /dev/null
@@ -1,21 +0,0 @@
-import assert from "node:assert";
-import test from "node:test";
-import elements from "../../../src/queries/elements.ts";
-
-test(
- "queries",
- () =>
- assert.deepStrictEqual(
- elements(["hello"]),
- '(p=>u=>(l=> l!==-1?p(u.slice(l)) :null)(u.indexOf("?")))(s => ({ hello: encodeURIComponent( (a =>a !== -1? (l => l !== -1 ? s.slice(a+6,l):s.slice(a+6,s.length))(s.indexOf("&",a)):null)(s.indexOf("hello=")) )}))',
- ),
-);
-
-test(
- "queries",
- () =>
- assert.deepStrictEqual(
- elements(["hello", "hi"]),
- '(p=>u=>(l=> l!==-1?p(u.slice(l)) :null)(u.indexOf("?")))(s => ({ hello: encodeURIComponent( (a =>a !== -1? (l => l !== -1 ? s.slice(a+6,l):s.slice(a+6,s.length))(s.indexOf("&",a)):null)(s.indexOf("hello=")) ), hi: encodeURIComponent( (a =>a !== -1? (l => l !== -1 ? s.slice(a+3,l):s.slice(a+3,s.length))(s.indexOf("&",a)):null)(s.indexOf("hi=")) )}))',
- ),
-);
diff --git a/components/http/test/optimizer/queries/finder.test.ts b/components/http/test/optimizer/queries/finder.test.ts
deleted file mode 100644
index ffebf5d..0000000
--- a/components/http/test/optimizer/queries/finder.test.ts
+++ /dev/null
@@ -1,12 +0,0 @@
-import assert from "node:assert";
-import test from "node:test";
-import finder from "../../../src/queries/finder.ts";
-
-test(
- "queries",
- () =>
- assert.deepStrictEqual(
- finder("hello"),
- ' (a =>a !== -1? (l => l !== -1 ? s.slice(a+6,l):s.slice(a+6,s.length))(s.indexOf("&",a)):null)(s.indexOf("hello=")) ',
- ),
-);
diff --git a/components/http/test/optimizer/resolve.test.ts b/components/http/test/optimizer/resolve.test.ts
deleted file mode 100644
index 099d925..0000000
--- a/components/http/test/optimizer/resolve.test.ts
+++ /dev/null
@@ -1,88 +0,0 @@
-import assert from "node:assert";
-import test from "node:test";
-
-import resolveComposer from "../../src/optimizer/resolveComposer.ts";
-import morphism from "../../src/optimizer/morphism.ts";
-
-test(
- "check for async",
- async () =>
- assert.deepStrictEqual(
- await resolveComposer()({
- first: {
- f: async (f) => await (await f.req.blob()).text(),
- },
- })(
- new Request("http://hi.com/", { method: "POST", body: "hello" }),
- ) as Record,
- { first: "hello" },
- ),
-);
-
-test(
- "check for sync",
- () =>
- assert.deepStrictEqual(
- resolveComposer()({
- hi: {
- f: () => "hello",
- },
- })(new Request("http://hi.com/")),
- { hi: "hello" },
- ),
-);
-
-test(
- "check for sync",
- async () =>
- assert.deepStrictEqual(
- await resolveComposer(
- { mutable: { hi: "hello", res: new Response() } },
- )({
- resolve: {
- f: (f) => f.mutable.hi,
- },
- })(new Request("http://hi.com/")),
- { resolve: "hello" },
- ),
-);
-test(
- "check for async",
- async () =>
- assert.deepStrictEqual(
- await resolveComposer()({
- first: {
- resolve: {
- second: morphism()(
- {
- f: async (f) => (await f.req.blob()).text(),
- },
- ),
- },
- options: {
- add: ["resolve"],
- },
- f: (f) => f.resolve,
- },
- })(new Request("http://hi.com/", { method: "POST", body: "hello" })),
- { first: { second: "hello" } },
- ),
-);
-
-test(
- "check for sync",
- () =>
- assert.deepStrictEqual(
- resolveComposer()({
- first: {
- resolve: {
- second: morphism()({
- f: () => "hello",
- }),
- },
- f: (f) => f.resolve,
- },
- })(new Request("http://hi.com/")),
- { first: { second: "hello" } },
- ),
-);
diff --git a/components/http/test/optimizer/response1.test.ts b/components/http/test/optimizer/response1.test.ts
deleted file mode 100644
index 7ef5540..0000000
--- a/components/http/test/optimizer/response1.test.ts
+++ /dev/null
@@ -1,27 +0,0 @@
-import assert from "node:assert";
-import test from "node:test";
-import response from "../../src/framework/optimizer/response.ts";
-
-test(
- "Response response",
- async (_) =>
- assert.deepStrictEqual(
- await (response()({
- path: "/hello/:id",
- f: (f) => JSON.stringify(f.param),
- })(new Request("http://localhost:8080/hello/hello"))).text(),
- '{"id":"hello"}',
- ),
-);
-test(
- "Response response",
- async (_) =>
- assert.deepStrictEqual(
- await (response()({
- path: "/hello/:id",
- type: "request",
- f: (f) => new Response(JSON.stringify(f.param)),
- })(new Request("http://localhost:8080/hello/hello"))).text(),
- '{"id":"hello"}',
- ),
-);
diff --git a/components/http/test/optimizer/static/composedPaths.test.ts b/components/http/test/optimizer/static/composedPaths.test.ts
deleted file mode 100644
index 41a41e1..0000000
--- a/components/http/test/optimizer/static/composedPaths.test.ts
+++ /dev/null
@@ -1,26 +0,0 @@
-import assert from "node:assert";
-import test from "node:test";
-
-import composer from "../../../src/framework/optimizer/staticFiles/composedPaths.ts";
-
-test(
- "hello",
- () =>
- assert.deepStrictEqual(
- "/fun.test.ts",
- composer({ type: "fileServer", path: "./misc/", name: "/", mime: false })(
- "./test/",
- )("./")(["./test/fun.test.ts"])([])[0].path,
- ),
-);
-test(
- "hello",
- () =>
- assert.deepStrictEqual(
- "/fun.test.ts",
- composer({ type: "fileServer", path: "./misc/", name: "/", mime: false })(
- "./test/",
- )("./")(["./test/fun.test.ts"])([[".ts", "null"]])[0]
- .path,
- ),
-);
diff --git a/components/http/test/optimizer/static/getDir.test.ts b/components/http/test/optimizer/static/getDir.test.ts
deleted file mode 100644
index 2803b58..0000000
--- a/components/http/test/optimizer/static/getDir.test.ts
+++ /dev/null
@@ -1,13 +0,0 @@
-import assert from "node:assert";
-import test from "node:test";
-
-import getDir from "../../../src/framework/optimizer/staticFiles/getDir.ts";
-
-test(
- "static",
- () =>
- assert.deepStrictEqual(
- getDir("./misc/").every((x) => x[0] === "." && x[1] === "/"),
- true,
- ),
-);
diff --git a/components/http/test/optimizer/static/getMime.test.ts b/components/http/test/optimizer/static/getMime.test.ts
deleted file mode 100644
index 79fe2a1..0000000
--- a/components/http/test/optimizer/static/getMime.test.ts
+++ /dev/null
@@ -1,22 +0,0 @@
-import assert from "node:assert";
-import test from "node:test";
-
-import getMime from "../../../src/framework/optimizer/staticFiles/getMime.ts";
-
-test(
- "test",
- () =>
- assert.deepStrictEqual(
- getMime([[".txt", "hello"]])(".hello"),
- "text/html",
- ),
-);
-
-test(
- "test",
- () =>
- assert.deepStrictEqual(
- getMime([[".hello", "hello"]])(".hello"),
- "hello",
- ),
-);
diff --git a/components/http/test/optimizer/static/main.test.ts b/components/http/test/optimizer/static/main.test.ts
deleted file mode 100644
index eb05636..0000000
--- a/components/http/test/optimizer/static/main.test.ts
+++ /dev/null
@@ -1,76 +0,0 @@
-import assert from "node:assert";
-import test from "node:test";
-import main from "../../../src/framework/optimizer/staticFiles/main.ts";
-
-test(
- "test",
- () =>
- assert.deepStrictEqual(
- main({ type: "fileServer", path: "./misc/", name: "/hello", mime: false })
- .some((x) => x.path === "/hello/logo.png"),
- true,
- ),
-);
-
-test(
- "test",
- () =>
- assert.deepStrictEqual(
- main({
- type: "fileServer",
- path: "./misc/",
- name: "/hello",
- mime: false,
- removeExtensionOf: [".png"],
- })
- .some((x) => x.path === "/hello/logo"),
- true,
- ),
-);
-
-test(
- "test",
- () =>
- assert.deepStrictEqual(
- main({ type: "fileServer", path: "./misc/", name: "/", mime: false })
- .some((x) => x.path === "/logo.png"),
- true,
- ),
-);
-
-test(
- "test",
- () =>
- assert.deepStrictEqual(
- main({
- type: "fileServer",
- path: "./misc/",
- name: "/hello/nested",
- mime: false,
- }).some((x) => x.path === "/hello/nested/logo.png"),
- true,
- ),
-);
-
-test(
- "test",
- () =>
- assert.deepStrictEqual(
- main({
- type: "fileServer",
- path: "./misc/",
- name: "/hello/nested",
- mime: false,
- template: [{
- checker: (s) => s.includes(".png"),
- r: (options) => ({
- type: "response",
- path: options.relativeName.slice(0, -4),
- r: () => new Response(""),
- }),
- }],
- })
- .some((x) => x.path === "/hello/nested/logo"),
- true,
- ),
-);
diff --git a/components/http/test/optimizer/static/mime.test.ts b/components/http/test/optimizer/static/mime.test.ts
deleted file mode 100644
index ea5a4a3..0000000
--- a/components/http/test/optimizer/static/mime.test.ts
+++ /dev/null
@@ -1,37 +0,0 @@
-import assert from "node:assert";
-import test from "node:test";
-
-import mime from "../../../src/framework/optimizer/staticFiles/mime.ts";
-
-test(
- "hello",
- () =>
- assert.deepStrictEqual(
- mime({ type: "fileServer", path: "./", name: "/hello/" }).length,
- 74,
- ),
-);
-
-test(
- "hello",
- () =>
- assert.deepStrictEqual(
- mime({ type: "fileServer", path: "./", name: "/hello/", mime: false })
- .length,
- 0,
- ),
-);
-
-test(
- "hello",
- () =>
- assert.deepStrictEqual(
- mime({
- type: "fileServer",
- path: "./",
- name: "/hello/",
- extra: [[".ts", "hello/hello"]],
- }).at(74),
- [".ts", "hello/hello"],
- ),
-);
diff --git a/components/http/test/util/paths.ts b/components/http/test/util/paths.ts
deleted file mode 100644
index 899a634..0000000
--- a/components/http/test/util/paths.ts
+++ /dev/null
@@ -1,36 +0,0 @@
-import { Petition } from "../../src/framework/optimizer/types.ts";
-
-export default [
- { type: "response", path: "/", r: (_) => new Response("GET:main") },
- { type: "response", path: "/one", r: (_) => new Response("1") },
- { type: "response", path: "/two", r: (_) => new Response("2") },
- { type: "response", path: "/three", r: (_) => new Response("3") },
- { type: "response", path: "/four", r: (_) => new Response("4") },
- { type: "response", path: "/five", r: (_) => new Response("5") },
- { type: "response", path: "/six", r: (_) => new Response("6") },
- { type: "response", path: "/test", r: (_) => new Response("GET:test") },
- { type: "response", path: "/test/", r: (_) => new Response("GET:test/") },
- {
- type: "response",
- path: "/test/:id/:name/",
- r: (_) => new Response("GET:test/:id/:name/"),
- },
- {
- type: "response",
- method: "POST",
- path: "/",
- r: (_) => new Response("POST:main"),
- },
- {
- type: "response",
- method: "HEAD",
- path: "/",
- r: (_) => new Response("HEAD:main"),
- },
- {
- type: "response",
- method: "DELETE",
- path: "/",
- r: (_) => new Response("DELETE:main"),
- },
-] as Petition[];
diff --git a/components/http/test/util/url.ts b/components/http/test/util/url.ts
deleted file mode 100644
index 6cc996d..0000000
--- a/components/http/test/util/url.ts
+++ /dev/null
@@ -1,16 +0,0 @@
-export default [
- [
- ["test", ""],
- ["test/"],
- ["test/"],
- ],
- [
- [""],
- ],
- [
- [""],
- ],
- [
- [""],
- ],
-] as string[][][];
diff --git a/docs/init.md b/docs/init.md
deleted file mode 100644
index 99d0cf2..0000000
--- a/docs/init.md
+++ /dev/null
@@ -1,142 +0,0 @@
-
-
-
-
-
-
-
-
-In the `versatile` world of JavaScript, wrap plays a key role in harmonizing the
-language's polymorphic nature with Vixeny's functional approach. It ensures
-scalability and maintains code purity, crucial for efficient web development.
-
-```ts
-// name of this file: api.ts
-import { wrap } from "vixeny";
-//routing options
-import { options } from "somewhere.ts";
-
-const api = wrap({
- //setting up options
- ...options,
- startWith: "/api",
-})()
- //creating a petition
- .stdPetition({
- path: "/ping",
- f: () => "pong",
- });
-
-export { api };
-```
-
-Simplifing handling diverse HTTP requests, offering a structured,
-side-effect-free programming environment. This makes building, maintaining, and
-scaling web applications more intuitive and manageable, showcasing wrap as an
-essential tool in the Vixeny toolkit.
-
-```ts
-import { vixeny, wrap } from "vixeny";
-import { options } from "somewhere.ts";
-import { api } from "api.ts";
-
-const router = wrap(options)()
- .stdPetition({
- path: "/",
- f: () => "hello world",
- })
- //joining `api` to this wrap
- .union(api.unwrap())
- // console logging:
- // outputs: '/'
- // '/api/ping'
- .logPaths();
-
-// unwrapping all the petitions giving them to the router
-vixeny(options)(router.unwrap());
-```
-
-
-
-Let's create a Petition without wrap and export it an create new differents
-routes out of it.
-
-```ts
-import { Petition } from "vixeny/optimizer/types";
-
-const surprise: Petition = {
- path: "/meow",
- headings: {
- status: 307,
- statusText: "Temporary Redirect",
- headers: {
- Location: "https://www.youtube.com/watch?v=_e9yMqmXWo0",
- },
- },
- f: (c) => "",
-};
-
-export { surprise };
-```
-
-In another file:
-
-```ts
-import { surprise } from "somewhere.ts";
-
-export default wrap(options)()
- .stdPetition(surprise)
- .stdPetition({ ...surprise, path: "/woof" })
- .stdPetition({ ...surprise, path: "/woooow" })
- // console logging:
- // outputs: '/meow'
- // '/woof'
- // '/woooow'
- .logPaths();
-```
-
-Applies to any other key in the object.
-
-
-
-There are two type of petitions:
-
-- `stdPetition`: where you have to return a `BodyInt` or `Promise`
-- `customPetition`: where you have to return a `Response` or `Promise`
-
-```ts
-wrap(options)()
- .stdPetition({
- path: "/",
- f: () => "hello world",
- })
- .customPetition({
- path: "/response/who/:name",
- f: (c) => new Response(c.param.name),
- });
-```
-
-It is important to note that `wrap` only supports these types although there are
-more types which serve different purposes which must be directly inserted.
-
-```ts
-vixeny(options)([
- //importing all the paths
- ...wrap(options)()
- .union(root.unwrap())
- .union(api.unwrap())
- .unwrap(),
- //adding the static server
- {
- type: "fileServer",
- path: "./public/",
- name: "/public/",
- },
- // petition without ctx
- {
- path: "/responseType",
- type: "response",
- r: () => new Response("Hello"),
- },
-]);
-```
diff --git a/docs/introduction.md b/docs/introduction.md
deleted file mode 100644
index 8da8810..0000000
--- a/docs/introduction.md
+++ /dev/null
@@ -1,106 +0,0 @@
-
-
-
-
-
-
-# Introduction:
-
-/// talk about vixeny in general
-
-## Bateries included:
-
-As simple as:
-
-```bash
-npx create-vixeny
-```
-
-or:
-
-```bash
-bun create vixeny
-```
-
-Templates for :
-
-- Pug
-- Ejs
-- Jsx
-- Tsx
-- Sass
-- PostCSS
-- Remaker and more ...
-
-## Testability end-to-end
-
-Check anything at any state
-
-```ts
-const router = routes.testRequests();
-
-test("Checking in `/`", async () => {
- expect(
- await router(new Request(serverName))
- .then((res) => res.status),
- ).toStrictEqual(200);
-});
-```
-
-## Reusable
-
-Make your own life cycle with `resolve`
-
-```ts
-import { isValidUser } from "../resolve.ts"
-
-export default wrap()()
- .stdPetition({
- path: "/api/path1",
- resolve:{
- user: isValidUser // <--
- }
- f: (c) => c.resolve.user
- ? "Hello: " + c.resolve.user.name
- : "notFound",
- })
- .stdPetition({
- path: "/api/path1",
- resolve:{
- user: isValidUser // <--
- }
- f: (c) => c.resolve.user
- ? "Hello: " + c.resolve.user.name
- : "notFound",
- })
-```
-
-## Clean an easy to transport
-
-Zero side effets
-
-```ts
-import api from "./api.ts";
-
-const main = wrap(o)()
- .stdPetition({
- path: "/",
- headings: {
- headers: ".html",
- },
- f: () => "hello world",
- })
- .stdPetition({
- path: "/get/:id",
- param: {
- unique: true,
- },
- f: (c) => c.param,
- });
-
-composeResponse()(
- main.union(
- api.unwrap(),
- ).unwrap(),
-);
-```
diff --git a/docs/morphisim.md b/docs/morphisim.md
deleted file mode 100644
index bc5a126..0000000
--- a/docs/morphisim.md
+++ /dev/null
@@ -1,372 +0,0 @@
-
-
-
-
-
-
-# Demystifying Vixeny: Your Guide to Building Digital Experiences
-
-Imagine Vixeny guiding you through the process of crafting your dream home,
-simplifying the complexities of web development into something straightforward
-and manageable. It employs two key concepts —`Resolve` and `Branch`— much like
-the essential steps in building a house, laying the foundation and then
-expanding upon it to add the final touches.
-
-## Foundations First: Resolve
-
-`Resolve` prepares your site, organizing all the essentials before construction
-starts. It's like getting the land ready, ensuring materials are on-site. This
-includes setting up data and permissions in advance, guaranteeing that when it's
-time to build, everything's in place.
-
-## Adding Features: Branch
-
-Once the basics are set, `Branch` lets you customize, adding unique features to
-your site. Think of it as choosing room designs or adding a garden, enhancing
-your home's functionality and appeal without starting over.
-
-## Building with Intention: The Vixeny Way
-
-Vixeny’s approach mirrors thoughtful home construction, emphasizing:
-
-- **Reusability**: Modular design lets you replicate and adapt features easily,
- akin to using a beloved room design throughout your home.
-- **Purity**: Ensuring operations are clean and predictable, much like choosing
- quality materials for your home, Vixeny keeps your project stable and
- reliable.
-- **Testing for the Future**: Mocking tests different scenarios, preparing your
- site for future needs—just as planning for potential home additions or
- changes.
-
-## Morphism
-
-### Resolve and Branch
-
-Now, let's talk more about the Optimizer in Vixeny; after identifying all
-necessary functions, orchestrates the composition of petitions. This process
-intricately weaves together all resolves and branches, both of which are
-considered types of morphisms. Interestingly, a petition in itself is
-conceptualized as a morphism. This highlights the functional and compositional
-core of Vixeny, where both resolves and branches play pivotal roles:
-
-## Resolve
-
-- **Definition**: In any morphism, a `resolve` guarantees its resolution prior
- to the execution of the petition's main function (`f`).
-
- ```ts
- wrap(options)()
- .stdPetition({
- path: "/withResolve",
- resolve: {
- hi: { c: () => "Hello world" },
- },
- // This petition consistently outputs "Hello world"
- f: (c) => c.resolve.hi,
- });
- ```
-
-- **Asynchronous Functions**: Asynchronous resolves maintain the state of the
- morphism, meaning the asynchronous result is merged without altering the
- original state.
-
- ```ts
- wrap()()
- .stdPetition({
- path: "/withResolveAsync",
- resolve: {
- hi: { async c: () => await Promise.resolve("Hello world") }
- },
- // Note: The function in `f` is synchronous
- f: (c) => c.resolve.hi,
- })
- ```
-
-- **Execution Order**: All resolves are executed and completed prior to their
- integration into the `CTX`, ensuring their resolved outputs are accessible
- within the `CTX` for the petition's logic.
-
- ```ts
- wrap(options)()
- .stdPetition({
- path: "/helloWorld",
- resolve: {
- hello: { async f: () => await Promise.resolve("Hello") },
- world: { f: () => 'world' }
- },
- f: c => `${c.resolve.hello} ${c.resolve.world}`,
- })
- ```
-
-- **Uniqueness of `CTX`**: With the exception of `mutable`, each `CTX` instance
- remains unique and isolated, ensuring petitions remain decoupled.
-
- ```ts
- wrap(options)()
- .stdPetition({
- path: "/date",
- resolve: {
- date: morphism(o)({ f: (c) => c.date }),
- },
- f: (c) => c.resolve.date !== c.date ? "Always true" : "Unreachable",
- });
- ```
-
-- **Nested Resolves and Branches**: Vixeny supports an unlimited nesting of
- resolves and branches within each other.
-
- ```ts
- const hello = morphism(options)({
- resolve: {
- nestedHello: {
- f: () => "hello world",
- },
- },
- f: (c) => c.resolve.nestedHello,
- });
-
- wrap(options)()
- .stdPetition({
- path: "/hello",
- resolve: {
- hello: hello,
- },
- f: (c) => c.resolve.hello,
- });
- ```
-
-In Vixeny, `f` stands for `functor`, because: `functor preserve structure`. This
-concept underscores how resolves and the main function interact while
-maintaining the integrity of the petition's structure.
-
-### Branch
-
-In Vixeny, a `Branch` is used to incorporate additional logic or operations
-within the execution of a petition,which has its own `CTX`. Branches, like
-resolves, are morphisms but are specifically designed to execute alongside or
-within the main function (`f`) of a petition, offering a direct way to extend
-functionality without cluttering the primary logic.
-
-### 1. Defining a Simple Branch
-
-A branch can be as simple as a function that returns a static message. This
-example demonstrates how to define and use a simple branch within a petition:
-
-```ts
-const helloBranch = morphism(options)({
- f: (c) => "Hello from branch",
-});
-
-wrap(options)()
- .stdPetition({
- path: "/helloBranch",
- branch: {
- hello: helloBranch,
- },
- f: (c) => new Response(c.branch.hello(null)),
- });
-```
-
-- **Explanation**: Here, `helloBranch` is defined as a morphism with a function
- (`f`) that returns a static string. Within the petition, this branch is
- invoked, and its return value is used to construct a response.
-
-### 2. Branch with Parameters
-
-Branches can also accept parameters, making them dynamic in their operation.
-This example illustrates a branch that utilizes parameters from the `CTX`:
-
-```ts
-const greetUserBranch = morphism()({
- f: (c) => `Hello, ${c.arguments.name}`,
-});
-
-wrap(options)()
- .stdPetition({
- path: "/greet/:name",
- branch: {
- greetUser: greetUserBranch,
- },
- f: (c) => new Response(c.branch.greetUser({ name: c.param.name })),
- });
-```
-
-- **Explanation**: `greetUserBranch` takes a name parameter through
- `c.arguments` and returns a personalized greeting. The branch is executed in
- the petition's main function, using the name parameter extracted from the URL.
-
-### 3. Asynchronous Branch
-
-Branches can perform asynchronous operations, such as fetching data from a
-database or an external API:
-
-```ts
-const fetchUserDataBranch = morphism(options)({
- async f: (c) => {
- const userId = c.arguments.userId;
- return await fetch(`https://api.example.com/users/${userId}`).then(res => res.json());
- },
-});
-
-wrap(options)()
- .stdPetition({
- path: "/user/:userId",
- branch: {
- fetchUserData: fetchUserDataBranch,
- },
- f: async (c) => {
- const userData = await c.branch.fetchUserData({ userId: c.param.userId });
- return new Response(JSON.stringify(userData));
- },
- })
-```
-
-### Explaining `Mutable` in Context
-
-- **Mutability Concept**: In this scenario, `Mutable` refers to the ability of
- the context (`c`) to have its state changed and those changes preserved across
- subsequent transformations or operations.
-
-- **Implementation with `mutStdPetition`**: By using `mutStdPetition`, adds the
- key `mutable` which persistent. This allows subsequent operations or morphisms
- to access and further modify the updated state. Specifically, any property
- added to `c.mutable` becomes a preserved state that can be referenced or
- altered in later stages of processing.
-
-### Practical Example
-
-```ts
-// Initial operation with mutStdPetition, introducing a mutable context
-.mutStdPetition({
- // Configuration and initial transformation
- resolve: {
- // Use morphism to modify and use the mutable state
- randomNumber: morphism(options)({ f : c =>
- {
- c.mutable.randomNumber = c.randomNumber;
- return c.randomNumber;
- }
- )
- },
- // Subsequent operation accessing and evaluating the mutable state
- f: c => c.mutable.randomNumber !== c.randomNumber
- ? 'Condition based on mutable state'
- : 'Potentially reachable if state matches'
-})
-```
-
-In this example, `c.mutable.randomNumber` is set in one operation, and this
-state is then available for comparison in the next operation. This demonstrates
-how `Mutable` allows for complex, state-dependent logic to be implemented across
-a sequence of morphisms, leveraging the state preserved in `c.mutable`.
-
-It's important to notice that `mutStdPetition` and `stdPetition` are composed
-differently and a pure state like `stdPetition` is totally independent of
-`mutStdPetition`
-
-### Purpose of morphism
-
-`morphism` functions are designed to facilitate explicit data transformation in
-a type-safe manner, especially useful in scenarios where TypeScript's type
-inference capabilities are stretched thin by deep nesting or complex operations.
-By breaking down transformations into manageable, clearly defined steps,
-`morphism` ensures that each operation is both comprehensible and type-safe.
-
-### TypeScript's Typing Limitation
-
-TypeScript's type system, while robust, cannot always effectively manage or
-infer types in deeply nested or highly complex transformations. This limitation
-can lead to challenges in enforcing type safety, particularly in applications
-that require detailed manipulation of nested data structures.
-
-### Practical Application
-
-To explain the provided code snippets effectively, let's break down the concept
-of morphisms as used here, especially
-
-#### Hello Morphism
-
-The first morphism, `hello`, is defined to perform no direct transformation but
-specifies a nested `resolve` structure with a static value and a function that
-returns a string "hello". The final function `f` extracts the `nested` part of
-the resolved structure.
-
-```ts
-const hello = morphism(options)({
- resolve: {
- //resolves first
- nested: {
- crypto: {
- globalKey: "your secret",
- },
- f: () => "hello",
- },
- },
- // showing inference from a nested resolve
- f: (f) => f.resolve.nested,
-});
-```
-
-#### NestedHello Morphism
-
-The `nestedHello` morphism wraps the `hello` morphism within its `resolve`,
-showing how morphisms can be nested or chained to build upon the results of
-previous transformations.
-
-```ts
-const nestedHello = morphism(options)({
- resolve: {
- hello: hello,
- },
- // showing inference from a nested resolve
- f: (f) => f.resolve.hello,
-});
-```
-
-#### isValidUser Morphism
-
-This morphism validates a JWT token by checking if it exists and if its `iat`
-(issued at time) is before the current time. It showcases how to perform
-conditional checks within a morphism.
-
-```ts
-const isValidUser = morphism(options)({
- crypto: {
- globalKey: "your secret",
- token: {
- jwtToken: {},
- },
- },
- f: (c) =>
- c.token.jwtToken &&
- (c.token.jwtToken as { name: string; iat: number }).iat < Date.now()
- ? c.token.jwtToken
- : null,
-});
-```
-
-#### Please Morphism
-
-Finally, the `check` morphism demonstrates how to resolve dependencies using
-previous morphisms (`isValidUser`) and process the result further.
-
-```ts
-const please = morphism(options)({
- resolve: {
- check: isValidUser,
- },
- f: (c) => c.resolve.check !== null ? "Valid token" : "Invalid token",
-});
-```
-
-### Key Concepts
-
-- **Branching and Resolving**: These operations allow for the construction of
- complex data transformation pipelines. Branching can be seen as defining
- various paths of data flow and logic, while resolving handles the actual
- execution of these paths to produce a final outcome.
-- **Modularity**: Morphisms can be nested and reused, promoting modularity and
- reuse of logic.
-- **Declarative Logic**: The structure allows for a clear, declarative
- definition of data transformations and conditions, improving readability and
- maintainability.
diff --git a/docs/routing.md b/docs/routing.md
deleted file mode 100644
index feaa0d2..0000000
--- a/docs/routing.md
+++ /dev/null
@@ -1,219 +0,0 @@
-
-
-
-
-
-
-# Wrap
-
-### Union
-
-One of the most important uses of `wrap` in Vixeny is to protect and modularize
-`Petitions`, especially when they are exported or modified. This ensures that
-your code remains organized and maintainable. Let's demonstrate this with an
-example involving multiple files:
-
-First, create a file named `extension.ts`:
-
-```ts
-//file: extension.ts
-export default wrap()()
- .stdPetition({
- path: "/",
- f: () => "helloWorld",
- });
-```
-
-Next, create two separate files, `a.ts` and `b.ts`, which import and utilize
-`extension.ts`:
-
-```ts
-import extencion from "./extension.ts";
-
-// file: a.ts
-export default wrap()()
- .union(extension.unwrap())
- .stdPetition({
- path: "/hello",
- f: () => "helloWorld",
- })
- // console logging
- // outputs: "/"
- // "/hello"
- .logPaths();
-```
-
-```ts
-import extension from "./extension.ts";
-
-// file: b.ts
-export default wrap()()
- .union(extension.unwrap())
- .stdPetition({
- path: "/api",
- f: () => "helloWorld",
- })
- // console logging
- // outputs: "/"
- // "/api"
- .logPaths();
-```
-
-Additionally, you can add `extension` to its second curried function
-(`wrap()(here)`) and modify the `base`. This allows for further customization of
-the routing:
-
-```ts
-import extension from "./extension.ts";
-
-export default wrap()(
- extension.union(
- // changing the start path of the wrap `extension`
- extension.changeOptions({ "startWith": "/api" })
- .unwrap(),
- ),
-)
- .stdPetition({
- path: "/",
- f: () => "helloWorld",
- })
- // console logging
- // outputs: "/api/"
- // "/"
- .logSize();
-```
-
-
-
-In the `versatile` world of JavaScript, wrap plays a key role in harmonizing the
-language's polymorphic nature with Vixeny's functional approach. It ensures
-scalability and maintains code purity, crucial for efficient web development.
-
-```ts
-// name of this file: api.ts
-import { wrap } from "vixeny";
-//routing options
-import { options } from "somewhere.ts";
-
-const api = wrap({
- //setting up options
- ...options,
- startWith: "/api",
-})()
- //creating a petition
- .stdPetition({
- path: "/ping",
- f: () => "pong",
- });
-
-export { api };
-```
-
-Simplifing handling diverse HTTP requests, offering a structured,
-side-effect-free programming environment. This makes building, maintaining, and
-scaling web applications more intuitive and manageable, showcasing wrap as an
-essential tool in the Vixeny toolkit.
-
-```ts
-import { vixeny, wrap } from "vixeny";
-import { options } from "somewhere.ts";
-import { api } from "api.ts";
-
-const router = wrap(options)()
- .stdPetition({
- path: "/",
- f: () => "hello world",
- })
- //joining `api` to this wrap
- .union(api.unwrap())
- // console logging:
- // outputs: '/'
- // '/api/ping'
- .logPaths();
-
-// unwrapping all the petitions giving them to the router
-vixeny(options)(router.unwrap());
-```
-
-
-
-Let's create a Petition without wrap and export it an create new differents
-routes out of it.
-
-```ts
-const surprise = {
- path: "/meow",
- headings: {
- status: 307,
- statusText: "Temporary Redirect",
- headers: {
- Location: "https://www.youtube.com/watch?v=_e9yMqmXWo0",
- },
- },
- f: (c) => "",
-};
-
-export { surprise };
-```
-
-In another file:
-
-```ts
-import { surprise } from "somewhere.ts";
-
-export default wrap(options)()
- .stdPetition(surprise)
- .stdPetition({ ...surprise, path: "/woof" })
- .stdPetition({ ...surprise, path: "/woooow" })
- // console logging:
- // outputs: '/meow'
- // '/woof'
- // '/woooow'
- .logPaths();
-```
-
-Applies to any other key in the object.
-
-
-
-There are two type of petitions:
-
-- `stdPetition`: where you have to return a `BodyInt` or `Promise`
-- `customPetition`: where you have to return a `Response` or `Promise`
-
-```ts
-wrap(options)()
- .stdPetition({
- path: "/",
- f: () => "hello world",
- })
- .customPetition({
- path: "/response/who/:name",
- f: (c) => new Response(c.param.name),
- });
-```
-
-It is important to note that `wrap` only supports these types although there are
-more types which serve different purposes which must be directly inserted.
-
-```ts
-vixeny(options)([
- //importing all the paths
- ...wrap(options)()
- .union(root.unwrap())
- .union(api.unwrap())
- .unwrap(),
- //adding the static server
- {
- type: "fileServer",
- path: "./public/",
- name: "/public/",
- },
- // petition without ctx
- {
- path: "/responseType",
- type: "response",
- r: () => new Response("Hello"),
- },
-]);
-```
diff --git a/docs/testing.md b/docs/testing.md
deleted file mode 100644
index 397a144..0000000
--- a/docs/testing.md
+++ /dev/null
@@ -1,148 +0,0 @@
-
-
-
-
-
-
-## Testing: The Keystone of Digital Construction
-
-In building, thorough testing and inspections are non-negotiable, ensuring every
-part of the structure meets exacting standards. Vixeny embeds this principle
-deeply within its framework, offering a comprehensive testing suite that
-simulates various scenarios, ensuring every component functions as intended.
-
-### Case Study: Simulating Conditions
-
-Imagine a feature in our digital architecture that responds to environmental
-changes, much like a smart home system adjusting to weather variations. Vixeny
-enables us to test these dynamic responses, ensuring they act precisely under
-varied simulated conditions.
-
-#### Scenario: Predicting Outcomes
-
-Our focus falls on a `/random` feature, designed to yield different outcomes
-based on a random number generator. This setup mirrors real-life scenarios where
-outcomes pivot on user interactions or external data.
-
-```ts
-const routes = wrap(options)()
- .stdPetition({
- path: "/random",
- f: (c) =>
- c.randomNumber > .5
- ? c.randomNumber > .99 ? "winner" : "almost"
- : "try again",
- });
-```
-
-#### Crafting the Tests
-
-To ensure our feature behaves predictably across a range of states, we
-manipulate the random number generator, crafting scenarios to test the
-anticipated outcomes.
-
-```ts
-test("/random", async () => {
- // Testing for the "try again" outcome.
- expect(
- await routes
- .handleRequest("/random")({
- options: {
- setRandomNumber: .25,
- },
- })(new Request("/random"))
- .then((res) => res.text()),
- ).toStrictEqual("try again");
-
- // Testing for the "almost" outcome.
- expect(
- await routes
- .handleRequest("/random")({
- options: {
- setRandomNumber: .51,
- },
- })(new Request("/random"))
- .then((res) => res.text()),
- ).toStrictEqual("almost");
-
- // Testing for the "winner" outcome.
- expect(
- await routes
- .handleRequest("/random")({
- options: {
- setRandomNumber: .999,
- },
- })(new Request("/random"))
- .then((res) => res.text()),
- ).toStrictEqual("winner");
-});
-```
-
-### Refining the Process with Mocked Resolves
-
-For a feature reliant on external APIs, like fetching current weather data, we
-aim to test without real-time data fetches. Here, we introduce a mocked
-synchronous function to simulate the data fetching:
-
-```ts
-// Original asynchronous resolve function for fetching weather data
-const routes = wrap(options)()
- .stdPetition({
- path: "/weather",
- resolve: {
- currentWeather: {
- async f: () => {
- return await fetch("https://api.weather.com/current").then(res => res.json());
- }
- }
- },
- f: (c) => {
- return c.resolve.currentWeather.temperature > 75 ? "It's warm outside" : "It's cool outside";
- },
- });
-
-// Mocking the resolve function for controlled testing
-const mockedWeatherResolve = () => ({ temperature: 80 });
-
-// Injecting the mocked resolve using handleRequest
-const mockRoutes = routes.handleRequest("/weather")({
- resolve: {
- currentWeather: mockedWeatherResolve
- }
-});
-
-// Verifying behavior with the mocked data
-test("/weather", async () => {
- expect(
- await mockRoutes(new Request("/weather"))
- .then(res => res.text())
- ).toStrictEqual("It's warm outside");
-});
-```
-
-### The Virtues of Mocked Testing
-
-This approach grants us unparalleled control over the testing environment,
-mirroring the precision and adaptability seen in the most advanced construction
-methodologies. It allows for:
-
-- **Precision and Predictability**: Creating a controlled environment that
- simulates specific conditions, ensuring components react as expected.
-- **Efficiency**: Streamlining the testing process by removing dependencies on
- external data sources.
-- **Confidence**: Providing assurance in the reliability and functionality of
- the digital structure, much like the final inspection before a home's
- completion.
-
-## Conclusion: Building Digital Foundations with Assurance
-
-Just as thorough inspections ensure a home is ready for habitation, Vixeny's
-testing capabilities, particularly the use of mocked resolves, ensure that every
-digital component is built to perfection. This meticulous approach to testing
-empowers developers to construct with confidence, knowing every part of the
-application is crafted to meet and exceed expectations, ensuring a robust,
-functional, and adaptable digital experience. Through Resolve, Branch, and
-precise testing, Vixeny lays the groundwork for web applications that stand the
-test of time, embodying the principles of a well-constructed home.
-
-Thank you for your time.
diff --git a/docs/wrap.md b/docs/wrap.md
deleted file mode 100644
index f2d0c4f..0000000
--- a/docs/wrap.md
+++ /dev/null
@@ -1,163 +0,0 @@
-
-
-
-
-
-# Wrap
-
-### Union
-
-One of the most important uses of `wrap` in Vixeny is to protect and modularize
-`Petitions`, especially when they are exported or modified. This ensures that
-your code remains organized and maintainable. Let's demonstrate this with an
-example involving multiple files:
-
-First, create a file named `extension.ts`:
-
-```ts
-//file: extension.ts
-export default wrap()()
- .stdPetition({
- path: "/",
- f: () => "helloWorld",
- });
-```
-
-Next, create two separate files, `a.ts` and `b.ts`, which import and utilize
-`extension.ts`:
-
-```ts
-import extencion from "./extension.ts";
-
-// file: a.ts
-export default wrap()()
- .union(extension.unwrap())
- .stdPetition({
- path: "/hello",
- f: () => "helloWorld",
- })
- // console logging
- // outputs: "/"
- // "/hello"
- .logPaths();
-```
-
-```ts
-import extension from "./extension.ts";
-
-// file: b.ts
-export default wrap()()
- .union(extension.unwrap())
- .stdPetition({
- path: "/api",
- f: () => "helloWorld",
- })
- // console logging
- // outputs: "/"
- // "/api"
- .logPaths();
-```
-
-Additionally, you can add `extension` to its second curried function
-(`wrap()(here)`) and modify the `base`. This allows for further customization of
-the routing:
-
-```ts
-import extension from "./extension.ts";
-
-export default wrap()(
- extension.union(
- // changing the start path of the wrap `extension`
- extension.changeOptions({ "startWith": "/api" })
- .unwrap(),
- ),
-)
- .stdPetition({
- path: "/",
- f: () => "helloWorld",
- })
- // console logging
- // outputs: "/api/"
- // "/"
- .logPaths();
-```
-
-### Optimizer
-
-In Vixeny, the `optimizer` is a crucial function that oversees the `CTX` in `f`,
-composes the petition, chains `resolve` and `branch`, and efficiently handles
-all asynchronous and synchronous functions. But what does this mean? Let's first
-explore the `CTX`, which in TypeScript shows you all the native functions
-(including plugins, which are not included here):
-
-- `"req"`: Gives access to the `Request`.
-- `"query"`: Retrieves the query parameters.
-- `"param"`: Fetches the URL parameters.
-- `"date"`: Returns the current date.
-- `"randomNumber"`: Generates a random number from 0 to 1.
-- `"hash"`: Produces a random hash (string).
-- `"cookie"`: Accesses cookies.
-- `"resolve"`: Resolves any `morpishim` before the execution of the current
- `CTX`.
-- `"branch"`: A function within `CTX` that is also a `morpishim` and it has its
- own `CTX`.
-- `"mutable"`: Adds a fixed point to all `morpishim` in the `petition`,
- regardless of depth.
-- `"arguments"`: Arguments passed to `branch`.
-- `"token"`: (requires `crypto`) Checks and parses a cookie with the given key.
-- `"sign"`: (requires `crypto`) Signs a JSON.
-- `"verify"`: (requires `crypto`) Verifies and parses a string.
-
-However, none of these are actually included in the `CTX` by default. The
-`Optimizer` analyzes (tokenizes `f` and checks for the keys used) your petition
-and adds only what's required. If there's nothing required, it simply handles
-the `Request`.
-
-```ts
-export default wrap()()
- .stdPetition({
- path: "/",
- f: () => "helloWorld",
- })
- // console logging
- // outputs: []
- .logLastCheck()
- .stdPetition({
- path: "/hello/:id",
- f: (c) => c.param.id,
- })
- // console logging
- // outputs: ["param"]
- .logLastCheck();
-```
-
-There are some limitations to this, for example, the optimizer cannot understand
-what functions outside of the context need, but you can manually add them:
-
-```ts
-export default wrap()()
- .stdPetition({
- path: "/hello/query1",
- f: (c) => functionOutsideOfContext(c),
- })
- // console logging
- // outputs: []
- .logLastCheck()
- .stdPetition({
- path: "/hello/query2",
- f: (c) => functionOutsideOfContext(c),
- options: {
- add: ["query"],
- },
- })
- // console logging
- // outputs: ["query"]
- .logLastCheck();
-```
-
-You have three options for customization:
-
-- `only`: Bypasses the optimizer, adding only the requested functions.
-- `add`: Adds specified functions to the list.
-- `remove`: Removes a function if it is added but not required, which could
- happen but is harmless to the `CTX`.
diff --git a/misc/buildMD.mjs b/misc/buildMD.mjs
deleted file mode 100644
index 9d7b05c..0000000
--- a/misc/buildMD.mjs
+++ /dev/null
@@ -1,58 +0,0 @@
-import findAllFiles from "../components/files/findAllFiles.mjs";
-import { duration } from "mitata/reporter/fmt.mjs";
-import { readFileSync, writeFileSync } from "node:fs";
-
-function summaryToMarkdown(benchmarks) {
- benchmarks = benchmarks.filter((b) => !b.error);
- benchmarks.sort((a, b) => a.stats.avg - b.stats.avg);
- const baseline = benchmarks.find((b) => b.baseline) || benchmarks[0];
-
- let output = `## **Summary** ${
- baseline.group ? `for *${baseline.group}*` : ""
- }\n\n`;
- output += `### **${baseline.name}** \n\n`;
-
- benchmarks.filter((b) => b !== baseline).forEach((b) => {
- const diff = Number((1 / baseline.stats.avg * b.stats.avg).toFixed(2));
- const indicator = diff > 1 ? "faster" : "slower";
- const color = diff > 1 ? "green" : "red";
- output +=
- `- ${diff}x **${indicator}** than *${b.name}*\n`;
- });
-
- return output;
-}
-
-const parserd = (json) =>
- `\n# ${json.runtime}\n` +
- Array.from(
- json.benchmarks.reduce(
- (acc, benchmark) => acc.add(benchmark.group),
- new Set(),
- ),
- ).map((groupName) =>
- json.benchmarks.filter((benchmark) => benchmark.group === groupName).filter(
- (x) => "stats" in x,
- )
- ).map((groupBenchmarks) =>
- `\n## ${groupBenchmarks[0].group}\n` +
- "| Name | Time (Avg) | Range | p75 | p99 | p995 |\n|------|------------|-------|-----|-----|------|\n" +
- [
- ...groupBenchmarks.map((y, i) =>
- `| ${y.name} | ${duration(y.stats?.avg ?? 0)} | (${
- duration(y.stats?.min ?? 0)
- } .. ${duration(y.stats?.max ?? 0)}/iter) | ${
- duration(y.stats?.p75 ?? 0)
- } | ${duration(y.stats?.p99 ?? 0)} | ${duration(y.stats?.p995 ?? 0)} |`
- ),
- ].join("\n") + summaryToMarkdown(groupBenchmarks) + "\n\n"
- ).join("\n\n");
-
-findAllFiles("./bench/json/")
- .map((x) => x[0])
- .forEach((x) =>
- writeFileSync(
- "./bench/results/" + x.split("/").at(-1) + ".md",
- parserd(JSON.parse(readFileSync(x))),
- )
- );
diff --git a/package.json b/package.json
index 67b1899..8cb8f90 100644
--- a/package.json
+++ b/package.json
@@ -1,13 +1,13 @@
{
"name": "vixeny",
- "version": "0.0.955",
+ "version": "0.1.0",
"description": "A functional router for Bun and Deno",
"main": "main.ts",
"directories": {
"test": "test"
},
"scripts": {
- "test": "deno test -A ./"
+ "test": "deno test -A ./test/*"
},
"repository": {
"type": "git",
@@ -32,7 +32,9 @@
"homepage": "https://vixeny.dev/",
"devDependencies": {
"bun-types": "^1.0.2",
- "jose": "^4.14.6",
"mitata": "^0.1.6"
+ },
+ "peerDependencies": {
+ "typescript": "^5.0.0"
}
}
diff --git a/src/components/cookieToToken/cookieToTokenBodyParser.ts b/src/components/cookieToToken/cookieToTokenBodyParser.ts
new file mode 100644
index 0000000..36743e1
--- /dev/null
+++ b/src/components/cookieToToken/cookieToTokenBodyParser.ts
@@ -0,0 +1,6 @@
+export default (ar: string[]) =>
+ new Function(
+ ` return (${ar.reduce((acc, x) => acc + x + "=>", "")}r => ({${
+ ar.map((x) => ` ${x}: ${x}(r)`).join(",")
+ }}))`,
+ )();
diff --git a/src/components/cookieToToken/cookieToTokenFilter.ts b/src/components/cookieToToken/cookieToTokenFilter.ts
new file mode 100644
index 0000000..2516454
--- /dev/null
+++ b/src/components/cookieToToken/cookieToTokenFilter.ts
@@ -0,0 +1,28 @@
+export default (elements: string[]) => (input: string) =>
+ elements
+ .filter((x, index, arr) =>
+ index === 0 ||
+ (!arr[index - 1].startsWith("resolve.") &&
+ !arr[index - 1].startsWith("branch."))
+ )
+ .map((element) =>
+ // If the element matches the input and the next element exists
+ element.indexOf(input) !== -1
+ ? element.slice(
+ element
+ .indexOf(input) + input.length + 1,
+ (element
+ .indexOf(".", element.indexOf(input) + input.length + 1) +
+ 1 || element.length + 1) - 1,
+ )
+ : null
+ )
+ .filter((x) => x !== null)
+ .filter((x) => x !== "")
+ .sort()
+ .filter((v, i, a) => !i || v !== a[i - 1])
+ .reduce(
+ (acc, v) =>
+ acc.includes(v as string) ? acc : acc.concat(v as unknown as string[]),
+ [] as string[],
+ );
diff --git a/src/components/cookieToToken/cookieToTokenGets.ts b/src/components/cookieToToken/cookieToTokenGets.ts
new file mode 100644
index 0000000..e3f59e6
--- /dev/null
+++ b/src/components/cookieToToken/cookieToTokenGets.ts
@@ -0,0 +1,24 @@
+import verifySha256 from "../jwt/verifySha256.mjs";
+import type { SupportedKeys } from "../../morphism.ts";
+
+export default (secret: SupportedKeys) => (name: string) =>
+ (
+ (sha256) => (c: string | null) =>
+ (
+ (p) =>
+ p !== -1
+ ? sha256(
+ //@ts-ignore
+ c.slice(
+ p + name.length + 1,
+ //@ts-ignore
+ (c.indexOf(",", p) + 1 || c.length + 1) - 1,
+ ),
+ )
+ : null
+ )(
+ typeof c === "string" ? c.indexOf(name + "=") : -1,
+ )
+ )(
+ verifySha256()(secret),
+ );
diff --git a/src/components/cookieToToken/cookieToTokenMain.ts b/src/components/cookieToToken/cookieToTokenMain.ts
new file mode 100644
index 0000000..18fb762
--- /dev/null
+++ b/src/components/cookieToToken/cookieToTokenMain.ts
@@ -0,0 +1,36 @@
+import type { FunRouterOptions } from "../../options.ts";
+import type { Petition, SupportedKeys } from "../../morphism.ts";
+import cookieToTokenBodyParser from "./cookieToTokenBodyParser.ts";
+import cookieToTokenGets from "./cookieToTokenGets.ts";
+import cookieToTokenFilter from "./cookieToTokenFilter.ts";
+
+export default (o?: FunRouterOptions) => (f: Petition) =>
+ f.crypto && "globalKey" in f.crypto
+ ? (
+ (getCookies) =>
+ "token" in f.crypto
+ ? ((s: SupportedKeys) => (arr: string[]) =>
+ arr.reduce(
+ (acc, x) => acc(cookieToTokenGets(s)(x)),
+ cookieToTokenBodyParser(arr),
+ ))(f.crypto.globalKey)(
+ //@ts-ignore
+ Object.keys(f.crypto.token),
+ )
+ : getCookies.length > 0
+ ? ((s: SupportedKeys) => (arr: string[]) =>
+ arr.reduce(
+ (acc, x) => acc(cookieToTokenGets(s)(x)),
+ cookieToTokenBodyParser(arr),
+ ))(f.crypto.globalKey)(
+ getCookies,
+ )
+ : void console.error("No token found, please use 'token' ") ??
+ (() => null)
+ )(
+ cookieToTokenFilter(
+ f.f.toString()
+ .split(" "),
+ )("token"),
+ )
+ : () => ({ SystemError: "Crypto is requieres" });
diff --git a/src/components/cookies/main.ts b/src/components/cookies/main.ts
new file mode 100644
index 0000000..2f37732
--- /dev/null
+++ b/src/components/cookies/main.ts
@@ -0,0 +1,12 @@
+export default (_o: any) => (s: string) =>
+ s
+ ? Object.fromEntries(
+ s
+ .split("; ")
+ .filter((x) =>
+ x
+ .indexOf("=") !== -1
+ )
+ .map((x) => x.split("=")),
+ )
+ : null;
diff --git a/src/components/cors/mainCORS.ts b/src/components/cors/mainCORS.ts
new file mode 100644
index 0000000..85048ad
--- /dev/null
+++ b/src/components/cors/mainCORS.ts
@@ -0,0 +1,13 @@
+import type { CORSOptions } from "./types.ts";
+
+export const parse = () => (o: CORSOptions) =>
+ Object.keys(o).reduce(
+ //@ts-ignore
+ (acc, key) => ({ ...acc, [key]: o[key].toString() }),
+ {},
+ );
+
+export const stringToFunction = (obj: { [key: string]: string }) =>
+ (new Function(`return () => (${JSON.stringify(obj)})`))() as () => {
+ [key: string]: string;
+ };
diff --git a/src/components/cors/types.ts b/src/components/cors/types.ts
new file mode 100644
index 0000000..dac48e0
--- /dev/null
+++ b/src/components/cors/types.ts
@@ -0,0 +1,55 @@
+type RequestMethod =
+ | "ACL"
+ | "BIND"
+ | "CHECKOUT"
+ | "CONNECT"
+ | "COPY"
+ | "DELETE"
+ | "GET"
+ | "HEAD"
+ | "LINK"
+ | "LOCK"
+ | "M-SEARCH"
+ | "MERGE"
+ | "MKACTIVITY"
+ | "MKCALENDAR"
+ | "MKCOL"
+ | "MOVE"
+ | "NOTIFY"
+ | "OPTIONS"
+ | "PATCH"
+ | "POST"
+ | "PRI"
+ | "PROPFIND"
+ | "PROPPATCH"
+ | "PURGE"
+ | "PUT"
+ | "REBIND"
+ | "REPORT"
+ | "SEARCH"
+ | "SOURCE"
+ | "SUBSCRIBE"
+ | "TRACE"
+ | "UNBIND"
+ | "UNLINK"
+ | "UNLOCK"
+ | "UNSUBSCRIBE";
+
+export type CORSOptions = {
+ allowOrigins?: string | string[];
+ allowMethods?: string | RequestMethod | RequestMethod[];
+ exposeHeaders?: string | string[];
+ maxAge?: number;
+ allowCredentials?: boolean;
+ allowHeaders?: string | string[];
+ appendHeaders?: boolean;
+};
+
+type HeadersName =
+ | "Access-Control-Max-Age"
+ | "Access-Control-Allow-Credentials"
+ | "Access-Control-Allow-Headers"
+ | "Access-Control-Expose-Headers"
+ | "Access-Control-Allow-Methods"
+ | "Vary"
+ | "Access-Control-Allow-Origin";
diff --git a/src/components/encode/b64UrlTob64.mjs b/src/components/encode/b64UrlTob64.mjs
new file mode 100644
index 0000000..0f80707
--- /dev/null
+++ b/src/components/encode/b64UrlTob64.mjs
@@ -0,0 +1,11 @@
+export default () => (b64url) =>
+ !/^[-_A-Z0-9]*?={0,2}$/i.test(b64url) ? null : (
+ (l) =>
+ l === 2
+ ? b64url.replace(/-/g, "+").replace(/_/g, "/") + "=="
+ : l === 3
+ ? b64url.replace(/-/g, "+").replace(/_/g, "/") + "="
+ : l === 0
+ ? b64url.replace(/-/g, "+").replace(/_/g, "/")
+ : null
+ )(b64url.length % 4);
diff --git a/src/components/encode/b64toUrl.mjs b/src/components/encode/b64toUrl.mjs
new file mode 100644
index 0000000..1c73580
--- /dev/null
+++ b/src/components/encode/b64toUrl.mjs
@@ -0,0 +1,28 @@
+import bun from "./src/base64toUrl/convertBase64ToBase64urlBun.mjs";
+import deno from "./src/base64toUrl/convertBase64ToBase64urlDeno.mjs";
+import node from "./src/base64toUrl/convertBase64ToBase64urlNode.mjs";
+import name from "../runtime/name.mjs";
+
+/**
+ * Selects and returns a function to convert Base64 strings to Base64Url strings based on the runtime environment.
+ *
+ * The function checks the runtime (Bun, Deno, or Node) and returns the respective conversion function. If the runtime
+ * is not Bun or Deno, it defaults to Node.
+ *
+ * @function
+ * @returns {Function} A function that takes a Base64 string and returns its Base64Url representation.
+ *
+ * @example
+ * const base64ToBase64Url = unwrapBase64ToBase64UrlFunction();
+ * const myBase64UrlString = base64ToBase64Url(myBase64String);
+ *
+ * @note
+ * The function relies on the `name` module to determine the runtime environment. Ensure the module correctly detects your environment.
+ */
+
+export default () =>
+ (
+ (rt) => rt === "Bun" ? bun() : rt === "Deno" ? deno() : node()
+ )(
+ name(),
+ );
diff --git a/src/components/encode/jsonString.mjs b/src/components/encode/jsonString.mjs
new file mode 100644
index 0000000..c283972
--- /dev/null
+++ b/src/components/encode/jsonString.mjs
@@ -0,0 +1,38 @@
+import unsafe from "./src/stringify/unsafe.mjs";
+import safe from "./src/stringify/safe.mjs";
+
+/**
+ * Stringifies a given schema based on provided options.
+ *
+ * @function
+ * @param {Object} [options] - Configuration options for stringifying.
+ * @param {("unsafe" | "safe")} [options.type="safe"] - The type of stringify method to use, can be "unsafe" or "safe".
+ * @returns {Function} A function that takes a `JsonStringify` schema and returns the stringified result.
+ *
+ * @example
+ * // Using the default safe stringify method
+ * const str_one_string = stringify()({
+ * type: "object",
+ * properties: {
+ * hello: { type: "string" },
+ * },
+ * required: ["hello"],
+ * });
+ *
+ * // Using the unsafe stringify method
+ * const ustr_one_string = stringify({type:"unsafe"})({
+ * type: "object",
+ * properties: {
+ * hello: { type: "string" },
+ * },
+ * required: ["hello"],
+ * });
+ * @note
+ * To use the TypeScript typings for this function, import the `JsonStringifyFunction` type from the corresponding type definition file. Example:
+ * `import { JsonStringifyFunction } from 'vixeny/components/encode/types;`
+ */
+
+export default (options) => (schema) =>
+ typeof options === "object" && "type" in options && options.type === "unsafe"
+ ? unsafe(schema)
+ : safe(schema);
diff --git a/src/components/encode/src/base64toUrl/convertBase64ToBase64urlBun.mjs b/src/components/encode/src/base64toUrl/convertBase64ToBase64urlBun.mjs
new file mode 100644
index 0000000..0a50994
--- /dev/null
+++ b/src/components/encode/src/base64toUrl/convertBase64ToBase64urlBun.mjs
@@ -0,0 +1,2 @@
+export default () => (b64) =>
+ b64.replace(/\+/g, "-").replace(/\//g, "_").replace(/=/g, "");
diff --git a/src/components/encode/src/base64toUrl/convertBase64ToBase64urlDeno.mjs b/src/components/encode/src/base64toUrl/convertBase64ToBase64urlDeno.mjs
new file mode 100644
index 0000000..00f40b6
--- /dev/null
+++ b/src/components/encode/src/base64toUrl/convertBase64ToBase64urlDeno.mjs
@@ -0,0 +1,6 @@
+export default () => (b64) =>
+ b64.endsWith("=")
+ ? b64.endsWith("==")
+ ? b64.replace(/\+/g, "-").replace(/\//g, "_").slice(0, -2)
+ : b64.replace(/\+/g, "-").replace(/\//g, "_").slice(0, -1)
+ : b64.replace(/\+/g, "-").replace(/\//g, "_");
diff --git a/src/components/encode/src/base64toUrl/convertBase64ToBase64urlNode.mjs b/src/components/encode/src/base64toUrl/convertBase64ToBase64urlNode.mjs
new file mode 100644
index 0000000..66f0fd9
--- /dev/null
+++ b/src/components/encode/src/base64toUrl/convertBase64ToBase64urlNode.mjs
@@ -0,0 +1,6 @@
+export default () => (b64) =>
+ b64.length > 2 && b64[b64.length - 1] === "="
+ ? b64[b64.length - 2] === "="
+ ? b64.replace(/\+/g, "-").replace(/\//g, "_").slice(0, -2)
+ : b64.replace(/\+/g, "-").replace(/\//g, "_").slice(0, -1)
+ : b64.replace(/\+/g, "-").replace(/\//g, "_");
diff --git a/src/components/encode/src/others/concatThreeUint8Array.mjs b/src/components/encode/src/others/concatThreeUint8Array.mjs
new file mode 100644
index 0000000..12c3ca1
--- /dev/null
+++ b/src/components/encode/src/others/concatThreeUint8Array.mjs
@@ -0,0 +1,13 @@
+export default (a) => (b) => (d) =>
+ (
+ (result) => (
+ (
+ result.set(a),
+ result.set(b, a.length),
+ result.set(d, a.length + b.length),
+ result
+ )
+ )
+ )(
+ new Uint8Array(a.length + b.length + d.length),
+ );
diff --git a/src/components/encode/src/others/concatTwoUint8Array.mjs b/src/components/encode/src/others/concatTwoUint8Array.mjs
new file mode 100644
index 0000000..b914899
--- /dev/null
+++ b/src/components/encode/src/others/concatTwoUint8Array.mjs
@@ -0,0 +1,10 @@
+export default () => (a) => (b) =>
+ (
+ (result) => (
+ (
+ result.set(a), result.set(b, a.length), result
+ )
+ )
+ )(
+ new Uint8Array(a.length + b.length),
+ );
diff --git a/src/components/encode/src/stringify/composer/decoder.mjs b/src/components/encode/src/stringify/composer/decoder.mjs
new file mode 100644
index 0000000..c8040e1
--- /dev/null
+++ b/src/components/encode/src/stringify/composer/decoder.mjs
@@ -0,0 +1,8 @@
+export default (j) =>
+ Object.keys(j.properties)
+ .map((x) => ({
+ type: j.properties[x].type,
+ required: j.required?.includes(x) === true ? true : false,
+ name: x,
+ const: "const" in j.properties[x] ? j.properties.const : undefined,
+ }));
diff --git a/src/components/encode/src/stringify/composer/decoder.ts b/src/components/encode/src/stringify/composer/decoder.ts
new file mode 100644
index 0000000..ee345dc
--- /dev/null
+++ b/src/components/encode/src/stringify/composer/decoder.ts
@@ -0,0 +1,13 @@
+import { JsonMap, JsonStringify } from "../types.ts";
+
+export default (j: JsonStringify) =>
+ Object.keys(j.properties)
+ .map(
+ (x) =>
+ ({
+ type: j.properties[x].type,
+ required: j.required?.includes(x) === true ? true : false,
+ name: x,
+ const: "const" in j.properties[x] ? j.properties.const : undefined,
+ }) as JsonMap,
+ );
diff --git a/src/components/encode/src/stringify/composer/finder.mjs b/src/components/encode/src/stringify/composer/finder.mjs
new file mode 100644
index 0000000..ed1e894
--- /dev/null
+++ b/src/components/encode/src/stringify/composer/finder.mjs
@@ -0,0 +1,51 @@
+import string from "../methods/json_string.mjs";
+import boolean from "../methods/json_boolean.mjs";
+import number from "../methods/json_number.mjs";
+import array from "../methods/json_array.mjs";
+
+export default (o) =>
+ '"{" +' + (((f) =>
+ ((x) => x(x))((x) => f((y) => x(x)(y))))((f) => (o) => (s) =>
+ Object.keys(o.properties)
+ .map((x) =>
+ o.properties[x].type !== "object"
+ ? o.properties[x].type === "string"
+ ? string(
+ {
+ ...o.properties[x],
+ name: x,
+ required: o.required?.includes(x) ?? false,
+ path: s + "." + x,
+ },
+ )
+ : o.properties[x].type === "number"
+ ? number(
+ {
+ ...o.properties[x],
+ name: x,
+ required: o.required?.includes(x) ?? false,
+ path: s + "." + x,
+ },
+ )
+ : o.properties[x].type === "boolean"
+ ? boolean(
+ {
+ ...o.properties[x],
+ name: x,
+ required: o.required?.includes(x) ?? false,
+ path: s + "." + x,
+ },
+ )
+ : array(
+ {
+ ...o.properties[x],
+ name: x,
+ required: o.required?.includes(x) ?? false,
+ path: s + "." + x,
+ },
+ )
+ : `'"${x}":{' + ` +
+ (f(o.properties[x])(s + "." + x).join(" + ',' +")) + ' + "}"'
+ )
+ )(o)("")).join(" + ',' +") +
+ ' + "}"';
diff --git a/src/components/encode/src/stringify/composer/finder.ts b/src/components/encode/src/stringify/composer/finder.ts
new file mode 100644
index 0000000..0eece56
--- /dev/null
+++ b/src/components/encode/src/stringify/composer/finder.ts
@@ -0,0 +1,70 @@
+// deno-lint-ignore-file no-explicit-any
+import {
+ JsonArrayType,
+ JsonBooleanType,
+ JsonNumberType,
+ JsonStringify,
+ JsonStringType,
+} from "../types.ts";
+import string from "../methods/json_string.ts";
+import boolean from "../methods/json_boolean.ts";
+import number from "../methods/json_number.ts";
+import array from "../methods/json_array.ts";
+
+export default (o: JsonStringify) =>
+ '"{" +' + (((f: (arg0: (y: any) => any) => any) =>
+ ((x) =>
+ x(x))((x: (arg0: any) => { (arg0: any): any; new (): any }) =>
+ f((y: any) => x(x)(y))
+ ))((f) => (o: JsonStringify) => (s: string) =>
+ Object.keys(o.properties)
+ .map((x) =>
+ o.properties[x].type !== "object"
+ ? o.properties[x].type === "string"
+ ? string(
+ {
+ ...o.properties[x],
+ ...{
+ name: x,
+ required: o.required?.includes(x) ?? false,
+ },
+ ...{ path: s + "." + x },
+ } as JsonStringType,
+ )
+ : o.properties[x].type === "number"
+ ? number(
+ {
+ ...o.properties[x],
+ ...{
+ name: x,
+ required: o.required?.includes(x) ?? false,
+ },
+ ...{ path: s + "." + x },
+ } as JsonNumberType,
+ )
+ : o.properties[x].type === "boolean"
+ ? boolean(
+ {
+ ...o.properties[x],
+ ...{
+ name: x,
+ required: o.required?.includes(x) ?? false,
+ },
+ ...{ path: s + "." + x },
+ } as JsonBooleanType,
+ )
+ : array(
+ {
+ ...o.properties[x],
+ ...{
+ name: x,
+ required: o.required?.includes(x) ?? false,
+ },
+ ...{ path: s + "." + x },
+ } as JsonArrayType,
+ )
+ : `'"${x}":{' + ` +
+ (f(o.properties[x])(s + "." + x).join(" + ',' +")) + ' + "}"'
+ )
+ )(o)("")).join(" + ',' +") +
+ ' + "}"';
diff --git a/src/components/encode/src/stringify/composer/sanitizer.mjs b/src/components/encode/src/stringify/composer/sanitizer.mjs
new file mode 100644
index 0000000..e6e1e62
--- /dev/null
+++ b/src/components/encode/src/stringify/composer/sanitizer.mjs
@@ -0,0 +1,12 @@
+/**
+ * Returns a string safely wrapped in double quotes, escaping it if necessary.
+ *
+ * @param {string} s - The input string.
+ * @returns {string} - The safely quoted string.
+ */
+
+export default (
+ (escapes) => (s) => escapes.test(s) ? JSON.stringify(s) : `"${s}"`
+)(
+ /[\\"\\u0000-\\u001f\u007f-\u009f\u00ad\u0600-\u0604\u070f\u17b4\u17b5\u200c-\u200f\u2028-\u202f\u2060-\u206f\ufeff\ufff0-\uffff]/g,
+);
diff --git a/src/components/encode/src/stringify/composer/sanitizer.ts b/src/components/encode/src/stringify/composer/sanitizer.ts
new file mode 100644
index 0000000..47f1356
--- /dev/null
+++ b/src/components/encode/src/stringify/composer/sanitizer.ts
@@ -0,0 +1,6 @@
+export default (
+ (escapes) => (s: string) =>
+ escapes.test(s) ? JSON.stringify(s) : '"' + s + '"'
+)(
+ /[\\"\\u0000-\\u001f\u007f-\u009f\u00ad\u0600-\u0604\u070f\u17b4\u17b5\u200c-\u200f\u2028-\u202f\u2060-\u206f\ufeff\ufff0-\uffff]/g,
+);
diff --git a/src/components/encode/src/stringify/composer/selector.mjs b/src/components/encode/src/stringify/composer/selector.mjs
new file mode 100644
index 0000000..733fcee
--- /dev/null
+++ b/src/components/encode/src/stringify/composer/selector.mjs
@@ -0,0 +1,16 @@
+import string from "../methods/json_string.mjs";
+import boolean from "../methods/json_boolean.mjs";
+import number from "../methods/json_number.mjs";
+import array from "../methods/json_array.mjs";
+
+export default (element) =>
+ element.map(
+ (x) =>
+ x.type === "string"
+ ? string(x)
+ : x.type === "boolean"
+ ? boolean(x)
+ : x.type === "number"
+ ? number(x)
+ : array(x),
+ ).join(" + ',' +");
diff --git a/src/components/encode/src/stringify/composer/selector.ts b/src/components/encode/src/stringify/composer/selector.ts
new file mode 100644
index 0000000..61b1bfd
--- /dev/null
+++ b/src/components/encode/src/stringify/composer/selector.ts
@@ -0,0 +1,18 @@
+import { JsonOptionsType } from "../types.ts";
+import string from "../methods/json_string.ts";
+import boolean from "../methods/json_boolean.ts";
+import number from "../methods/json_number.ts";
+import array from "../methods/json_array.ts";
+
+export default (element: JsonOptionsType[]) => (
+ element.map(
+ (x) =>
+ x.type === "string"
+ ? string(x)
+ : x.type === "boolean"
+ ? boolean(x)
+ : x.type === "number"
+ ? number(x)
+ : array(x),
+ ).join(" + ',' +")
+);
diff --git a/src/components/encode/src/stringify/methods/json_array.mjs b/src/components/encode/src/stringify/methods/json_array.mjs
new file mode 100644
index 0000000..f61a94b
--- /dev/null
+++ b/src/components/encode/src/stringify/methods/json_array.mjs
@@ -0,0 +1 @@
+export default (x) => `'"${x.name}":' + JSON.stringify(o${x.path})`;
diff --git a/src/components/encode/src/stringify/methods/json_array.ts b/src/components/encode/src/stringify/methods/json_array.ts
new file mode 100644
index 0000000..bbe3298
--- /dev/null
+++ b/src/components/encode/src/stringify/methods/json_array.ts
@@ -0,0 +1,4 @@
+import { JsonArrayType } from "../types.ts";
+
+export default (x: JsonArrayType) =>
+ `'"${x.name}":' + JSON.stringify(o${x.path})`;
diff --git a/src/components/encode/src/stringify/methods/json_boolean.mjs b/src/components/encode/src/stringify/methods/json_boolean.mjs
new file mode 100644
index 0000000..ef9b8ce
--- /dev/null
+++ b/src/components/encode/src/stringify/methods/json_boolean.mjs
@@ -0,0 +1,6 @@
+export default (x) =>
+ "const" in x && typeof x.const === "boolean"
+ ? `'"${x.name}":' + ${x.const}`
+ : `'"${x.name}":'+( typeof o${x.path} === "boolean"?o${x.path}:'${
+ "default" in x ? x.default : null
+ }')`;
diff --git a/src/components/encode/src/stringify/methods/json_boolean.ts b/src/components/encode/src/stringify/methods/json_boolean.ts
new file mode 100644
index 0000000..b69754f
--- /dev/null
+++ b/src/components/encode/src/stringify/methods/json_boolean.ts
@@ -0,0 +1,8 @@
+import { JsonBooleanType } from "../types.ts";
+
+export default (x: JsonBooleanType) =>
+ "const" in x && typeof x.const === "boolean"
+ ? `'"${x.name}":' + ${x.const}`
+ : `'"${x.name}":'+( typeof o${x.path} === "boolean"?o${x.path}:'${
+ "default" in x ? x.default : null
+ }')`;
diff --git a/src/components/encode/src/stringify/methods/json_number.mjs b/src/components/encode/src/stringify/methods/json_number.mjs
new file mode 100644
index 0000000..70319ee
--- /dev/null
+++ b/src/components/encode/src/stringify/methods/json_number.mjs
@@ -0,0 +1,6 @@
+export default (x) =>
+ "const" in x && typeof x.const === "number"
+ ? `'"${x.name}":' + ${x.const}`
+ : `'"${x.name}":'+( typeof o${x.path} === "number"?o${x.path}:'${
+ "default" in x ? x.default : null
+ }')`;
diff --git a/src/components/encode/src/stringify/methods/json_number.ts b/src/components/encode/src/stringify/methods/json_number.ts
new file mode 100644
index 0000000..52633aa
--- /dev/null
+++ b/src/components/encode/src/stringify/methods/json_number.ts
@@ -0,0 +1,8 @@
+import { JsonNumberType } from "../types.ts";
+
+export default (x: JsonNumberType) =>
+ "const" in x && typeof x.const === "number"
+ ? `'"${x.name}":' + ${x.const}`
+ : `'"${x.name}":'+( typeof o${x.path} === "number"?o${x.path}:'${
+ "default" in x ? x.default : null
+ }')`;
diff --git a/src/components/encode/src/stringify/methods/json_string.mjs b/src/components/encode/src/stringify/methods/json_string.mjs
new file mode 100644
index 0000000..d091478
--- /dev/null
+++ b/src/components/encode/src/stringify/methods/json_string.mjs
@@ -0,0 +1,10 @@
+export default (x) =>
+ "const" in x && typeof x.const === "string"
+ ? `'"${x.name}":"${x.const}"'`
+ : x.required && !("default" in x)
+ ? `'"${x.name}":' + str(o${x.path})`
+ : `'"${x.name}":' + (typeof o${x.path} === "string"?str(o${x.path}):'${
+ "default" in x && typeof x.default === "string"
+ ? '"' + x.default + '"'
+ : null
+ }')`;
diff --git a/src/components/encode/src/stringify/methods/json_string.ts b/src/components/encode/src/stringify/methods/json_string.ts
new file mode 100644
index 0000000..fb1de20
--- /dev/null
+++ b/src/components/encode/src/stringify/methods/json_string.ts
@@ -0,0 +1,12 @@
+import { JsonStringType } from "../types.ts";
+
+export default (x: JsonStringType) =>
+ "const" in x && typeof x.const === "string"
+ ? `'"${x.name}":"${x.const}"'`
+ : x.required && !("default" in x)
+ ? `'"${x.name}":' + str(o${x.path})`
+ : `'"${x.name}":' + (typeof o${x.path} === "string"?str(o${x.path}):'${
+ "default" in x && typeof x.default === "string"
+ ? '"' + x.default + '"'
+ : null
+ }')`;
diff --git a/src/components/encode/src/stringify/safe.mjs b/src/components/encode/src/stringify/safe.mjs
new file mode 100644
index 0000000..34af01f
--- /dev/null
+++ b/src/components/encode/src/stringify/safe.mjs
@@ -0,0 +1,7 @@
+import sanitizer from "./composer/sanitizer.mjs";
+import finder from "./composer/finder.mjs";
+
+export default (o) =>
+ (
+ new Function(`return str=>o=> ${finder(o)} `)
+ )()(sanitizer);
diff --git a/src/components/encode/src/stringify/stringify.ts b/src/components/encode/src/stringify/stringify.ts
new file mode 100644
index 0000000..7127595
--- /dev/null
+++ b/src/components/encode/src/stringify/stringify.ts
@@ -0,0 +1,8 @@
+import sanitizer from "./composer/sanitizer.ts";
+import { JsonStringify, JsonType } from "./types.ts";
+import finder from "./composer/finder.ts";
+
+export default (o: JsonStringify) =>
+ (
+ new Function(`return str=>o=> ${finder(o)} `)
+ )()(sanitizer) as (o: JsonType | Promise) => string;
diff --git a/src/components/encode/src/stringify/types.ts b/src/components/encode/src/stringify/types.ts
new file mode 100644
index 0000000..39b0742
--- /dev/null
+++ b/src/components/encode/src/stringify/types.ts
@@ -0,0 +1,79 @@
+export type JsonTypes = "string" | "boolean" | "number";
+
+type Extra = { name: string; required: boolean; path?: string };
+type JsonString = {
+ type: "string";
+} | {
+ type: "string";
+ const: string;
+} | {
+ type: "string";
+ default: string;
+};
+export type JsonStringType = JsonString & Extra;
+
+type JsonBoolean = {
+ type: "boolean";
+} | {
+ type: "boolean";
+ const: boolean;
+} | {
+ type: "boolean";
+ default: boolean;
+};
+
+export type JsonBooleanType = JsonBoolean & Extra;
+
+type JsonNumber = {
+ type: "number";
+} | {
+ type: "number";
+ const: number;
+} | {
+ type: "number";
+ default: number;
+};
+
+export type JsonNumberType = JsonNumber & Extra;
+
+export type JsonArray = {
+ type: "array";
+};
+
+export type JsonArrayType = JsonBoolean & Extra;
+
+export type JsonStringify = {
+ type: "object";
+ properties: {
+ [key: string]: JsonElements;
+ };
+ required?: string[];
+};
+
+export type JsonType = {
+ [x: string]:
+ | string
+ | number
+ | boolean
+ | Array
+ | JsonType;
+};
+
+export type JsonOptionsType =
+ | JsonStringType
+ | JsonBooleanType
+ | JsonNumberType
+ | JsonArrayType;
+
+export type JsonElements =
+ | JsonString
+ | JsonBoolean
+ | JsonNumber
+ | JsonArray
+ | JsonStringify;
+
+export type JsonMap = { name: string; type: JsonTypes; required: boolean };
+
+export type JsonOptions = {
+ scheme: JsonStringify;
+};
diff --git a/src/components/encode/src/stringify/unsafe.mjs b/src/components/encode/src/stringify/unsafe.mjs
new file mode 100644
index 0000000..2ff3a03
--- /dev/null
+++ b/src/components/encode/src/stringify/unsafe.mjs
@@ -0,0 +1,6 @@
+import finder from "./composer/finder.mjs";
+
+export default (o) =>
+ (
+ new Function(`return str=>o=> ${finder(o)} `)
+ )()((i) => i);
diff --git a/src/components/encode/types.ts b/src/components/encode/types.ts
new file mode 100644
index 0000000..4f1fd69
--- /dev/null
+++ b/src/components/encode/types.ts
@@ -0,0 +1,11 @@
+import { JsonStringify } from "./src/stringify/types.ts";
+
+// Define the options type for the function
+export interface StringifyOptions {
+ type?: "unsafe" | "safe";
+}
+
+// Define the type for the main function
+export type JsonStringifyFunction = (
+ options?: StringifyOptions,
+) => (schema: JsonStringify) => string;
diff --git a/src/components/jwt/signSha256.mjs b/src/components/jwt/signSha256.mjs
new file mode 100644
index 0000000..e080ded
--- /dev/null
+++ b/src/components/jwt/signSha256.mjs
@@ -0,0 +1,18 @@
+import signer from "./src/sign/sha256.mjs";
+import nodeCrypto from "node:crypto";
+import BufferProto from "node:buffer";
+import name from "../runtime/name.mjs";
+
+export default () =>
+ (
+ (rt) =>
+ signer(
+ rt === "Bun" ? Buffer : BufferProto.Buffer,
+ )(
+ rt === "Bun"
+ ? (d) => new Bun.CryptoHasher("sha256").update(d)
+ : (d) => nodeCrypto.createHash("sha256").update(d),
+ )
+ )(
+ name(),
+ )();
diff --git a/src/components/jwt/src/sign/sha256.mjs b/src/components/jwt/src/sign/sha256.mjs
new file mode 100644
index 0000000..af79afc
--- /dev/null
+++ b/src/components/jwt/src/sign/sha256.mjs
@@ -0,0 +1,79 @@
+export default (Buffer) =>
+(sha256) =>
+(
+ header = Buffer.from(JSON.stringify({
+ alg: "HS256",
+ typ: "JWT",
+ })).toString("base64url") + ".",
+) =>
+(key) =>
+ (
+ (hmac) =>
+ ((lf) => (rg) => (message) =>
+ (
+ (json) =>
+ header + json + "." +
+ sha256(
+ Buffer.concat([
+ lf,
+ sha256(
+ Buffer.concat([
+ rg,
+ Buffer.from(header + json),
+ ]),
+ ).digest(),
+ ]),
+ )
+ .digest().toString("base64url")
+ )(
+ Buffer.from(JSON.stringify(message)).toString("base64url"),
+ ))(new Uint8Array(64).map((_x, i) => hmac[i] ^ 0x5c))(
+ new Uint8Array(64).map((_x, i) => hmac[i] ^ 0x36),
+ )
+ )(
+ key.length > 64
+ ? sha256(key).digest()
+ : key.length < 64
+ ? Buffer.concat([key, Buffer.alloc(64 - key.length)])
+ : key,
+ );
+
+// import concatTwoUint8Array from "../../../bytes/src/concatTwoUint8Array.mjs";
+// export default (Buffer) =>
+// (sha256) =>
+// (
+// header = Buffer.from(JSON.stringify({
+// alg: "HS256",
+// typ: "JWT",
+// })).toString("base64url") + ".",
+// ) =>
+// (key) =>
+// (
+// (hmac) => (message) =>
+// (
+// (json) =>
+// header + json + "." +
+// sha256(
+// concatTwoUint8Array(
+// new Uint8Array(64).map((_x, i) => hmac[i] ^ 0x5c)
+// )(
+// sha256(
+// concatTwoUint8Array(
+// new Uint8Array(64).map((_x, i) => hmac[i] ^ 0x36)
+// )(
+// Buffer.from(header + json)
+// )
+// ).digest(),
+// )
+// )
+// .digest().toString("base64url")
+// )(
+// Buffer.from(JSON.stringify(message)).toString("base64url"),
+// )
+// )(
+// key.length > 64
+// ? sha256(key).digest()
+// : key.length < 64
+// ? Buffer.concat([key, Buffer.alloc(64 - key.length)])
+// : key,
+// );
diff --git a/src/components/jwt/src/verify/sha256.mjs b/src/components/jwt/src/verify/sha256.mjs
new file mode 100644
index 0000000..a182619
--- /dev/null
+++ b/src/components/jwt/src/verify/sha256.mjs
@@ -0,0 +1,41 @@
+export default (Buffer) => (hash) => (key) =>
+ (
+ (hmac) =>
+ (
+ (lf) => (rg) => (message) =>
+ message.substring(message.lastIndexOf(".") + 1) ===
+ hash(
+ Buffer.concat([
+ lf,
+ hash(
+ Buffer.concat([
+ rg,
+ Buffer.from(
+ message.substring(0, message.lastIndexOf(".")),
+ ),
+ ]),
+ ).digest(),
+ ]),
+ )
+ .digest()
+ .toString("base64url")
+ ? JSON.parse(
+ Buffer.from(
+ message.substring(
+ message.indexOf(".") + 1,
+ message.lastIndexOf("."),
+ ),
+ "base64url",
+ ).toString(),
+ )
+ : null
+ )(new Uint8Array(64).map((_x, i) => hmac[i] ^ 0x5c))(
+ new Uint8Array(64).map((_x, i) => hmac[i] ^ 0x36),
+ )
+ )(
+ key.length > 64
+ ? hash(key).digest()
+ : key.length < 64
+ ? Buffer.concat([key, Buffer.alloc(64 - key.length)])
+ : key,
+ );
diff --git a/src/components/jwt/verifySha256.mjs b/src/components/jwt/verifySha256.mjs
new file mode 100644
index 0000000..cd9192f
--- /dev/null
+++ b/src/components/jwt/verifySha256.mjs
@@ -0,0 +1,21 @@
+import verify from "./src/verify/sha256.mjs";
+import nodeCrypto from "node:crypto";
+import BufferProto from "node:buffer";
+
+export default () =>
+ (
+ (rt) =>
+ verify(
+ rt === "Bun" ? Buffer : BufferProto.Buffer,
+ )(
+ rt === "Bun"
+ ? (d) => new Bun.CryptoHasher("sha256").update(d)
+ : (d) => nodeCrypto.createHash("sha256").update(d),
+ )
+ )(
+ typeof Bun !== "undefined"
+ ? "Bun"
+ : typeof Bun !== "undefined"
+ ? "Deno"
+ : "Node",
+ );
diff --git a/src/components/parameters/finder.ts b/src/components/parameters/finder.ts
new file mode 100644
index 0000000..88308e6
--- /dev/null
+++ b/src/components/parameters/finder.ts
@@ -0,0 +1,31 @@
+import type { info } from "./types.ts";
+
+export default (info: info) =>
+ `s=>${
+ Array.from(
+ {
+ length: info.elements.length - 1,
+ },
+ (
+ _,
+ i,
+ ) => [
+ `(a${i}=>`,
+ `)(s.indexOf("/"${i !== 0 ? `,a${i - 1}` : ""}) + 1)`,
+ ],
+ ).reverse().reduce(
+ (acc, v) => v[0] + acc + v[1],
+ `({${
+ Array.from({
+ length: info.elements.length,
+ }, (_, id) =>
+ id === 0
+ ? ` ${info.elements[id].slice(1)} : s.slice(0, a0 - 1)`
+ : id === (info.elements.length - 1)
+ ? ` ${info.elements[id].slice(1)} : s.slice(a${id - 1})`
+ : ` ${info.elements[id].slice(1)} : s.slice(a${
+ id - 1
+ }, a${id} - 1)`).join(",")
+ }})`,
+ )
+ }`;
diff --git a/src/components/parameters/main.ts b/src/components/parameters/main.ts
new file mode 100644
index 0000000..119000a
--- /dev/null
+++ b/src/components/parameters/main.ts
@@ -0,0 +1,23 @@
+import type { FunRouterOptions } from "../../options.ts";
+import type { Petition } from "../../morphism.ts";
+import multi from "./multi.ts";
+import one from "./one.ts";
+import map from "./map.ts";
+import unique from "./unique.ts";
+
+export default (options?: FunRouterOptions) => (f: Petition) =>
+ (
+ (info) =>
+ f.param && "unique" in f.param && typeof f.param.unique === "boolean" &&
+ f.param.unique
+ ? new Function(`return ${unique(info)}`)()
+ : info.firstParam === -1
+ ? () => null
+ : info.elements.length === 1 &&
+ (info.elements.at(-1) || "")[0] === info.startsWith &&
+ f.path.at(-1) !== "/"
+ ? new Function(`return ${one(info)}`)()
+ : new Function(`return ${multi(info)}`)()
+ )(
+ map(options)(f),
+ );
diff --git a/src/components/parameters/map.ts b/src/components/parameters/map.ts
new file mode 100644
index 0000000..440e2bd
--- /dev/null
+++ b/src/components/parameters/map.ts
@@ -0,0 +1,47 @@
+import type { FunRouterOptions } from "../../options.ts";
+import type { Petition } from "../../morphism.ts";
+import type { info } from "./types.ts";
+
+export default (options?: FunRouterOptions) => (f: Petition): info =>
+ (
+ (list) => (
+ ((startsWith) =>
+ (
+ (endsInSlash) =>
+ (
+ (point) => ({
+ list: list,
+ map: list.map((x) => x[0] === startsWith),
+ startsWith: startsWith,
+ elements: point.tail === point.head
+ ? [list[point.head]]
+ : list.slice(point.tail, point.head + 1),
+ firstParam: f.path.indexOf("/" + startsWith),
+ lastParam: list.slice(point.head + 1, list.length).reduce(
+ (acc, x) => x.length + 1 + acc,
+ 0,
+ ) + (endsInSlash ? 1 : 0),
+ endsInSlash: endsInSlash,
+ hasName: options?.hasName,
+ })
+ )({
+ tail: list.reduce(
+ (acc, x, i) => (x[0] === startsWith && acc === -1) ? i : acc,
+ -1,
+ ),
+ head: list.reduceRight(
+ (acc, x, i) => (x[0] === startsWith && acc === 0) ? i : acc,
+ 0,
+ ),
+ })
+ )(
+ f.path.at(-1) === "/",
+ ))(
+ options && "paramsStartsWith" in options
+ ? options.paramsStartsWith?.at(1)
+ : ":",
+ )
+ )
+ )(
+ f.path.split("/").filter((x) => x !== ""),
+ );
diff --git a/src/components/parameters/multi.ts b/src/components/parameters/multi.ts
new file mode 100644
index 0000000..cbd99b3
--- /dev/null
+++ b/src/components/parameters/multi.ts
@@ -0,0 +1,16 @@
+import type { info } from "./types.ts";
+
+import finder from "./finder.ts";
+import slicer from "./slicer.ts";
+
+export default (info: info) =>
+ (
+ (slice) =>
+ (
+ (find) => `( sl => (fi => p => fi(sl(p)))(${find} ))(${slice})`
+ )(
+ finder(info),
+ )
+ )(
+ slicer(info),
+ );
diff --git a/src/components/parameters/one.ts b/src/components/parameters/one.ts
new file mode 100644
index 0000000..20cd903
--- /dev/null
+++ b/src/components/parameters/one.ts
@@ -0,0 +1,34 @@
+import type { info } from "./types.ts";
+
+export default (info: info) =>
+ info && "hasName" in info && typeof info.hasName === "string"
+ ? `(s => s.indexOf("?") === -1 ? ({${info.elements[0].slice(1)}: s.slice(
+ ${(info.hasName?.length || 0) + info.firstParam}
+ ${info.lastParam === 0 ? "" : ", -" + info.lastParam})}): ({${
+ info.elements[0].slice(1)
+ }: s.slice(${
+ (info.hasName?.length || 0) + info.firstParam
+ }, s.indexOf("?") ${info.lastParam === 0 ? "" : " -" + info.lastParam})})
+)`
+ : `(n =>s=> n !== -1 ? s.indexOf("?") === -1 ?
+ ({${info.elements[0].slice(1)}: s.slice(n ${
+ info.lastParam === 0 ? "" : " , - " + info.lastParam
+ })}) :
+ ({${info.elements[0].slice(1)}: s.slice(n , s.indexOf("?") ${
+ info.lastParam === 0 ? "" : " -" + info.lastParam
+ }) }) : s.indexOf("?") === -1 ?
+ ({${
+ info.elements[0].slice(1)
+ }: s.slice( n = s.split("/").filter((x) => x !== "" ).reduce((acc, x, u) =>u<= 1 ? acc + x.length : acc,2,0) + ${
+ info.firstParam + 1
+ } ${
+ info.lastParam === 0 ? "" : ", -" + info.lastParam
+ } ).split("/").filter((x) => x !== "").join("/") })
+ :
+ ({${
+ info.elements[0].slice(1)
+ }: s.slice( n = s.split("/").filter((x) => x !== "").reduce((acc, x, u) =>u<= 1 ? acc + x.length : acc,2,0 ${
+ info.lastParam === 0 ? "" : ", -" + info.lastParam
+ }) + ${info.firstParam + 1} , s.indexOf("?") ${
+ info.lastParam === 0 ? "" : " -" + info.lastParam
+ } ).split("/").filter((x) => x !== "").join("/")}) )(-1)`;
diff --git a/src/components/parameters/parser.ts b/src/components/parameters/parser.ts
new file mode 100644
index 0000000..1bd0b78
--- /dev/null
+++ b/src/components/parameters/parser.ts
@@ -0,0 +1,4 @@
+export default ((a: string[]) =>
+ (new Function(
+ `return e => ({ ${a.reduce((acc, v, i) => acc + `"${v}": e[${i}],`, "")}})`,
+ ))()) as (m: string[]) => (e: string[]) => Record;
diff --git a/src/components/parameters/slicer.ts b/src/components/parameters/slicer.ts
new file mode 100644
index 0000000..4e2337b
--- /dev/null
+++ b/src/components/parameters/slicer.ts
@@ -0,0 +1,33 @@
+import type { info } from "./types.ts";
+
+export default (info: info) =>
+ info && "hasName" in info && typeof info.hasName === "string"
+ ? `(u => u.indexOf("?") === -1
+ ? u.slice(${(info.hasName?.length || 0) + info.firstParam} ${
+ info.lastParam === 0 ? "" : ", -" + info.lastParam
+ })
+ : u.slice(${
+ (info.hasName?.length || 0) + info.firstParam
+ }, u.indexOf("?") ${info.lastParam === 0 ? "" : " -" + info.lastParam})
+ )`
+ : `(n => u =>
+ n !== -1
+ ? u.indexOf("?") === -1
+ ? u.slice(n ${
+ info.lastParam === 0 ? "" : " , - " + info.lastParam
+ })
+ : u.slice(n , u.indexOf("?") ${
+ info.lastParam === 0 ? "" : " -" + info.lastParam
+ })
+ : u.indexOf("?") === -1
+ ? u.slice( n = u.split("/").filter((x) => x !== "" ).reduce((acc, x, ul) =>ul<= 1 ? acc + x.length : acc,2,0) + ${
+ info.firstParam + 1
+ } ${
+ info.lastParam === 0 ? "" : ", -" + info.lastParam
+ } ).split("/").filter((x) => x !== "").join("/")
+ : u.slice( n = u.split("/").filter((x) => x !== "").reduce((acc, x, ul) =>ul<= 1 ? acc + x.length : acc,2,0 ${
+ info.lastParam === 0 ? "" : ", -" + info.lastParam
+ }) + ${info.firstParam + 1} , u.indexOf("?") ${
+ info.lastParam === 0 ? "" : " -" + info.lastParam
+ } ).split("/").filter((x) => x !== "").join("/")
+ )(-1)`;
diff --git a/src/components/parameters/types.ts b/src/components/parameters/types.ts
new file mode 100644
index 0000000..f595c9a
--- /dev/null
+++ b/src/components/parameters/types.ts
@@ -0,0 +1,10 @@
+export type info = {
+ list: string[];
+ map: boolean[];
+ startsWith: string | undefined;
+ elements: string[];
+ firstParam: number;
+ lastParam: number;
+ endsInSlash: boolean;
+ hasName: string | undefined;
+};
diff --git a/src/components/parameters/unique.ts b/src/components/parameters/unique.ts
new file mode 100644
index 0000000..3bdebe8
--- /dev/null
+++ b/src/components/parameters/unique.ts
@@ -0,0 +1,25 @@
+import type { info } from "./types.ts";
+
+export default (info: info) =>
+ info && "hasName" in info && typeof info.hasName === "string"
+ ? `s => s.indexOf("?") === -1 ? s.slice(
+ ${(info.hasName?.length || 0) + info.firstParam}
+ ${info.lastParam === 0 ? "" : ", -" + info.lastParam}): (s.slice(${
+ (info.hasName?.length || 0) + info.firstParam
+ }, s.indexOf("?") ${info.lastParam === 0 ? "" : " -" + info.lastParam}))`
+ : `(n =>s=> n !== -1 ? s.indexOf("?") === -1 ?
+ s.slice(n ${info.lastParam === 0 ? "" : " , - " + info.lastParam}) :
+ s.slice(n , s.indexOf("?") ${
+ info.lastParam === 0 ? "" : " -" + info.lastParam
+ }) : s.indexOf("?") === -1 ?
+ s.slice( n = s.split("/").filter((x) => x !== "" ).reduce((acc, x, u) =>u<= 1 ? acc + x.length : acc,2,0) + ${
+ info.firstParam + 1
+ } ${
+ info.lastParam === 0 ? "" : ", -" + info.lastParam
+ } ).split("/").filter((x) => x !== "").join("/")
+ :
+ s.slice( n = s.split("/").filter((x) => x !== "").reduce((acc, x, u) =>u<= 1 ? acc + x.length : acc,2,0 ${
+ info.lastParam === 0 ? "" : ", -" + info.lastParam
+ }) + ${info.firstParam + 1} , s.indexOf("?") ${
+ info.lastParam === 0 ? "" : " -" + info.lastParam
+ } ).split("/").filter((x) => x !== "").join("/") )(-1)`;
diff --git a/src/components/queries/common.ts b/src/components/queries/common.ts
new file mode 100644
index 0000000..52e9a8e
--- /dev/null
+++ b/src/components/queries/common.ts
@@ -0,0 +1,41 @@
+import type { FunRouterOptions } from "../../options.ts";
+import type { Petition } from "../../morphism.ts";
+
+export default (o?: FunRouterOptions) => (f: Petition) =>
+ (
+ (b) =>
+ (
+ (p) =>
+ b !== -1
+ ? `s=>(i=>
+ i!==-1?
+ Object.fromEntries(
+ s.slice(i+1).split("&").map((x) => x.split("="))
+ )
+ :null)(s.indexOf("?"))`
+ : ` (b=>s =>
+
+ b !== -1
+ ? Object.fromEntries(
+ s.slice(b).split("&").map((x) => x.split("=")),
+ )
+ : Object.fromEntries(
+ s.slice(
+ b = s
+ .split("/")
+ .filter((x) => x !== "")
+ .reduce(
+ (acc, x, u) => u <= 1 ? acc + x.length : acc,
+ 3,
+ ) +
+ ${p},
+ ).split("&").map((x) => x.split("=")),
+ ))(-1)`
+ )(
+ f.path.includes("/" + (o?.paramsStartsWith || ":"))
+ ? f.path.indexOf("/" + (o?.paramsStartsWith || ":"))
+ : f.path.length,
+ )
+ )(
+ typeof o?.hasName === "string" ? o.hasName.length : -1,
+ );
diff --git a/src/components/queries/elements.ts b/src/components/queries/elements.ts
new file mode 100644
index 0000000..c705bf2
--- /dev/null
+++ b/src/components/queries/elements.ts
@@ -0,0 +1,6 @@
+import finder from "./finder.ts";
+
+export default (ar: string[]) =>
+ `(p=>u=>(l=> l!==-1?p(u.slice(l)) :null)(u.indexOf("?")))(s => ({${
+ ar.map((x) => ` ${x}: encodeURIComponent(${finder(x)})`).join(",")
+ }}))`;
diff --git a/src/components/queries/filter.ts b/src/components/queries/filter.ts
new file mode 100644
index 0000000..2bc7a4e
--- /dev/null
+++ b/src/components/queries/filter.ts
@@ -0,0 +1,14 @@
+export default (elements: string[]) => (input: string) =>
+ elements
+ .filter((x, index, arr) =>
+ index === 0 ||
+ (!arr[index - 1].startsWith("resolve.") &&
+ !arr[index - 1].startsWith("branch."))
+ )
+ .filter((v) =>
+ (input
+ .match(/(?:[?.])(\w+)\s*\(\)/g) || []) // extract potential matches from input
+ .map((token) => token.slice(1, token.indexOf("("))) // extract function names from tokens
+ .includes(v)
+ )
+ .reduce((acc, v) => acc.includes(v) ? acc : acc.concat(v), [] as string[]);
diff --git a/src/components/queries/finder.ts b/src/components/queries/finder.ts
new file mode 100644
index 0000000..eb38ba4
--- /dev/null
+++ b/src/components/queries/finder.ts
@@ -0,0 +1,4 @@
+export default (s: string) =>
+ ` (a =>a !== -1? (l => l !== -1 ? s.slice(a+${s.length + 1},l):s.slice(a+${
+ s.length + 1
+ },s.length))(s.indexOf("&",a)):null)(s.indexOf("${s + "="}")) `;
diff --git a/src/components/queries/main.ts b/src/components/queries/main.ts
new file mode 100644
index 0000000..1595b6e
--- /dev/null
+++ b/src/components/queries/main.ts
@@ -0,0 +1,18 @@
+import type { FunRouterOptions } from "../../options.ts";
+import type { Petition } from "../../morphism.ts";
+import common from "./common.ts";
+import elements from "./elements.ts";
+
+import filter from "./filter.ts";
+import unique from "./unique.ts";
+export default (o?: FunRouterOptions) => (f: Petition) =>
+ f.query && "name" in f.query
+ ? new Function(`return ${unique([f.query.name])}`)()
+ : f.query && "only" in f.query && Array.isArray(f.query.only)
+ ? new Function(`return ${elements(f.query.only)}`)()
+ : (
+ (only) =>
+ only.length > 0
+ ? new Function(`return ${elements(only)}`)()
+ : new Function(`return ${common(o)(f)}`)()
+ )(filter(f.f.toString().split(" "))("query"));
diff --git a/src/components/queries/unique.ts b/src/components/queries/unique.ts
new file mode 100644
index 0000000..b0323c7
--- /dev/null
+++ b/src/components/queries/unique.ts
@@ -0,0 +1,8 @@
+export default (s: string[]) =>
+ `(p=>u=>(l=> l!==-1?p(u.slice(l)) :null)(u.indexOf("?")))(s => ${` (a =>a !== -1? (l => l !== -1 ?
+
+ encodeURIComponent(s.slice(a+${s[0].length + 1},l))
+
+ :encodeURIComponent(s.slice(a+${s[0].length + 1},s.length))
+
+ )(s.indexOf("&",a)):null)(s.indexOf("${s[0] + "="}")) `})`;
diff --git a/src/components/runtime/name.mjs b/src/components/runtime/name.mjs
new file mode 100644
index 0000000..505073e
--- /dev/null
+++ b/src/components/runtime/name.mjs
@@ -0,0 +1,26 @@
+/**
+ * Identifies the current JavaScript runtime environment. It prioritizes the detection in the following order:
+ * 1. Bun
+ * 2. Deno
+ *
+ * By default, if neither Bun nor Deno environments are detected, it assumes the Node environment.
+ *
+ * This function is useful for applications that need to adapt their behavior based on the runtime environment.
+ *
+ * ```js
+ * import { runtime } from 'vixeny'
+ *
+ * //logging runtime name
+ * console.log(
+ * runtime.name()
+ * )
+ *
+ * ```
+ */
+
+export default () =>
+ typeof Bun !== "undefined"
+ ? "Bun"
+ : typeof Bun !== "undefined"
+ ? "Deno"
+ : "Node";
diff --git a/src/components/runtime/parseArguments.ts b/src/components/runtime/parseArguments.ts
new file mode 100644
index 0000000..cfa4e30
--- /dev/null
+++ b/src/components/runtime/parseArguments.ts
@@ -0,0 +1,42 @@
+/**
+ * Parses command-line arguments passed to the script and returns an object with key-value pairs.
+ * For flags without explicit values, the value is set to `true`.
+ *
+ * This function is designed to work with both Deno and Node.js environments, automatically detecting
+ * the environment to use the appropriate source of arguments.
+ *
+ * Example usage in Node.js:
+ * ```bash
+ * node script.js --name=John --age=30 --admin
+ * ```
+ * This would result in: `{ name: "John", age: "30", admin: true }`
+ *
+ * Example usage in Deno:
+ * ```bash
+ * deno run script.js --name=John --age=30 --admin
+ * ```
+ * Similar output as Node.js example.
+ *
+ * @returns {ParsedArgs} An object representing the parsed command-line arguments.
+ */
+
+//TODO: introduce `name` and add , interface
+type ParsedArgs = {
+ [key: string]: string | boolean;
+};
+
+export default (): ParsedArgs =>
+ //@ts-ignore
+ (typeof Deno !== "undefined" ? Deno.args : process.argv.slice(2))
+ .map<[string, string | boolean]>((arg: string) =>
+ arg.startsWith("--")
+ ? arg.slice(2).split("=") as [string, string]
+ : [arg, true]
+ )
+ .reduce(
+ (acc: ParsedArgs, [key, value]: [string, string | boolean]) => ({
+ ...acc,
+ [key]: value === undefined ? true : value,
+ }),
+ {},
+ );
diff --git a/components/http/src/framework/optimizer/branch/main.ts b/src/composer/branch/main.ts
similarity index 69%
rename from components/http/src/framework/optimizer/branch/main.ts
rename to src/composer/branch/main.ts
index f8507cc..f5c2fb0 100644
--- a/components/http/src/framework/optimizer/branch/main.ts
+++ b/src/composer/branch/main.ts
@@ -1,16 +1,13 @@
-import recursiveCheck from "../checkAsync.ts";
-import { BranchOptions, ResponseResponse } from "./types.ts";
+import tools from "../composerTools.ts";
+import type { BranchOptions, ResponseResponse } from "./types.ts";
import table from "./table.ts";
-import { specialOptions } from "../aComposer.ts";
-import {
- AnyMorphismMap,
- CommonRequestMorphism,
- RequestMorphism,
-} from "../types.ts";
+import type { specialOptions } from "../linker.ts";
+import type { BranchMap } from "../../morphism.ts";
+import type { Petition } from "../../morphism.ts";
export default (o?: specialOptions) =>
(path: string) =>
-(input: AnyMorphismMap): ResponseResponse =>
+(input: BranchMap): ResponseResponse =>
(
(ar) =>
(
@@ -30,8 +27,8 @@ export default (o?: specialOptions) =>
)(),
))(
ar.some((x) =>
- recursiveCheck(
- x as unknown as CommonRequestMorphism | RequestMorphism,
+ tools.recursiveCheckAsync(
+ x as unknown as Petition,
)
),
)
diff --git a/src/composer/branch/table.ts b/src/composer/branch/table.ts
new file mode 100644
index 0000000..83ccded
--- /dev/null
+++ b/src/composer/branch/table.ts
@@ -0,0 +1,28 @@
+import aComposer, { type specialOptions } from "../linker.ts";
+import tools from "../composerTools.ts";
+import type { BranchOptions } from "./types.ts";
+
+export default (o?: specialOptions) =>
+(path: string) =>
+(table: BranchOptions) =>
+ table
+ .map((x) => ({ ...x, path: path }))
+ .map((x) => ({
+ name: x.name,
+ f: (
+ (composed) =>
+ x.f.constructor.name === "AsyncFunction" ||
+ composed.constructor.name === "AsyncFunction"
+ ? //void console.log(composed.toString()) ??
+ ((a) =>
+ (k: (arg0: any) => any) =>
+ (r: Request) =>
+ async (b: unknown) => k(await a( r)(b)))(composed)(x.f)
+ : ((a) => (k: (arg0: any) => any) => (r: Request) => (b: unknown) =>
+ k(a(r)(b)))(composed)(x.f)
+ )(
+ aComposer(o ? { ...o, branch: false } : { branch: false })(x)(
+ tools.isUsing(o)(x)(tools.elements),
+ ),
+ ),
+ }));
diff --git a/src/composer/branch/types.ts b/src/composer/branch/types.ts
new file mode 100644
index 0000000..512cfe0
--- /dev/null
+++ b/src/composer/branch/types.ts
@@ -0,0 +1,11 @@
+import type { Petition, PetitionOptions } from "../../morphism.ts";
+
+export type BranchOption = Petition & {
+ name: string;
+ options?: PetitionOptions;
+};
+export type BranchOptions = BranchOption[];
+
+export type ResponseResponse = (
+ r: Request,
+) => { [key: string]: (arg?: any) => any };
diff --git a/src/composer/checkPetition/checkParse.ts b/src/composer/checkPetition/checkParse.ts
new file mode 100644
index 0000000..59c0852
--- /dev/null
+++ b/src/composer/checkPetition/checkParse.ts
@@ -0,0 +1,23 @@
+import type { Petition } from "../../morphism.ts";
+import checkTool from "./checkTool.ts";
+
+export default (elements: string[]) =>
+(remove: string[]) =>
+(add: string[]) =>
+(f: Petition): string[] =>
+ (
+ (filteredString: string): string[] =>
+ checkTool
+ .isUsingResolve(f)(
+ checkTool
+ .filtersBranchAndResolve(elements)(remove)(filteredString)
+ .concat(add)
+ .reduce(
+ (acc: string[], element) =>
+ acc.includes(element) === false ? acc.concat(element) : acc,
+ [] as string[],
+ ),
+ )
+ )(
+ checkTool.normalize(f.f.toString()),
+ );
diff --git a/src/composer/checkPetition/checkTool.ts b/src/composer/checkPetition/checkTool.ts
new file mode 100644
index 0000000..b7713ae
--- /dev/null
+++ b/src/composer/checkPetition/checkTool.ts
@@ -0,0 +1,55 @@
+
+import type { Petition } from "../../morphism.ts";
+
+export default {
+ normalize: (s: string) =>
+ s.replace(/(? (elements: string[]) =>
+ elements.includes("resolve")
+ ? "resolve" in f ? elements : elements.filter((s) => s === "resolve")
+ : elements,
+
+ filtersBranchAndResolve:
+ (elements: string[]) => (remove: string[]) => (filteredString: string) =>
+ // First filter: Remove elements as specified and handle 'resolve.' and 'branch.' prefix cases
+ elements.filter((element, index, arr) =>
+ !remove.includes(element) &&
+ (index === 0 ||
+ (!arr[index - 1].startsWith("resolve.") &&
+ !arr[index - 1].startsWith("branch.")))
+ )
+ // Second filter: Match elements against the code string for exact matches
+ .filter((element) =>
+ new RegExp(`\\b${element}\\b`).test(filteredString)
+ )
+ ,
+ updateListOfAddAndRemove: (f: Petition) => (elements: string[]) => (plugins : {[key: string]: any}) =>
+ (
+ listOfElements =>
+ (
+ keysOnMorphisim =>
+ ({
+ add: [...new Set(keysOnMorphisim.reduce(
+ (acc,val) =>
+ listOfElements.includes(val)
+ ? [...acc , val]
+ : acc
+ ,
+ f.options?.add ?? []
+ ))
+ ],
+ remove: f.options?.remove ?? [],
+ elements: listOfElements.filter(s => listOfElements.includes(s))
+ })
+
+
+ ) (
+ Object.keys(f)
+ )
+ )(
+ [...elements, ... Object.keys(plugins)]
+ )
+};
diff --git a/src/composer/checkPetition/mainCheck.ts b/src/composer/checkPetition/mainCheck.ts
new file mode 100644
index 0000000..07aa1c2
--- /dev/null
+++ b/src/composer/checkPetition/mainCheck.ts
@@ -0,0 +1,20 @@
+
+import type { Petition } from "../../morphism.ts";
+import type { FunRouterOptions } from "../../options.ts";
+import composerTools from "../composerTools.ts";
+import checkParse from "./checkParse.ts";
+import checkTool from "./checkTool.ts";
+
+export default (o?: FunRouterOptions) => (f: Petition) =>
+ "options" in f && f.options
+ ? f.options.only
+ ? f.options.only
+ : (
+ newOptions =>
+ checkParse(newOptions.elements)(newOptions.remove)(newOptions.add)(f)
+
+ )(
+ checkTool.updateListOfAddAndRemove(f)(composerTools.elements(f))(o?.cyclePlugin ?? {})
+ )
+
+ : checkParse(composerTools.elements(f))([])([])(f)
diff --git a/components/http/src/framework/optimizer/checker.ts b/src/composer/checker.ts
similarity index 100%
rename from components/http/src/framework/optimizer/checker.ts
rename to src/composer/checker.ts
diff --git a/components/http/src/framework/optimizer/response.ts b/src/composer/compose.ts
similarity index 62%
rename from components/http/src/framework/optimizer/response.ts
rename to src/composer/compose.ts
index fb9f33c..e293248 100644
--- a/components/http/src/framework/optimizer/response.ts
+++ b/src/composer/compose.ts
@@ -1,39 +1,39 @@
-import { FunRouterOptions } from "../../../types.ts";
-import { CommonRequestMorphism, RequestMorphism } from "./types.ts";
-import { parse, stringToFunction } from "../../cors/mainCORS.ts";
-import checkAsync from "./recursiveCheckAsync.ts";
-import aComposer from "./aComposer.ts";
-import mime from "../../util/mime.ts";
-import isUsing from "./tools/isUsing.ts";
+import type { FunRouterOptions } from "../options.ts";
+import type { Petition } from "../morphism.ts";
+import { parse, stringToFunction } from "../components/cors/mainCORS.ts";
+import tools from "./composerTools.ts";
+import linker from "./linker.ts";
+import mime from "../util/mime.ts";
export default (o?: FunRouterOptions) =>
-(f: CommonRequestMorphism | RequestMorphism) =>
+(f: Petition): (ctx: Request) => Promise | Response =>
((elementsUsed) =>
(
(table) =>
((composition) =>
- (table.headers && table.json)
+ (table.headers && table.json && f.type !== "request")
? composition(table.json)(table.headers)(f.f)(
- aComposer(o)(f)(elementsUsed),
+ linker(o)(f)(elementsUsed),
)
: table.headers
? composition(table.headers)(f.f)(
- aComposer(o)(f)(elementsUsed),
+ linker(o)(f)(elementsUsed),
)
: table.json
? composition(table.json)(f.f)(
- aComposer(o)(f)(elementsUsed),
+ linker(o)(f)(elementsUsed),
)
: composition(f.f)(
- aComposer(o)(f)(elementsUsed),
+ linker(o)(f)(elementsUsed),
))(
- "type" in f
+ f.type === "request" || f.type === "morphism" ||
+ typeof f.type === "undefined"
? new Function(`
- return f=>c=>${table.async || table.asyncResolve ? "async " : ""}r=>${
- table.async || table.asyncResolve ? "await f" : "f"
- }(${table.asyncResolve ? "await c" : "c"}(${
- "mutable" in f ? "[r,{res: new Response()}]" : "r"
- }))`)()
+ return ${table.headers ? "h=>" : ""}f=>c=>${
+ table.async || table.asyncResolve ? "async " : ""
+ }r=>${table.async || table.asyncResolve ? "await f" : "f"}(${
+ table.asyncResolve ? "await c" : "c"
+ }(${"mutable" in f ? "[r,{res: {}}]" : "r"}))`)()
: new Function(
`return ${table.headers ? "h=>" : ""}${
table.async ? "f=>" : "f=>"
@@ -42,11 +42,12 @@ export default (o?: FunRouterOptions) =>
}r=> new Response(${
table.async || table.asyncResolve ? "await f" : "f"
}(${table.asyncResolve ? "await c" : "c"}(${
- "mutable" in f ? "[r,{res: new Response()}]" : "r"
+ "mutable" in f ? "[r,{res: {}}]" : "r"
}))${table.headers ? ",h" : ""})`,
)(),
)
)(
+ //elements int table
{
async: f.f.constructor.name === "AsyncFunction" ||
(
@@ -58,7 +59,7 @@ export default (o?: FunRouterOptions) =>
: false
)
),
- asyncResolve: checkAsync(f) ||
+ asyncResolve: tools.recursiveCheckAsync(f) ||
(
o && o.cyclePlugin && Object.keys(o.cyclePlugin || {})
.some((x) =>
@@ -73,8 +74,9 @@ export default (o?: FunRouterOptions) =>
? {
...f.headings,
headers: {
- "Content-Type":
- mime.find((x) => x[0] === f.headings?.headers)![1],
+ "Content-Type": mime.find((x) =>
+ x[0] === f.headings?.headers
+ )![1],
...(o && o.cors ? stringToFunction(parse()(o.cors))() : {}),
},
}
@@ -88,5 +90,5 @@ export default (o?: FunRouterOptions) =>
: null,
},
))(
- isUsing(o)(f),
+ tools.isUsing(o)(f)(tools.elements),
);
diff --git a/src/composer/composerTools.ts b/src/composer/composerTools.ts
new file mode 100644
index 0000000..aef477e
--- /dev/null
+++ b/src/composer/composerTools.ts
@@ -0,0 +1,102 @@
+import type { Petition } from "../morphism.ts";
+import type { FunRouterOptions } from "../options.ts";
+import mainCheck from "./checkPetition/mainCheck.ts";
+type RecFunc = (f: Petition) => boolean;
+
+export default {
+ syncCheckerDir:
+ (joiner: (base: string) => (target: string) => string) =>
+ (readdir: (directoryPath: string) => string[]) =>
+ (stat: (directoryPath: string) => { isDirectory: () => boolean }) =>
+ (dir: string): [string, boolean][] =>
+ (
+ (Y) => (
+ Y((f: (arg0: string) => [string, boolean][]) => (
+ (dir: string): [string, boolean][] =>
+ readdir(dir).flatMap((item) =>
+ stat(joiner(dir)(item)).isDirectory()
+ ? [[joiner(dir)(item), true], ...f(joiner(dir)(item))]
+ : [[joiner(dir)(item), false]]
+ ) as [string, boolean][]
+ ))(dir)
+ )
+ )(
+ // Setting up the Y combinator.
+ (f: (arg0: (y: any) => any) => any) =>
+ ((x) => x(x))((x: (arg0: any) => { (arg0: any): any; new (): any }) =>
+ f((y: any) => x(x)(y))
+ ),
+ ),
+ recursiveCheckAsync:
+ ((f: (x: RecFunc) => RecFunc) =>
+ ((x: (arg: any) => any) => (v: any) => x(x)(v))(
+ (x: (arg: any) => any) => (v: any) => f((y: Petition) => x(x)(y))(v),
+ ))(
+ (solver: RecFunc) => (f: Petition) =>
+ f.f.constructor.name === "AsyncFunction" ||
+ ("isAsync" in f && f.isAsync)
+ ? true
+ : f.f.constructor.name === "Function" &&
+ typeof f.resolve === "undefined"
+ ? false
+ : ("resolve" in f && f.resolve &&
+ Object.keys(f.resolve).some((ob) =>
+ f.resolve &&
+ solver(
+ f.resolve[ob] as unknown as Petition,
+ )
+ )) ??
+ ("branch" in f && f.branch &&
+ Object.keys(f.branch).some((ob) =>
+ f.branch &&
+ solver(
+ f.branch[ob] as unknown as Petition,
+ )
+ )) ??
+ false,
+ ) as unknown as (f: Petition) => boolean,
+ parsingToHexa: (crypto: { globalKey: string }) =>
+ typeof crypto.globalKey === "string"
+ ? /^[0-9a-fA-F]+$/g.test(crypto.globalKey)
+ ? new Uint8Array([...crypto.globalKey].map((x) => x.charCodeAt(0)))
+ : new Uint8Array([...crypto.globalKey].map((x) => x.charCodeAt(0)))
+ : crypto.globalKey,
+ isUsing:
+ (o?: FunRouterOptions) =>
+ (f: Petition) =>
+ (elements: { (f: Petition): string[] }) =>
+ mainCheck(o)(f),
+ elements: (f: Petition) =>
+ f.crypto && "globalKey" in f.crypto
+ ? [
+ "cookie",
+ "headers",
+ "randomNumber",
+ "hash",
+ "param",
+ "query",
+ "req",
+ "date",
+ "resolve",
+ "mutable",
+ "branch",
+ "arguments",
+ "token",
+ "verify",
+ "sign",
+ ]
+ : [
+ "cookie",
+ "headers",
+ "randomNumber",
+ "hash",
+ "param",
+ "query",
+ "req",
+ "date",
+ "resolve",
+ "mutable",
+ "branch",
+ "arguments",
+ ],
+};
diff --git a/components/http/src/framework/optimizer/aComposer.ts b/src/composer/linker.ts
similarity index 75%
rename from components/http/src/framework/optimizer/aComposer.ts
rename to src/composer/linker.ts
index 3d6e9b3..49d2a80 100644
--- a/components/http/src/framework/optimizer/aComposer.ts
+++ b/src/composer/linker.ts
@@ -1,7 +1,7 @@
-import checkAsync from "./recursiveCheckAsync.ts";
-import { FunRouterOptions } from "../../../types.ts";
-import { CommonRequestMorphism, RequestMorphism } from "./types.ts";
-import nativeComponets from "./nativeComponets.ts";
+import tools from "./composerTools.ts";
+import type { FunRouterOptions } from "../options.ts";
+import type { Petition } from "../morphism.ts";
+import nativeComponets from "./nativeComponents.ts";
import nativeMaps from "./nativeMaps.ts";
export type specialOptions = {
@@ -9,9 +9,7 @@ export type specialOptions = {
branch?: boolean;
} & FunRouterOptions;
-export default (o?: specialOptions) =>
-(f: CommonRequestMorphism | RequestMorphism) =>
-(ar: string[]) =>
+export default (o?: specialOptions) => (f: Petition) => (ar: string[]) =>
ar.length === 0 && !(o && "branch" in o) ? ((r: Request) => r) : (
(el) => el
)(
@@ -25,7 +23,7 @@ export default (o?: specialOptions) =>
` return ${
table.map((x) => x.type === 1 ? x.name + "=>" : "").join("")
} ${
- f.resolve && checkAsync(f) ||
+ f.resolve && tools.recursiveCheckAsync(f) ||
f.f.constructor.name === "AsyncFunction" ||
table.some((x) => "isAsync" in x && x.isAsync === true)
? o && "branch" in o ? " r=>async b=> " : " async r=> "
diff --git a/components/http/src/framework/optimizer/nativeComponets.ts b/src/composer/nativeComponents.ts
similarity index 69%
rename from components/http/src/framework/optimizer/nativeComponets.ts
rename to src/composer/nativeComponents.ts
index 3db09b5..201bee5 100644
--- a/components/http/src/framework/optimizer/nativeComponets.ts
+++ b/src/composer/nativeComponents.ts
@@ -1,21 +1,17 @@
-import params from "../../parameters/main.ts";
-import query from "../../queries/main.ts";
-import cookies from "../../cookies/main.ts";
+import params from "../components/parameters/main.ts";
+import query from "../components/queries/main.ts";
+import cookies from "../components/cookies/main.ts";
import resolve from "./resolve/main.ts";
import branch from "./branch/main.ts";
-import cookieToTokenMain from "../../cookieToToken/cookieToTokenMain.ts";
-import signSha256 from "../../../../jwt/signSha256.mjs";
-import verifySha256 from "../../../../jwt/verifySha256.mjs";
-import { parse, stringToFunction } from "../../cors/mainCORS.ts";
+import cookieToTokenMain from "../components/cookieToToken/cookieToTokenMain.ts";
+import signSha256 from "../components/jwt/signSha256.mjs";
+import verifySha256 from "../components/jwt/verifySha256.mjs";
+import { parse, stringToFunction } from "../components/cors/mainCORS.ts";
-import { FunRouterOptions } from "../../../types.ts";
-import {
- AnyMorphismMap,
- CommonRequestMorphism,
- MorphismMap,
- RequestMorphism,
-} from "./types.ts";
-import parsingToHexa from "./tools/parsingToHexa.ts";
+import type { FunRouterOptions } from "../options.ts";
+import type { Petition } from "../morphism.ts";
+
+import tools from "./composerTools.ts";
type NativeMaps = {
name: string;
@@ -24,7 +20,7 @@ type NativeMaps = {
};
export default (o?: FunRouterOptions) =>
-(f: CommonRequestMorphism | RequestMorphism) =>
+(f: Petition) =>
(native: NativeMaps[]) =>
((list) =>
native.map((x) =>
@@ -42,7 +38,9 @@ export default (o?: FunRouterOptions) =>
condition: (x: NativeMaps) => x.name === "verify",
action: () =>
f.crypto && "globalKey" in f.crypto
- ? verifySha256()(parsingToHexa(f.crypto as { globalKey: string }))
+ ? verifySha256()(
+ tools.parsingToHexa(f.crypto as { globalKey: string }),
+ )
: void console.error(
"I don't know you got this message, contact me in discord," +
" also verify will always return `false` ",
@@ -52,7 +50,9 @@ export default (o?: FunRouterOptions) =>
condition: (x: NativeMaps) => x.name === "sign",
action: () =>
f.crypto && "globalKey" in f.crypto
- ? signSha256()(parsingToHexa(f.crypto as { globalKey: string }))
+ ? signSha256()(
+ tools.parsingToHexa(f.crypto as { globalKey: string }),
+ )
: void console.error(
"I don't know you got this message, contact me in discord," +
" also sign will always return '' ",
@@ -65,7 +65,7 @@ export default (o?: FunRouterOptions) =>
...f,
crypto: {
...f.crypto,
- globalKey: parsingToHexa(f.crypto as { globalKey: string }),
+ globalKey: tools.parsingToHexa(f.crypto as { globalKey: string }),
},
}),
},
@@ -80,16 +80,14 @@ export default (o?: FunRouterOptions) =>
{
condition: (x: NativeMaps) => x.name === "resolve",
action: () =>
- ("resolve" in f)
- ? resolve(o)(f.path)(f.resolve as MorphismMap)
- : null,
+ ("resolve" in f) ? resolve(o)(f.path as string)(f.resolve) : null,
},
{
condition: (x: NativeMaps) => x.name === "branch",
action: () =>
("branch" in f)
? branch({ ...o, branch: true })(f.path)(
- f!.branch as AnyMorphismMap,
+ f!.branch,
)
: null,
},
diff --git a/components/http/src/framework/optimizer/nativeMaps.ts b/src/composer/nativeMaps.ts
similarity index 86%
rename from components/http/src/framework/optimizer/nativeMaps.ts
rename to src/composer/nativeMaps.ts
index 1351cad..aff5f4f 100644
--- a/components/http/src/framework/optimizer/nativeMaps.ts
+++ b/src/composer/nativeMaps.ts
@@ -1,9 +1,10 @@
-import { FunRouterOptions } from "../../../types.ts";
-import { CommonRequestMorphism, RequestMorphism } from "./types.ts";
-import checkAsync from "./recursiveCheckAsync.ts";
+import type { FunRouterOptions } from "../options.ts";
+import type { Petition } from "../morphism.ts";
+
+import tools from "./composerTools.ts";
export default (o?: FunRouterOptions) =>
-(f: CommonRequestMorphism | RequestMorphism) =>
+(f: Petition) =>
(ar: string[]) =>
(mutable: boolean) =>
([
@@ -58,13 +59,17 @@ export default (o?: FunRouterOptions) =>
},
{
name: "resolve",
- value: `${checkAsync(f) ? " await resolve(r)" : "resolve(r)"}`,
+ value: `${
+ tools.recursiveCheckAsync(f) ? " await resolve(r)" : "resolve(r)"
+ }`,
type: 1,
},
{ name: "mutable", value: mutable ? "r[1]" : "{}", type: 0 },
{
name: "branch",
- value: `${checkAsync(f) ? " await branch(r)" : "branch(r)"}`,
+ value: `${
+ tools.recursiveCheckAsync(f) ? " await branch(r)" : "branch(r)"
+ }`,
type: 1,
},
{
diff --git a/components/http/src/framework/optimizer/resolve/main.ts b/src/composer/resolve/main.ts
similarity index 69%
rename from components/http/src/framework/optimizer/resolve/main.ts
rename to src/composer/resolve/main.ts
index dba8a69..3f3b413 100644
--- a/components/http/src/framework/optimizer/resolve/main.ts
+++ b/src/composer/resolve/main.ts
@@ -1,17 +1,13 @@
-import recursiveCheck from "../checkAsync.ts";
-import { ResolveOptions, ResponseResponse } from "./types.ts";
-import { FunRouterOptions } from "../../../../types.ts";
-import {
- CommonRequestMorphism,
- MorphismMap,
- RequestMorphism,
-} from "../types.ts";
+import tools from "../composerTools.ts";
+import type { ResolveOptions, ResponseResponse } from "./types.ts";
+import type { FunRouterOptions } from "../../options.ts";
+import type { Petition, ResolveMap } from "../../morphism.ts";
import table from "./table.ts";
export default (o?: FunRouterOptions) =>
(path: string) =>
-(input: MorphismMap): ResponseResponse =>
+(input: ResolveMap): ResponseResponse =>
(
(ar) =>
(
@@ -31,8 +27,8 @@ export default (o?: FunRouterOptions) =>
)(),
) as unknown as ResponseResponse)(
ar.some((x) =>
- recursiveCheck(
- x as unknown as CommonRequestMorphism | RequestMorphism,
+ tools.recursiveCheckAsync(
+ x as unknown as Petition,
)
),
)
diff --git a/src/composer/resolve/table.ts b/src/composer/resolve/table.ts
new file mode 100644
index 0000000..1c0fcf8
--- /dev/null
+++ b/src/composer/resolve/table.ts
@@ -0,0 +1,28 @@
+import aComposer from "../linker.ts";
+import tools from "../composerTools.ts";
+import type { ResolveOptions } from "./types.ts";
+import type { FunRouterOptions } from "../../options.ts";
+import type { Petition } from "../../morphism.ts";
+
+export default (o?: FunRouterOptions) =>
+(path: string) =>
+(table: ResolveOptions) =>
+ table
+ .map((x) => ({ ...x, path: path }))
+ .map((x) => ({
+ name: x.name,
+ f: (
+ (composed: Petition["f"]) =>
+ x.f.constructor.name === "AsyncFunction" ||
+ composed.constructor.name === "AsyncFunction"
+ ? ((a) => (k: (arg0: any) => any) => async (r: any) =>
+ await k(await a(r)))(composed)(x.f)
+ : ((a) => (k: (arg0: any) => any) => (r: any) => k(a(r)))(
+ composed,
+ )(x.f)
+ )(
+ aComposer(o)(x as unknown as Petition)(
+ tools.isUsing(o)(x as unknown as Petition)(tools.elements),
+ ),
+ ),
+ }));
diff --git a/components/http/src/framework/optimizer/resolve/types.ts b/src/composer/resolve/types.ts
similarity index 56%
rename from components/http/src/framework/optimizer/resolve/types.ts
rename to src/composer/resolve/types.ts
index 64bea65..9e100ea 100644
--- a/components/http/src/framework/optimizer/resolve/types.ts
+++ b/src/composer/resolve/types.ts
@@ -1,12 +1,12 @@
-import { Morphism, PetitionOptions } from "../types.ts";
+import type { PetitionOptions, ResolveMorphism } from "../../morphism.ts";
-export type ResolveOption = Morphism & {
+export type ResolveOption = ResolveMorphism & {
name: string;
options?: PetitionOptions;
};
export type ResolveOptions = ResolveOption[];
-export type ResponseResponse = (r: Request) => unknown;
+export type ResponseResponse = (r: Request) => { [key: string]: any };
export type TypeResolveOptions =
| ({ async: false; f: (f: any) => BodyInit })[]
diff --git a/src/composer/tokens/jSigner.ts b/src/composer/tokens/jSigner.ts
new file mode 100644
index 0000000..0cc9a12
--- /dev/null
+++ b/src/composer/tokens/jSigner.ts
@@ -0,0 +1,24 @@
+import signer from "./signer.ts";
+
+import stringify from "../../../../encode/src/stringify/safe.mjs";
+
+import { SignVerifyOptions } from "./types.ts";
+import {
+ JsonStringify,
+ JsonType,
+} from "../../../../encode/src/stringify/types.ts";
+export type JsonSinger = SignVerifyOptions & {
+ schema?: JsonStringify;
+};
+
+export default (o: JsonSinger) =>
+ (
+ (sign) =>
+ "schema" in o && typeof o.schema == "object"
+ ? ((str) => (obj: JsonType) => sign(btoa(str(obj))))(
+ stringify(o.schema),
+ )
+ : (obj: JsonType) => sign(btoa(JSON.stringify(obj)))
+ )(
+ signer(o),
+ );
diff --git a/src/composer/tokens/jVerify.ts b/src/composer/tokens/jVerify.ts
new file mode 100644
index 0000000..45151e7
--- /dev/null
+++ b/src/composer/tokens/jVerify.ts
@@ -0,0 +1,14 @@
+import verifier from "./verifier.ts";
+import { SignVerifyOptions } from "./types.ts";
+type JSONVerifier = SignVerifyOptions;
+
+export default (o: JSONVerifier) =>
+ typeof o.expires == "number"
+ ? ((v) => (s: string) =>
+ v(s) ? JSON.parse(atob(s.substring(13, s.indexOf(".")))) : null)(
+ verifier(o),
+ )
+ : ((v) => (s: string) =>
+ v(s) ? JSON.parse(atob(s.substring(0, s.indexOf(".")))) : null)(
+ verifier(o),
+ );
diff --git a/src/composer/tokens/readme.md b/src/composer/tokens/readme.md
new file mode 100644
index 0000000..528b401
--- /dev/null
+++ b/src/composer/tokens/readme.md
@@ -0,0 +1,215 @@
+# Vixeny's Tokens
+
+## Introduction
+
+JSON Web Tokens (JWTs) are renowned for their effectiveness and robustness in
+asynchronously signing claims and authenticating with either public or private
+keys. Despite their advantages, there are several inherent challenges with JWTs:
+
+- JWTs necessitate payload decoding from Base64 and parsing to JSON to validate
+ claims like expiration dates. Even though this operation is straightforward,
+ it could be computationally intensive, particularly in high-traffic
+ applications or in resource-constrained environments.
+- Waiting for the entire hash to determine the validity of a token can be
+ inefficient as there is no mechanism for early detection of invalid tokens.
+ The hashing process depends on the entire message and the key.
+- JWTs are not specifically designed or optimized for signing strings and they
+ return an "Error" upon failure, which is not always the most helpful response.
+
+In response to these challenges, we propose an innovative approach that draws
+upon the strengths of two well-established encryption algorithms: RC4 and
+Salsa20. Using these algorithms as our foundation, we developed a prototype that
+utilizes a seed value to generate a unique signing and verifying algorithm for
+each signer and verifier. This strategy employs the concept of function
+composition, the process of crafting a complex function by integrating simpler
+ones, and takes full advantage of a runtime environment, in this case,
+JavaScript.
+
+Our proposed solution presents numerous advantages:
+
+- The payload does not need to be decoded to check the expiration, enhancing
+ performance efficiency.
+- The algorithm checks the validity at each character level, enabling early
+ rejection of invalid tokens.
+- Instead of returning an "Error", it returns "False" or "Null" depending on the
+ mode when an error occurs, providing more versatile error handling.
+- Key strength issues become irrelevant, as the seed used to plot the unique
+ algorithm ensures robust security without the need for a separate secret key.
+- The size of the claim decreases significantly for small claims, optimizing
+ data transfer efficiency.
+
+However, our approach is not without potential limitations:
+
+- The nature of the algorithm makes it synchronous, meaning only those with the
+ correct seed can verify the claim.
+- The solution requires a minimum length of 8 for functionality.
+
+## Retrieving Signer and Verifier
+
+We provide two sets of signers and verifiers, each set tailored to handle either
+JSON-like objects or plain strings.
+
+Let's fetch these functions:
+
+### Using Deno
+
+```ts
+import jSigner from "https://deno.land/x/endofunctor/components/tokens/jSigner.ts";
+import jVerifier from "https://deno.land/x/endofunctor/components/tokens/jVerify.ts";
+import signer from "https://deno.land/x/endofunctor/components/tokens/signer.ts";
+import verifier from "https://deno.land/x/endofunctor/components/tokens/verify.ts";
+```
+
+### Using Bun
+
+```ts
+import jSigner from "vixeny/components/tokens/jSigner";
+import jVerifier from "vixeny/components/tokens/jVerify";
+import signer from "vixeny/components/tokens/signer";
+import verifier from "vixeny/components/tokens/verifier";
+```
+
+## Handling Plain Claims
+
+We've designed this mode with session ID in mind. For optimal security, we
+strongly recommend adding expiration to all your claims.
+
+The SignVerifyOptions type contains these parameters:
+
+```ts
+type SignVerifyOptions = {
+ seed: string;
+ // this option allows you to fix the token size, improving performance. Note that it does not include the size of expiration - you'll need to add 13 to the size of your token.
+ size?: NumericRange, 40>;
+ // set at 4 by default, this parameter adjusts the complexity of the function. The value of 4 is four times more complex than 1.
+ sequence?: 1 | 2 | 3 | 4;
+ // add the time in ms based on Date.now()
+ expires?: number;
+};
+```
+
+Let's sign and verify a message:
+
+```ts
+const seed = "hello",
+ message = "12345678",
+ inValidClaim = "12345678.xT7u34qa";
+
+const sign = signer({ seed: seed });
+const verify = verifier({ seed: seed });
+
+console.log(sign(message));
+// Output: 12345678.xT7u34qz
+
+console.log(verify(sign(message)));
+// Output: true
+console.log(verify(inValidClaim));
+// Output: false
+```
+
+Adding expiration:
+
+```ts
+const seed = "hello",
+ message = "12345678";
+
+const sign = signer({ seed: seed, expires: 10_000 });
+// This signer will generate tokens but the verifiers will always reject them.
+const signExpired = signer({ seed: seed, expires: -1 });
+// The expires option does not affect the verifier directly but informs it that it should expect an expiration date.
+const verify = verifier({ seed: seed, expires: 10_000 });
+
+console.log(verify(sign(message)));
+// Output: true
+console.log(verify(signExpired(message)));
+// Output: false
+```
+
+Working with a fixed size:
+
+```ts
+const seed = "hello",
+ message = "12345678";
+
+// The length of our message is 8, and the timestamp size is 13, so our size in this case will be 21.
+const sign = signer({ seed: seed, expires: 10_000, size: 21 });
+
+const CommonVerify = verifier({ seed: seed, expires: 10_000 });
+const verify = verifier({ seed: seed, expires: 10_000, size: 21 });
+
+console.log(verify(sign(message)));
+// Output: true
+console.log(verify(signer(message)));
+// Output: true
+console.log(CommonVerify(signer(message)));
+// Output: true
+```
+
+It's important to note:
+
+```ts
+const seed = "hello",
+ message = "12345678";
+
+const sign = signer({ seed: seed });
+const sign_sequence3 = signer({ seed: seed, sequence: 3 });
+
+// These two signed messages will be completely different
+console.log(sign(message) === sign_sequence3(message));
+// Output: false
+```
+
+## Managing Tokens
+
+The handling of tokens follows the same principle as plain claims, but setting a
+fixed size isn't recommended for tokens.
+
+> Important: Always add an expiration time to your tokens. The following are
+> merely illustrative examples:
+
+```ts
+const seed = "hello",
+ obj = { hello: "world" },
+ invalidToken = "eyJoZWxsbyI6IndvcmxkIn0=.rwY85qhxKJXaHivubE+sDunr";
+
+const sign = jSigner({ seed: seed });
+const verify = jVerifier({ seed: seed });
+
+console.log(sign(obj));
+// Output: eyJoZWxsbyI6IndvcmxkIn0=.rwY85qhxKJXaHivubE+sDunt
+
+console.log(verify(sign(message)));
+// Output: {seed: seed }
+console.log(verify(invalidToken));
+// Output: null
+```
+
+You can utilize a schema to accelerate the process. This is based on JSONSchema:
+
+```ts
+const seed = "hello",
+ obj = { hello: "world" };
+
+const sign = jSigner({
+ seed: "hello",
+ schema: {
+ type: "object",
+ properties: {
+ hello: { type: "string" },
+ },
+ required: ["hello"],
+ },
+});
+
+const verify = jVerifier({ seed: seed });
+
+console.log(sign(obj));
+// Output: eyJoZWxsbyI6IndvcmxkIn0=.rwY85qhxKJXaHivubE+sDunt
+
+console.log(verify(sign(message)));
+// Output: {hello: "world"}
+```
+
+Utilizing a schema not only makes the token generation process faster, but it
+also provides a clear structure for the data encapsulated within the token,
+ensuring its validity and consistency.
diff --git a/src/composer/tokens/signer.ts b/src/composer/tokens/signer.ts
new file mode 100644
index 0000000..8de7e8b
--- /dev/null
+++ b/src/composer/tokens/signer.ts
@@ -0,0 +1,87 @@
+import solver from "./src/solver.ts";
+
+import validChar from "../../../../util/validChar.ts";
+import { SignVerifyOptions } from "./types.ts";
+import signerWithSize from "./src/signerWithSize.ts";
+
+export default (seed: SignVerifyOptions) =>
+ (
+ (ar) =>
+ (
+ (p) =>
+ typeof seed.size == "number"
+ ? typeof seed.expires === "number"
+ ? (
+ (f) =>
+ ((n: number) => (s: string) =>
+ f((Date.now() + n).toString() + s))(seed.expires)
+ )(
+ signerWithSize(seed.size)(ar)(p),
+ )
+ : signerWithSize(seed.size)(ar)(p)
+ : typeof seed.expires === "number"
+ ? ((n: number) => (s: string) =>
+ ((d) =>
+ [...d].map((x) => x.charCodeAt(0)).map((x, i, a) =>
+ i < 7
+ ? p[
+ ar[i % 8]([
+ a.at(i - 7) as number,
+ a.at(i - 6) as number,
+ a.at(i - 5) as number,
+ a.at(i - 4) as number,
+ a.at(i - 3) as number,
+ a.at(i - 2) as number,
+ a.at(i - 1) as number,
+ x,
+ ])
+ ]
+ : p[
+ ar[i % 8]([
+ a[i - 7],
+ a[i - 6],
+ a[i - 5],
+ a[i - 4],
+ a[i - 3],
+ a[i - 2],
+ a[i - 1],
+ x,
+ ])
+ ]
+ ).reduce((acc, x) => acc + x, d + "."))(
+ (Date.now() + n).toString() + s,
+ ))(seed.expires)
+ : (s: string) =>
+ [...s].map((x) => x.charCodeAt(0)).map((x, i, a) =>
+ i < 7
+ ? p[
+ ar[i % 8]([
+ a.at(i - 7) as number,
+ a.at(i - 6) as number,
+ a.at(i - 5) as number,
+ a.at(i - 4) as number,
+ a.at(i - 3) as number,
+ a.at(i - 2) as number,
+ a.at(i - 1) as number,
+ x,
+ ])
+ ]
+ : p[
+ ar[i % 8]([
+ a[i - 7],
+ a[i - 6],
+ a[i - 5],
+ a[i - 4],
+ a[i - 3],
+ a[i - 2],
+ a[i - 1],
+ x,
+ ])
+ ]
+ ).reduce((acc, x) => acc + x, s + ".")
+ )(
+ [...validChar],
+ )
+ )(
+ solver(seed),
+ );
diff --git a/src/composer/tokens/src/crcTable.ts b/src/composer/tokens/src/crcTable.ts
new file mode 100644
index 0000000..f921a58
--- /dev/null
+++ b/src/composer/tokens/src/crcTable.ts
@@ -0,0 +1,18 @@
+export default (start = 0xEDB88320) =>
+ new Int32Array(
+ (() =>
+ Array.from(
+ { length: 256 },
+ (_, i) =>
+ Array.from(
+ { length: 8 },
+ ).reduce(
+ (acc: number) => ((acc & 1)
+ ? (start ^ (acc >>> 1))
+ : (acc >>> 1) === 0
+ ? 0xFFFFFFF
+ : (acc >>> 1)),
+ i,
+ ),
+ ))() as number[],
+ );
diff --git a/src/composer/tokens/src/digits.ts b/src/composer/tokens/src/digits.ts
new file mode 100644
index 0000000..de7fe93
--- /dev/null
+++ b/src/composer/tokens/src/digits.ts
@@ -0,0 +1,12 @@
+import table from "./table.ts";
+import shaTable from "./tableSha.ts";
+import { SignVerifyOptions } from "../types.ts";
+
+export default (txt: string) => (seed: SignVerifyOptions) =>
+ (
+ (
+ new Function(`
+ return a=> ar => ${table(seed)(txt)}
+ `)
+ )()
+ )(shaTable(txt + seed.seed)) as (ar: number[]) => number;
diff --git a/src/composer/tokens/src/hash.ts b/src/composer/tokens/src/hash.ts
new file mode 100644
index 0000000..9efabfb
--- /dev/null
+++ b/src/composer/tokens/src/hash.ts
@@ -0,0 +1,5 @@
+import { SignVerifyOptions } from "../types.ts";
+import crypto from "node:crypto";
+
+export default (o?: SignVerifyOptions) => (message: string) =>
+ crypto.createHash("sha256").update(message).digest("hex");
diff --git a/src/composer/tokens/src/signerWithSize.ts b/src/composer/tokens/src/signerWithSize.ts
new file mode 100644
index 0000000..0ed2cdd
--- /dev/null
+++ b/src/composer/tokens/src/signerWithSize.ts
@@ -0,0 +1,13 @@
+export default (n: number) =>
+ new Function(
+ `return ar => p=> s=> ( a=>[${
+ Array.from({ length: n }, (_, i) =>
+ `p[ar[${i % 8}]([${
+ Array.from({ length: 8 }, (_, j) => `a[${(n - 7 + i + j) % n}]`).join(
+ ",",
+ )
+ }])]`).join(",")
+ }].reduce((acc,x)=> acc+x, s + "." ))([${
+ Array.from({ length: n }, (_, i) => `s.charCodeAt(${i})`).join(",")
+ }]) `,
+ )();
diff --git a/src/composer/tokens/src/solver.ts b/src/composer/tokens/src/solver.ts
new file mode 100644
index 0000000..49c89a7
--- /dev/null
+++ b/src/composer/tokens/src/solver.ts
@@ -0,0 +1,8 @@
+import digits from "./digits.ts";
+import { SignVerifyOptions } from "../types.ts";
+
+export default (o: SignVerifyOptions) =>
+ Array.from(
+ { length: (typeof o.size === "number" ? o.size : 8) },
+ (_, i) => digits(o.seed + i)(o),
+ );
diff --git a/src/composer/tokens/src/table.ts b/src/composer/tokens/src/table.ts
new file mode 100644
index 0000000..13a2d6e
--- /dev/null
+++ b/src/composer/tokens/src/table.ts
@@ -0,0 +1,45 @@
+import hash from "./hash.ts";
+import { SignVerifyOptions } from "../types.ts";
+
+export default (o: SignVerifyOptions) => (key: string) =>
+ (
+ (s) =>
+ (
+ (p) =>
+ (
+ (el) =>
+ "(((" + Array.from(
+ {
+ length: 8 * (typeof o.sequence === "number" ? o.sequence : 4),
+ },
+ (_, i) => `( ${p[i]} ^ a[ar[${el[i]}]])`,
+ ).join("+") + ") >>> 0) % 65)"
+ )(
+ Array.from(
+ { length: 16 },
+ () =>
+ Array.from(
+ { length: 8 },
+ (_, i) => "" + i,
+ ),
+ ).flat(),
+ )
+ )(
+ Array.from(
+ { length: 64 },
+ (_, i) => "0x" + s.slice(i === 0 ? 0 : i * 8, i * 8 + 8),
+ ),
+ )
+ )(
+ (
+ (s1) =>
+ (Array.from(
+ {
+ length: 16,
+ },
+ (_, i) => hash(o)(s1 + " " + i),
+ )).join("")
+ )(
+ hash(o)(key),
+ ),
+ );
diff --git a/src/composer/tokens/src/tableSha.ts b/src/composer/tokens/src/tableSha.ts
new file mode 100644
index 0000000..49107d5
--- /dev/null
+++ b/src/composer/tokens/src/tableSha.ts
@@ -0,0 +1,28 @@
+import hash from "./hash.ts";
+
+export default (seed: string) =>
+ (
+ (s1) =>
+ new Int32Array(
+ (Array.from(
+ {
+ length: 32,
+ },
+ (_, i) => hash()(s1 + "table" + i),
+ )).map(
+ (x) =>
+ [
+ x.slice(0, 7),
+ x.slice(8, 15),
+ x.slice(16, 23),
+ x.slice(24, 31),
+ x.slice(32, 39),
+ x.slice(40, 47),
+ x.slice(48, 55),
+ x.slice(56, 63),
+ ].map((x) => Number("0x" + x)),
+ ).flatMap((x) => x),
+ )
+ )(
+ hash()(seed),
+ );
diff --git a/src/composer/tokens/src/verifyWithSize.ts b/src/composer/tokens/src/verifyWithSize.ts
new file mode 100644
index 0000000..82a5880
--- /dev/null
+++ b/src/composer/tokens/src/verifyWithSize.ts
@@ -0,0 +1,13 @@
+export default (n: number) =>
+ new Function(
+ ` return ar => p=> s=>( a=> s.length===${(n * 2) + 1} &&${
+ Array.from({ length: n }, (_, i) =>
+ `p[ar[${i % 8}]([${
+ Array.from({ length: 8 }, (_, j) => `a[${(n - 7 + i + j) % n}]`).join(
+ ",",
+ )
+ }])] === s[${i + 1 + n}]`).join("&&")
+ })([${
+ Array.from({ length: n }, (_, i) => `s.charCodeAt(${i})`).join(",")
+ }]) `,
+ )();
diff --git a/src/composer/tokens/types.ts b/src/composer/tokens/types.ts
new file mode 100644
index 0000000..07b839f
--- /dev/null
+++ b/src/composer/tokens/types.ts
@@ -0,0 +1,19 @@
+type CreateArrayWithLengthX<
+ LENGTH extends number,
+ ACC extends unknown[] = [],
+> = ACC["length"] extends LENGTH ? ACC
+ : CreateArrayWithLengthX;
+
+type NumericRange<
+ START_ARR extends number[],
+ END extends number,
+ ACC extends number = never,
+> = START_ARR["length"] extends END ? ACC | END
+ : NumericRange<[...START_ARR, 1], END, ACC | START_ARR["length"]>;
+
+export type SignVerifyOptions = {
+ seed: string;
+ size?: NumericRange, 40>;
+ sequence?: 1 | 2 | 3 | 4;
+ expires?: number;
+};
diff --git a/src/composer/tokens/verifier.ts b/src/composer/tokens/verifier.ts
new file mode 100644
index 0000000..5a85c07
--- /dev/null
+++ b/src/composer/tokens/verifier.ts
@@ -0,0 +1,71 @@
+import solver from "./src/solver.ts";
+import validChar from "../../../../util/validChar.ts";
+import { SignVerifyOptions } from "./types.ts";
+import verifyWithSize from "./src/verifyWithSize.ts";
+
+export default (seed: SignVerifyOptions) =>
+ (
+ (ar) =>
+ (
+ (p) =>
+ typeof seed.size == "number"
+ ? typeof seed.expires === "number"
+ ? (
+ (f) => (s: string) =>
+ Number(s.slice(0, 13)) > Date.now() && f(s)
+ )(
+ verifyWithSize(seed.size)(ar)(p),
+ )
+ : verifyWithSize(seed.size)(ar)(p)
+ : (
+ (f) =>
+ typeof seed.expires === "number"
+ ? (s: string) => Number(s.slice(0, 13)) > Date.now() && f(s)
+ : f
+ )(
+ ((ar) => (p: string[]) => ((s: string) =>
+ s.length >= 17
+ ? (
+ (m) =>
+ [...s
+ .slice(0, m - 1)]
+ .map((x) => x.charCodeAt(0))
+ .every((x, i, a) =>
+ i < 7
+ ? p[
+ ar[i % 8]([
+ a.at(i - 7) as number,
+ a.at(i - 6) as number,
+ a.at(i - 5) as number,
+ a.at(i - 4) as number,
+ a.at(i - 3) as number,
+ a.at(i - 2) as number,
+ a.at(i - 1) as number,
+ x,
+ ])
+ ] === s[m + i]
+ : p[
+ ar[i % 8]([
+ a[i - 7],
+ a[i - 6],
+ a[i - 5],
+ a[i - 4],
+ a[i - 3],
+ a[i - 2],
+ a[i - 1],
+ x,
+ ])
+ ] ===
+ s[m + i]
+ )
+ )(
+ (s.length / 2 >> 0) + 1,
+ )
+ : false))(ar)(p),
+ )
+ )(
+ [...validChar],
+ )
+ )(
+ solver(seed),
+ );
diff --git a/checkTypes.ts b/src/morphism.ts
similarity index 79%
rename from checkTypes.ts
rename to src/morphism.ts
index fc1984a..cf4c73f 100644
--- a/checkTypes.ts
+++ b/src/morphism.ts
@@ -1,24 +1,53 @@
-import response from "./components/http/src/framework/optimizer/response";
-import { CyclePluginMap } from "./components/http/types";
-import test from "./components/util/test.mjs";
-import { FunRouterOptions } from "./types";
+import type { CyclePluginMap, FunRouterOptions } from "./options.ts";
+import compose from "./composer/compose.ts";
+
+export type Petition = Morphism<
+ {
+ isAPetition: true;
+ type: typeMorphisim;
+ hasPath: true;
+ },
+ any,
+ any,
+ any,
+ any,
+ any,
+ any,
+ any,
+ any
+>;
+export type ResolveMorphism = Morphism<
+ {
+ type: "morphism";
+ },
+ any,
+ any,
+ any,
+ any,
+ any,
+ any,
+ any,
+ any
+>;
export const petitions = {
- standart: (O?: RO) => <
- RM extends ResolveMap,
- BM extends BranchMap,
+ standart: (O?: RO) =>
+ <
+ RM extends ResolveMap,
+ BM extends BranchMap,
QO extends QueryOptions,
PO extends ParamOptions,
RO extends FunRouterOptions,
CO extends CryptoOptions,
AR = any,
- R = any >(
+ R = any,
+ >(
I: Morphism<
{
type: "request";
hasPath: true;
isAPetition: true;
- typeNotNeeded: true
+ typeNotNeeded: true;
},
RM,
BM,
@@ -29,23 +58,11 @@ export const petitions = {
AR,
R
>,
- ): Morphism<{
- type: "request";
- hasPath: true;
- isAPetition: true;
- },
- RM,
- BM,
- QO,
- PO,
- RO,
- CO,
- AR,
- R
- > => ({ ...I, type: "request" }),
- common: (O?: RO) => <
- RM extends ResolveMap,
- BM extends BranchMap,
+ ) => ({ ...I, type: "request" }) as unknown as Petition,
+ common: (O?: RO) =>
+ <
+ RM extends ResolveMap,
+ BM extends BranchMap,
QO extends QueryOptions,
PO extends ParamOptions,
RO extends FunRouterOptions,
@@ -69,23 +86,11 @@ export const petitions = {
AR,
R
>,
- ): Morphism<{
- type: "base";
- hasPath: true;
- isAPetition: true;
- },
- RM,
- BM,
- QO,
- PO,
- RO,
- CO,
- AR,
- R> => ({ ...I, type: "base" }),
+ ) => ({ ...I, type: "base" }) as unknown as Petition,
response: (O?: RO) =>
<
- RM extends ResolveMap,
- BM extends BranchMap,
+ RM extends ResolveMap,
+ BM extends BranchMap,
QO extends QueryOptions,
PO extends ParamOptions,
RO extends FunRouterOptions,
@@ -93,14 +98,10 @@ export const petitions = {
AR = any,
R = any,
>(I: {
- path: string;
- f: {
- (ctx: Request): Response | Promise;
- };
+ f: { (ctx: Request): Response | Promise };
}): Morphism<
{
type: "response";
- hasPath: true;
},
RM,
BM,
@@ -113,8 +114,8 @@ export const petitions = {
> => ({ ...I, type: "response" }),
resolve: (O?: RO) =>
<
- RM extends ResolveMap,
- BM extends BranchMap,
+ RM extends ResolveMap,
+ BM extends BranchMap,
QO extends QueryOptions,
PO extends ParamOptions,
RO extends FunRouterOptions,
@@ -138,8 +139,8 @@ export const petitions = {
) => I,
branch: (O?: RO) =>
<
- RM extends ResolveMap,
- BM extends BranchMap,
+ RM extends ResolveMap,
+ BM extends BranchMap,
QO extends QueryOptions,
PO extends ParamOptions,
RO extends FunRouterOptions,
@@ -162,75 +163,124 @@ export const petitions = {
R
>,
) => I,
+ join: (O?: RO) =>
+ <
+ RM extends ResolveMap,
+ BM extends BranchMap,
+ QO extends QueryOptions,
+ PO extends ParamOptions,
+ RO extends FunRouterOptions,
+ CO extends CryptoOptions,
+ AT = any,
+ R = any,
+ >(
+ A: Morphism<
+ {
+ isAPetition: true;
+ hasPath: true;
+ },
+ RM,
+ BM,
+ QO,
+ PO,
+ RO,
+ CO,
+ AT,
+ R
+ >[],
+ ) =>
+ <
+ RM extends ResolveMap,
+ BM extends BranchMap,
+ QO extends QueryOptions,
+ PO extends ParamOptions,
+ RO extends FunRouterOptions,
+ CO extends CryptoOptions,
+ AT = any,
+ R = any,
+ >(
+ B:
+ | Morphism<
+ {
+ isAPetition: true;
+ hasPath: true;
+ },
+ RM,
+ BM,
+ QO,
+ PO,
+ RO,
+ CO,
+ AT,
+ R
+ >
+ | {
+ type: typeMorphisim;
+ path: string;
+ f: any;
+ },
+ ) => [
+ ...A,
+ B as Morphism<
+ {
+ isAPetition: true;
+ hasPath: true;
+ },
+ RM,
+ BM,
+ QO,
+ PO,
+ RO,
+ CO,
+ AT,
+ R
+ >,
+ ],
};
-const a = petitions.branch()({
- arguments: 'string',
- crypto: {
- globalKey: 'hello'
- },
- f(ctx) {
- return new Response(ctx.arguments);
- },
-});
-
-
-const b = petitions.standart()({
- path: '/string',
- branch: {
- test: a
- },
- f(ctx) {
-
- return ctx.branch.test('hello')
- }
-})
-const c:Morphism<{
- isAPetition: true
-},any,any,any,any,any,any,any,any>[] = [b]
-
-
type typeMorphisim = "response" | "request" | "morphism" | "base";
-type ResolveMap = {
- [key: string]: Morphism<
+export type ResolveMap = {
+ [K in keyof T]: T[K] extends Morphism<
{
type: "morphism";
- },
- any,
- any,
- any,
- any,
- any,
- any,
- any,
- any
- >;
+ }
+ > ? Morphism<
+ {
+ type: "morphism";
+ }
+ >
+ : T[K] extends { f: any } ? any
+ : never;
};
-type BranchMap = {
- [key: string]: Morphism<
+const composed = {
+ resolve: 1,
+ branch: 1,
+};
+
+export type BranchMap = {
+ [K in keyof T]: T[K] extends Morphism<
{
type: "morphism";
branch: true;
- },
- any,
- any,
- any,
- any,
- any,
- any,
- any,
- any
- >;
+ }
+ > ? Morphism<
+ {
+ type: "morphism";
+ branch: true;
+ }
+ >
+ : T[K] extends { f: any } ? any
+ : never;
};
type MapOptions = {
- hasPath?: true;
- typeNotNeeded?: true;
+ hasPath?: boolean;
+ typeNotNeeded?: boolean;
type?: typeMorphisim;
- branch?: true;
- isAPetition?: true;
+ branch?: boolean;
+ isAPetition?: boolean;
};
type HasPath
= P extends { hasPath: true }
@@ -245,10 +295,25 @@ type HasType
= P extends { type: typeMorphisim }
type ExtraKeys