klaim 1.2.3 → 1.2.16

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 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, Registry, Route, Hook} from 'klaim';
43
- // OR
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.3",
23
+ "version": "1.2.16",
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": "dotenv release-it --"
33
+ "release": "dotenv release-it -- patch --config release-it.config.cjs --ci",
34
+ "release:minor": "dotenv release-it -- minor --config release-it.config.cjs --ci",
35
+ "release:major": "dotenv release-it -- major --config release-it.config.cjs --ci"
34
36
  },
35
37
  "devDependencies": {
36
38
  "@eslint/js": "^9.6.0",
@@ -0,0 +1,29 @@
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: false,
11
+ },
12
+ git: {
13
+ requiredBranch: 'main',
14
+ requireCleanWorkingDir: false,
15
+ commitMessage: 'chore: release v%s'
16
+ },
17
+ hooks: {
18
+ 'before:init': [
19
+ 'git pull',
20
+ 'bun run lint',
21
+ 'bun run build'
22
+ ],
23
+ 'after:bump': [
24
+ // `npx jsr publish --token ${process.env.JSR_TOKEN} --allow-dirty`
25
+ `npm config set //registry.npmjs.org/:_authToken=${process.env.NPM_TOKEN}`,
26
+ `npm publish`
27
+ ]
28
+ }
29
+ };
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";
@@ -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
+ }
@@ -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
+ }
@@ -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
+ }
@@ -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
+ }
@@ -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: Release on NPM
34
- run: bun run release --ci
35
- env:
36
- GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
37
- NPM_TOKEN: ${{ secrets.NPM_TOKEN }}
38
- - name: Publish on JSR
39
- run: npx jsr publish
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
- }