klaim 1.2.2 → 1.2.12
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/Makefile +5 -5
- package/README.md +2 -3
- package/deno.json +38 -38
- package/eslint.config.mjs +210 -210
- package/index.ts +2 -2
- package/load-env.cjs +1 -0
- package/mod.ts +2 -2
- package/package.json +4 -2
- package/release-it.config.cjs +28 -0
- package/src/core/Api.ts +63 -63
- package/src/core/Hook.ts +32 -32
- package/src/index.ts +5 -5
- package/src/tools/cleanUrl.ts +12 -12
- package/src/tools/slugify.ts +17 -17
- package/src/tools/toCamelCase.ts +11 -11
- package/src/tools/token.ts +14 -14
- package/tests/arguments.test.ts +89 -89
- package/vite.config.ts +31 -31
- package/.github/workflows/release.yml +0 -40
- package/.release-it.json +0 -22
package/Makefile
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
dev:
|
|
2
|
-
nr dev
|
|
3
|
-
|
|
4
|
-
dev-test:
|
|
5
|
-
cd ../klaim-test && nr dev
|
|
1
|
+
dev:
|
|
2
|
+
nr dev
|
|
3
|
+
|
|
4
|
+
dev-test:
|
|
5
|
+
cd ../klaim-test && nr dev
|
package/README.md
CHANGED
|
@@ -39,9 +39,8 @@ deno add @antharuu/klaim
|
|
|
39
39
|
Here’s a basic example to get you started:
|
|
40
40
|
|
|
41
41
|
```typescript
|
|
42
|
-
import {Api, Klaim,
|
|
43
|
-
//
|
|
44
|
-
import {Api, Klaim, Registry, Route, Hook} from "@antharuu/klaim";
|
|
42
|
+
import {Api, Klaim, Route, Hook} from 'klaim';
|
|
43
|
+
// For deno: import {Api, Klaim, Route, Hook} from "@antharuu/klaim";
|
|
45
44
|
|
|
46
45
|
// Your simple Todo type
|
|
47
46
|
type Todo = {
|
package/deno.json
CHANGED
|
@@ -1,38 +1,38 @@
|
|
|
1
|
-
{
|
|
2
|
-
"name": "@antharuu/klaim",
|
|
3
|
-
"version": "1.2.1",
|
|
4
|
-
"description": "Klaim is a lightweight TypeScript library designed to manage APIs and record requests, optimized for an optimal user experience.",
|
|
5
|
-
"repository": {
|
|
6
|
-
"type": "git",
|
|
7
|
-
"url": "https://github.com/antharuu/klaim.git"
|
|
8
|
-
},
|
|
9
|
-
"keywords": [
|
|
10
|
-
"typescript",
|
|
11
|
-
"api",
|
|
12
|
-
"request",
|
|
13
|
-
"user experience",
|
|
14
|
-
"optimization",
|
|
15
|
-
"lightweight"
|
|
16
|
-
],
|
|
17
|
-
"author": "antharuu",
|
|
18
|
-
"license": "MIT",
|
|
19
|
-
"bugs": {
|
|
20
|
-
"url": "https://github.com/antharuu/klaim/issues"
|
|
21
|
-
},
|
|
22
|
-
"homepage": "https://github.com/antharuu/klaim#readme",
|
|
23
|
-
"main": "dist/klaim.cjs.js",
|
|
24
|
-
"module": "dist/klaim.es.js",
|
|
25
|
-
"types": "dist/index.d.ts",
|
|
26
|
-
"exports": "./mod.ts",
|
|
27
|
-
"scripts": {
|
|
28
|
-
"build": "vite build",
|
|
29
|
-
"dev": "vite build --watch",
|
|
30
|
-
"test": "vitest",
|
|
31
|
-
"lint": "eslint src",
|
|
32
|
-
"lint:fix": "eslint src **/*.ts --fix",
|
|
33
|
-
"release": "dotenv release-it --"
|
|
34
|
-
},
|
|
35
|
-
"peerDependencies": {
|
|
36
|
-
"typescript": "^5.5.3"
|
|
37
|
-
}
|
|
38
|
-
}
|
|
1
|
+
{
|
|
2
|
+
"name": "@antharuu/klaim",
|
|
3
|
+
"version": "1.2.1",
|
|
4
|
+
"description": "Klaim is a lightweight TypeScript library designed to manage APIs and record requests, optimized for an optimal user experience.",
|
|
5
|
+
"repository": {
|
|
6
|
+
"type": "git",
|
|
7
|
+
"url": "https://github.com/antharuu/klaim.git"
|
|
8
|
+
},
|
|
9
|
+
"keywords": [
|
|
10
|
+
"typescript",
|
|
11
|
+
"api",
|
|
12
|
+
"request",
|
|
13
|
+
"user experience",
|
|
14
|
+
"optimization",
|
|
15
|
+
"lightweight"
|
|
16
|
+
],
|
|
17
|
+
"author": "antharuu",
|
|
18
|
+
"license": "MIT",
|
|
19
|
+
"bugs": {
|
|
20
|
+
"url": "https://github.com/antharuu/klaim/issues"
|
|
21
|
+
},
|
|
22
|
+
"homepage": "https://github.com/antharuu/klaim#readme",
|
|
23
|
+
"main": "dist/klaim.cjs.js",
|
|
24
|
+
"module": "dist/klaim.es.js",
|
|
25
|
+
"types": "dist/index.d.ts",
|
|
26
|
+
"exports": "./mod.ts",
|
|
27
|
+
"scripts": {
|
|
28
|
+
"build": "vite build",
|
|
29
|
+
"dev": "vite build --watch",
|
|
30
|
+
"test": "vitest",
|
|
31
|
+
"lint": "eslint src",
|
|
32
|
+
"lint:fix": "eslint src **/*.ts --fix",
|
|
33
|
+
"release": "dotenv release-it --"
|
|
34
|
+
},
|
|
35
|
+
"peerDependencies": {
|
|
36
|
+
"typescript": "^5.5.3"
|
|
37
|
+
}
|
|
38
|
+
}
|
package/eslint.config.mjs
CHANGED
|
@@ -1,210 +1,210 @@
|
|
|
1
|
-
// @ts-check
|
|
2
|
-
import stylistic from "@stylistic/eslint-plugin";
|
|
3
|
-
import simpleImportSort from "eslint-plugin-simple-import-sort";
|
|
4
|
-
import JSdoc from "eslint-plugin-jsdoc";
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
import eslint from '@eslint/js';
|
|
8
|
-
import tseslint from 'typescript-eslint';
|
|
9
|
-
|
|
10
|
-
export default tseslint.config(
|
|
11
|
-
eslint.configs.recommended,
|
|
12
|
-
...tseslint.configs.recommended,
|
|
13
|
-
{
|
|
14
|
-
plugins: {
|
|
15
|
-
"@stylistic": stylistic,
|
|
16
|
-
"simple-import-sort": simpleImportSort,
|
|
17
|
-
"jsdoc": JSdoc
|
|
18
|
-
},
|
|
19
|
-
files: ["src/**/*.ts"],
|
|
20
|
-
rules: {
|
|
21
|
-
// ----------------------------------------
|
|
22
|
-
// ---------------------- Simple Import Sort
|
|
23
|
-
// ----------------------------------------
|
|
24
|
-
"simple-import-sort/exports": "error",
|
|
25
|
-
"simple-import-sort/imports": [
|
|
26
|
-
"error",
|
|
27
|
-
{
|
|
28
|
-
"groups": [
|
|
29
|
-
["^\u0000"],
|
|
30
|
-
["^@?\\w"],
|
|
31
|
-
["^/"],
|
|
32
|
-
["^\\.\\.(?!/?$)", "^\\.\\./?$"],
|
|
33
|
-
[
|
|
34
|
-
"^\\./(?=.*/)(?!/?$)",
|
|
35
|
-
"^\\.(?!/?$)",
|
|
36
|
-
"^\\./?$"
|
|
37
|
-
],
|
|
38
|
-
["^.+\\.s?css$"]
|
|
39
|
-
]
|
|
40
|
-
}
|
|
41
|
-
],
|
|
42
|
-
// ----------------------------------------
|
|
43
|
-
// ---------------------- TypeScript
|
|
44
|
-
// ----------------------------------------
|
|
45
|
-
"@typescript-eslint/no-explicit-any": "off",
|
|
46
|
-
"@typescript-eslint/ban-ts-comment": "off",
|
|
47
|
-
"@typescript-eslint/no-dynamic-delete": "off",
|
|
48
|
-
"@typescript-eslint/no-namespace": "off",
|
|
49
|
-
"@typescript-eslint/ban-types": "error",
|
|
50
|
-
"@typescript-eslint/explicit-function-return-type": "error",
|
|
51
|
-
"@typescript-eslint/consistent-indexed-object-style": "error",
|
|
52
|
-
|
|
53
|
-
// ----------------------------------------
|
|
54
|
-
// ---------------------- Stylistic
|
|
55
|
-
// ----------------------------------------
|
|
56
|
-
"@stylistic/array-bracket-spacing": ["error", "always"],
|
|
57
|
-
"@stylistic/function-paren-newline": ["error", "multiline"],
|
|
58
|
-
"@stylistic/multiline-ternary": ["error", "always-multiline"],
|
|
59
|
-
"@stylistic/quotes": [
|
|
60
|
-
"error",
|
|
61
|
-
"double",
|
|
62
|
-
{
|
|
63
|
-
"avoidEscape": true, "allowTemplateLiterals": true
|
|
64
|
-
}
|
|
65
|
-
],
|
|
66
|
-
"@stylistic/semi": [
|
|
67
|
-
"error",
|
|
68
|
-
"always",
|
|
69
|
-
{
|
|
70
|
-
"omitLastInOneLineBlock": true, "omitLastInOneLineClassBody": true
|
|
71
|
-
}
|
|
72
|
-
],
|
|
73
|
-
"@stylistic/space-before-function-paren": ["error", "always"],
|
|
74
|
-
"@stylistic/space-in-parens": ["error", "never"],
|
|
75
|
-
"@stylistic/space-infix-ops": ["error", {"int32Hint": false}],
|
|
76
|
-
"@stylistic/space-before-blocks": ["error", "always"],
|
|
77
|
-
"@stylistic/space-unary-ops": ["error", {"words": true, "nonwords": false}],
|
|
78
|
-
"@stylistic/keyword-spacing": ["error", {"before": true, "after": true}],
|
|
79
|
-
"@stylistic/block-spacing": ["error", "always"],
|
|
80
|
-
"@stylistic/comma-dangle": ["error", "never"],
|
|
81
|
-
"@stylistic/array-bracket-newline": ["error", {"multiline": true}],
|
|
82
|
-
"@stylistic/array-element-newline": ["error", {"multiline": true, "minItems": 3}],
|
|
83
|
-
"@stylistic/object-curly-newline": ["error", {"multiline": true, "consistent": true}],
|
|
84
|
-
"@stylistic/max-len": [
|
|
85
|
-
"error",
|
|
86
|
-
{
|
|
87
|
-
"code": 120,
|
|
88
|
-
"tabWidth": 4,
|
|
89
|
-
"ignoreComments": true,
|
|
90
|
-
"ignoreUrls": true,
|
|
91
|
-
"ignoreStrings": true,
|
|
92
|
-
"ignoreTemplateLiterals": true,
|
|
93
|
-
"ignoreRegExpLiterals": true,
|
|
94
|
-
"ignorePattern": "d=.*"
|
|
95
|
-
}
|
|
96
|
-
],
|
|
97
|
-
"@stylistic/padded-blocks": ["error", "never"],
|
|
98
|
-
"@stylistic/no-multiple-empty-lines": ["error", {"max": 1, "maxEOF": 0}],
|
|
99
|
-
"@stylistic/eol-last": ["error", "always"],
|
|
100
|
-
"@stylistic/lines-between-class-members": ["error", "always"],
|
|
101
|
-
"@stylistic/brace-style": [
|
|
102
|
-
"error",
|
|
103
|
-
"1tbs",
|
|
104
|
-
{"allowSingleLine": true}
|
|
105
|
-
],
|
|
106
|
-
"@stylistic/object-curly-spacing": ["error", "always"],
|
|
107
|
-
"@stylistic/arrow-spacing": ["error", {"before": true, "after": true}],
|
|
108
|
-
"@stylistic/implicit-arrow-linebreak": ["error", "beside"],
|
|
109
|
-
"@stylistic/arrow-parens": ["error", "as-needed"],
|
|
110
|
-
"@stylistic/no-trailing-spaces": ["error"],
|
|
111
|
-
"@stylistic/no-tabs": ["error"],
|
|
112
|
-
"@stylistic/no-whitespace-before-property": ["error"],
|
|
113
|
-
"@stylistic/template-curly-spacing": ["error", "never"],
|
|
114
|
-
"@stylistic/rest-spread-spacing": ["error", "never"],
|
|
115
|
-
"@stylistic/operator-linebreak": ["error", "before"],
|
|
116
|
-
"@stylistic/type-annotation-spacing": [
|
|
117
|
-
"error",
|
|
118
|
-
{
|
|
119
|
-
"before": false, "after": true, "overrides": {
|
|
120
|
-
"arrow": {
|
|
121
|
-
"before": true, "after": true
|
|
122
|
-
}
|
|
123
|
-
}
|
|
124
|
-
}
|
|
125
|
-
],
|
|
126
|
-
"@stylistic/type-generic-spacing": ["error"],
|
|
127
|
-
"@stylistic/type-named-tuple-spacing": ["error"],
|
|
128
|
-
|
|
129
|
-
// ----------------------------------------
|
|
130
|
-
// ---------------------- JSdoc
|
|
131
|
-
// ----------------------------------------
|
|
132
|
-
"jsdoc/check-access": "error",
|
|
133
|
-
"jsdoc/check-alignment": "error",
|
|
134
|
-
"jsdoc/check-param-names": "error",
|
|
135
|
-
"jsdoc/check-property-names": "error",
|
|
136
|
-
"jsdoc/check-tag-names": "error",
|
|
137
|
-
"jsdoc/check-types": "error",
|
|
138
|
-
"jsdoc/check-values": "error",
|
|
139
|
-
"jsdoc/empty-tags": "error",
|
|
140
|
-
"jsdoc/implements-on-classes": "error",
|
|
141
|
-
"jsdoc/multiline-blocks": "error",
|
|
142
|
-
"jsdoc/no-defaults": "error",
|
|
143
|
-
"jsdoc/no-multi-asterisks": "error",
|
|
144
|
-
"jsdoc/require-jsdoc": [
|
|
145
|
-
"error",
|
|
146
|
-
{
|
|
147
|
-
"require": {
|
|
148
|
-
"FunctionDeclaration": true,
|
|
149
|
-
"MethodDefinition": true,
|
|
150
|
-
"ClassDeclaration": true,
|
|
151
|
-
"ArrowFunctionExpression": true,
|
|
152
|
-
"FunctionExpression": true
|
|
153
|
-
}
|
|
154
|
-
}
|
|
155
|
-
],
|
|
156
|
-
"jsdoc/require-param": "error",
|
|
157
|
-
"jsdoc/require-param-description": "error",
|
|
158
|
-
"jsdoc/require-param-name": "error",
|
|
159
|
-
"jsdoc/require-property": "error",
|
|
160
|
-
"jsdoc/require-property-description": "error",
|
|
161
|
-
"jsdoc/require-property-name": "error",
|
|
162
|
-
"jsdoc/require-returns": "error",
|
|
163
|
-
"jsdoc/require-returns-check": "error",
|
|
164
|
-
"jsdoc/require-returns-description": "error",
|
|
165
|
-
"jsdoc/require-yields": "error",
|
|
166
|
-
"jsdoc/require-yields-check": "error",
|
|
167
|
-
"jsdoc/tag-lines": [
|
|
168
|
-
"error",
|
|
169
|
-
"never",
|
|
170
|
-
{
|
|
171
|
-
"applyToEndTag": false,
|
|
172
|
-
"count": 1,
|
|
173
|
-
"startLines": 1,
|
|
174
|
-
"endLines": 0
|
|
175
|
-
}
|
|
176
|
-
],
|
|
177
|
-
"jsdoc/valid-types": "error",
|
|
178
|
-
|
|
179
|
-
// ----------------------------------------
|
|
180
|
-
// ---------------------- General
|
|
181
|
-
// ----------------------------------------
|
|
182
|
-
|
|
183
|
-
"no-void": "off",
|
|
184
|
-
"no-undef": "off",
|
|
185
|
-
"indent": ["error", 4],
|
|
186
|
-
"no-console": [
|
|
187
|
-
"error",
|
|
188
|
-
{
|
|
189
|
-
allow: [
|
|
190
|
-
"warn",
|
|
191
|
-
"error",
|
|
192
|
-
"info",
|
|
193
|
-
"table"
|
|
194
|
-
]
|
|
195
|
-
}
|
|
196
|
-
],
|
|
197
|
-
"camelcase": [
|
|
198
|
-
"error",
|
|
199
|
-
{
|
|
200
|
-
"properties": "never", "ignoreDestructuring": true, "allow": ["^_[a-z]+_[a-z]+$"]
|
|
201
|
-
}
|
|
202
|
-
],
|
|
203
|
-
"dot-notation": "off",
|
|
204
|
-
"no-underscore-dangle": "off",
|
|
205
|
-
"func-style": ["error", "declaration"]
|
|
206
|
-
|
|
207
|
-
}
|
|
208
|
-
}
|
|
209
|
-
);
|
|
210
|
-
|
|
1
|
+
// @ts-check
|
|
2
|
+
import stylistic from "@stylistic/eslint-plugin";
|
|
3
|
+
import simpleImportSort from "eslint-plugin-simple-import-sort";
|
|
4
|
+
import JSdoc from "eslint-plugin-jsdoc";
|
|
5
|
+
|
|
6
|
+
|
|
7
|
+
import eslint from '@eslint/js';
|
|
8
|
+
import tseslint from 'typescript-eslint';
|
|
9
|
+
|
|
10
|
+
export default tseslint.config(
|
|
11
|
+
eslint.configs.recommended,
|
|
12
|
+
...tseslint.configs.recommended,
|
|
13
|
+
{
|
|
14
|
+
plugins: {
|
|
15
|
+
"@stylistic": stylistic,
|
|
16
|
+
"simple-import-sort": simpleImportSort,
|
|
17
|
+
"jsdoc": JSdoc
|
|
18
|
+
},
|
|
19
|
+
files: ["src/**/*.ts"],
|
|
20
|
+
rules: {
|
|
21
|
+
// ----------------------------------------
|
|
22
|
+
// ---------------------- Simple Import Sort
|
|
23
|
+
// ----------------------------------------
|
|
24
|
+
"simple-import-sort/exports": "error",
|
|
25
|
+
"simple-import-sort/imports": [
|
|
26
|
+
"error",
|
|
27
|
+
{
|
|
28
|
+
"groups": [
|
|
29
|
+
["^\u0000"],
|
|
30
|
+
["^@?\\w"],
|
|
31
|
+
["^/"],
|
|
32
|
+
["^\\.\\.(?!/?$)", "^\\.\\./?$"],
|
|
33
|
+
[
|
|
34
|
+
"^\\./(?=.*/)(?!/?$)",
|
|
35
|
+
"^\\.(?!/?$)",
|
|
36
|
+
"^\\./?$"
|
|
37
|
+
],
|
|
38
|
+
["^.+\\.s?css$"]
|
|
39
|
+
]
|
|
40
|
+
}
|
|
41
|
+
],
|
|
42
|
+
// ----------------------------------------
|
|
43
|
+
// ---------------------- TypeScript
|
|
44
|
+
// ----------------------------------------
|
|
45
|
+
"@typescript-eslint/no-explicit-any": "off",
|
|
46
|
+
"@typescript-eslint/ban-ts-comment": "off",
|
|
47
|
+
"@typescript-eslint/no-dynamic-delete": "off",
|
|
48
|
+
"@typescript-eslint/no-namespace": "off",
|
|
49
|
+
"@typescript-eslint/ban-types": "error",
|
|
50
|
+
"@typescript-eslint/explicit-function-return-type": "error",
|
|
51
|
+
"@typescript-eslint/consistent-indexed-object-style": "error",
|
|
52
|
+
|
|
53
|
+
// ----------------------------------------
|
|
54
|
+
// ---------------------- Stylistic
|
|
55
|
+
// ----------------------------------------
|
|
56
|
+
"@stylistic/array-bracket-spacing": ["error", "always"],
|
|
57
|
+
"@stylistic/function-paren-newline": ["error", "multiline"],
|
|
58
|
+
"@stylistic/multiline-ternary": ["error", "always-multiline"],
|
|
59
|
+
"@stylistic/quotes": [
|
|
60
|
+
"error",
|
|
61
|
+
"double",
|
|
62
|
+
{
|
|
63
|
+
"avoidEscape": true, "allowTemplateLiterals": true
|
|
64
|
+
}
|
|
65
|
+
],
|
|
66
|
+
"@stylistic/semi": [
|
|
67
|
+
"error",
|
|
68
|
+
"always",
|
|
69
|
+
{
|
|
70
|
+
"omitLastInOneLineBlock": true, "omitLastInOneLineClassBody": true
|
|
71
|
+
}
|
|
72
|
+
],
|
|
73
|
+
"@stylistic/space-before-function-paren": ["error", "always"],
|
|
74
|
+
"@stylistic/space-in-parens": ["error", "never"],
|
|
75
|
+
"@stylistic/space-infix-ops": ["error", {"int32Hint": false}],
|
|
76
|
+
"@stylistic/space-before-blocks": ["error", "always"],
|
|
77
|
+
"@stylistic/space-unary-ops": ["error", {"words": true, "nonwords": false}],
|
|
78
|
+
"@stylistic/keyword-spacing": ["error", {"before": true, "after": true}],
|
|
79
|
+
"@stylistic/block-spacing": ["error", "always"],
|
|
80
|
+
"@stylistic/comma-dangle": ["error", "never"],
|
|
81
|
+
"@stylistic/array-bracket-newline": ["error", {"multiline": true}],
|
|
82
|
+
"@stylistic/array-element-newline": ["error", {"multiline": true, "minItems": 3}],
|
|
83
|
+
"@stylistic/object-curly-newline": ["error", {"multiline": true, "consistent": true}],
|
|
84
|
+
"@stylistic/max-len": [
|
|
85
|
+
"error",
|
|
86
|
+
{
|
|
87
|
+
"code": 120,
|
|
88
|
+
"tabWidth": 4,
|
|
89
|
+
"ignoreComments": true,
|
|
90
|
+
"ignoreUrls": true,
|
|
91
|
+
"ignoreStrings": true,
|
|
92
|
+
"ignoreTemplateLiterals": true,
|
|
93
|
+
"ignoreRegExpLiterals": true,
|
|
94
|
+
"ignorePattern": "d=.*"
|
|
95
|
+
}
|
|
96
|
+
],
|
|
97
|
+
"@stylistic/padded-blocks": ["error", "never"],
|
|
98
|
+
"@stylistic/no-multiple-empty-lines": ["error", {"max": 1, "maxEOF": 0}],
|
|
99
|
+
"@stylistic/eol-last": ["error", "always"],
|
|
100
|
+
"@stylistic/lines-between-class-members": ["error", "always"],
|
|
101
|
+
"@stylistic/brace-style": [
|
|
102
|
+
"error",
|
|
103
|
+
"1tbs",
|
|
104
|
+
{"allowSingleLine": true}
|
|
105
|
+
],
|
|
106
|
+
"@stylistic/object-curly-spacing": ["error", "always"],
|
|
107
|
+
"@stylistic/arrow-spacing": ["error", {"before": true, "after": true}],
|
|
108
|
+
"@stylistic/implicit-arrow-linebreak": ["error", "beside"],
|
|
109
|
+
"@stylistic/arrow-parens": ["error", "as-needed"],
|
|
110
|
+
"@stylistic/no-trailing-spaces": ["error"],
|
|
111
|
+
"@stylistic/no-tabs": ["error"],
|
|
112
|
+
"@stylistic/no-whitespace-before-property": ["error"],
|
|
113
|
+
"@stylistic/template-curly-spacing": ["error", "never"],
|
|
114
|
+
"@stylistic/rest-spread-spacing": ["error", "never"],
|
|
115
|
+
"@stylistic/operator-linebreak": ["error", "before"],
|
|
116
|
+
"@stylistic/type-annotation-spacing": [
|
|
117
|
+
"error",
|
|
118
|
+
{
|
|
119
|
+
"before": false, "after": true, "overrides": {
|
|
120
|
+
"arrow": {
|
|
121
|
+
"before": true, "after": true
|
|
122
|
+
}
|
|
123
|
+
}
|
|
124
|
+
}
|
|
125
|
+
],
|
|
126
|
+
"@stylistic/type-generic-spacing": ["error"],
|
|
127
|
+
"@stylistic/type-named-tuple-spacing": ["error"],
|
|
128
|
+
|
|
129
|
+
// ----------------------------------------
|
|
130
|
+
// ---------------------- JSdoc
|
|
131
|
+
// ----------------------------------------
|
|
132
|
+
"jsdoc/check-access": "error",
|
|
133
|
+
"jsdoc/check-alignment": "error",
|
|
134
|
+
"jsdoc/check-param-names": "error",
|
|
135
|
+
"jsdoc/check-property-names": "error",
|
|
136
|
+
"jsdoc/check-tag-names": "error",
|
|
137
|
+
"jsdoc/check-types": "error",
|
|
138
|
+
"jsdoc/check-values": "error",
|
|
139
|
+
"jsdoc/empty-tags": "error",
|
|
140
|
+
"jsdoc/implements-on-classes": "error",
|
|
141
|
+
"jsdoc/multiline-blocks": "error",
|
|
142
|
+
"jsdoc/no-defaults": "error",
|
|
143
|
+
"jsdoc/no-multi-asterisks": "error",
|
|
144
|
+
"jsdoc/require-jsdoc": [
|
|
145
|
+
"error",
|
|
146
|
+
{
|
|
147
|
+
"require": {
|
|
148
|
+
"FunctionDeclaration": true,
|
|
149
|
+
"MethodDefinition": true,
|
|
150
|
+
"ClassDeclaration": true,
|
|
151
|
+
"ArrowFunctionExpression": true,
|
|
152
|
+
"FunctionExpression": true
|
|
153
|
+
}
|
|
154
|
+
}
|
|
155
|
+
],
|
|
156
|
+
"jsdoc/require-param": "error",
|
|
157
|
+
"jsdoc/require-param-description": "error",
|
|
158
|
+
"jsdoc/require-param-name": "error",
|
|
159
|
+
"jsdoc/require-property": "error",
|
|
160
|
+
"jsdoc/require-property-description": "error",
|
|
161
|
+
"jsdoc/require-property-name": "error",
|
|
162
|
+
"jsdoc/require-returns": "error",
|
|
163
|
+
"jsdoc/require-returns-check": "error",
|
|
164
|
+
"jsdoc/require-returns-description": "error",
|
|
165
|
+
"jsdoc/require-yields": "error",
|
|
166
|
+
"jsdoc/require-yields-check": "error",
|
|
167
|
+
"jsdoc/tag-lines": [
|
|
168
|
+
"error",
|
|
169
|
+
"never",
|
|
170
|
+
{
|
|
171
|
+
"applyToEndTag": false,
|
|
172
|
+
"count": 1,
|
|
173
|
+
"startLines": 1,
|
|
174
|
+
"endLines": 0
|
|
175
|
+
}
|
|
176
|
+
],
|
|
177
|
+
"jsdoc/valid-types": "error",
|
|
178
|
+
|
|
179
|
+
// ----------------------------------------
|
|
180
|
+
// ---------------------- General
|
|
181
|
+
// ----------------------------------------
|
|
182
|
+
|
|
183
|
+
"no-void": "off",
|
|
184
|
+
"no-undef": "off",
|
|
185
|
+
"indent": ["error", 4],
|
|
186
|
+
"no-console": [
|
|
187
|
+
"error",
|
|
188
|
+
{
|
|
189
|
+
allow: [
|
|
190
|
+
"warn",
|
|
191
|
+
"error",
|
|
192
|
+
"info",
|
|
193
|
+
"table"
|
|
194
|
+
]
|
|
195
|
+
}
|
|
196
|
+
],
|
|
197
|
+
"camelcase": [
|
|
198
|
+
"error",
|
|
199
|
+
{
|
|
200
|
+
"properties": "never", "ignoreDestructuring": true, "allow": ["^_[a-z]+_[a-z]+$"]
|
|
201
|
+
}
|
|
202
|
+
],
|
|
203
|
+
"dot-notation": "off",
|
|
204
|
+
"no-underscore-dangle": "off",
|
|
205
|
+
"func-style": ["error", "declaration"]
|
|
206
|
+
|
|
207
|
+
}
|
|
208
|
+
}
|
|
209
|
+
);
|
|
210
|
+
|
package/index.ts
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
export * from './src';
|
|
2
|
-
|
|
1
|
+
export * from './src';
|
|
2
|
+
|
package/load-env.cjs
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
require('dotenv').config();
|
package/mod.ts
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
export * from './src';
|
|
2
|
-
|
|
1
|
+
export * from './src';
|
|
2
|
+
|
package/package.json
CHANGED
|
@@ -20,7 +20,7 @@
|
|
|
20
20
|
},
|
|
21
21
|
"homepage": "https://github.com/antharuu/klaim#readme",
|
|
22
22
|
"type": "module",
|
|
23
|
-
"version": "1.2.
|
|
23
|
+
"version": "1.2.12",
|
|
24
24
|
"main": "dist/klaim.cjs.js",
|
|
25
25
|
"module": "dist/klaim.es.js",
|
|
26
26
|
"types": "dist/index.d.ts",
|
|
@@ -30,7 +30,9 @@
|
|
|
30
30
|
"test": "vitest",
|
|
31
31
|
"lint": "eslint src",
|
|
32
32
|
"lint:fix": "eslint src **/*.ts --fix",
|
|
33
|
-
"release": "
|
|
33
|
+
"release": "release-it patch --config release-it.config.cjs",
|
|
34
|
+
"release:minor": "release-it minor --config release-it.config.cjs",
|
|
35
|
+
"release:major": "release-it major --config release-it.config.cjs"
|
|
34
36
|
},
|
|
35
37
|
"devDependencies": {
|
|
36
38
|
"@eslint/js": "^9.6.0",
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
// release-it.config.cjs
|
|
2
|
+
require('./load-env.cjs');
|
|
3
|
+
|
|
4
|
+
module.exports = {
|
|
5
|
+
github: {
|
|
6
|
+
release: true,
|
|
7
|
+
tokenRef: 'GITHUB_TOKEN'
|
|
8
|
+
},
|
|
9
|
+
npm: {
|
|
10
|
+
publish: true,
|
|
11
|
+
tokenRef: 'NPM_TOKEN'
|
|
12
|
+
},
|
|
13
|
+
git: {
|
|
14
|
+
requiredBranch: 'main',
|
|
15
|
+
requireCleanWorkingDir: false,
|
|
16
|
+
commitMessage: 'chore: release v%s'
|
|
17
|
+
},
|
|
18
|
+
hooks: {
|
|
19
|
+
'before:init': [
|
|
20
|
+
'git pull',
|
|
21
|
+
'bun run lint',
|
|
22
|
+
'bun run build'
|
|
23
|
+
],
|
|
24
|
+
'after:bump': [
|
|
25
|
+
`npx jsr publish --token ${process.env.JSR_TOKEN} --allow-dirty`
|
|
26
|
+
]
|
|
27
|
+
}
|
|
28
|
+
};
|
package/src/core/Api.ts
CHANGED
|
@@ -1,63 +1,63 @@
|
|
|
1
|
-
import cleanUrl from "../tools/cleanUrl";
|
|
2
|
-
import toCamelCase from "../tools/toCamelCase";
|
|
3
|
-
|
|
4
|
-
import { Registry } from "./Registry";
|
|
5
|
-
import { Route } from "./Route";
|
|
6
|
-
|
|
7
|
-
interface IApi {
|
|
8
|
-
name: string;
|
|
9
|
-
url: string;
|
|
10
|
-
headers: IHeaders;
|
|
11
|
-
routes: Map<string, Route>;
|
|
12
|
-
}
|
|
13
|
-
|
|
14
|
-
export type IApiCallback = () => void;
|
|
15
|
-
export type IHeaders = Record<string, string>;
|
|
16
|
-
|
|
17
|
-
/**
|
|
18
|
-
* Represents an API
|
|
19
|
-
*/
|
|
20
|
-
export class Api implements IApi {
|
|
21
|
-
public name: string;
|
|
22
|
-
|
|
23
|
-
public url: string;
|
|
24
|
-
|
|
25
|
-
public headers: IHeaders;
|
|
26
|
-
|
|
27
|
-
public routes: Map<string, Route> = new Map<string, Route>();
|
|
28
|
-
|
|
29
|
-
/**
|
|
30
|
-
* Constructor
|
|
31
|
-
*
|
|
32
|
-
* @param name - The name of the API
|
|
33
|
-
* @param url - The base URL of the API
|
|
34
|
-
* @param headers - The headers to be sent with each request
|
|
35
|
-
*/
|
|
36
|
-
private constructor (name: string, url: string, headers: IHeaders) {
|
|
37
|
-
this.name = name;
|
|
38
|
-
this.url = cleanUrl(url);
|
|
39
|
-
this.headers = headers || {};
|
|
40
|
-
}
|
|
41
|
-
|
|
42
|
-
/**
|
|
43
|
-
* Creates a new API
|
|
44
|
-
*
|
|
45
|
-
* @param name - The name of the API
|
|
46
|
-
* @param url - The base URL of the API
|
|
47
|
-
* @param callback - The callback to define the routes
|
|
48
|
-
* @param headers - The headers to be sent with each request
|
|
49
|
-
* @returns The new API
|
|
50
|
-
*/
|
|
51
|
-
public static create (name: string, url: string, callback: IApiCallback, headers: IHeaders = {}): Api {
|
|
52
|
-
const newName = toCamelCase(name);
|
|
53
|
-
if (newName !== name) {
|
|
54
|
-
console.warn(`API name "${name}" has been camelCased to "${newName}"`);
|
|
55
|
-
}
|
|
56
|
-
const api = new Api(newName, url, headers);
|
|
57
|
-
Registry.i.registerApi(api);
|
|
58
|
-
Registry.i.setCurrent(newName);
|
|
59
|
-
callback();
|
|
60
|
-
Registry.i.clearCurrent();
|
|
61
|
-
return api;
|
|
62
|
-
}
|
|
63
|
-
}
|
|
1
|
+
import cleanUrl from "../tools/cleanUrl";
|
|
2
|
+
import toCamelCase from "../tools/toCamelCase";
|
|
3
|
+
|
|
4
|
+
import { Registry } from "./Registry";
|
|
5
|
+
import { Route } from "./Route";
|
|
6
|
+
|
|
7
|
+
interface IApi {
|
|
8
|
+
name: string;
|
|
9
|
+
url: string;
|
|
10
|
+
headers: IHeaders;
|
|
11
|
+
routes: Map<string, Route>;
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
export type IApiCallback = () => void;
|
|
15
|
+
export type IHeaders = Record<string, string>;
|
|
16
|
+
|
|
17
|
+
/**
|
|
18
|
+
* Represents an API
|
|
19
|
+
*/
|
|
20
|
+
export class Api implements IApi {
|
|
21
|
+
public name: string;
|
|
22
|
+
|
|
23
|
+
public url: string;
|
|
24
|
+
|
|
25
|
+
public headers: IHeaders;
|
|
26
|
+
|
|
27
|
+
public routes: Map<string, Route> = new Map<string, Route>();
|
|
28
|
+
|
|
29
|
+
/**
|
|
30
|
+
* Constructor
|
|
31
|
+
*
|
|
32
|
+
* @param name - The name of the API
|
|
33
|
+
* @param url - The base URL of the API
|
|
34
|
+
* @param headers - The headers to be sent with each request
|
|
35
|
+
*/
|
|
36
|
+
private constructor (name: string, url: string, headers: IHeaders) {
|
|
37
|
+
this.name = name;
|
|
38
|
+
this.url = cleanUrl(url);
|
|
39
|
+
this.headers = headers || {};
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
/**
|
|
43
|
+
* Creates a new API
|
|
44
|
+
*
|
|
45
|
+
* @param name - The name of the API
|
|
46
|
+
* @param url - The base URL of the API
|
|
47
|
+
* @param callback - The callback to define the routes
|
|
48
|
+
* @param headers - The headers to be sent with each request
|
|
49
|
+
* @returns The new API
|
|
50
|
+
*/
|
|
51
|
+
public static create (name: string, url: string, callback: IApiCallback, headers: IHeaders = {}): Api {
|
|
52
|
+
const newName = toCamelCase(name);
|
|
53
|
+
if (newName !== name) {
|
|
54
|
+
console.warn(`API name "${name}" has been camelCased to "${newName}"`);
|
|
55
|
+
}
|
|
56
|
+
const api = new Api(newName, url, headers);
|
|
57
|
+
Registry.i.registerApi(api);
|
|
58
|
+
Registry.i.setCurrent(newName);
|
|
59
|
+
callback();
|
|
60
|
+
Registry.i.clearCurrent();
|
|
61
|
+
return api;
|
|
62
|
+
}
|
|
63
|
+
}
|
package/src/core/Hook.ts
CHANGED
|
@@ -1,32 +1,32 @@
|
|
|
1
|
-
type IHookCallback = () => any;
|
|
2
|
-
|
|
3
|
-
/**
|
|
4
|
-
* Represents hooks
|
|
5
|
-
*/
|
|
6
|
-
export class Hook {
|
|
7
|
-
private static _callbacks: Map<string, IHookCallback> = new Map<string, IHookCallback>();
|
|
8
|
-
|
|
9
|
-
/**
|
|
10
|
-
* Subscribes to the hook
|
|
11
|
-
*
|
|
12
|
-
* @param routeName - The name of the route to subscribe to
|
|
13
|
-
* @param callback - The callback to subscribe
|
|
14
|
-
*/
|
|
15
|
-
public static subscribe (routeName: string, callback: IHookCallback): void {
|
|
16
|
-
this._callbacks.set(routeName, callback);
|
|
17
|
-
}
|
|
18
|
-
|
|
19
|
-
/**
|
|
20
|
-
* Runs the hook
|
|
21
|
-
*
|
|
22
|
-
* @param routeName - The name of the route to run
|
|
23
|
-
*/
|
|
24
|
-
public static run (routeName: string): void {
|
|
25
|
-
const callback = this._callbacks.get(routeName);
|
|
26
|
-
if (!callback) {
|
|
27
|
-
return;
|
|
28
|
-
}
|
|
29
|
-
|
|
30
|
-
callback();
|
|
31
|
-
}
|
|
32
|
-
}
|
|
1
|
+
type IHookCallback = () => any;
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Represents hooks
|
|
5
|
+
*/
|
|
6
|
+
export class Hook {
|
|
7
|
+
private static _callbacks: Map<string, IHookCallback> = new Map<string, IHookCallback>();
|
|
8
|
+
|
|
9
|
+
/**
|
|
10
|
+
* Subscribes to the hook
|
|
11
|
+
*
|
|
12
|
+
* @param routeName - The name of the route to subscribe to
|
|
13
|
+
* @param callback - The callback to subscribe
|
|
14
|
+
*/
|
|
15
|
+
public static subscribe (routeName: string, callback: IHookCallback): void {
|
|
16
|
+
this._callbacks.set(routeName, callback);
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
/**
|
|
20
|
+
* Runs the hook
|
|
21
|
+
*
|
|
22
|
+
* @param routeName - The name of the route to run
|
|
23
|
+
*/
|
|
24
|
+
public static run (routeName: string): void {
|
|
25
|
+
const callback = this._callbacks.get(routeName);
|
|
26
|
+
if (!callback) {
|
|
27
|
+
return;
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
callback();
|
|
31
|
+
}
|
|
32
|
+
}
|
package/src/index.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
export { Api } from "./core/Api";
|
|
2
|
-
export { Hook } from "./core/Hook";
|
|
3
|
-
export { Klaim } from "./core/Klaim";
|
|
4
|
-
export { Registry } from "./core/Registry";
|
|
5
|
-
export { Route } from "./core/Route";
|
|
1
|
+
export { Api } from "./core/Api";
|
|
2
|
+
export { Hook } from "./core/Hook";
|
|
3
|
+
export { Klaim } from "./core/Klaim";
|
|
4
|
+
export { Registry } from "./core/Registry";
|
|
5
|
+
export { Route } from "./core/Route";
|
package/src/tools/cleanUrl.ts
CHANGED
|
@@ -1,12 +1,12 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Clean the URL by removing slashes at the beginning and end of the string.
|
|
3
|
-
*
|
|
4
|
-
* @param url - The URL to clean
|
|
5
|
-
* @returns The cleaned URL
|
|
6
|
-
*/
|
|
7
|
-
export default function (url: string): string {
|
|
8
|
-
return url
|
|
9
|
-
.trim()
|
|
10
|
-
// remove slashes at the beginning and end of the string
|
|
11
|
-
.replace(/^\/|\/$/g, "");
|
|
12
|
-
}
|
|
1
|
+
/**
|
|
2
|
+
* Clean the URL by removing slashes at the beginning and end of the string.
|
|
3
|
+
*
|
|
4
|
+
* @param url - The URL to clean
|
|
5
|
+
* @returns The cleaned URL
|
|
6
|
+
*/
|
|
7
|
+
export default function (url: string): string {
|
|
8
|
+
return url
|
|
9
|
+
.trim()
|
|
10
|
+
// remove slashes at the beginning and end of the string
|
|
11
|
+
.replace(/^\/|\/$/g, "");
|
|
12
|
+
}
|
package/src/tools/slugify.ts
CHANGED
|
@@ -1,17 +1,17 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Slugify a text
|
|
3
|
-
*
|
|
4
|
-
* @param text - The text to slugify
|
|
5
|
-
* @param splitCharacter - The character to use to split the text
|
|
6
|
-
* @returns The slugified text
|
|
7
|
-
*/
|
|
8
|
-
export default function (text: string, splitCharacter: string = "_"): string {
|
|
9
|
-
return text
|
|
10
|
-
.toString()
|
|
11
|
-
.normalize("NFD") // split an accented letter in the base letter and the acent
|
|
12
|
-
.replace(/[\u0300-\u036f]/g, "") // remove all previously split accents
|
|
13
|
-
.toLowerCase()
|
|
14
|
-
.trim()
|
|
15
|
-
.replace(/[^a-z0-9 ]/g, "") // remove all chars not letters, numbers and spaces (to be replaced)
|
|
16
|
-
.replace(/\s+/g, splitCharacter); // separator
|
|
17
|
-
}
|
|
1
|
+
/**
|
|
2
|
+
* Slugify a text
|
|
3
|
+
*
|
|
4
|
+
* @param text - The text to slugify
|
|
5
|
+
* @param splitCharacter - The character to use to split the text
|
|
6
|
+
* @returns The slugified text
|
|
7
|
+
*/
|
|
8
|
+
export default function (text: string, splitCharacter: string = "_"): string {
|
|
9
|
+
return text
|
|
10
|
+
.toString()
|
|
11
|
+
.normalize("NFD") // split an accented letter in the base letter and the acent
|
|
12
|
+
.replace(/[\u0300-\u036f]/g, "") // remove all previously split accents
|
|
13
|
+
.toLowerCase()
|
|
14
|
+
.trim()
|
|
15
|
+
.replace(/[^a-z0-9 ]/g, "") // remove all chars not letters, numbers and spaces (to be replaced)
|
|
16
|
+
.replace(/\s+/g, splitCharacter); // separator
|
|
17
|
+
}
|
package/src/tools/toCamelCase.ts
CHANGED
|
@@ -1,11 +1,11 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Convert a string to camel case
|
|
3
|
-
*
|
|
4
|
-
* @param text - The text to convert
|
|
5
|
-
* @returns The text in camel case
|
|
6
|
-
*/
|
|
7
|
-
export default function (text: string): string {
|
|
8
|
-
return text
|
|
9
|
-
.replace(/([-_][a-z])/gi, match => match.toUpperCase().replace("-", "").replace("_", ""))
|
|
10
|
-
.replace(/(^\w)/, match => match.toLowerCase());
|
|
11
|
-
}
|
|
1
|
+
/**
|
|
2
|
+
* Convert a string to camel case
|
|
3
|
+
*
|
|
4
|
+
* @param text - The text to convert
|
|
5
|
+
* @returns The text in camel case
|
|
6
|
+
*/
|
|
7
|
+
export default function (text: string): string {
|
|
8
|
+
return text
|
|
9
|
+
.replace(/([-_][a-z])/gi, match => match.toUpperCase().replace("-", "").replace("_", ""))
|
|
10
|
+
.replace(/(^\w)/, match => match.toLowerCase());
|
|
11
|
+
}
|
package/src/tools/token.ts
CHANGED
|
@@ -1,14 +1,14 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Generate a new token
|
|
3
|
-
*
|
|
4
|
-
* @param {number} length The length of the token
|
|
5
|
-
* @returns {string} The generated token
|
|
6
|
-
*/
|
|
7
|
-
export default function (length?: number): string {
|
|
8
|
-
const chars = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789";
|
|
9
|
-
let token = "";
|
|
10
|
-
for (let i = 0; i < (length || 32); i++) {
|
|
11
|
-
token += chars.charAt(Math.floor(Math.random() * chars.length));
|
|
12
|
-
}
|
|
13
|
-
return token;
|
|
14
|
-
}
|
|
1
|
+
/**
|
|
2
|
+
* Generate a new token
|
|
3
|
+
*
|
|
4
|
+
* @param {number} length The length of the token
|
|
5
|
+
* @returns {string} The generated token
|
|
6
|
+
*/
|
|
7
|
+
export default function (length?: number): string {
|
|
8
|
+
const chars = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789";
|
|
9
|
+
let token = "";
|
|
10
|
+
for (let i = 0; i < (length || 32); i++) {
|
|
11
|
+
token += chars.charAt(Math.floor(Math.random() * chars.length));
|
|
12
|
+
}
|
|
13
|
+
return token;
|
|
14
|
+
}
|
package/tests/arguments.test.ts
CHANGED
|
@@ -1,89 +1,89 @@
|
|
|
1
|
-
import {describe, expect, it, vi} from 'vitest';
|
|
2
|
-
import {Route, RouteArgumentType} from '../src/core/Route';
|
|
3
|
-
|
|
4
|
-
// Mocks
|
|
5
|
-
vi.mock('../tools/token', () => ({
|
|
6
|
-
default: vi.fn(() => 'mocked-token'),
|
|
7
|
-
}));
|
|
8
|
-
|
|
9
|
-
vi.mock('../tools/slugify', () => ({
|
|
10
|
-
default: vi.fn((str: string) => str.replace(/\s+/g, '-').toLowerCase()),
|
|
11
|
-
}));
|
|
12
|
-
|
|
13
|
-
describe('Route.detectArgumentsOfUrl', () => {
|
|
14
|
-
it('should detect arguments of type ANY', () => {
|
|
15
|
-
const route = new Route('/user/[id]');
|
|
16
|
-
const args = route._arguments;
|
|
17
|
-
|
|
18
|
-
expect(args.size).toBe(1);
|
|
19
|
-
expect(Array.from(args)).toEqual([
|
|
20
|
-
{name: 'id', type: RouteArgumentType.ANY, default: null, required: true},
|
|
21
|
-
]);
|
|
22
|
-
});
|
|
23
|
-
|
|
24
|
-
it('should detect multiple arguments', () => {
|
|
25
|
-
const route = new Route('/posts/[post]/comments/[comment]');
|
|
26
|
-
const args = route._arguments;
|
|
27
|
-
|
|
28
|
-
expect(args.size).toBe(2);
|
|
29
|
-
expect(Array.from(args)).toEqual([
|
|
30
|
-
{name: 'post', type: RouteArgumentType.ANY, default: null, required: true},
|
|
31
|
-
{name: 'comment', type: RouteArgumentType.ANY, default: null, required: true},
|
|
32
|
-
]);
|
|
33
|
-
});
|
|
34
|
-
|
|
35
|
-
it('should detect arguments with specific types', () => {
|
|
36
|
-
const route = new Route('/user/[id:number]');
|
|
37
|
-
const args = route._arguments;
|
|
38
|
-
|
|
39
|
-
expect(args.size).toBe(1);
|
|
40
|
-
expect(Array.from(args)).toEqual([
|
|
41
|
-
{name: 'id', type: RouteArgumentType.NUMBER, default: null, required: true},
|
|
42
|
-
]);
|
|
43
|
-
});
|
|
44
|
-
|
|
45
|
-
it('should detect arguments with default values', () => {
|
|
46
|
-
const route = new Route('/user/[id:number=1]');
|
|
47
|
-
const args = route._arguments;
|
|
48
|
-
|
|
49
|
-
expect(args.size).toBe(1);
|
|
50
|
-
expect(Array.from(args)).toEqual([
|
|
51
|
-
{name: 'id', type: RouteArgumentType.NUMBER, default: 1, required: true},
|
|
52
|
-
]);
|
|
53
|
-
});
|
|
54
|
-
|
|
55
|
-
it('should detect optional arguments', () => {
|
|
56
|
-
const route = new Route('/user/[name?]');
|
|
57
|
-
const args = route._arguments;
|
|
58
|
-
|
|
59
|
-
expect(args.size).toBe(1);
|
|
60
|
-
expect(Array.from(args)).toEqual([
|
|
61
|
-
{name: 'name', type: RouteArgumentType.ANY, default: null, required: false},
|
|
62
|
-
]);
|
|
63
|
-
});
|
|
64
|
-
|
|
65
|
-
it('should detect multiple arguments with different types', () => {
|
|
66
|
-
const route = new Route('/profile/[user:string]/settings/[setting:boolean]');
|
|
67
|
-
const args = route._arguments;
|
|
68
|
-
|
|
69
|
-
expect(args.size).toBe(2);
|
|
70
|
-
expect(Array.from(args)).toEqual([
|
|
71
|
-
{name: 'user', type: RouteArgumentType.STRING, default: null, required: true},
|
|
72
|
-
{name: 'setting', type: RouteArgumentType.BOOLEAN, default: null, required: true},
|
|
73
|
-
]);
|
|
74
|
-
});
|
|
75
|
-
|
|
76
|
-
it('should handle invalid JSON in default value gracefully', () => {
|
|
77
|
-
const consoleSpy = vi.spyOn(console, 'warn').mockImplementation(() => {
|
|
78
|
-
});
|
|
79
|
-
const route = new Route('/user/[id:number=invalid]');
|
|
80
|
-
const args = route._arguments;
|
|
81
|
-
|
|
82
|
-
expect(args.size).toBe(1);
|
|
83
|
-
expect(Array.from(args)).toEqual([
|
|
84
|
-
{name: 'id', type: RouteArgumentType.NUMBER, default: 'invalid', required: true},
|
|
85
|
-
]);
|
|
86
|
-
expect(consoleSpy).toHaveBeenCalled();
|
|
87
|
-
consoleSpy.mockRestore();
|
|
88
|
-
});
|
|
89
|
-
});
|
|
1
|
+
import {describe, expect, it, vi} from 'vitest';
|
|
2
|
+
import {Route, RouteArgumentType} from '../src/core/Route';
|
|
3
|
+
|
|
4
|
+
// Mocks
|
|
5
|
+
vi.mock('../tools/token', () => ({
|
|
6
|
+
default: vi.fn(() => 'mocked-token'),
|
|
7
|
+
}));
|
|
8
|
+
|
|
9
|
+
vi.mock('../tools/slugify', () => ({
|
|
10
|
+
default: vi.fn((str: string) => str.replace(/\s+/g, '-').toLowerCase()),
|
|
11
|
+
}));
|
|
12
|
+
|
|
13
|
+
describe('Route.detectArgumentsOfUrl', () => {
|
|
14
|
+
it('should detect arguments of type ANY', () => {
|
|
15
|
+
const route = new Route('/user/[id]');
|
|
16
|
+
const args = route._arguments;
|
|
17
|
+
|
|
18
|
+
expect(args.size).toBe(1);
|
|
19
|
+
expect(Array.from(args)).toEqual([
|
|
20
|
+
{name: 'id', type: RouteArgumentType.ANY, default: null, required: true},
|
|
21
|
+
]);
|
|
22
|
+
});
|
|
23
|
+
|
|
24
|
+
it('should detect multiple arguments', () => {
|
|
25
|
+
const route = new Route('/posts/[post]/comments/[comment]');
|
|
26
|
+
const args = route._arguments;
|
|
27
|
+
|
|
28
|
+
expect(args.size).toBe(2);
|
|
29
|
+
expect(Array.from(args)).toEqual([
|
|
30
|
+
{name: 'post', type: RouteArgumentType.ANY, default: null, required: true},
|
|
31
|
+
{name: 'comment', type: RouteArgumentType.ANY, default: null, required: true},
|
|
32
|
+
]);
|
|
33
|
+
});
|
|
34
|
+
|
|
35
|
+
it('should detect arguments with specific types', () => {
|
|
36
|
+
const route = new Route('/user/[id:number]');
|
|
37
|
+
const args = route._arguments;
|
|
38
|
+
|
|
39
|
+
expect(args.size).toBe(1);
|
|
40
|
+
expect(Array.from(args)).toEqual([
|
|
41
|
+
{name: 'id', type: RouteArgumentType.NUMBER, default: null, required: true},
|
|
42
|
+
]);
|
|
43
|
+
});
|
|
44
|
+
|
|
45
|
+
it('should detect arguments with default values', () => {
|
|
46
|
+
const route = new Route('/user/[id:number=1]');
|
|
47
|
+
const args = route._arguments;
|
|
48
|
+
|
|
49
|
+
expect(args.size).toBe(1);
|
|
50
|
+
expect(Array.from(args)).toEqual([
|
|
51
|
+
{name: 'id', type: RouteArgumentType.NUMBER, default: 1, required: true},
|
|
52
|
+
]);
|
|
53
|
+
});
|
|
54
|
+
|
|
55
|
+
it('should detect optional arguments', () => {
|
|
56
|
+
const route = new Route('/user/[name?]');
|
|
57
|
+
const args = route._arguments;
|
|
58
|
+
|
|
59
|
+
expect(args.size).toBe(1);
|
|
60
|
+
expect(Array.from(args)).toEqual([
|
|
61
|
+
{name: 'name', type: RouteArgumentType.ANY, default: null, required: false},
|
|
62
|
+
]);
|
|
63
|
+
});
|
|
64
|
+
|
|
65
|
+
it('should detect multiple arguments with different types', () => {
|
|
66
|
+
const route = new Route('/profile/[user:string]/settings/[setting:boolean]');
|
|
67
|
+
const args = route._arguments;
|
|
68
|
+
|
|
69
|
+
expect(args.size).toBe(2);
|
|
70
|
+
expect(Array.from(args)).toEqual([
|
|
71
|
+
{name: 'user', type: RouteArgumentType.STRING, default: null, required: true},
|
|
72
|
+
{name: 'setting', type: RouteArgumentType.BOOLEAN, default: null, required: true},
|
|
73
|
+
]);
|
|
74
|
+
});
|
|
75
|
+
|
|
76
|
+
it('should handle invalid JSON in default value gracefully', () => {
|
|
77
|
+
const consoleSpy = vi.spyOn(console, 'warn').mockImplementation(() => {
|
|
78
|
+
});
|
|
79
|
+
const route = new Route('/user/[id:number=invalid]');
|
|
80
|
+
const args = route._arguments;
|
|
81
|
+
|
|
82
|
+
expect(args.size).toBe(1);
|
|
83
|
+
expect(Array.from(args)).toEqual([
|
|
84
|
+
{name: 'id', type: RouteArgumentType.NUMBER, default: 'invalid', required: true},
|
|
85
|
+
]);
|
|
86
|
+
expect(consoleSpy).toHaveBeenCalled();
|
|
87
|
+
consoleSpy.mockRestore();
|
|
88
|
+
});
|
|
89
|
+
});
|
package/vite.config.ts
CHANGED
|
@@ -1,31 +1,31 @@
|
|
|
1
|
-
import {defineConfig} from 'vite';
|
|
2
|
-
import {configDefaults} from 'vitest/config';
|
|
3
|
-
import * as path from 'path';
|
|
4
|
-
|
|
5
|
-
export default defineConfig({
|
|
6
|
-
build: {
|
|
7
|
-
lib: {
|
|
8
|
-
entry: path.resolve(__dirname, 'src/index.ts'),
|
|
9
|
-
name: 'klaim',
|
|
10
|
-
fileName: format => {
|
|
11
|
-
if (format === 'cjs') return `klaim.${format}`;
|
|
12
|
-
return `klaim.${format}.js`;
|
|
13
|
-
},
|
|
14
|
-
formats: ['es', 'cjs', 'umd']
|
|
15
|
-
},
|
|
16
|
-
rollupOptions: {
|
|
17
|
-
external: [],
|
|
18
|
-
output: {
|
|
19
|
-
globals: {}
|
|
20
|
-
}
|
|
21
|
-
}
|
|
22
|
-
},
|
|
23
|
-
test: {
|
|
24
|
-
globals: true,
|
|
25
|
-
environment: 'jsdom',
|
|
26
|
-
coverage: {
|
|
27
|
-
provider: 'v8'
|
|
28
|
-
},
|
|
29
|
-
exclude: [...configDefaults.exclude, 'tests/e2e/**'],
|
|
30
|
-
},
|
|
31
|
-
});
|
|
1
|
+
import {defineConfig} from 'vite';
|
|
2
|
+
import {configDefaults} from 'vitest/config';
|
|
3
|
+
import * as path from 'path';
|
|
4
|
+
|
|
5
|
+
export default defineConfig({
|
|
6
|
+
build: {
|
|
7
|
+
lib: {
|
|
8
|
+
entry: path.resolve(__dirname, 'src/index.ts'),
|
|
9
|
+
name: 'klaim',
|
|
10
|
+
fileName: format => {
|
|
11
|
+
if (format === 'cjs') return `klaim.${format}`;
|
|
12
|
+
return `klaim.${format}.js`;
|
|
13
|
+
},
|
|
14
|
+
formats: ['es', 'cjs', 'umd']
|
|
15
|
+
},
|
|
16
|
+
rollupOptions: {
|
|
17
|
+
external: [],
|
|
18
|
+
output: {
|
|
19
|
+
globals: {}
|
|
20
|
+
}
|
|
21
|
+
}
|
|
22
|
+
},
|
|
23
|
+
test: {
|
|
24
|
+
globals: true,
|
|
25
|
+
environment: 'jsdom',
|
|
26
|
+
coverage: {
|
|
27
|
+
provider: 'v8'
|
|
28
|
+
},
|
|
29
|
+
exclude: [...configDefaults.exclude, 'tests/e2e/**'],
|
|
30
|
+
},
|
|
31
|
+
});
|
|
@@ -1,40 +0,0 @@
|
|
|
1
|
-
name: Release & Publish to NPM
|
|
2
|
-
on:
|
|
3
|
-
push:
|
|
4
|
-
branches:
|
|
5
|
-
- main
|
|
6
|
-
jobs:
|
|
7
|
-
release:
|
|
8
|
-
runs-on: ubuntu-latest
|
|
9
|
-
permissions:
|
|
10
|
-
contents: read
|
|
11
|
-
id-token: write
|
|
12
|
-
steps:
|
|
13
|
-
- name: Checkout
|
|
14
|
-
uses: actions/checkout@v2
|
|
15
|
-
- name: Setup Bun
|
|
16
|
-
uses: oven-sh/setup-bun@v1
|
|
17
|
-
with:
|
|
18
|
-
bun-version: "latest"
|
|
19
|
-
- name: Install Dependencies
|
|
20
|
-
run: bun install
|
|
21
|
-
- name: Lint & Check
|
|
22
|
-
run: bun run lint
|
|
23
|
-
- name: Build
|
|
24
|
-
run: bun run build
|
|
25
|
-
- name: Initialize Git
|
|
26
|
-
run: |
|
|
27
|
-
git config --global user.email "antho.eclips@gmail.com"
|
|
28
|
-
git config --global user.name "Anthony Bellancourt"
|
|
29
|
-
- name: Configure NPM
|
|
30
|
-
run: npm config set //registry.npmjs.org/:_authToken $NPM_TOKEN
|
|
31
|
-
env:
|
|
32
|
-
NPM_TOKEN: ${{ secrets.NPM_TOKEN }}
|
|
33
|
-
- name: Publish on JSR
|
|
34
|
-
run: npx jsr publish
|
|
35
|
-
- name: Release on NPM
|
|
36
|
-
run: bun run release --ci
|
|
37
|
-
env:
|
|
38
|
-
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
|
39
|
-
NPM_TOKEN: ${{ secrets.NPM_TOKEN }}
|
|
40
|
-
|
package/.release-it.json
DELETED
|
@@ -1,22 +0,0 @@
|
|
|
1
|
-
{
|
|
2
|
-
"$schema": "https://unpkg.com/release-it/schema/release-it.json",
|
|
3
|
-
"github": {
|
|
4
|
-
"release": true,
|
|
5
|
-
"tokenRef": "GITHUB_TOKEN"
|
|
6
|
-
},
|
|
7
|
-
"npm": {
|
|
8
|
-
"publish": true,
|
|
9
|
-
"tokenRef": "NPM_TOKEN"
|
|
10
|
-
},
|
|
11
|
-
"git": {
|
|
12
|
-
"requiredBranch": "main",
|
|
13
|
-
"requireCleanWorkingDir": false,
|
|
14
|
-
"commitMessage": "chore: release v%s"
|
|
15
|
-
},
|
|
16
|
-
"hooks": {
|
|
17
|
-
"before:init": [
|
|
18
|
-
"git pull",
|
|
19
|
-
"npm run lint"
|
|
20
|
-
]
|
|
21
|
-
}
|
|
22
|
-
}
|