@guanghechen/path 1.0.0-alpha.2

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/CHANGELOG.md ADDED
@@ -0,0 +1,16 @@
1
+ # Change Log
2
+
3
+ All notable changes to this project will be documented in this file.
4
+ See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
5
+
6
+ # 1.0.0-alpha.2 (2023-10-09)
7
+
8
+
9
+ ### Features
10
+
11
+ * ✨ add @guanghechen/path ([cf68a08](https://github.com/guanghechen/sora/commit/cf68a08d661896d642254c58a5377b0556452cde))
12
+
13
+
14
+ ### Performance Improvements
15
+
16
+ * ✅ update tests ([ad6cd01](https://github.com/guanghechen/sora/commit/ad6cd01188a9b3739dbe390053de9de3ea32770a))
@@ -0,0 +1,176 @@
1
+ 'use strict';
2
+
3
+ var path = require('node:path');
4
+
5
+ function _interopDefault (e) { return e && e.__esModule ? e : { default: e }; }
6
+
7
+ var path__default = /*#__PURE__*/_interopDefault(path);
8
+
9
+ const clazz$2 = 'PhysicalPathResolver';
10
+ class PhysicalPathResolver {
11
+ basename(filepath) {
12
+ this.ensureAbsolute(filepath);
13
+ const p = this.normalize(filepath);
14
+ return path__default.default.basename(p);
15
+ }
16
+ ensureAbsolute(filepath, message) {
17
+ if (this.isAbsolute(filepath))
18
+ return;
19
+ throw new Error(message ?? `[${clazz$2}] not an absolute path: ${filepath}.`);
20
+ }
21
+ dirname(filepath) {
22
+ this.ensureAbsolute(filepath);
23
+ const p = path__default.default.dirname(filepath);
24
+ return this.normalize(p);
25
+ }
26
+ isAbsolute(filepath) {
27
+ return path__default.default.isAbsolute(filepath);
28
+ }
29
+ join(filepath, ...pathPieces) {
30
+ this.ensureAbsolute(filepath, `[${clazz$2}.join] not an absolute path: ${filepath}.`);
31
+ for (const pathPiece of pathPieces) {
32
+ if (this.isAbsolute(pathPiece)) {
33
+ throw new Error(`[${clazz$2}.join] pathPiece shouldn't be absolute path. ${pathPiece}`);
34
+ }
35
+ }
36
+ const p = path__default.default.join(filepath, ...pathPieces);
37
+ return this.normalize(p);
38
+ }
39
+ normalize(filepath) {
40
+ this.ensureAbsolute(filepath);
41
+ const p = path__default.default
42
+ .normalize(filepath)
43
+ .replace(/[/\\]+/g, path__default.default.sep)
44
+ .replace(/[/\\]+$/, '');
45
+ return p.length <= 0 ? '/' : p;
46
+ }
47
+ relative(from_, to_) {
48
+ this.ensureAbsolute(from_, `[${clazz$2}.relative] from is not an absolute path: ${from_}`);
49
+ this.ensureAbsolute(to_, `[${clazz$2}.relative] to is not an absolute path: ${to_}`);
50
+ const from = this.normalize(from_);
51
+ const to = this.normalize(to_);
52
+ const relativePath = path__default.default.relative(from, to);
53
+ return relativePath;
54
+ }
55
+ }
56
+
57
+ const clazz$1 = 'WorkspacePathResolver';
58
+ class WorkspacePathResolver {
59
+ root;
60
+ pathResolver;
61
+ constructor(root, pathResolver) {
62
+ this.root = root;
63
+ this.pathResolver = pathResolver;
64
+ }
65
+ ensureSafePath(filepath, message) {
66
+ if (this.isSafePath(filepath))
67
+ return;
68
+ throw new Error(message ?? `[${clazz$1}] not an absolute path: ${filepath}.`);
69
+ }
70
+ isSafePath(filepath) {
71
+ const { root, pathResolver } = this;
72
+ if (!pathResolver.isAbsolute(filepath))
73
+ return true;
74
+ if (filepath === root)
75
+ return true;
76
+ const relativePath = pathResolver.relative(root, filepath);
77
+ return !relativePath.startsWith('..');
78
+ }
79
+ resolve(filepath) {
80
+ this.ensureSafePath(filepath);
81
+ const { root, pathResolver } = this;
82
+ if (pathResolver.isAbsolute(filepath))
83
+ return pathResolver.normalize(filepath);
84
+ return pathResolver.join(root, filepath);
85
+ }
86
+ relative(filepath_) {
87
+ this.ensureSafePath(filepath_);
88
+ const filepath = this.resolve(filepath_);
89
+ return this.pathResolver.relative(this.root, filepath);
90
+ }
91
+ }
92
+
93
+ class PhysicalWorkspacePathResolver extends WorkspacePathResolver {
94
+ constructor(root) {
95
+ const pathResolver = new PhysicalPathResolver();
96
+ super(root, pathResolver);
97
+ }
98
+ }
99
+
100
+ const clazz = 'VirtualPathResolver';
101
+ class VirtualPathResolver {
102
+ basename(filepath) {
103
+ this.ensureAbsolute(filepath);
104
+ const p = this.normalize(filepath);
105
+ const i = p.lastIndexOf('/');
106
+ return p.slice(i + 1);
107
+ }
108
+ ensureAbsolute(filepath, message) {
109
+ if (this.isAbsolute(filepath))
110
+ return;
111
+ throw new Error(message ?? `[${clazz}] not an absolute path: ${filepath}.`);
112
+ }
113
+ dirname(filepath) {
114
+ this.ensureAbsolute(filepath);
115
+ const p = this.normalize(filepath);
116
+ const i = p.lastIndexOf('/');
117
+ return i <= 0 ? '/' : p.slice(0, i);
118
+ }
119
+ isAbsolute(filepath) {
120
+ return filepath.startsWith('/') || filepath.startsWith('\\');
121
+ }
122
+ join(filepath, ...pathPieces) {
123
+ this.ensureAbsolute(filepath, `[${clazz}.join] not an absolute path: ${filepath}.`);
124
+ for (const pathPiece of pathPieces) {
125
+ if (this.isAbsolute(pathPiece)) {
126
+ throw new Error(`[${clazz}.join] pathPiece shouldn't be absolute path. ${pathPiece}`);
127
+ }
128
+ }
129
+ const p = filepath + '/' + pathPieces.join('/');
130
+ return this.normalize(p);
131
+ }
132
+ normalize(filepath) {
133
+ this.ensureAbsolute(filepath);
134
+ const pieces = [];
135
+ for (const piece of filepath.split(/[/\\]+/g)) {
136
+ if (!piece)
137
+ continue;
138
+ if (piece === '.')
139
+ continue;
140
+ if (piece === '..') {
141
+ pieces.pop();
142
+ continue;
143
+ }
144
+ pieces.push(piece);
145
+ }
146
+ return '/' + pieces.join('/');
147
+ }
148
+ relative(from_, to_) {
149
+ this.ensureAbsolute(from_, `[${clazz}.relative] from is not an absolute path: ${from_}`);
150
+ this.ensureAbsolute(to_, `[${clazz}.relative] to is not an absolute path: ${to_}`);
151
+ const from = this.normalize(from_);
152
+ const to = this.normalize(to_);
153
+ const fromPieces = from.split('/');
154
+ const toPieces = to.split('/');
155
+ let ci = 0;
156
+ const L = fromPieces.length < toPieces.length ? fromPieces.length : toPieces.length;
157
+ for (; ci < L; ++ci) {
158
+ if (fromPieces[ci] !== toPieces[ci])
159
+ break;
160
+ }
161
+ return '../'.repeat(fromPieces.length - ci) + toPieces.slice(ci).join('/');
162
+ }
163
+ }
164
+
165
+ class VirtualWorkspacePathResolver extends WorkspacePathResolver {
166
+ constructor(root) {
167
+ const pathResolver = new VirtualPathResolver();
168
+ super(root, pathResolver);
169
+ }
170
+ }
171
+
172
+ exports.PhysicalPathResolver = PhysicalPathResolver;
173
+ exports.PhysicalWorkspacePathResolver = PhysicalWorkspacePathResolver;
174
+ exports.VirtualPathResolver = VirtualPathResolver;
175
+ exports.VirtualWorkspacePathResolver = VirtualWorkspacePathResolver;
176
+ exports.WorkspacePathResolver = WorkspacePathResolver;
@@ -0,0 +1,166 @@
1
+ import path from 'node:path';
2
+
3
+ const clazz$2 = 'PhysicalPathResolver';
4
+ class PhysicalPathResolver {
5
+ basename(filepath) {
6
+ this.ensureAbsolute(filepath);
7
+ const p = this.normalize(filepath);
8
+ return path.basename(p);
9
+ }
10
+ ensureAbsolute(filepath, message) {
11
+ if (this.isAbsolute(filepath))
12
+ return;
13
+ throw new Error(message ?? `[${clazz$2}] not an absolute path: ${filepath}.`);
14
+ }
15
+ dirname(filepath) {
16
+ this.ensureAbsolute(filepath);
17
+ const p = path.dirname(filepath);
18
+ return this.normalize(p);
19
+ }
20
+ isAbsolute(filepath) {
21
+ return path.isAbsolute(filepath);
22
+ }
23
+ join(filepath, ...pathPieces) {
24
+ this.ensureAbsolute(filepath, `[${clazz$2}.join] not an absolute path: ${filepath}.`);
25
+ for (const pathPiece of pathPieces) {
26
+ if (this.isAbsolute(pathPiece)) {
27
+ throw new Error(`[${clazz$2}.join] pathPiece shouldn't be absolute path. ${pathPiece}`);
28
+ }
29
+ }
30
+ const p = path.join(filepath, ...pathPieces);
31
+ return this.normalize(p);
32
+ }
33
+ normalize(filepath) {
34
+ this.ensureAbsolute(filepath);
35
+ const p = path
36
+ .normalize(filepath)
37
+ .replace(/[/\\]+/g, path.sep)
38
+ .replace(/[/\\]+$/, '');
39
+ return p.length <= 0 ? '/' : p;
40
+ }
41
+ relative(from_, to_) {
42
+ this.ensureAbsolute(from_, `[${clazz$2}.relative] from is not an absolute path: ${from_}`);
43
+ this.ensureAbsolute(to_, `[${clazz$2}.relative] to is not an absolute path: ${to_}`);
44
+ const from = this.normalize(from_);
45
+ const to = this.normalize(to_);
46
+ const relativePath = path.relative(from, to);
47
+ return relativePath;
48
+ }
49
+ }
50
+
51
+ const clazz$1 = 'WorkspacePathResolver';
52
+ class WorkspacePathResolver {
53
+ root;
54
+ pathResolver;
55
+ constructor(root, pathResolver) {
56
+ this.root = root;
57
+ this.pathResolver = pathResolver;
58
+ }
59
+ ensureSafePath(filepath, message) {
60
+ if (this.isSafePath(filepath))
61
+ return;
62
+ throw new Error(message ?? `[${clazz$1}] not an absolute path: ${filepath}.`);
63
+ }
64
+ isSafePath(filepath) {
65
+ const { root, pathResolver } = this;
66
+ if (!pathResolver.isAbsolute(filepath))
67
+ return true;
68
+ if (filepath === root)
69
+ return true;
70
+ const relativePath = pathResolver.relative(root, filepath);
71
+ return !relativePath.startsWith('..');
72
+ }
73
+ resolve(filepath) {
74
+ this.ensureSafePath(filepath);
75
+ const { root, pathResolver } = this;
76
+ if (pathResolver.isAbsolute(filepath))
77
+ return pathResolver.normalize(filepath);
78
+ return pathResolver.join(root, filepath);
79
+ }
80
+ relative(filepath_) {
81
+ this.ensureSafePath(filepath_);
82
+ const filepath = this.resolve(filepath_);
83
+ return this.pathResolver.relative(this.root, filepath);
84
+ }
85
+ }
86
+
87
+ class PhysicalWorkspacePathResolver extends WorkspacePathResolver {
88
+ constructor(root) {
89
+ const pathResolver = new PhysicalPathResolver();
90
+ super(root, pathResolver);
91
+ }
92
+ }
93
+
94
+ const clazz = 'VirtualPathResolver';
95
+ class VirtualPathResolver {
96
+ basename(filepath) {
97
+ this.ensureAbsolute(filepath);
98
+ const p = this.normalize(filepath);
99
+ const i = p.lastIndexOf('/');
100
+ return p.slice(i + 1);
101
+ }
102
+ ensureAbsolute(filepath, message) {
103
+ if (this.isAbsolute(filepath))
104
+ return;
105
+ throw new Error(message ?? `[${clazz}] not an absolute path: ${filepath}.`);
106
+ }
107
+ dirname(filepath) {
108
+ this.ensureAbsolute(filepath);
109
+ const p = this.normalize(filepath);
110
+ const i = p.lastIndexOf('/');
111
+ return i <= 0 ? '/' : p.slice(0, i);
112
+ }
113
+ isAbsolute(filepath) {
114
+ return filepath.startsWith('/') || filepath.startsWith('\\');
115
+ }
116
+ join(filepath, ...pathPieces) {
117
+ this.ensureAbsolute(filepath, `[${clazz}.join] not an absolute path: ${filepath}.`);
118
+ for (const pathPiece of pathPieces) {
119
+ if (this.isAbsolute(pathPiece)) {
120
+ throw new Error(`[${clazz}.join] pathPiece shouldn't be absolute path. ${pathPiece}`);
121
+ }
122
+ }
123
+ const p = filepath + '/' + pathPieces.join('/');
124
+ return this.normalize(p);
125
+ }
126
+ normalize(filepath) {
127
+ this.ensureAbsolute(filepath);
128
+ const pieces = [];
129
+ for (const piece of filepath.split(/[/\\]+/g)) {
130
+ if (!piece)
131
+ continue;
132
+ if (piece === '.')
133
+ continue;
134
+ if (piece === '..') {
135
+ pieces.pop();
136
+ continue;
137
+ }
138
+ pieces.push(piece);
139
+ }
140
+ return '/' + pieces.join('/');
141
+ }
142
+ relative(from_, to_) {
143
+ this.ensureAbsolute(from_, `[${clazz}.relative] from is not an absolute path: ${from_}`);
144
+ this.ensureAbsolute(to_, `[${clazz}.relative] to is not an absolute path: ${to_}`);
145
+ const from = this.normalize(from_);
146
+ const to = this.normalize(to_);
147
+ const fromPieces = from.split('/');
148
+ const toPieces = to.split('/');
149
+ let ci = 0;
150
+ const L = fromPieces.length < toPieces.length ? fromPieces.length : toPieces.length;
151
+ for (; ci < L; ++ci) {
152
+ if (fromPieces[ci] !== toPieces[ci])
153
+ break;
154
+ }
155
+ return '../'.repeat(fromPieces.length - ci) + toPieces.slice(ci).join('/');
156
+ }
157
+ }
158
+
159
+ class VirtualWorkspacePathResolver extends WorkspacePathResolver {
160
+ constructor(root) {
161
+ const pathResolver = new VirtualPathResolver();
162
+ super(root, pathResolver);
163
+ }
164
+ }
165
+
166
+ export { PhysicalPathResolver, PhysicalWorkspacePathResolver, VirtualPathResolver, VirtualWorkspacePathResolver, WorkspacePathResolver };
@@ -0,0 +1,41 @@
1
+ import { IPathResolver, IWorkspacePathResolver } from '@guanghechen/path.types';
2
+
3
+ declare class PhysicalPathResolver implements IPathResolver {
4
+ basename(filepath: string): string;
5
+ ensureAbsolute(filepath: string, message?: string | undefined): void | never;
6
+ dirname(filepath: string): string | never;
7
+ isAbsolute(filepath: string): boolean;
8
+ join(filepath: string, ...pathPieces: string[]): string | never;
9
+ normalize(filepath: string): string | never;
10
+ relative(from_: string, to_: string): string | never;
11
+ }
12
+
13
+ declare class WorkspacePathResolver implements IWorkspacePathResolver {
14
+ readonly root: string;
15
+ readonly pathResolver: IPathResolver;
16
+ constructor(root: string, pathResolver: IPathResolver);
17
+ ensureSafePath(filepath: string, message?: string | undefined): void | never;
18
+ isSafePath(filepath: string): boolean;
19
+ resolve(filepath: string): string | never;
20
+ relative(filepath_: string): string | never;
21
+ }
22
+
23
+ declare class PhysicalWorkspacePathResolver extends WorkspacePathResolver implements IWorkspacePathResolver {
24
+ constructor(root: string);
25
+ }
26
+
27
+ declare class VirtualPathResolver implements IPathResolver {
28
+ basename(filepath: string): string;
29
+ ensureAbsolute(filepath: string, message?: string | undefined): void | never;
30
+ dirname(filepath: string): string | never;
31
+ isAbsolute(filepath: string): boolean;
32
+ join(filepath: string, ...pathPieces: string[]): string | never;
33
+ normalize(filepath: string): string | never;
34
+ relative(from_: string, to_: string): string | never;
35
+ }
36
+
37
+ declare class VirtualWorkspacePathResolver extends WorkspacePathResolver implements IWorkspacePathResolver {
38
+ constructor(root: string);
39
+ }
40
+
41
+ export { PhysicalPathResolver, PhysicalWorkspacePathResolver, VirtualPathResolver, VirtualWorkspacePathResolver, WorkspacePathResolver };
package/package.json ADDED
@@ -0,0 +1,54 @@
1
+ {
2
+ "name": "@guanghechen/path",
3
+ "version": "1.0.0-alpha.2",
4
+ "description": "Path utils.",
5
+ "author": {
6
+ "name": "guanghechen",
7
+ "url": "https://github.com/guanghechen/"
8
+ },
9
+ "repository": {
10
+ "type": "git",
11
+ "url": "https://github.com/guanghechen/sora/tree/@guanghechen/path@1.0.0-alpha.1",
12
+ "directory": "packages/path"
13
+ },
14
+ "homepage": "https://github.com/guanghechen/sora/tree/@guanghechen/path@1.0.0-alpha.1/packages/path#readme",
15
+ "type": "module",
16
+ "exports": {
17
+ ".": {
18
+ "source": "./src/index.ts",
19
+ "import": "./lib/esm/index.mjs",
20
+ "require": "./lib/cjs/index.cjs",
21
+ "types": "./lib/types/index.d.ts"
22
+ }
23
+ },
24
+ "source": "./src/index.ts",
25
+ "main": "./lib/cjs/index.cjs",
26
+ "module": "./lib/esm/index.mjs",
27
+ "types": "./lib/types/index.d.ts",
28
+ "license": "MIT",
29
+ "engines": {
30
+ "node": ">= 16.0.0"
31
+ },
32
+ "files": [
33
+ "lib/",
34
+ "!lib/**/*.map",
35
+ "package.json",
36
+ "CHANGELOG.md",
37
+ "LICENSE",
38
+ "README.md"
39
+ ],
40
+ "scripts": {
41
+ "build": "rimraf lib/ && cross-env NODE_ENV=production rollup -c ../../rollup.config.mjs",
42
+ "prepublishOnly": "yarn build",
43
+ "test": "node --experimental-vm-modules ../../node_modules/.bin/jest --config ../../jest.config.mjs --rootDir ."
44
+ },
45
+ "dependencies": {
46
+ "@guanghechen/path.types": "^1.0.0-alpha.2"
47
+ },
48
+ "devDependencies": {
49
+ "cross-env": "*",
50
+ "rimraf": "*",
51
+ "rollup": "*"
52
+ },
53
+ "gitHead": "b8d110d46e40575b2c7bc018ea823a779c3cff5a"
54
+ }