@tkeron/tools 0.2.1 → 0.3.0

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.
@@ -4,22 +4,26 @@ on:
4
4
  branches:
5
5
  - main
6
6
 
7
+ permissions:
8
+ id-token: write
9
+ contents: read
10
+
7
11
  jobs:
8
12
  build-test-publish:
9
13
  runs-on: ubuntu-latest
14
+
10
15
  steps:
11
16
  - uses: actions/checkout@v4
12
17
 
13
18
  - uses: actions/setup-node@v4
14
19
  with:
15
- node-version: 22.x
16
- registry-url: "https://registry.npmjs.org/"
20
+ node-version: "lts/*"
21
+ registry-url: "https://registry.npmjs.org"
17
22
 
18
23
  - uses: oven-sh/setup-bun@v2
19
24
 
20
- - run: |
21
- bun i
22
- bun test
23
- npm publish --access public
24
- env:
25
- NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }}
25
+ - run: npm install -g npm@latest
26
+ - run: bun i
27
+ - run: bun run test
28
+
29
+ - run: npm publish --provenance
package/bun.lock CHANGED
@@ -1,28 +1,28 @@
1
1
  {
2
2
  "lockfileVersion": 1,
3
+ "configVersion": 0,
3
4
  "workspaces": {
4
5
  "": {
5
6
  "name": "@tkeron/tools",
6
7
  "devDependencies": {
7
- "@types/bun": "latest",
8
+ "@types/bun": "^1.3.9",
9
+ "prettier": "^3.8.1",
8
10
  },
9
11
  "peerDependencies": {
10
- "typescript": "^5.7.3",
12
+ "typescript": "^5.9.3",
11
13
  },
12
14
  },
13
15
  },
14
16
  "packages": {
15
- "@types/bun": ["@types/bun@1.2.18", "", { "dependencies": { "bun-types": "1.2.18" } }, "sha512-Xf6RaWVheyemaThV0kUfaAUvCNokFr+bH8Jxp+tTZfx7dAPA8z9ePnP9S9+Vspzuxxx9JRAXhnyccRj3GyCMdQ=="],
17
+ "@types/bun": ["@types/bun@1.3.9", "", { "dependencies": { "bun-types": "1.3.9" } }, "sha512-KQ571yULOdWJiMH+RIWIOZ7B2RXQGpL1YQrBtLIV3FqDcCu6FsbFUBwhdKUlCKUpS3PJDsHlJ1QKlpxoVR+xtw=="],
16
18
 
17
19
  "@types/node": ["@types/node@22.13.1", "", { "dependencies": { "undici-types": "~6.20.0" } }, "sha512-jK8uzQlrvXqEU91UxiK5J7pKHyzgnI1Qnl0QDHIgVGuolJhRb9EEl28Cj9b3rGR8B2lhFCtvIm5os8lFnO/1Ew=="],
18
20
 
19
- "@types/react": ["@types/react@19.1.8", "", { "dependencies": { "csstype": "^3.0.2" } }, "sha512-AwAfQ2Wa5bCx9WP8nZL2uMZWod7J7/JSplxbTmBQ5ms6QpqNYm672H0Vu9ZVKVngQ+ii4R/byguVEUZQyeg44g=="],
21
+ "bun-types": ["bun-types@1.3.9", "", { "dependencies": { "@types/node": "*" } }, "sha512-+UBWWOakIP4Tswh0Bt0QD0alpTY8cb5hvgiYeWCMet9YukHbzuruIEeXC2D7nMJPB12kbh8C7XJykSexEqGKJg=="],
20
22
 
21
- "bun-types": ["bun-types@1.2.18", "", { "dependencies": { "@types/node": "*" }, "peerDependencies": { "@types/react": "^19" } }, "sha512-04+Eha5NP7Z0A9YgDAzMk5PHR16ZuLVa83b26kH5+cp1qZW4F6FmAURngE7INf4tKOvCE69vYvDEwoNl1tGiWw=="],
23
+ "prettier": ["prettier@3.8.1", "", { "bin": { "prettier": "bin/prettier.cjs" } }, "sha512-UOnG6LftzbdaHZcKoPFtOcCKztrQ57WkHDeRD9t/PTQtmT0NHSeWWepj6pS0z/N7+08BHFDQVUrfmfMRcZwbMg=="],
22
24
 
23
- "csstype": ["csstype@3.1.3", "", {}, "sha512-M1uQkMl8rQK/szD0LNhtqxIPLpimGm8sOBwU7lLnCpSbTyY3yeU1Vc7l4KT5zT4s/yOxHH5O7tIuuLOCnLADRw=="],
24
-
25
- "typescript": ["typescript@5.7.3", "", { "bin": { "tsc": "bin/tsc", "tsserver": "bin/tsserver" } }, "sha512-84MVSjMEHP+FQRPy3pX9sTVV/INIex71s9TL2Gm5FG/WG1SqXeKyZ0k7/blY/4FdOzI12CBy1vGc4og/eus0fw=="],
25
+ "typescript": ["typescript@5.9.3", "", { "bin": { "tsc": "bin/tsc", "tsserver": "bin/tsserver" } }, "sha512-jl1vZzPDinLr9eUt3J/t7V6FgNEw9QjvBPdysz9KfQDD41fQrC2Y4vKQdiaUpFT4bXlb1RHhLpp8wtm6M5TgSw=="],
26
26
 
27
27
  "undici-types": ["undici-types@6.20.0", "", {}, "sha512-Ny6QZ2Nju20vw1SRHe3d9jVu6gJ+4e3+MMpqu7pqE5HT6WsTSlce++GQmK5UXS8mzV8DSYHrQH+Xrf2jVcuKNg=="],
28
28
  }
package/changelog.md ADDED
@@ -0,0 +1,25 @@
1
+ # Changelog
2
+
3
+ ## [0.3.0] - 2026-02-15
4
+
5
+ ### Added
6
+
7
+ - Configured trusted publisher with OIDC for npm deployment
8
+ - Added `lint` script using Prettier for code formatting
9
+ - Added Prettier as devDependency
10
+
11
+ ### Changed
12
+
13
+ - Updated npm deployment workflow to use OIDC authentication instead of NPM_TOKEN
14
+ - Standardized repository URL format in package.json
15
+ - Code formatting applied across all source and test files
16
+
17
+ ### Infrastructure
18
+
19
+ - GitHub Actions now uses `permissions: id-token: write` for secure publishing
20
+ - npm publish now includes `--provenance` flag for supply chain security
21
+ - Node.js version standardized to `lts/*` in CI workflow
22
+
23
+ ## [0.2.2] - Previous releases
24
+
25
+ (Previous version history not documented)
package/package.json CHANGED
@@ -1,20 +1,25 @@
1
1
  {
2
2
  "name": "@tkeron/tools",
3
- "version": "0.2.1",
3
+ "version": "0.3.0",
4
4
  "description": "Useful JavaScript utilities for Bun runtime",
5
5
  "main": "src/index.ts",
6
6
  "module": "src/index.ts",
7
7
  "type": "module",
8
8
  "author": "tkeron",
9
9
  "license": "MIT",
10
+ "scripts": {
11
+ "test": "bun test --concurrent",
12
+ "lint": "prettier --write ."
13
+ },
10
14
  "engines": {
11
15
  "bun": ">=1.0.0"
12
16
  },
13
17
  "devDependencies": {
14
- "@types/bun": "latest"
18
+ "@types/bun": "^1.3.9",
19
+ "prettier": "^3.8.1"
15
20
  },
16
21
  "peerDependencies": {
17
- "typescript": "^5.7.3"
22
+ "typescript": "^5.9.3"
18
23
  },
19
24
  "keywords": [
20
25
  "bun",
@@ -22,7 +27,11 @@
22
27
  "utils",
23
28
  "tools"
24
29
  ],
30
+ "publishConfig": {
31
+ "access": "public"
32
+ },
25
33
  "repository": {
26
- "url": "git@github.com:tkeron/tools.git"
34
+ "type": "git",
35
+ "url": "git+https://github.com/tkeron/tools.git"
27
36
  }
28
37
  }
package/readme.md CHANGED
@@ -21,10 +21,10 @@ This package provides a growing collection of utility functions and data structu
21
21
 
22
22
  ```typescript
23
23
  // Import all utilities
24
- import * as tools from '@tkeron/tools';
24
+ import * as tools from "@tkeron/tools";
25
25
 
26
26
  // Or import specific utilities
27
- import { rng, getLIFO, getPaths } from '@tkeron/tools';
27
+ import { rng, getLIFO, getPaths } from "@tkeron/tools";
28
28
  ```
29
29
 
30
30
  ## 📚 Documentation
@@ -39,7 +39,4 @@ The project includes comprehensive tests for all utilities:
39
39
  bun test
40
40
  ```
41
41
 
42
-
43
-
44
-
45
- Built with ❤️ for the Bun ecosystem
42
+ Built with ❤️ for the Bun ecosystem
package/src/getPaths.ts CHANGED
@@ -1,112 +1,101 @@
1
1
  import { Glob } from "bun";
2
2
  import { statSync } from "fs";
3
+ import { join } from "path";
3
4
 
4
- /**
5
- * Gets file paths, directory paths, or both based on the specified parameters
6
- * @param path - The base directory path to search in
7
- * @param pattern - The glob pattern to match files/directories (default: **\/*)
8
- * @param includeDirectories - Controls what to include: yes (files + dirs), no (files only), onlyDirectories (dirs only)
9
- * @param absolute - Whether to return absolute paths (default: true)
10
- * @returns Array of paths matching the criteria
11
- */
12
5
  export const getPaths = (
13
- path: string,
14
- pattern: string = "**/*",
15
- includeDirectories: "yes" | "no" | "onlyDirectories" = "no",
16
- absolute: boolean = true,
6
+ path: string,
7
+ pattern: string = "**/*",
8
+ includeDirectories: "yes" | "no" | "onlyDirectories" = "no",
9
+ absolute: boolean = true,
17
10
  ): string[] => {
18
- try {
19
- if (includeDirectories === "no") return getFilePaths(path, pattern, absolute);
20
- if (includeDirectories === "onlyDirectories") return getDirectoryPaths(path, pattern, absolute);
21
-
22
- const paths: string[] = [];
23
-
24
- const glob = new Glob(pattern);
25
-
26
- const files = glob.scanSync({
27
- cwd: path,
28
- onlyFiles: false,
29
- absolute: absolute,
30
- dot: true,
31
- followSymlinks: false,
32
- });
33
-
34
- paths.push(...files);
35
-
36
- return paths;
37
- } catch (error) {
38
- console.error(`Error getting paths from ${path}:`, error);
39
- return [];
40
- }
11
+ try {
12
+ if (includeDirectories === "no")
13
+ return getFilePaths(path, pattern, absolute);
14
+ if (includeDirectories === "onlyDirectories")
15
+ return getDirectoryPaths(path, pattern, absolute);
16
+
17
+ const paths: string[] = [];
18
+
19
+ const glob = new Glob(pattern);
20
+
21
+ const files = glob.scanSync({
22
+ cwd: path,
23
+ onlyFiles: false,
24
+ absolute: absolute,
25
+ dot: true,
26
+ followSymlinks: false,
27
+ });
28
+
29
+ paths.push(...files);
30
+
31
+ return paths;
32
+ } catch (error) {
33
+ console.error(`Error getting paths from ${path}:`, error);
34
+ return [];
35
+ }
41
36
  };
42
37
 
43
-
44
- /**
45
- * Gets only file paths (excluding directories) matching the pattern
46
- * @param path - The base directory path to search in
47
- * @param pattern - The glob pattern to match files (default: **\/*)
48
- * @param absolute - Whether to return absolute paths (default: true)
49
- * @returns Array of file paths
50
- */
51
- export const getFilePaths = (path: string, pattern: string = "**/*", absolute: boolean = true): string[] => {
52
- try {
53
- const paths: string[] = [];
54
-
55
- const glob = new Glob(pattern);
56
-
57
- const files = glob.scanSync({
58
- cwd: path,
59
- onlyFiles: true,
60
- absolute: absolute,
61
- dot: true,
62
- followSymlinks: false,
63
- });
64
-
65
- paths.push(...files);
66
-
67
- return paths;
68
- } catch (error) {
69
- console.error(`Error getting file paths from ${path}:`, error);
70
- return [];
71
- }
38
+ export const getFilePaths = (
39
+ path: string,
40
+ pattern: string = "**/*",
41
+ absolute: boolean = true,
42
+ ): string[] => {
43
+ try {
44
+ const paths: string[] = [];
45
+
46
+ const glob = new Glob(pattern);
47
+
48
+ const files = glob.scanSync({
49
+ cwd: path,
50
+ onlyFiles: true,
51
+ absolute: absolute,
52
+ dot: true,
53
+ followSymlinks: false,
54
+ });
55
+
56
+ paths.push(...files);
57
+
58
+ return paths;
59
+ } catch (error) {
60
+ console.error(`Error getting file paths from ${path}:`, error);
61
+ return [];
62
+ }
72
63
  };
73
64
 
74
- /**
75
- * Gets only directory paths (excluding files) matching the pattern
76
- * @param path - The base directory path to search in
77
- * @param pattern - The glob pattern to match directories (default: **\/*)
78
- * @param absolute - Whether to return absolute paths (default: true)
79
- * @returns Array of directory paths
80
- */
81
- export const getDirectoryPaths = (path: string, pattern: string = "**/*", absolute: boolean = true): string[] => {
82
- try {
83
- const paths: string[] = [];
84
-
85
- const glob = new Glob(pattern);
86
-
87
- const allItems = [...glob.scanSync({
88
- cwd: path,
89
- onlyFiles: false,
90
- absolute: absolute,
91
- dot: true,
92
- followSymlinks: false,
93
- })];
94
-
95
- const directories = allItems.filter(item => {
96
- try {
97
- return statSync(item).isDirectory();
98
- } catch {
99
- return false;
100
- }
101
- });
102
-
103
- paths.push(...directories);
104
-
105
- return paths;
106
- } catch (error) {
107
- console.error(`Error getting directory paths from ${path}:`, error);
108
- return [];
109
- }
65
+ export const getDirectoryPaths = (
66
+ path: string,
67
+ pattern: string = "**/*",
68
+ absolute: boolean = true,
69
+ ): string[] => {
70
+ try {
71
+ const paths: string[] = [];
72
+
73
+ const glob = new Glob(pattern);
74
+
75
+ const allItems = [
76
+ ...glob.scanSync({
77
+ cwd: path,
78
+ onlyFiles: false,
79
+ absolute: absolute,
80
+ dot: true,
81
+ followSymlinks: false,
82
+ }),
83
+ ];
84
+
85
+ const directories = allItems.filter((item) => {
86
+ try {
87
+ const fullPath = absolute ? item : join(path, item);
88
+ return statSync(fullPath).isDirectory();
89
+ } catch {
90
+ return false;
91
+ }
92
+ });
93
+
94
+ paths.push(...directories);
95
+
96
+ return paths;
97
+ } catch (error) {
98
+ console.error(`Error getting directory paths from ${path}:`, error);
99
+ return [];
100
+ }
110
101
  };
111
-
112
-
package/src/stack.ts CHANGED
@@ -1,70 +1,53 @@
1
-
2
1
  export interface Stack<T> {
3
- pop: () => T;
4
- push: (item: T) => void;
5
- readonly length: number;
6
- current: T | null;
2
+ pop: () => T;
3
+ push: (item: T) => void;
4
+ readonly length: number;
5
+ current: T | null;
7
6
  }
8
7
 
9
- /**
10
- * Returns a LIFO (Last In First Out) stack.
11
- * Same as FILO (First In Last Out) stack.
12
- * @returns an empty LIFO stack.
13
- */
14
8
  export const getLIFO = <T>(): Stack<T> => {
15
-
16
- const _stack: T[] = [];
17
-
18
-
19
- const stack = <Stack<T>>{
20
- pop: () => _stack.pop(),
21
- push: (item) => _stack.push(item),
22
- length: 0,
23
- current: <T><unknown>null
24
- };
25
-
26
- Object.defineProperty(stack, "current", {
27
- get: () => _stack.length ? _stack[_stack.length - 1] : null,
28
- set: (value) => {
29
- if (_stack.length) _stack[_stack.length - 1] = value;
30
- }
31
- });
32
-
33
- Object.defineProperty(stack, "length", {
34
- get: () => _stack.length,
35
- });
36
-
37
-
38
- return stack;
39
-
40
-
9
+ const _stack: T[] = [];
10
+
11
+ const stack = <Stack<T>>{
12
+ pop: () => _stack.pop(),
13
+ push: (item) => _stack.push(item),
14
+ length: 0,
15
+ current: <T>(<unknown>null),
16
+ };
17
+
18
+ Object.defineProperty(stack, "current", {
19
+ get: () => (_stack.length ? _stack[_stack.length - 1] : null),
20
+ set: (value) => {
21
+ if (_stack.length) _stack[_stack.length - 1] = value;
22
+ },
23
+ });
24
+
25
+ Object.defineProperty(stack, "length", {
26
+ get: () => _stack.length,
27
+ });
28
+
29
+ return stack;
41
30
  };
42
31
 
43
- /**
44
- * Returns a FIFO (First In First Out) stack
45
- * @returns an empty FIFO stack
46
- */
47
32
  export const getFIFO = <T>(): Stack<T> => {
48
-
49
- const _stack: T[] = [];
50
- const stack = <Stack<T>>{
51
- pop: () => _stack.shift(),
52
- push: (item) => _stack.push(item),
53
- length: 0,
54
- current: <T><unknown>null
55
- };
56
-
57
- Object.defineProperty(stack, "current", {
58
- get: () => _stack.length ? _stack[0] : null,
59
- set: (value) => {
60
- if (_stack.length) _stack[0] = value;
61
- }
62
- });
63
-
64
- Object.defineProperty(stack, "length", {
65
- get: () => _stack.length,
66
- });
67
-
68
- return stack;
69
-
70
- }
33
+ const _stack: T[] = [];
34
+ const stack = <Stack<T>>{
35
+ pop: () => _stack.shift(),
36
+ push: (item) => _stack.push(item),
37
+ length: 0,
38
+ current: <T>(<unknown>null),
39
+ };
40
+
41
+ Object.defineProperty(stack, "current", {
42
+ get: () => (_stack.length ? _stack[0] : null),
43
+ set: (value) => {
44
+ if (_stack.length) _stack[0] = value;
45
+ },
46
+ });
47
+
48
+ Object.defineProperty(stack, "length", {
49
+ get: () => _stack.length,
50
+ });
51
+
52
+ return stack;
53
+ };