@decohere/core 0.0.1-dev.116
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/commonjs/src/caching/cache-manager.js +98 -0
- package/commonjs/src/caching/cache.decorator.js +69 -0
- package/commonjs/src/caching/cache.js +6 -0
- package/commonjs/src/caching/index.js +23 -0
- package/commonjs/src/caching/invalidate-cache.decorator.js +92 -0
- package/commonjs/src/caching/memoize.decorator.js +36 -0
- package/commonjs/src/caching/node-cache-memoize.adapter.js +49 -0
- package/commonjs/src/cli/action.js +65 -0
- package/commonjs/src/cli/command.js +127 -0
- package/commonjs/src/cli/index.js +61 -0
- package/commonjs/src/cli/module.type.js +18 -0
- package/commonjs/src/cli/options.js +115 -0
- package/commonjs/src/collections/collections.js +21 -0
- package/commonjs/src/collections/find-duplicates.js +35 -0
- package/commonjs/src/collections/index.js +52 -0
- package/commonjs/src/collections/merge-arrays.js +34 -0
- package/commonjs/src/collections/sum.js +63 -0
- package/commonjs/src/collections/unique-objects.js +39 -0
- package/commonjs/src/composition/index.js +4 -0
- package/commonjs/src/configuration/configuration.types.js +11 -0
- package/commonjs/src/configuration/index.js +18 -0
- package/commonjs/src/diagnostics/index.js +22 -0
- package/commonjs/src/diagnostics/trace.js +86 -0
- package/commonjs/src/extensibility/decorator-factory-base.js +22 -0
- package/commonjs/src/extensibility/decorator-factory.js +31 -0
- package/commonjs/src/extensibility/extension.js +37 -0
- package/commonjs/src/extensibility/index.js +23 -0
- package/commonjs/src/extensibility/mixwith.js +36 -0
- package/commonjs/src/extensibility/pipeline.js +56 -0
- package/commonjs/src/extensibility/step.js +18 -0
- package/commonjs/src/interop/docker/docker.js +54 -0
- package/commonjs/src/interop/errors/interop.error.js +12 -0
- package/commonjs/src/interop/git/git.js +134 -0
- package/commonjs/src/interop/git/git.types.js +4 -0
- package/commonjs/src/interop/index.js +97 -0
- package/commonjs/src/interop/node/index.js +18 -0
- package/commonjs/src/interop/node/node.js +45 -0
- package/commonjs/src/interop/npm/npm.js +231 -0
- package/commonjs/src/interop/npm/npm.types.js +16 -0
- package/commonjs/src/interop/pnpm/pnpm.js +34 -0
- package/commonjs/src/interop/pnpm/pnpm.types.js +4 -0
- package/commonjs/src/interop/shell/shell.argv.js +45 -0
- package/commonjs/src/interop/shell/shell.js +105 -0
- package/commonjs/src/interop/shell/shell.types.js +4 -0
- package/commonjs/src/interop/types/detect-package-manager.js +71 -0
- package/commonjs/src/interop/types/package-manager.js +4 -0
- package/commonjs/src/interop/yarn/yarn.js +34 -0
- package/commonjs/src/interop/yarn/yarn.types.js +4 -0
- package/commonjs/src/io/copy-file.js +25 -0
- package/commonjs/src/io/delete-file.js +21 -0
- package/commonjs/src/io/directory-exists.js +24 -0
- package/commonjs/src/io/file-exists.js +19 -0
- package/commonjs/src/io/find-directories.js +21 -0
- package/commonjs/src/io/find-file.js +45 -0
- package/commonjs/src/io/index.js +66 -0
- package/commonjs/src/io/io.js +28 -0
- package/commonjs/src/io/read-file.js +39 -0
- package/commonjs/src/io/remove-dir.js +22 -0
- package/commonjs/src/io/types/directory.type.js +4 -0
- package/commonjs/src/io/types/file.js +28 -0
- package/commonjs/src/io/types/index.js +19 -0
- package/commonjs/src/io/url-to-path.js +33 -0
- package/commonjs/src/io/watch.js +261 -0
- package/commonjs/src/io/write-file.js +30 -0
- package/commonjs/src/objects/deep-merge.js +67 -0
- package/commonjs/src/objects/index.js +11 -0
- package/commonjs/src/reflection/index.js +20 -0
- package/commonjs/src/reflection/types/index.js +18 -0
- package/commonjs/src/reflection/types/reflection.types.js +26 -0
- package/commonjs/src/reflection/utilities.js +118 -0
- package/commonjs/src/semver/index.js +18 -0
- package/commonjs/src/semver/semver.js +92 -0
- package/commonjs/src/system/camel-case.js +13 -0
- package/commonjs/src/system/debounce.js +19 -0
- package/commonjs/src/system/decorator.js +46 -0
- package/commonjs/src/system/environment.js +23 -0
- package/commonjs/src/system/function.types.js +18 -0
- package/commonjs/src/system/index.js +24 -0
- package/commonjs/src/system/retry.decorator.js +40 -0
- package/commonjs/src/system/sleep.js +13 -0
- package/commonjs/src/system/type.utils.js +4 -0
- package/commonjs/src/testing/flush-promises.js +16 -0
- package/commonjs/src/testing/glob-with-memfs.js +22 -0
- package/commonjs/src/testing/index.js +22 -0
- package/commonjs/src/testing/memfs.js +52 -0
- package/commonjs/src/testing/mock-logger.js +36 -0
- package/commonjs/src/testing/spy-on-constructor.js +27 -0
- package/es6/src/caching/cache-manager.js +82 -0
- package/es6/src/caching/cache.decorator.js +51 -0
- package/es6/src/caching/cache.js +3 -0
- package/es6/src/caching/index.js +6 -0
- package/es6/src/caching/invalidate-cache.decorator.js +71 -0
- package/es6/src/caching/memoize.decorator.js +27 -0
- package/es6/src/caching/node-cache-memoize.adapter.js +37 -0
- package/es6/src/cli/action.js +47 -0
- package/es6/src/cli/command.js +106 -0
- package/es6/src/cli/index.js +4 -0
- package/es6/src/cli/module.type.js +11 -0
- package/es6/src/cli/options.js +76 -0
- package/es6/src/collections/collections.js +4 -0
- package/es6/src/collections/find-duplicates.js +17 -0
- package/es6/src/collections/index.js +1 -0
- package/es6/src/collections/merge-arrays.js +16 -0
- package/es6/src/collections/sum.js +45 -0
- package/es6/src/collections/unique-objects.js +21 -0
- package/es6/src/composition/index.js +1 -0
- package/es6/src/configuration/configuration.types.js +1 -0
- package/es6/src/configuration/index.js +1 -0
- package/es6/src/diagnostics/index.js +1 -0
- package/es6/src/diagnostics/trace.js +68 -0
- package/es6/src/extensibility/decorator-factory-base.js +39 -0
- package/es6/src/extensibility/decorator-factory.js +21 -0
- package/es6/src/extensibility/extension.js +27 -0
- package/es6/src/extensibility/index.js +6 -0
- package/es6/src/extensibility/mixwith.js +26 -0
- package/es6/src/extensibility/pipeline.js +46 -0
- package/es6/src/extensibility/step.js +16 -0
- package/es6/src/interop/docker/docker.js +44 -0
- package/es6/src/interop/errors/interop.error.js +2 -0
- package/es6/src/interop/git/git.js +124 -0
- package/es6/src/interop/git/git.types.js +1 -0
- package/es6/src/interop/index.js +21 -0
- package/es6/src/interop/node/index.js +1 -0
- package/es6/src/interop/node/node.js +35 -0
- package/es6/src/interop/npm/npm.js +180 -0
- package/es6/src/interop/npm/npm.types.js +6 -0
- package/es6/src/interop/pnpm/pnpm.js +24 -0
- package/es6/src/interop/pnpm/pnpm.types.js +1 -0
- package/es6/src/interop/shell/shell.argv.js +35 -0
- package/es6/src/interop/shell/shell.js +95 -0
- package/es6/src/interop/shell/shell.types.js +1 -0
- package/es6/src/interop/types/detect-package-manager.js +50 -0
- package/es6/src/interop/types/package-manager.js +1 -0
- package/es6/src/interop/yarn/yarn.js +24 -0
- package/es6/src/interop/yarn/yarn.types.js +1 -0
- package/es6/src/io/copy-file.js +10 -0
- package/es6/src/io/delete-file.js +6 -0
- package/es6/src/io/directory-exists.js +9 -0
- package/es6/src/io/file-exists.js +9 -0
- package/es6/src/io/find-directories.js +11 -0
- package/es6/src/io/find-file.js +27 -0
- package/es6/src/io/index.js +2 -0
- package/es6/src/io/io.js +11 -0
- package/es6/src/io/read-file.js +13 -0
- package/es6/src/io/remove-dir.js +7 -0
- package/es6/src/io/types/directory.type.js +1 -0
- package/es6/src/io/types/file.js +18 -0
- package/es6/src/io/types/index.js +2 -0
- package/es6/src/io/url-to-path.js +15 -0
- package/es6/src/io/watch.js +238 -0
- package/es6/src/io/write-file.js +15 -0
- package/es6/src/objects/deep-merge.js +57 -0
- package/es6/src/objects/index.js +1 -0
- package/es6/src/reflection/index.js +3 -0
- package/es6/src/reflection/types/index.js +1 -0
- package/es6/src/reflection/types/reflection.types.js +8 -0
- package/es6/src/reflection/utilities.js +74 -0
- package/es6/src/semver/index.js +1 -0
- package/es6/src/semver/semver.js +71 -0
- package/es6/src/system/camel-case.js +3 -0
- package/es6/src/system/debounce.js +9 -0
- package/es6/src/system/decorator.js +30 -0
- package/es6/src/system/environment.js +5 -0
- package/es6/src/system/function.types.js +26 -0
- package/es6/src/system/index.js +7 -0
- package/es6/src/system/retry.decorator.js +30 -0
- package/es6/src/system/sleep.js +3 -0
- package/es6/src/system/type.utils.js +1 -0
- package/es6/src/testing/flush-promises.js +6 -0
- package/es6/src/testing/glob-with-memfs.js +20 -0
- package/es6/src/testing/index.js +5 -0
- package/es6/src/testing/memfs.js +25 -0
- package/es6/src/testing/mock-logger.js +26 -0
- package/es6/src/testing/spy-on-constructor.js +31 -0
- package/package.json +106 -0
- package/types/src/caching/cache-manager.d.ts +59 -0
- package/types/src/caching/cache.d.ts +11 -0
- package/types/src/caching/cache.decorator.d.ts +18 -0
- package/types/src/caching/index.d.ts +6 -0
- package/types/src/caching/invalidate-cache.decorator.d.ts +17 -0
- package/types/src/caching/memoize.decorator.d.ts +16 -0
- package/types/src/caching/node-cache-memoize.adapter.d.ts +22 -0
- package/types/src/cli/action.d.ts +36 -0
- package/types/src/cli/command.d.ts +34 -0
- package/types/src/cli/index.d.ts +7 -0
- package/types/src/cli/module.type.d.ts +36 -0
- package/types/src/cli/options.d.ts +28 -0
- package/types/src/collections/collections.d.ts +4 -0
- package/types/src/collections/find-duplicates.d.ts +2 -0
- package/types/src/collections/index.d.ts +1 -0
- package/types/src/collections/merge-arrays.d.ts +2 -0
- package/types/src/collections/sum.d.ts +4 -0
- package/types/src/collections/unique-objects.d.ts +2 -0
- package/types/src/composition/index.d.ts +37 -0
- package/types/src/configuration/configuration.types.d.ts +10 -0
- package/types/src/configuration/index.d.ts +1 -0
- package/types/src/diagnostics/index.d.ts +1 -0
- package/types/src/diagnostics/trace.d.ts +10 -0
- package/types/src/extensibility/decorator-factory-base.d.ts +39 -0
- package/types/src/extensibility/decorator-factory.d.ts +19 -0
- package/types/src/extensibility/extension.d.ts +9 -0
- package/types/src/extensibility/index.d.ts +6 -0
- package/types/src/extensibility/mixwith.d.ts +6 -0
- package/types/src/extensibility/pipeline.d.ts +12 -0
- package/types/src/extensibility/step.d.ts +16 -0
- package/types/src/interop/docker/docker.d.ts +19 -0
- package/types/src/interop/errors/interop.error.d.ts +2 -0
- package/types/src/interop/git/git.d.ts +16 -0
- package/types/src/interop/git/git.types.d.ts +14 -0
- package/types/src/interop/index.d.ts +14 -0
- package/types/src/interop/node/index.d.ts +1 -0
- package/types/src/interop/node/node.d.ts +5 -0
- package/types/src/interop/npm/npm.d.ts +29 -0
- package/types/src/interop/npm/npm.types.d.ts +24 -0
- package/types/src/interop/pnpm/pnpm.d.ts +9 -0
- package/types/src/interop/pnpm/pnpm.types.d.ts +3 -0
- package/types/src/interop/shell/shell.argv.d.ts +5 -0
- package/types/src/interop/shell/shell.d.ts +6 -0
- package/types/src/interop/shell/shell.types.d.ts +9 -0
- package/types/src/interop/types/detect-package-manager.d.ts +4 -0
- package/types/src/interop/types/package-manager.d.ts +10 -0
- package/types/src/interop/yarn/yarn.d.ts +9 -0
- package/types/src/interop/yarn/yarn.types.d.ts +3 -0
- package/types/src/io/copy-file.d.ts +4 -0
- package/types/src/io/delete-file.d.ts +1 -0
- package/types/src/io/directory-exists.d.ts +1 -0
- package/types/src/io/file-exists.d.ts +1 -0
- package/types/src/io/find-directories.d.ts +2 -0
- package/types/src/io/find-file.d.ts +9 -0
- package/types/src/io/index.d.ts +2 -0
- package/types/src/io/io.d.ts +11 -0
- package/types/src/io/read-file.d.ts +4 -0
- package/types/src/io/remove-dir.d.ts +5 -0
- package/types/src/io/types/directory.type.d.ts +4 -0
- package/types/src/io/types/file.d.ts +20 -0
- package/types/src/io/types/index.d.ts +2 -0
- package/types/src/io/url-to-path.d.ts +2 -0
- package/types/src/io/watch.d.ts +16 -0
- package/types/src/io/write-file.d.ts +5 -0
- package/types/src/objects/deep-merge.d.ts +41 -0
- package/types/src/objects/index.d.ts +1 -0
- package/types/src/reflection/index.d.ts +3 -0
- package/types/src/reflection/types/index.d.ts +1 -0
- package/types/src/reflection/types/reflection.types.d.ts +21 -0
- package/types/src/reflection/utilities.d.ts +27 -0
- package/types/src/semver/index.d.ts +1 -0
- package/types/src/semver/semver.d.ts +18 -0
- package/types/src/system/camel-case.d.ts +1 -0
- package/types/src/system/debounce.d.ts +1 -0
- package/types/src/system/decorator.d.ts +15 -0
- package/types/src/system/environment.d.ts +6 -0
- package/types/src/system/function.types.d.ts +55 -0
- package/types/src/system/index.d.ts +7 -0
- package/types/src/system/retry.decorator.d.ts +6 -0
- package/types/src/system/sleep.d.ts +1 -0
- package/types/src/system/type.utils.d.ts +1 -0
- package/types/src/testing/flush-promises.d.ts +1 -0
- package/types/src/testing/glob-with-memfs.d.ts +3 -0
- package/types/src/testing/index.d.ts +5 -0
- package/types/src/testing/memfs.d.ts +5 -0
- package/types/src/testing/mock-logger.d.ts +13 -0
- package/types/src/testing/spy-on-constructor.d.ts +21 -0
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
import { existsSync } from "node:fs";
|
|
2
|
+
import { join } from "node:path";
|
|
3
|
+
import { createInterface } from "node:readline/promises";
|
|
4
|
+
import { Npm } from "../npm/npm.js";
|
|
5
|
+
import { Pnpm } from "../pnpm/pnpm.js";
|
|
6
|
+
import { Yarn } from "../yarn/yarn.js";
|
|
7
|
+
const LOCKFILES = [
|
|
8
|
+
[
|
|
9
|
+
"pnpm-lock.yaml",
|
|
10
|
+
()=>new Pnpm()
|
|
11
|
+
],
|
|
12
|
+
[
|
|
13
|
+
"yarn.lock",
|
|
14
|
+
()=>new Yarn()
|
|
15
|
+
],
|
|
16
|
+
[
|
|
17
|
+
"package-lock.json",
|
|
18
|
+
()=>new Npm()
|
|
19
|
+
]
|
|
20
|
+
];
|
|
21
|
+
function fromLockfile(cwd) {
|
|
22
|
+
for (const [file, factory] of LOCKFILES){
|
|
23
|
+
if (existsSync(join(cwd, file))) return factory();
|
|
24
|
+
}
|
|
25
|
+
return undefined;
|
|
26
|
+
}
|
|
27
|
+
function fromUserAgent() {
|
|
28
|
+
const agent = process.env.npm_config_user_agent ?? "";
|
|
29
|
+
if (agent.startsWith("pnpm")) return new Pnpm();
|
|
30
|
+
if (agent.startsWith("yarn")) return new Yarn();
|
|
31
|
+
if (agent.startsWith("npm")) return new Npm();
|
|
32
|
+
return undefined;
|
|
33
|
+
}
|
|
34
|
+
export function detectPackageManager(cwd) {
|
|
35
|
+
return fromLockfile(cwd) ?? fromUserAgent();
|
|
36
|
+
}
|
|
37
|
+
export function packageManagerFromString(name) {
|
|
38
|
+
if (name === "yarn") return new Yarn();
|
|
39
|
+
if (name === "npm") return new Npm();
|
|
40
|
+
return new Pnpm();
|
|
41
|
+
}
|
|
42
|
+
export async function promptForPackageManager() {
|
|
43
|
+
const rl = createInterface({
|
|
44
|
+
input: process.stdin,
|
|
45
|
+
output: process.stdout
|
|
46
|
+
});
|
|
47
|
+
const answer = await rl.question("Package manager? [pnpm/yarn/npm] (default: pnpm): ");
|
|
48
|
+
rl.close();
|
|
49
|
+
return packageManagerFromString(answer.trim().toLowerCase());
|
|
50
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export { };
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
import { Shell } from "../shell/shell.js";
|
|
2
|
+
const Commands = {
|
|
3
|
+
install: "install"
|
|
4
|
+
};
|
|
5
|
+
export class Yarn extends Shell {
|
|
6
|
+
name = "yarn";
|
|
7
|
+
program = "yarn";
|
|
8
|
+
async install(options = {
|
|
9
|
+
cwd: "./"
|
|
10
|
+
}) {
|
|
11
|
+
const { cwd } = options;
|
|
12
|
+
return this.run({
|
|
13
|
+
cwd
|
|
14
|
+
}, Commands.install);
|
|
15
|
+
}
|
|
16
|
+
async syncLockFile(options = {
|
|
17
|
+
cwd: "./"
|
|
18
|
+
}) {
|
|
19
|
+
const { cwd } = options;
|
|
20
|
+
return this.run({
|
|
21
|
+
cwd
|
|
22
|
+
}, Commands.install, "--mode", "update-lockfile", "--ignore-scripts");
|
|
23
|
+
}
|
|
24
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export { };
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import { glob } from "glob";
|
|
2
|
+
export async function findDirectories(...pattern) {
|
|
3
|
+
const paths = await glob(pattern, {
|
|
4
|
+
withFileTypes: true
|
|
5
|
+
});
|
|
6
|
+
const dirs = paths.filter((p)=>p.isDirectory()).map((p)=>({
|
|
7
|
+
name: p.name,
|
|
8
|
+
parentPath: p.parentPath
|
|
9
|
+
}));
|
|
10
|
+
return dirs;
|
|
11
|
+
}
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
import { glob } from "glob";
|
|
2
|
+
import { FileEx } from "./types/file.js";
|
|
3
|
+
export async function findFile(pattern) {
|
|
4
|
+
const files = await glob(pattern, {
|
|
5
|
+
includeChildMatches: false
|
|
6
|
+
});
|
|
7
|
+
if (files.length === 0) {
|
|
8
|
+
return;
|
|
9
|
+
}
|
|
10
|
+
const file = {
|
|
11
|
+
relativePath: files.at(0)
|
|
12
|
+
};
|
|
13
|
+
return file;
|
|
14
|
+
}
|
|
15
|
+
export async function findFiles(patterns, options) {
|
|
16
|
+
const paths = await glob(patterns, {
|
|
17
|
+
...options,
|
|
18
|
+
withFileTypes: true
|
|
19
|
+
});
|
|
20
|
+
const files = paths.filter((p)=>p.isFile()).map((p)=>{
|
|
21
|
+
return new FileEx({
|
|
22
|
+
relativePath: p.relative(),
|
|
23
|
+
fullPath: p.fullpath()
|
|
24
|
+
});
|
|
25
|
+
});
|
|
26
|
+
return files;
|
|
27
|
+
}
|
package/es6/src/io/io.js
ADDED
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
export * from "./copy-file.js";
|
|
2
|
+
export * from "./delete-file.js";
|
|
3
|
+
export * from "./directory-exists.js";
|
|
4
|
+
export * from "./file-exists.js";
|
|
5
|
+
export * from "./find-directories.js";
|
|
6
|
+
export * from "./find-file.js";
|
|
7
|
+
export * from "./read-file.js";
|
|
8
|
+
export * from "./remove-dir.js";
|
|
9
|
+
export * from "./url-to-path.js";
|
|
10
|
+
export * from "./watch.js";
|
|
11
|
+
export * from "./write-file.js";
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import fs from "node:fs/promises";
|
|
2
|
+
export async function readFiles(filePaths, encoding = "utf8") {
|
|
3
|
+
const data = await Promise.all(filePaths.map((file)=>readFile(file.fullPath, encoding)));
|
|
4
|
+
return data;
|
|
5
|
+
}
|
|
6
|
+
export async function readFile(filePath, encoding = "utf8") {
|
|
7
|
+
const data = await fs.readFile(filePath, encoding);
|
|
8
|
+
return data;
|
|
9
|
+
}
|
|
10
|
+
export async function readJsonFile(filePath, encoding = "utf8") {
|
|
11
|
+
const data = await readFile(filePath, encoding);
|
|
12
|
+
return JSON.parse(data);
|
|
13
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export { };
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import { readFile } from "../read-file.js";
|
|
2
|
+
export class FileEx {
|
|
3
|
+
constructor(data){
|
|
4
|
+
this.fullPath = data.fullPath;
|
|
5
|
+
this.relativePath = data.relativePath ?? data.fullPath;
|
|
6
|
+
this.#content = data.content;
|
|
7
|
+
}
|
|
8
|
+
#content;
|
|
9
|
+
fullPath;
|
|
10
|
+
relativePath;
|
|
11
|
+
toString() {
|
|
12
|
+
return this.relativePath;
|
|
13
|
+
}
|
|
14
|
+
async getContent() {
|
|
15
|
+
if (this.#content != null) return this.#content;
|
|
16
|
+
return readFile(this.fullPath);
|
|
17
|
+
}
|
|
18
|
+
}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import { fileURLToPath, pathToFileURL } from "node:url";
|
|
2
|
+
export const fileUrlToPath = (url)=>{
|
|
3
|
+
try {
|
|
4
|
+
return fileURLToPath(url);
|
|
5
|
+
} catch {
|
|
6
|
+
return url;
|
|
7
|
+
}
|
|
8
|
+
};
|
|
9
|
+
export const pathToFileUrl = (path)=>{
|
|
10
|
+
try {
|
|
11
|
+
return pathToFileURL(path).toString();
|
|
12
|
+
} catch {
|
|
13
|
+
return path;
|
|
14
|
+
}
|
|
15
|
+
};
|
|
@@ -0,0 +1,238 @@
|
|
|
1
|
+
import { watch as nativeWatch, readdirSync, statSync } from "node:fs";
|
|
2
|
+
import path from "node:path";
|
|
3
|
+
import picomatch from "picomatch";
|
|
4
|
+
import { FileEx } from "./types/file.js";
|
|
5
|
+
export const WatchEvents = {
|
|
6
|
+
add: "add",
|
|
7
|
+
change: "change",
|
|
8
|
+
addDir: "addDir",
|
|
9
|
+
unlink: "unlink",
|
|
10
|
+
unlinkDir: "unlinkDir"
|
|
11
|
+
};
|
|
12
|
+
export function watch(directory, options = {
|
|
13
|
+
cwd: "."
|
|
14
|
+
}) {
|
|
15
|
+
const { include, ignore, ignoreInitial = false } = options;
|
|
16
|
+
const changeCoalesceMs = 25;
|
|
17
|
+
const handlers = {
|
|
18
|
+
ready: new Set(),
|
|
19
|
+
add: new Set(),
|
|
20
|
+
change: new Set(),
|
|
21
|
+
addDir: new Set(),
|
|
22
|
+
unlink: new Set(),
|
|
23
|
+
unlinkDir: new Set()
|
|
24
|
+
};
|
|
25
|
+
let resolveReady;
|
|
26
|
+
const ready = new Promise((resolve)=>{
|
|
27
|
+
resolveReady = resolve;
|
|
28
|
+
});
|
|
29
|
+
const snapshot = buildSnapshot(directory);
|
|
30
|
+
const isFiltered = (relativePath)=>{
|
|
31
|
+
const posixRelativePath = toPosixPath(relativePath);
|
|
32
|
+
const posixFullPath = toPosixPath(path.resolve(directory, relativePath));
|
|
33
|
+
const matchesEitherPath = (patterns)=>picomatch.isMatch(posixRelativePath, patterns) || picomatch.isMatch(posixFullPath, patterns);
|
|
34
|
+
if (include && include.length > 0) {
|
|
35
|
+
return !matchesEitherPath(include);
|
|
36
|
+
}
|
|
37
|
+
if (ignore && ignore.length > 0) {
|
|
38
|
+
return matchesEitherPath(ignore);
|
|
39
|
+
}
|
|
40
|
+
return false;
|
|
41
|
+
};
|
|
42
|
+
const emit = (event, relativePath)=>{
|
|
43
|
+
if (isFiltered(relativePath)) {
|
|
44
|
+
return;
|
|
45
|
+
}
|
|
46
|
+
const fullPath = path.resolve(directory, relativePath);
|
|
47
|
+
for (const handler of handlers[event]){
|
|
48
|
+
handler(new FileEx({
|
|
49
|
+
fullPath,
|
|
50
|
+
relativePath
|
|
51
|
+
}));
|
|
52
|
+
}
|
|
53
|
+
};
|
|
54
|
+
const pendingChangeTimers = new Map();
|
|
55
|
+
const emitChange = (relativePath)=>{
|
|
56
|
+
const existing = pendingChangeTimers.get(relativePath);
|
|
57
|
+
if (existing != null) {
|
|
58
|
+
clearTimeout(existing);
|
|
59
|
+
}
|
|
60
|
+
const timer = setTimeout(()=>{
|
|
61
|
+
pendingChangeTimers.delete(relativePath);
|
|
62
|
+
emit("change", relativePath);
|
|
63
|
+
}, changeCoalesceMs);
|
|
64
|
+
pendingChangeTimers.set(relativePath, timer);
|
|
65
|
+
};
|
|
66
|
+
const emitReady = ()=>{
|
|
67
|
+
for (const handler of handlers.ready){
|
|
68
|
+
handler();
|
|
69
|
+
}
|
|
70
|
+
};
|
|
71
|
+
queueMicrotask(()=>{
|
|
72
|
+
if (!ignoreInitial) {
|
|
73
|
+
for (const [relativePath, entry] of snapshot){
|
|
74
|
+
emit(entry.isDirectory ? "addDir" : "add", relativePath);
|
|
75
|
+
}
|
|
76
|
+
}
|
|
77
|
+
emitReady();
|
|
78
|
+
resolveReady?.();
|
|
79
|
+
resolveReady = undefined;
|
|
80
|
+
});
|
|
81
|
+
// One non-recursive watcher per directory. Node's recursive mode on Linux tracks files
|
|
82
|
+
// individually and goes silent for a file once an editor replaces it with an atomic save
|
|
83
|
+
// (write temp file, rename over the original); directory watchers keep seeing it (#505).
|
|
84
|
+
const directoryWatchers = new Map();
|
|
85
|
+
const watchDirectory = (relativeDir)=>{
|
|
86
|
+
if (directoryWatchers.has(relativeDir)) {
|
|
87
|
+
return;
|
|
88
|
+
}
|
|
89
|
+
try {
|
|
90
|
+
const watcher = nativeWatch(path.resolve(directory, relativeDir), (_eventType, fileName)=>{
|
|
91
|
+
if (fileName != null) {
|
|
92
|
+
onFsEvent(path.posix.join(relativeDir, toPosixPath(fileName.toString())));
|
|
93
|
+
}
|
|
94
|
+
});
|
|
95
|
+
watcher.on("error", ()=>unwatchDirectory(relativeDir));
|
|
96
|
+
directoryWatchers.set(relativeDir, watcher);
|
|
97
|
+
} catch {
|
|
98
|
+
// The directory vanished before we could watch it; its unlink event covers it.
|
|
99
|
+
}
|
|
100
|
+
};
|
|
101
|
+
const unwatchDirectory = (relativeDir)=>{
|
|
102
|
+
for (const [watchedDir, watcher] of directoryWatchers){
|
|
103
|
+
if (watchedDir === relativeDir || watchedDir.startsWith(`${relativeDir}/`)) {
|
|
104
|
+
watcher.close();
|
|
105
|
+
directoryWatchers.delete(watchedDir);
|
|
106
|
+
}
|
|
107
|
+
}
|
|
108
|
+
};
|
|
109
|
+
/** A directory appeared: watch it, and report what was created in it before we were watching. */ const addDirectory = (relativeDir)=>{
|
|
110
|
+
watchDirectory(relativeDir);
|
|
111
|
+
const found = new Map();
|
|
112
|
+
try {
|
|
113
|
+
collectSnapshotEntries(directory, path.resolve(directory, relativeDir), found);
|
|
114
|
+
} catch {
|
|
115
|
+
return;
|
|
116
|
+
}
|
|
117
|
+
for (const [relativePath, entry] of found){
|
|
118
|
+
if (snapshot.has(relativePath)) continue;
|
|
119
|
+
snapshot.set(relativePath, entry);
|
|
120
|
+
if (entry.isDirectory) watchDirectory(relativePath);
|
|
121
|
+
emit(entry.isDirectory ? "addDir" : "add", relativePath);
|
|
122
|
+
}
|
|
123
|
+
};
|
|
124
|
+
/** A directory went away: stop watching it and forget everything that was under it. */ const removeDirectoryContents = (relativeDir)=>{
|
|
125
|
+
unwatchDirectory(relativeDir);
|
|
126
|
+
// oxlint-disable-next-line unicorn/no-useless-spread -- iterate a copy: the loop deletes from the snapshot
|
|
127
|
+
for (const [relativePath, entry] of [
|
|
128
|
+
...snapshot
|
|
129
|
+
]){
|
|
130
|
+
if (relativePath.startsWith(`${relativeDir}/`)) {
|
|
131
|
+
snapshot.delete(relativePath);
|
|
132
|
+
emit(entry.isDirectory ? "unlinkDir" : "unlink", relativePath);
|
|
133
|
+
}
|
|
134
|
+
}
|
|
135
|
+
};
|
|
136
|
+
const onFsEvent = (eventPath)=>{
|
|
137
|
+
const relativePath = eventPath === "." ? "" : eventPath;
|
|
138
|
+
if (relativePath.length === 0) {
|
|
139
|
+
return;
|
|
140
|
+
}
|
|
141
|
+
const fullPath = path.resolve(directory, relativePath);
|
|
142
|
+
const previous = snapshot.get(relativePath);
|
|
143
|
+
try {
|
|
144
|
+
const stat = statSync(fullPath);
|
|
145
|
+
const current = toSnapshotEntry(stat);
|
|
146
|
+
snapshot.set(relativePath, current);
|
|
147
|
+
if (previous == null) {
|
|
148
|
+
emit(current.isDirectory ? "addDir" : "add", relativePath);
|
|
149
|
+
if (current.isDirectory) addDirectory(relativePath);
|
|
150
|
+
return;
|
|
151
|
+
}
|
|
152
|
+
if (previous.isDirectory !== current.isDirectory) {
|
|
153
|
+
if (previous.isDirectory) removeDirectoryContents(relativePath);
|
|
154
|
+
emit(previous.isDirectory ? "unlinkDir" : "unlink", relativePath);
|
|
155
|
+
emit(current.isDirectory ? "addDir" : "add", relativePath);
|
|
156
|
+
return;
|
|
157
|
+
}
|
|
158
|
+
if (!current.isDirectory && previous.fingerprint !== current.fingerprint) {
|
|
159
|
+
emitChange(relativePath);
|
|
160
|
+
}
|
|
161
|
+
} catch {
|
|
162
|
+
if (previous == null) {
|
|
163
|
+
return;
|
|
164
|
+
}
|
|
165
|
+
snapshot.delete(relativePath);
|
|
166
|
+
const pending = pendingChangeTimers.get(relativePath);
|
|
167
|
+
if (pending != null) {
|
|
168
|
+
clearTimeout(pending);
|
|
169
|
+
pendingChangeTimers.delete(relativePath);
|
|
170
|
+
}
|
|
171
|
+
emit(previous.isDirectory ? "unlinkDir" : "unlink", relativePath);
|
|
172
|
+
}
|
|
173
|
+
};
|
|
174
|
+
watchDirectory("");
|
|
175
|
+
for (const [relativePath, entry] of snapshot){
|
|
176
|
+
if (entry.isDirectory) watchDirectory(relativePath);
|
|
177
|
+
}
|
|
178
|
+
const watchApi = {
|
|
179
|
+
ready,
|
|
180
|
+
on (event, handler) {
|
|
181
|
+
if (event === "ready") {
|
|
182
|
+
handlers.ready.add(handler);
|
|
183
|
+
return watchApi;
|
|
184
|
+
}
|
|
185
|
+
handlers[event].add(handler);
|
|
186
|
+
return watchApi;
|
|
187
|
+
},
|
|
188
|
+
close: ()=>{
|
|
189
|
+
for (const pending of pendingChangeTimers.values()){
|
|
190
|
+
clearTimeout(pending);
|
|
191
|
+
}
|
|
192
|
+
pendingChangeTimers.clear();
|
|
193
|
+
for (const watcher of directoryWatchers.values()){
|
|
194
|
+
watcher.close();
|
|
195
|
+
}
|
|
196
|
+
directoryWatchers.clear();
|
|
197
|
+
}
|
|
198
|
+
};
|
|
199
|
+
return watchApi;
|
|
200
|
+
}
|
|
201
|
+
function buildSnapshot(directoryPath) {
|
|
202
|
+
const snapshot = new Map();
|
|
203
|
+
collectSnapshotEntries(directoryPath, directoryPath, snapshot);
|
|
204
|
+
return snapshot;
|
|
205
|
+
}
|
|
206
|
+
/** Never source, and huge: watching every folder inside them could exhaust OS watch limits. */ const UNWATCHED_DIRECTORIES = new Set([
|
|
207
|
+
"node_modules",
|
|
208
|
+
".git"
|
|
209
|
+
]);
|
|
210
|
+
function collectSnapshotEntries(rootDirectoryPath, currentDirectoryPath, snapshot) {
|
|
211
|
+
for (const entry of readdirSync(currentDirectoryPath, {
|
|
212
|
+
encoding: "utf8"
|
|
213
|
+
})){
|
|
214
|
+
const name = typeof entry === "string" ? entry : String(entry);
|
|
215
|
+
const fullPath = path.join(currentDirectoryPath, name);
|
|
216
|
+
if (UNWATCHED_DIRECTORIES.has(name)) {
|
|
217
|
+
continue;
|
|
218
|
+
}
|
|
219
|
+
const relativePath = toPosixPath(path.relative(rootDirectoryPath, fullPath));
|
|
220
|
+
const stat = statSync(fullPath);
|
|
221
|
+
const snapshotEntry = toSnapshotEntry(stat);
|
|
222
|
+
snapshot.set(relativePath, snapshotEntry);
|
|
223
|
+
if (!snapshotEntry.isDirectory) {
|
|
224
|
+
continue;
|
|
225
|
+
}
|
|
226
|
+
collectSnapshotEntries(rootDirectoryPath, fullPath, snapshot);
|
|
227
|
+
}
|
|
228
|
+
}
|
|
229
|
+
function toSnapshotEntry(stat) {
|
|
230
|
+
const isDirectory = stat.isDirectory();
|
|
231
|
+
return {
|
|
232
|
+
isDirectory,
|
|
233
|
+
fingerprint: isDirectory ? `dir:${stat.mtimeMs}` : `file:${stat.mtimeMs}:${stat.size}`
|
|
234
|
+
};
|
|
235
|
+
}
|
|
236
|
+
function toPosixPath(filePath) {
|
|
237
|
+
return filePath.split(path.sep).join(path.posix.sep);
|
|
238
|
+
}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import fs from "node:fs/promises";
|
|
2
|
+
import path from "node:path";
|
|
3
|
+
export async function writeFile(filePath, content, options = {
|
|
4
|
+
encoding: "utf8",
|
|
5
|
+
mkdir: false
|
|
6
|
+
}) {
|
|
7
|
+
const { encoding, mkdir } = options;
|
|
8
|
+
if (mkdir) {
|
|
9
|
+
const directory = path.dirname(filePath);
|
|
10
|
+
await fs.mkdir(directory, {
|
|
11
|
+
recursive: true
|
|
12
|
+
});
|
|
13
|
+
}
|
|
14
|
+
await fs.writeFile(filePath, content, encoding);
|
|
15
|
+
}
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
// Source https://github.com/voodoocreation/ts-deepmerge/blob/master/package.json
|
|
2
|
+
// istanbul ignore next
|
|
3
|
+
const isObject = (obj)=>{
|
|
4
|
+
if (typeof obj === "object" && obj !== null) {
|
|
5
|
+
if (typeof Object.getPrototypeOf === "function") {
|
|
6
|
+
const prototype = Object.getPrototypeOf(obj);
|
|
7
|
+
return prototype === Object.prototype || prototype === null;
|
|
8
|
+
}
|
|
9
|
+
return Object.prototype.toString.call(obj) === "[object Object]";
|
|
10
|
+
}
|
|
11
|
+
return false;
|
|
12
|
+
};
|
|
13
|
+
export const merge = (...objects)=>objects.reduce((result, current)=>{
|
|
14
|
+
if (current === undefined) {
|
|
15
|
+
return result;
|
|
16
|
+
}
|
|
17
|
+
if (Array.isArray(current)) {
|
|
18
|
+
throw new TypeError("Arguments provided to ts-deepmerge must be objects, not arrays.");
|
|
19
|
+
}
|
|
20
|
+
Object.keys(current).forEach((key)=>{
|
|
21
|
+
if ([
|
|
22
|
+
"__proto__",
|
|
23
|
+
"constructor",
|
|
24
|
+
"prototype"
|
|
25
|
+
].includes(key)) {
|
|
26
|
+
return;
|
|
27
|
+
}
|
|
28
|
+
if (Array.isArray(result[key]) && Array.isArray(current[key])) {
|
|
29
|
+
result[key] = merge.options.mergeArrays ? merge.options.uniqueArrayItems ? Array.from(new Set(result[key].concat(current[key]))) : [
|
|
30
|
+
...result[key],
|
|
31
|
+
...current[key]
|
|
32
|
+
] : current[key];
|
|
33
|
+
} else if (isObject(result[key]) && isObject(current[key])) {
|
|
34
|
+
result[key] = merge(result[key], current[key]);
|
|
35
|
+
} else if (!isObject(result[key]) && isObject(current[key])) {
|
|
36
|
+
result[key] = merge(current[key], undefined);
|
|
37
|
+
} else {
|
|
38
|
+
result[key] = current[key] === undefined ? merge.options.allowUndefinedOverrides ? current[key] : result[key] : current[key];
|
|
39
|
+
}
|
|
40
|
+
});
|
|
41
|
+
return result;
|
|
42
|
+
}, {});
|
|
43
|
+
const defaultOptions = {
|
|
44
|
+
allowUndefinedOverrides: true,
|
|
45
|
+
mergeArrays: true,
|
|
46
|
+
uniqueArrayItems: true
|
|
47
|
+
};
|
|
48
|
+
merge.options = defaultOptions;
|
|
49
|
+
merge.withOptions = (options, ...objects)=>{
|
|
50
|
+
merge.options = {
|
|
51
|
+
...defaultOptions,
|
|
52
|
+
...options
|
|
53
|
+
};
|
|
54
|
+
const result = merge(...objects);
|
|
55
|
+
merge.options = defaultOptions;
|
|
56
|
+
return result;
|
|
57
|
+
};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export { merge } from "./deep-merge.js";
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export * from "./reflection.types.js";
|
|
@@ -0,0 +1,74 @@
|
|
|
1
|
+
import { ReflectionMeta } from "./types/reflection.types.js";
|
|
2
|
+
const Primitives = [
|
|
3
|
+
"string",
|
|
4
|
+
"number",
|
|
5
|
+
"bigint",
|
|
6
|
+
"boolean",
|
|
7
|
+
"undefined",
|
|
8
|
+
"symbol",
|
|
9
|
+
"null"
|
|
10
|
+
];
|
|
11
|
+
export const isPrimitiveOrDateType = (type)=>{
|
|
12
|
+
return Primitives.includes(type.name.toLocaleLowerCase()) || isDateType(type);
|
|
13
|
+
};
|
|
14
|
+
export const isDateType = (type)=>{
|
|
15
|
+
return type?.prototype === Date.prototype;
|
|
16
|
+
};
|
|
17
|
+
export function isConstructable(type) {
|
|
18
|
+
const proto = type?.prototype;
|
|
19
|
+
const isConstructable = typeof type === "function" && typeof proto === "object";
|
|
20
|
+
return isConstructable;
|
|
21
|
+
}
|
|
22
|
+
export const isArrayType = (type)=>{
|
|
23
|
+
return type?.prototype === Array.prototype;
|
|
24
|
+
};
|
|
25
|
+
export function getMeta(key, target, propertyKey) {
|
|
26
|
+
const meta = Reflect.getMetadata(key, target, propertyKey);
|
|
27
|
+
return meta;
|
|
28
|
+
}
|
|
29
|
+
export function getFunctions(object) {
|
|
30
|
+
const functions = Object.entries(Object.getOwnPropertyDescriptors(object.prototype)).filter(([key])=>key !== "constructor").map(([, value])=>value);
|
|
31
|
+
return functions;
|
|
32
|
+
}
|
|
33
|
+
export function getFunction(object, functionName) {
|
|
34
|
+
const [, value] = Object.entries(Object.getOwnPropertyDescriptors(object.prototype)).find(([k])=>k !== "constructor" && k === functionName);
|
|
35
|
+
return value;
|
|
36
|
+
}
|
|
37
|
+
export function getFunctionMetadata(key, target, func) {
|
|
38
|
+
const meta = Reflect.getMetadata(key, target, func.name);
|
|
39
|
+
return meta;
|
|
40
|
+
}
|
|
41
|
+
export function getFunctionArgs(target, func) {
|
|
42
|
+
const meta = getFunctionMetadata(ReflectionMeta.paramtypes, target, func);
|
|
43
|
+
return meta;
|
|
44
|
+
}
|
|
45
|
+
/**
|
|
46
|
+
* @description Gets the fields from an object
|
|
47
|
+
* @param object
|
|
48
|
+
* @returns
|
|
49
|
+
*/ export function getFields(object) {
|
|
50
|
+
const fields = Object.entries(Object.getOwnPropertyDescriptors(object)).filter(([, val])=>typeof val.value !== "function").map(([key, propertyDescriptor])=>({
|
|
51
|
+
key,
|
|
52
|
+
propertyDescriptor
|
|
53
|
+
}));
|
|
54
|
+
return fields;
|
|
55
|
+
}
|
|
56
|
+
export function getFieldType(target, fieldName) {
|
|
57
|
+
return Reflect.getMetadata(ReflectionMeta.type, target, fieldName);
|
|
58
|
+
}
|
|
59
|
+
export function getArgumentMeta(key, target, argIndex) {
|
|
60
|
+
const meta = Reflect.getMetadata(key, target, argIndex.toString());
|
|
61
|
+
return meta;
|
|
62
|
+
}
|
|
63
|
+
export function defineMeta(key, value, target) {
|
|
64
|
+
Reflect.defineMetadata(key, value, target);
|
|
65
|
+
}
|
|
66
|
+
/**
|
|
67
|
+
* @description Facade function to define metadata for a function argument
|
|
68
|
+
* @param key
|
|
69
|
+
* @param value
|
|
70
|
+
* @param func
|
|
71
|
+
* @param argIndex
|
|
72
|
+
*/ export function defineArgumentMeta(key, value, func, argIndex) {
|
|
73
|
+
Reflect.defineMetadata(key, value, func, argIndex.toString());
|
|
74
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export * from "./semver.js";
|