@kikiutils/shared 13.4.0 → 13.5.1
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/README.md +2 -0
- package/dist/classes/path.d.ts +220 -0
- package/dist/classes/path.d.ts.map +1 -0
- package/dist/classes/path.js +245 -0
- package/dist/classes/path.js.map +1 -0
- package/dist/classes/precision-number.d.ts +58 -0
- package/dist/classes/precision-number.d.ts.map +1 -0
- package/dist/classes/precision-number.js +133 -0
- package/dist/classes/precision-number.js.map +1 -0
- package/dist/classes/ssh-client.d.ts +43 -0
- package/dist/classes/ssh-client.d.ts.map +1 -0
- package/dist/classes/ssh-client.js +131 -0
- package/dist/classes/ssh-client.js.map +1 -0
- package/dist/types/filtered-key-path.d.ts +30 -0
- package/dist/types/filtered-key-path.d.ts.map +1 -0
- package/dist/types/index.d.ts +17 -0
- package/dist/types/index.d.ts.map +1 -0
- package/dist/types/vue.d.ts +22 -0
- package/dist/types/vue.d.ts.map +1 -0
- package/dist/vue.d.ts +7 -6
- package/dist/vue.d.ts.map +1 -1
- package/dist/vue.js +3 -3
- package/dist/vue.js.map +1 -1
- package/dist/web.js.map +1 -1
- package/package.json +78 -39
- package/src/classes/path.ts +428 -0
- package/src/classes/precision-number.ts +180 -0
- package/src/classes/ssh-client.ts +174 -0
- package/src/types/filtered-key-path.ts +46 -0
- package/src/types/index.ts +18 -0
- package/src/types/vue.ts +18 -0
- package/src/vue.ts +8 -7
- package/src/web.ts +1 -1
|
@@ -0,0 +1,180 @@
|
|
|
1
|
+
import { Decimal } from 'decimal.js';
|
|
2
|
+
|
|
3
|
+
export type PrecisionNumberValue = Decimal.Value | PrecisionNumber | { toString: () => string };
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
* Class representing a precision number with configurable decimal places and rounding.
|
|
7
|
+
*
|
|
8
|
+
* This class leverages the Decimal.js library to ensure accurate arithmetic operations
|
|
9
|
+
* with floating point numbers. It provides methods for various arithmetic operations
|
|
10
|
+
* (addition, subtraction, multiplication, division) as well as comparison and utility
|
|
11
|
+
* methods to check the state of the number (e.g., if it is finite, an integer, zero, etc.).
|
|
12
|
+
*
|
|
13
|
+
* The class also includes custom symbol methods to support Node.js inspection and primitive
|
|
14
|
+
* type conversion.
|
|
15
|
+
*
|
|
16
|
+
* The class supports in-place modification methods that alter the current instance's value,
|
|
17
|
+
* such as `plus`, `minus`, `times`, `dividedBy`, and others. Additionally, methods prefixed
|
|
18
|
+
* with `to` (e.g., `toPlus`, `toMinus`) return a new instance of `PrecisionNumber` with the
|
|
19
|
+
* modified value, leaving the original instance unchanged.
|
|
20
|
+
*/
|
|
21
|
+
export class PrecisionNumber {
|
|
22
|
+
// Private properties
|
|
23
|
+
readonly #decimalPlaces: number;
|
|
24
|
+
readonly #rounding: Decimal.Rounding;
|
|
25
|
+
#decimal: Decimal;
|
|
26
|
+
|
|
27
|
+
constructor(
|
|
28
|
+
value: PrecisionNumberValue = '0',
|
|
29
|
+
decimalPlaces: number = 2,
|
|
30
|
+
rounding: Decimal.Rounding = Decimal.ROUND_DOWN,
|
|
31
|
+
) {
|
|
32
|
+
this.#decimalPlaces = decimalPlaces;
|
|
33
|
+
this.#rounding = rounding;
|
|
34
|
+
this.#decimal = this.#decimalToFixedDecimal(new Decimal(value.toString().trim()));
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
// Symbols
|
|
38
|
+
[Symbol.for('nodejs.util.inspect.custom')]() {
|
|
39
|
+
return this.value;
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
[Symbol.toPrimitive](hint: string) {
|
|
43
|
+
if (hint === 'number') return this.#decimal.toNumber();
|
|
44
|
+
return this.value;
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
// Private methods
|
|
48
|
+
#decimalToFixedDecimal(decimal: Decimal) {
|
|
49
|
+
return decimal.toDecimalPlaces(this.#decimalPlaces, this.#rounding);
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
// Public getters
|
|
53
|
+
get value() {
|
|
54
|
+
return this.#decimal.toFixed(this.#decimalPlaces, this.#rounding);
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
// Static methods
|
|
58
|
+
static toFixed(
|
|
59
|
+
value: PrecisionNumberValue,
|
|
60
|
+
decimalPlaces: number = 2,
|
|
61
|
+
rounding: Decimal.Rounding = Decimal.ROUND_DOWN,
|
|
62
|
+
) {
|
|
63
|
+
return new Decimal(value.toString().trim()).toFixed(decimalPlaces, rounding);
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
// Public methods
|
|
67
|
+
absoluteValue() {
|
|
68
|
+
this.#decimal = this.#decimalToFixedDecimal(this.#decimal.absoluteValue());
|
|
69
|
+
return this;
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
dividedBy(value: PrecisionNumberValue) {
|
|
73
|
+
this.#decimal = this.#decimalToFixedDecimal(this.#decimal.dividedBy(value.toString().trim()));
|
|
74
|
+
return this;
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
equals(value: PrecisionNumberValue) {
|
|
78
|
+
return this.#decimal.equals(value.toString().trim());
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
gt(value: PrecisionNumberValue) {
|
|
82
|
+
return this.#decimal.gt(value.toString().trim());
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
gte(value: PrecisionNumberValue) {
|
|
86
|
+
return this.#decimal.gte(value.toString().trim());
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
isFinite() {
|
|
90
|
+
return this.#decimal.isFinite();
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
isInteger() {
|
|
94
|
+
return this.#decimal.isInteger();
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
isNaN() {
|
|
98
|
+
return this.#decimal.isNaN();
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
isNegative() {
|
|
102
|
+
return this.#decimal.isNegative();
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
isPositive() {
|
|
106
|
+
return this.#decimal.isPositive();
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
isZero() {
|
|
110
|
+
return this.#decimal.isZero();
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
lt(value: PrecisionNumberValue) {
|
|
114
|
+
return this.#decimal.lt(value.toString().trim());
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
lte(value: PrecisionNumberValue) {
|
|
118
|
+
return this.#decimal.lte(value.toString().trim());
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
minus(value: PrecisionNumberValue) {
|
|
122
|
+
this.#decimal = this.#decimalToFixedDecimal(this.#decimal.minus(value.toString().trim()));
|
|
123
|
+
return this;
|
|
124
|
+
}
|
|
125
|
+
|
|
126
|
+
negate() {
|
|
127
|
+
this.#decimal = this.#decimalToFixedDecimal(this.#decimal.negated());
|
|
128
|
+
return this;
|
|
129
|
+
}
|
|
130
|
+
|
|
131
|
+
plus(value: PrecisionNumberValue) {
|
|
132
|
+
this.#decimal = this.#decimalToFixedDecimal(this.#decimal.plus(value.toString().trim()));
|
|
133
|
+
return this;
|
|
134
|
+
}
|
|
135
|
+
|
|
136
|
+
times(value: PrecisionNumberValue) {
|
|
137
|
+
this.#decimal = this.#decimalToFixedDecimal(this.#decimal.times(value.toString().trim()));
|
|
138
|
+
return this;
|
|
139
|
+
}
|
|
140
|
+
|
|
141
|
+
toAbsoluteValue() {
|
|
142
|
+
return new PrecisionNumber(this.#decimal.absoluteValue(), this.#decimalPlaces, this.#rounding);
|
|
143
|
+
}
|
|
144
|
+
|
|
145
|
+
toDividedBy(value: PrecisionNumberValue) {
|
|
146
|
+
return new PrecisionNumber(
|
|
147
|
+
this.#decimal.dividedBy(value.toString().trim()),
|
|
148
|
+
this.#decimalPlaces,
|
|
149
|
+
this.#rounding,
|
|
150
|
+
);
|
|
151
|
+
}
|
|
152
|
+
|
|
153
|
+
toJSON() {
|
|
154
|
+
return this.value;
|
|
155
|
+
}
|
|
156
|
+
|
|
157
|
+
toMinus(value: PrecisionNumberValue) {
|
|
158
|
+
return new PrecisionNumber(this.#decimal.minus(value.toString().trim()), this.#decimalPlaces, this.#rounding);
|
|
159
|
+
}
|
|
160
|
+
|
|
161
|
+
toNegated() {
|
|
162
|
+
return new PrecisionNumber(this.#decimal.negated(), this.#decimalPlaces, this.#rounding);
|
|
163
|
+
}
|
|
164
|
+
|
|
165
|
+
toPlus(value: PrecisionNumberValue) {
|
|
166
|
+
return new PrecisionNumber(this.#decimal.plus(value.toString().trim()), this.#decimalPlaces, this.#rounding);
|
|
167
|
+
}
|
|
168
|
+
|
|
169
|
+
toString() {
|
|
170
|
+
return this.value;
|
|
171
|
+
}
|
|
172
|
+
|
|
173
|
+
toFixed(decimalPlaces: number = this.#decimalPlaces, rounding: Decimal.Rounding = this.#rounding) {
|
|
174
|
+
return this.#decimal.toFixed(decimalPlaces, rounding);
|
|
175
|
+
}
|
|
176
|
+
|
|
177
|
+
toTimes(value: PrecisionNumberValue) {
|
|
178
|
+
return new PrecisionNumber(this.#decimal.times(value.toString().trim()), this.#decimalPlaces, this.#rounding);
|
|
179
|
+
}
|
|
180
|
+
}
|
|
@@ -0,0 +1,174 @@
|
|
|
1
|
+
import { createConsola } from 'consola';
|
|
2
|
+
import type { ConsolaInstance } from 'consola';
|
|
3
|
+
import { NodeSSH } from 'node-ssh';
|
|
4
|
+
import type {
|
|
5
|
+
Config,
|
|
6
|
+
SSHExecCommandOptions,
|
|
7
|
+
SSHGetPutDirectoryOptions,
|
|
8
|
+
SSHPutFilesOptions,
|
|
9
|
+
} from 'node-ssh';
|
|
10
|
+
import type {
|
|
11
|
+
SFTPWrapper,
|
|
12
|
+
TransferOptions,
|
|
13
|
+
} from 'ssh2';
|
|
14
|
+
|
|
15
|
+
import type { Nullable } from '../types';
|
|
16
|
+
|
|
17
|
+
import type { PathLike } from './path';
|
|
18
|
+
|
|
19
|
+
const loggerLevelStringToConsolaLogLevelMap = {
|
|
20
|
+
debug: 4,
|
|
21
|
+
error: 0,
|
|
22
|
+
fatal: 0,
|
|
23
|
+
info: 3,
|
|
24
|
+
normal: 2,
|
|
25
|
+
silent: -999,
|
|
26
|
+
trace: 5,
|
|
27
|
+
verbose: 999,
|
|
28
|
+
warn: 1,
|
|
29
|
+
} as const;
|
|
30
|
+
|
|
31
|
+
export class SshClient {
|
|
32
|
+
readonly #connectConfig: Config;
|
|
33
|
+
readonly #logger: ConsolaInstance;
|
|
34
|
+
|
|
35
|
+
#nodeSsh: NodeSSH;
|
|
36
|
+
|
|
37
|
+
constructor(host: string, username: string, password: string, port: number = 22, connectConfig?: Config) {
|
|
38
|
+
this.#connectConfig = {
|
|
39
|
+
...connectConfig,
|
|
40
|
+
host,
|
|
41
|
+
password,
|
|
42
|
+
port,
|
|
43
|
+
username,
|
|
44
|
+
};
|
|
45
|
+
|
|
46
|
+
this.#logger = createConsola();
|
|
47
|
+
this.#nodeSsh = new NodeSSH();
|
|
48
|
+
if (process.env.NODE_ENV === 'production') this.setLoggerLevel('error');
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
get nodeSsh() {
|
|
52
|
+
return this.#nodeSsh;
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
async connect() {
|
|
56
|
+
try {
|
|
57
|
+
this.#nodeSsh = await this.#nodeSsh.connect(this.#connectConfig);
|
|
58
|
+
return true;
|
|
59
|
+
} catch (error) {
|
|
60
|
+
this.#logger.error(error);
|
|
61
|
+
return false;
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
disconnect() {
|
|
66
|
+
try {
|
|
67
|
+
this.#nodeSsh.dispose();
|
|
68
|
+
return true;
|
|
69
|
+
} catch (error) {
|
|
70
|
+
this.#logger.error(error);
|
|
71
|
+
return false;
|
|
72
|
+
}
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
execCommand(command: string, options?: SSHExecCommandOptions) {
|
|
76
|
+
return this.#nodeSsh.execCommand(command, options).catch(() => {});
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
execCommandWithIo(command: string, options?: SSHExecCommandOptions) {
|
|
80
|
+
return this.execCommand(
|
|
81
|
+
command,
|
|
82
|
+
{
|
|
83
|
+
...options,
|
|
84
|
+
onStderr: (data) => process.stderr.write(data.toString()),
|
|
85
|
+
onStdout: (data) => process.stdout.write(data.toString()),
|
|
86
|
+
},
|
|
87
|
+
);
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
getDir = this.getDirectory;
|
|
91
|
+
|
|
92
|
+
async getDirectory(localDirectory: PathLike, remoteDirectory: PathLike, options?: SSHGetPutDirectoryOptions) {
|
|
93
|
+
try {
|
|
94
|
+
return await this.#nodeSsh.getDirectory(localDirectory.toString(), remoteDirectory.toString(), options);
|
|
95
|
+
} catch (error) {
|
|
96
|
+
this.#logger.error(error);
|
|
97
|
+
return false;
|
|
98
|
+
}
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
async getFile(
|
|
102
|
+
localFile: PathLike,
|
|
103
|
+
remoteFile: PathLike,
|
|
104
|
+
givenSftp?: Nullable<SFTPWrapper>,
|
|
105
|
+
transferOptions?: Nullable<TransferOptions>,
|
|
106
|
+
) {
|
|
107
|
+
try {
|
|
108
|
+
await this.#nodeSsh.getFile(localFile.toString(), remoteFile.toString(), givenSftp, transferOptions);
|
|
109
|
+
return true;
|
|
110
|
+
} catch (error) {
|
|
111
|
+
this.#logger.error(error);
|
|
112
|
+
return false;
|
|
113
|
+
}
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
isConnected() {
|
|
117
|
+
return this.#nodeSsh.isConnected();
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
async mkdir(path: PathLike) {
|
|
121
|
+
try {
|
|
122
|
+
await this.#nodeSsh.mkdir(path.toString());
|
|
123
|
+
return true;
|
|
124
|
+
} catch (error) {
|
|
125
|
+
this.#logger.error(error);
|
|
126
|
+
return false;
|
|
127
|
+
}
|
|
128
|
+
}
|
|
129
|
+
|
|
130
|
+
putDir = this.putDirectory;
|
|
131
|
+
|
|
132
|
+
async putDirectory(localDirectory: PathLike, remoteDirectory: PathLike, options?: SSHGetPutDirectoryOptions) {
|
|
133
|
+
try {
|
|
134
|
+
return await this.#nodeSsh.putDirectory(localDirectory.toString(), remoteDirectory.toString(), options);
|
|
135
|
+
} catch (error) {
|
|
136
|
+
this.#logger.error(error);
|
|
137
|
+
return false;
|
|
138
|
+
}
|
|
139
|
+
}
|
|
140
|
+
|
|
141
|
+
async putFile(
|
|
142
|
+
localFile: PathLike,
|
|
143
|
+
remoteFile: PathLike,
|
|
144
|
+
givenSftp?: Nullable<SFTPWrapper>,
|
|
145
|
+
transferOptions?: Nullable<TransferOptions>,
|
|
146
|
+
) {
|
|
147
|
+
try {
|
|
148
|
+
await this.#nodeSsh.putFile(localFile.toString(), remoteFile.toString(), givenSftp, transferOptions);
|
|
149
|
+
return true;
|
|
150
|
+
} catch (error) {
|
|
151
|
+
this.#logger.error(error);
|
|
152
|
+
return false;
|
|
153
|
+
}
|
|
154
|
+
}
|
|
155
|
+
|
|
156
|
+
async putFiles(files: { local: PathLike; remote: PathLike }[], options?: SSHPutFilesOptions) {
|
|
157
|
+
try {
|
|
158
|
+
const convertedFiles = files.map(({ local, remote }) => ({
|
|
159
|
+
local: local.toString(),
|
|
160
|
+
remote: remote.toString(),
|
|
161
|
+
}));
|
|
162
|
+
|
|
163
|
+
await this.#nodeSsh.putFiles(convertedFiles, options);
|
|
164
|
+
return true;
|
|
165
|
+
} catch (error) {
|
|
166
|
+
this.#logger.error(error);
|
|
167
|
+
return false;
|
|
168
|
+
}
|
|
169
|
+
}
|
|
170
|
+
|
|
171
|
+
setLoggerLevel(level: keyof typeof loggerLevelStringToConsolaLogLevelMap) {
|
|
172
|
+
this.#logger.level = loggerLevelStringToConsolaLogLevelMap[level];
|
|
173
|
+
}
|
|
174
|
+
}
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
import type { ObjectId } from 'bson';
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* The following types are based on or inspired by types from the Element Plus project.
|
|
5
|
+
* Source: https://github.com/element-plus/element-plus
|
|
6
|
+
* License: MIT (https://opensource.org/licenses/MIT)
|
|
7
|
+
*
|
|
8
|
+
* Original types might have been modified to suit this project’s needs.
|
|
9
|
+
*/
|
|
10
|
+
|
|
11
|
+
/***/
|
|
12
|
+
type ConditionalPath<K extends number | string, V, U> = V extends U ? `${K}` : DefaultPath<K, V, U, never>;
|
|
13
|
+
type DefaultPath<
|
|
14
|
+
K extends number | string,
|
|
15
|
+
V,
|
|
16
|
+
U = never,
|
|
17
|
+
RK = `${K}`,
|
|
18
|
+
> = V extends TerminalType ? RK : `${K}.${FilteredKeyPath<V, U>}`;
|
|
19
|
+
|
|
20
|
+
/**
|
|
21
|
+
* A utility type that generates a union of key paths from a given object type `T`,
|
|
22
|
+
* filtered by a specific type `U`. If `U` is
|
|
23
|
+
* not provided, it defaults to including all key paths.
|
|
24
|
+
*
|
|
25
|
+
* @template T - The object type to traverse.
|
|
26
|
+
* @template U - The type used to filter key paths. Defaults to `never`, meaning no filtering.
|
|
27
|
+
*/
|
|
28
|
+
// eslint-disable-next-line style/max-len
|
|
29
|
+
export type FilteredKeyPath<T, U = never> = T extends ReadonlyArray<infer V> ? (IsTuple<T> extends true ? { [K in TupleKey<T>]-?: PathImpl<Exclude<K, symbol>, T[K], U> }[TupleKey<T>] : PathImpl<number, V, U>) : { [K in keyof T]-?: PathImpl<Exclude<K, symbol>, T[K], U> }[keyof T];
|
|
30
|
+
type IsTuple<T extends ReadonlyArray<any>> = number extends T['length'] ? false : true;
|
|
31
|
+
type PathImpl<K extends number | string, V, U> = [U] extends [never] ? DefaultPath<K, V> : ConditionalPath<K, V, U>;
|
|
32
|
+
type TerminalType =
|
|
33
|
+
| bigint
|
|
34
|
+
| Blob
|
|
35
|
+
| boolean
|
|
36
|
+
| Date
|
|
37
|
+
| File
|
|
38
|
+
| null
|
|
39
|
+
| number
|
|
40
|
+
| ObjectId
|
|
41
|
+
| RegExp
|
|
42
|
+
| string
|
|
43
|
+
| symbol
|
|
44
|
+
| undefined;
|
|
45
|
+
|
|
46
|
+
type TupleKey<T extends ReadonlyArray<any>> = Exclude<keyof T, keyof any[]>;
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import type {
|
|
2
|
+
Buffer,
|
|
3
|
+
Blob as NodeBlob,
|
|
4
|
+
File as NodeFile,
|
|
5
|
+
} from 'node:buffer';
|
|
6
|
+
|
|
7
|
+
export type { FilteredKeyPath } from './filtered-key-path';
|
|
8
|
+
|
|
9
|
+
export type AnyRecord = Record<string, any>;
|
|
10
|
+
export type BinaryInput = Blob | Buffer | File | NodeBlob | NodeFile;
|
|
11
|
+
export type Booleanish = 'false' | 'true' | boolean;
|
|
12
|
+
export type MaybePartial<T> = Partial<T> | T;
|
|
13
|
+
export type MaybeReadonly<T> = Readonly<T> | T;
|
|
14
|
+
export type Nullable<T> = null | T;
|
|
15
|
+
export type Numberish = number | string;
|
|
16
|
+
export type PartialRecord<K extends keyof any, T> = Partial<Record<K, T>>;
|
|
17
|
+
export type ReadonlyPartialRecord<K extends keyof any, T> = Readonly<PartialRecord<K, T>>;
|
|
18
|
+
export type ReadonlyRecord<K extends keyof any, T> = Readonly<Record<K, T>>;
|
package/src/types/vue.ts
ADDED
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import type { GlobalComponents } from 'vue';
|
|
2
|
+
|
|
3
|
+
import type { Nullable } from './';
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
* A type that represents a reference to a Vue component instance.
|
|
7
|
+
* The reference can be either an instance of the specified component or null.
|
|
8
|
+
*
|
|
9
|
+
* @template K - The key of the component in the GlobalComponents.
|
|
10
|
+
*
|
|
11
|
+
* @example
|
|
12
|
+
* ```typescript
|
|
13
|
+
* import type { ComponentRef } from '@kikiutils/types/vue';
|
|
14
|
+
*
|
|
15
|
+
* const keepAliveRef = ref<ComponentRef<'KeepAlive'>>(null);
|
|
16
|
+
* ```
|
|
17
|
+
*/
|
|
18
|
+
export type ComponentRef<K extends keyof GlobalComponents> = Nullable<InstanceType<GlobalComponents[K]>>;
|
package/src/vue.ts
CHANGED
|
@@ -5,7 +5,8 @@ import {
|
|
|
5
5
|
useRoute,
|
|
6
6
|
} from 'vue-router';
|
|
7
7
|
|
|
8
|
-
import {
|
|
8
|
+
import type { Nullable } from './types';
|
|
9
|
+
import { appendRedirectParamToUrl } from './url';
|
|
9
10
|
|
|
10
11
|
/**
|
|
11
12
|
* Appends the current Vue Router route's fullPath as the `redirect` query parameter to the given URL.
|
|
@@ -21,9 +22,9 @@ export function appendRedirectParamFromCurrentRouteToUrl(url: string) {
|
|
|
21
22
|
/**
|
|
22
23
|
* Clears an interval referenced by a Vue ref and sets it to null.
|
|
23
24
|
*
|
|
24
|
-
* @param {Ref<
|
|
25
|
+
* @param {Ref<Nullable<ReturnType<typeof setInterval>>>} intervalRef - A Vue ref holding a NodeJS.Timeout or null
|
|
25
26
|
*/
|
|
26
|
-
export function clearIntervalRef(intervalRef: Ref<
|
|
27
|
+
export function clearIntervalRef(intervalRef: Ref<Nullable<ReturnType<typeof setInterval>>>) {
|
|
27
28
|
if (intervalRef.value) clearInterval(intervalRef.value);
|
|
28
29
|
intervalRef.value = null;
|
|
29
30
|
}
|
|
@@ -31,9 +32,9 @@ export function clearIntervalRef(intervalRef: Ref<null | ReturnType<typeof setIn
|
|
|
31
32
|
/**
|
|
32
33
|
* Clears a timeout referenced by a Vue ref and sets it to null.
|
|
33
34
|
*
|
|
34
|
-
* @param {Ref<
|
|
35
|
+
* @param {Ref<Nullable<ReturnType<typeof setTimeout>>>} timeoutRef - A Vue ref holding a NodeJS.Timeout or null
|
|
35
36
|
*/
|
|
36
|
-
export function clearTimeoutRef(timeoutRef: Ref<
|
|
37
|
+
export function clearTimeoutRef(timeoutRef: Ref<Nullable<ReturnType<typeof setTimeout>>>) {
|
|
37
38
|
if (timeoutRef.value) clearTimeout(timeoutRef.value);
|
|
38
39
|
timeoutRef.value = null;
|
|
39
40
|
}
|
|
@@ -44,9 +45,9 @@ export function clearTimeoutRef(timeoutRef: Ref<null | ReturnType<typeof setTime
|
|
|
44
45
|
*
|
|
45
46
|
* @template T - The type of the scrollable element (defaults to HTMLElement)
|
|
46
47
|
*
|
|
47
|
-
* @param {Ref<
|
|
48
|
+
* @param {Ref<Nullable<T>>} containerRef - A ref to the scrollable HTML element
|
|
48
49
|
*/
|
|
49
|
-
export function usePreserveScroll<T extends Element = HTMLElement>(containerRef: Ref<
|
|
50
|
+
export function usePreserveScroll<T extends Element = HTMLElement>(containerRef: Ref<Nullable<T>>) {
|
|
50
51
|
let scrollLeft = 0;
|
|
51
52
|
let scrollTop = 0;
|
|
52
53
|
onActivated(() => {
|
package/src/web.ts
CHANGED