asljs-locator 0.0.0-stage → 0.1.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/LICENSE.md +20 -0
- package/README.md +89 -2
- package/dist/git-ignore.d.ts +17 -0
- package/dist/git-ignore.js +81 -0
- package/dist/index.d.ts +3 -0
- package/dist/index.js +3 -0
- package/dist/location.d.ts +59 -0
- package/dist/location.js +162 -0
- package/dist/paths.d.ts +2 -0
- package/dist/paths.js +4 -0
- package/package.json +59 -4
package/LICENSE.md
ADDED
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
# MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 Alexandrite Software Ltd
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy of
|
|
6
|
+
this software and associated documentation files (the "Software"), to deal in
|
|
7
|
+
the Software without restriction, including without limitation the rights to
|
|
8
|
+
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
|
|
9
|
+
the Software, and to permit persons to whom the Software is furnished to do so,
|
|
10
|
+
subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
|
|
17
|
+
FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
|
|
18
|
+
COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
|
|
19
|
+
IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
|
20
|
+
CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
package/README.md
CHANGED
|
@@ -1,3 +1,90 @@
|
|
|
1
|
-
#
|
|
1
|
+
# locator
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
> Part of [Alexandrite Software Library][1] – a set of high‑quality, performant
|
|
4
|
+
> JavaScript libraries for everyday use.
|
|
5
|
+
|
|
6
|
+
## Overview
|
|
7
|
+
|
|
8
|
+
`asljs-locator` locates files by glob patterns, exclusions and filters such as
|
|
9
|
+
`.gitignore`.
|
|
10
|
+
|
|
11
|
+
A location says where a set of files lives: the patterns that match them, the
|
|
12
|
+
patterns that take them away again, and the filters that drop whatever should
|
|
13
|
+
never have been listed. `.gitignore` is one of those filters, so a tool can
|
|
14
|
+
honour it without reimplementing it.
|
|
15
|
+
|
|
16
|
+
A pattern beginning with `/` resolves against the root the resolver was built
|
|
17
|
+
with. Any other pattern resolves against the base path given to the call. That
|
|
18
|
+
pair is what lets one vocabulary describe both a repository-wide location and a
|
|
19
|
+
location relative to the file that declared it.
|
|
20
|
+
|
|
21
|
+
## Scope
|
|
22
|
+
|
|
23
|
+
Finding paths, and answering whether a path belongs to a location. Reading the
|
|
24
|
+
files it finds is the caller's business.
|
|
25
|
+
|
|
26
|
+
## Installation
|
|
27
|
+
|
|
28
|
+
```bash
|
|
29
|
+
npm install asljs-locator
|
|
30
|
+
```
|
|
31
|
+
|
|
32
|
+
NPM Package: [asljs-locator][NPM]
|
|
33
|
+
|
|
34
|
+
## Usage
|
|
35
|
+
|
|
36
|
+
```js
|
|
37
|
+
import {
|
|
38
|
+
LocationResolver
|
|
39
|
+
} from 'asljs-locator';
|
|
40
|
+
import {
|
|
41
|
+
NullLogger
|
|
42
|
+
} from 'asljs-logging';
|
|
43
|
+
|
|
44
|
+
const resolver = new LocationResolver(new NullLogger(), process.cwd());
|
|
45
|
+
|
|
46
|
+
const files = await resolver.resolve(process.cwd(), {
|
|
47
|
+
patterns: ['docs/**/*.md'],
|
|
48
|
+
exclude: ['docs/drafts/**'],
|
|
49
|
+
filters: [{ name: 'GitIgnore' }]
|
|
50
|
+
});
|
|
51
|
+
```
|
|
52
|
+
|
|
53
|
+
`resolve` returns absolute paths, deduplicated and sorted. Give it one location
|
|
54
|
+
or several; several are merged.
|
|
55
|
+
|
|
56
|
+
`check` answers the same question for a single path without walking the tree,
|
|
57
|
+
which is what makes it usable per file:
|
|
58
|
+
|
|
59
|
+
```js
|
|
60
|
+
const belongs = await resolver.check(
|
|
61
|
+
'/repo/docs/guide.md',
|
|
62
|
+
'/repo',
|
|
63
|
+
{ pattern: 'docs/**/*.md' }
|
|
64
|
+
);
|
|
65
|
+
```
|
|
66
|
+
|
|
67
|
+
Patterns match files only. A pattern ending with `/` would name folders and
|
|
68
|
+
throws; to treat a folder as an item, point at a file inside it, e.g.
|
|
69
|
+
`packages/*/package.json`.
|
|
70
|
+
|
|
71
|
+
## Further reading
|
|
72
|
+
|
|
73
|
+
- [Architecture][2] for where this sits among the packages.
|
|
74
|
+
|
|
75
|
+
Questions and bugs: [asljs/issues][ISS].
|
|
76
|
+
|
|
77
|
+
## Related packages
|
|
78
|
+
|
|
79
|
+
- [asljs-logging][3] provides the logger the resolver traces through.
|
|
80
|
+
|
|
81
|
+
## License
|
|
82
|
+
|
|
83
|
+
MIT License. See [LICENSE][LIC] for details.
|
|
84
|
+
|
|
85
|
+
[1]: https://github.com/AlexandriteSoftware/asljs
|
|
86
|
+
[2]: ../../docs/Architecture.md
|
|
87
|
+
[3]: ../logging/README.md
|
|
88
|
+
[ISS]: https://github.com/AlexandriteSoftware/asljs/issues
|
|
89
|
+
[LIC]: LICENSE.md
|
|
90
|
+
[NPM]: https://www.npmjs.com/package/asljs-locator
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import { Logger } from 'asljs-logging';
|
|
2
|
+
/**
|
|
3
|
+
* Whether a path is ignored by a `.gitignore`.
|
|
4
|
+
*
|
|
5
|
+
* Matchers are loaded from the directory of the path being tested and every
|
|
6
|
+
* directory above it, because a nested `.gitignore` applies to its own subtree
|
|
7
|
+
* and git reads them all. Each directory is read once.
|
|
8
|
+
*/
|
|
9
|
+
export declare class GitIgnore {
|
|
10
|
+
private logger;
|
|
11
|
+
private matchers;
|
|
12
|
+
private visitedPaths;
|
|
13
|
+
constructor(logger: Logger);
|
|
14
|
+
isIgnored(targetPath: string): boolean;
|
|
15
|
+
filter(paths: string[]): string[];
|
|
16
|
+
loadMatchers(directoryPath: string): void;
|
|
17
|
+
}
|
|
@@ -0,0 +1,81 @@
|
|
|
1
|
+
import ignore from 'ignore';
|
|
2
|
+
import { readFileSync, statSync } from 'node:fs';
|
|
3
|
+
import path from 'node:path';
|
|
4
|
+
import { toPosixPath } from './paths.js';
|
|
5
|
+
/**
|
|
6
|
+
* Whether a path is ignored by a `.gitignore`.
|
|
7
|
+
*
|
|
8
|
+
* Matchers are loaded from the directory of the path being tested and every
|
|
9
|
+
* directory above it, because a nested `.gitignore` applies to its own subtree
|
|
10
|
+
* and git reads them all. Each directory is read once.
|
|
11
|
+
*/
|
|
12
|
+
export class GitIgnore {
|
|
13
|
+
logger;
|
|
14
|
+
matchers;
|
|
15
|
+
visitedPaths;
|
|
16
|
+
constructor(logger) {
|
|
17
|
+
this.logger = logger;
|
|
18
|
+
this.matchers = [];
|
|
19
|
+
this.visitedPaths = new Set();
|
|
20
|
+
}
|
|
21
|
+
isIgnored(targetPath) {
|
|
22
|
+
if (!path.isAbsolute(targetPath)) {
|
|
23
|
+
throw new Error(`Path must be absolute: ${targetPath}`);
|
|
24
|
+
}
|
|
25
|
+
const isDirectory = targetPath.endsWith(path.sep);
|
|
26
|
+
const normalisedPath = path.normalize(targetPath);
|
|
27
|
+
if (isDirectory) {
|
|
28
|
+
this.loadMatchers(normalisedPath);
|
|
29
|
+
}
|
|
30
|
+
else {
|
|
31
|
+
this.loadMatchers(path.dirname(normalisedPath));
|
|
32
|
+
}
|
|
33
|
+
for (const matcher of this.matchers) {
|
|
34
|
+
const relativePath = toPosixPath(path.relative(matcher.path, normalisedPath));
|
|
35
|
+
if (relativePath === ''
|
|
36
|
+
|| relativePath.startsWith('../')) {
|
|
37
|
+
continue;
|
|
38
|
+
}
|
|
39
|
+
const testRelativePath = isDirectory
|
|
40
|
+
? relativePath + '/'
|
|
41
|
+
: relativePath;
|
|
42
|
+
if (matcher.matcher.ignores(testRelativePath)) {
|
|
43
|
+
return true;
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
return false;
|
|
47
|
+
}
|
|
48
|
+
filter(paths) {
|
|
49
|
+
return paths.filter(filePath => !this.isIgnored(filePath));
|
|
50
|
+
}
|
|
51
|
+
loadMatchers(directoryPath) {
|
|
52
|
+
if (this.visitedPaths.has(directoryPath)) {
|
|
53
|
+
return;
|
|
54
|
+
}
|
|
55
|
+
this.visitedPaths
|
|
56
|
+
.add(directoryPath);
|
|
57
|
+
const gitIgnorePath = path.join(directoryPath, '.gitignore');
|
|
58
|
+
let gitIgnoreExists = false;
|
|
59
|
+
try {
|
|
60
|
+
statSync(gitIgnorePath);
|
|
61
|
+
gitIgnoreExists = true;
|
|
62
|
+
}
|
|
63
|
+
catch (err) {
|
|
64
|
+
const code = err.code;
|
|
65
|
+
if (code !== 'ENOENT') {
|
|
66
|
+
throw err;
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
if (gitIgnoreExists) {
|
|
70
|
+
const gitIgnoreContent = readFileSync(gitIgnorePath, 'utf8');
|
|
71
|
+
const matcher = ignore()
|
|
72
|
+
.add(gitIgnoreContent);
|
|
73
|
+
this.matchers.push({ path: directoryPath,
|
|
74
|
+
matcher });
|
|
75
|
+
}
|
|
76
|
+
const parentPath = path.dirname(directoryPath);
|
|
77
|
+
if (parentPath !== directoryPath) {
|
|
78
|
+
this.loadMatchers(parentPath);
|
|
79
|
+
}
|
|
80
|
+
}
|
|
81
|
+
}
|
package/dist/index.d.ts
ADDED
package/dist/index.js
ADDED
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
import { type Logger } from 'asljs-logging';
|
|
2
|
+
/**
|
|
3
|
+
* A named filter applied to the matches, rather than a pattern.
|
|
4
|
+
*
|
|
5
|
+
* `GitIgnore` is the only one implemented: it drops whatever git would ignore.
|
|
6
|
+
*/
|
|
7
|
+
export interface LocationFilter {
|
|
8
|
+
name: string;
|
|
9
|
+
}
|
|
10
|
+
/**
|
|
11
|
+
* Where a set of files lives.
|
|
12
|
+
*
|
|
13
|
+
* A pattern beginning with `/` is resolved against the root the resolver was
|
|
14
|
+
* built with; any other pattern is resolved against the base path passed to
|
|
15
|
+
* the call. That is what lets a definition name a repository-wide location and
|
|
16
|
+
* a location relative to itself in the same vocabulary.
|
|
17
|
+
*
|
|
18
|
+
* Give either `pattern` for one or `patterns` for several; both are accepted
|
|
19
|
+
* and read as one list.
|
|
20
|
+
*/
|
|
21
|
+
export interface Location {
|
|
22
|
+
pattern?: string;
|
|
23
|
+
patterns?: string[];
|
|
24
|
+
exclude?: string[];
|
|
25
|
+
filters?: LocationFilter[];
|
|
26
|
+
}
|
|
27
|
+
/** The patterns of a location, however they were given. */
|
|
28
|
+
export declare function toPatterns(location: Location): string[];
|
|
29
|
+
export declare class LocationResolver {
|
|
30
|
+
private logger;
|
|
31
|
+
private rootPath;
|
|
32
|
+
private gitIgnore;
|
|
33
|
+
constructor(logger: Logger, rootPath: string);
|
|
34
|
+
/**
|
|
35
|
+
* Every path the locations match, deduplicated and sorted.
|
|
36
|
+
*/
|
|
37
|
+
resolve(basePath: string, location: Location | readonly Location[]): Promise<string[]>;
|
|
38
|
+
/**
|
|
39
|
+
* Whether the target path belongs to any of the locations.
|
|
40
|
+
*
|
|
41
|
+
* This answers the question without walking the filesystem, which is what
|
|
42
|
+
* makes it usable per file.
|
|
43
|
+
*/
|
|
44
|
+
check(targetPath: string, basePath: string, location: Location | readonly Location[]): Promise<boolean>;
|
|
45
|
+
private resolveOne;
|
|
46
|
+
private checkOne;
|
|
47
|
+
/**
|
|
48
|
+
* The absolute paths the patterns match.
|
|
49
|
+
*
|
|
50
|
+
* A pattern beginning with `/` is expanded from the root, the rest from the
|
|
51
|
+
* base path, so one call can carry both kinds.
|
|
52
|
+
*
|
|
53
|
+
* Dotfiles are matched, because `check` matches them and the two have to
|
|
54
|
+
* agree: without it a path such as `.remarkrc.mjs` would be reported as
|
|
55
|
+
* belonging to a location that never finds it.
|
|
56
|
+
*/
|
|
57
|
+
private expand;
|
|
58
|
+
private applyFilters;
|
|
59
|
+
}
|
package/dist/location.js
ADDED
|
@@ -0,0 +1,162 @@
|
|
|
1
|
+
import { glob } from 'glob';
|
|
2
|
+
import { minimatch } from 'minimatch';
|
|
3
|
+
import path from 'node:path';
|
|
4
|
+
import { GitIgnore } from './git-ignore.js';
|
|
5
|
+
/** The patterns of a location, however they were given. */
|
|
6
|
+
export function toPatterns(location) {
|
|
7
|
+
const patterns = [...location.pattern === undefined
|
|
8
|
+
? []
|
|
9
|
+
: [location.pattern],
|
|
10
|
+
...location.patterns
|
|
11
|
+
?? []];
|
|
12
|
+
if (patterns.length === 0) {
|
|
13
|
+
throw new Error('A location needs a pattern or patterns.');
|
|
14
|
+
}
|
|
15
|
+
return patterns;
|
|
16
|
+
}
|
|
17
|
+
/**
|
|
18
|
+
* Patterns match files only. A pattern ending with `/` would name folders,
|
|
19
|
+
* which `resolve` and `check` cannot treat alike, so it is refused.
|
|
20
|
+
*/
|
|
21
|
+
function assertFilePatterns(patterns) {
|
|
22
|
+
const folderPattern = patterns.find(pattern => pattern.endsWith('/'));
|
|
23
|
+
if (folderPattern !== undefined) {
|
|
24
|
+
throw new Error(`Folder patterns are not supported: "${folderPattern}". Point the pattern at a file, e.g. "${folderPattern}package.json".`);
|
|
25
|
+
}
|
|
26
|
+
}
|
|
27
|
+
function toLocations(location) {
|
|
28
|
+
return Array.isArray(location)
|
|
29
|
+
? location
|
|
30
|
+
: [location];
|
|
31
|
+
}
|
|
32
|
+
export class LocationResolver {
|
|
33
|
+
logger;
|
|
34
|
+
rootPath;
|
|
35
|
+
gitIgnore;
|
|
36
|
+
constructor(logger, rootPath) {
|
|
37
|
+
this.logger = logger;
|
|
38
|
+
this.rootPath =
|
|
39
|
+
path.normalize(path.resolve(rootPath));
|
|
40
|
+
this.gitIgnore =
|
|
41
|
+
new GitIgnore(this.logger);
|
|
42
|
+
}
|
|
43
|
+
/**
|
|
44
|
+
* Every path the locations match, deduplicated and sorted.
|
|
45
|
+
*/
|
|
46
|
+
async resolve(basePath, location) {
|
|
47
|
+
const results = [];
|
|
48
|
+
for (const one of toLocations(location)) {
|
|
49
|
+
const resolved = await this.resolveOne(basePath, one);
|
|
50
|
+
results.push(...resolved);
|
|
51
|
+
}
|
|
52
|
+
const unique = [...new Set(results)];
|
|
53
|
+
unique.sort((a, b) => a.localeCompare(b));
|
|
54
|
+
return unique;
|
|
55
|
+
}
|
|
56
|
+
/**
|
|
57
|
+
* Whether the target path belongs to any of the locations.
|
|
58
|
+
*
|
|
59
|
+
* This answers the question without walking the filesystem, which is what
|
|
60
|
+
* makes it usable per file.
|
|
61
|
+
*/
|
|
62
|
+
async check(targetPath, basePath, location) {
|
|
63
|
+
for (const one of toLocations(location)) {
|
|
64
|
+
const matched = await this.checkOne(targetPath, basePath, one);
|
|
65
|
+
if (matched) {
|
|
66
|
+
return true;
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
return false;
|
|
70
|
+
}
|
|
71
|
+
async resolveOne(basePath, location) {
|
|
72
|
+
const patterns = toPatterns(location);
|
|
73
|
+
const exclude = location.exclude
|
|
74
|
+
?? [];
|
|
75
|
+
const filters = location.filters
|
|
76
|
+
?? [];
|
|
77
|
+
this.logger.trace('LocationResolver.resolve(%s, %s)', basePath, JSON.stringify(location));
|
|
78
|
+
const normalisedBasePath = path.normalize(path.resolve(basePath));
|
|
79
|
+
assertFilePatterns([...patterns,
|
|
80
|
+
...exclude]);
|
|
81
|
+
const matches = new Set(await this.expand(patterns, normalisedBasePath));
|
|
82
|
+
for (const excluded of await this.expand(exclude, normalisedBasePath)) {
|
|
83
|
+
matches.delete(excluded);
|
|
84
|
+
}
|
|
85
|
+
const result = this.applyFilters([...matches], filters);
|
|
86
|
+
result.sort((a, b) => a.localeCompare(b));
|
|
87
|
+
this.logger.trace('LocationResolver.resolve() => %d matches', result.length);
|
|
88
|
+
return result;
|
|
89
|
+
}
|
|
90
|
+
async checkOne(targetPath, basePath, location) {
|
|
91
|
+
const patterns = toPatterns(location);
|
|
92
|
+
const exclude = location.exclude
|
|
93
|
+
?? [];
|
|
94
|
+
const filters = location.filters
|
|
95
|
+
?? [];
|
|
96
|
+
assertFilePatterns([...patterns,
|
|
97
|
+
...exclude]);
|
|
98
|
+
const normalisedTargetPath = path.normalize(path.resolve(targetPath));
|
|
99
|
+
const normalisedBasePath = path.normalize(path.resolve(basePath));
|
|
100
|
+
const matchesPattern = (pattern) => {
|
|
101
|
+
const anchored = pattern.startsWith('/');
|
|
102
|
+
const relativePath = path.relative(anchored
|
|
103
|
+
? this.rootPath
|
|
104
|
+
: normalisedBasePath, normalisedTargetPath);
|
|
105
|
+
return minimatch(relativePath, anchored
|
|
106
|
+
? pattern.slice(1)
|
|
107
|
+
: pattern, { dot: true });
|
|
108
|
+
};
|
|
109
|
+
if (!patterns.some(matchesPattern)) {
|
|
110
|
+
return false;
|
|
111
|
+
}
|
|
112
|
+
if (exclude.some(matchesPattern)) {
|
|
113
|
+
return false;
|
|
114
|
+
}
|
|
115
|
+
const result = this.applyFilters([normalisedTargetPath], filters);
|
|
116
|
+
return result.length > 0;
|
|
117
|
+
}
|
|
118
|
+
/**
|
|
119
|
+
* The absolute paths the patterns match.
|
|
120
|
+
*
|
|
121
|
+
* A pattern beginning with `/` is expanded from the root, the rest from the
|
|
122
|
+
* base path, so one call can carry both kinds.
|
|
123
|
+
*
|
|
124
|
+
* Dotfiles are matched, because `check` matches them and the two have to
|
|
125
|
+
* agree: without it a path such as `.remarkrc.mjs` would be reported as
|
|
126
|
+
* belonging to a location that never finds it.
|
|
127
|
+
*/
|
|
128
|
+
async expand(patterns, basePath) {
|
|
129
|
+
const matches = [];
|
|
130
|
+
const rootPatterns = patterns
|
|
131
|
+
.filter(pattern => pattern.startsWith('/'))
|
|
132
|
+
.map(pattern => pattern.slice(1));
|
|
133
|
+
if (rootPatterns.length > 0) {
|
|
134
|
+
matches.push(...await glob(rootPatterns, { cwd: this.rootPath,
|
|
135
|
+
absolute: true,
|
|
136
|
+
dot: true,
|
|
137
|
+
nodir: true }));
|
|
138
|
+
}
|
|
139
|
+
const basePatterns = patterns.filter(pattern => !pattern.startsWith('/'));
|
|
140
|
+
if (basePatterns.length > 0) {
|
|
141
|
+
matches.push(...await glob(basePatterns, { cwd: basePath,
|
|
142
|
+
absolute: true,
|
|
143
|
+
dot: true,
|
|
144
|
+
nodir: true }));
|
|
145
|
+
}
|
|
146
|
+
return matches;
|
|
147
|
+
}
|
|
148
|
+
applyFilters(paths, filters) {
|
|
149
|
+
let result = paths;
|
|
150
|
+
for (const filter of filters) {
|
|
151
|
+
switch (filter.name) {
|
|
152
|
+
case 'GitIgnore':
|
|
153
|
+
result =
|
|
154
|
+
this.gitIgnore.filter(result);
|
|
155
|
+
break;
|
|
156
|
+
default:
|
|
157
|
+
throw new Error(`Unknown filter: ${filter.name}`);
|
|
158
|
+
}
|
|
159
|
+
}
|
|
160
|
+
return result;
|
|
161
|
+
}
|
|
162
|
+
}
|
package/dist/paths.d.ts
ADDED
package/dist/paths.js
ADDED
package/package.json
CHANGED
|
@@ -1,6 +1,61 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "asljs-locator",
|
|
3
|
-
"version": "0.
|
|
4
|
-
"
|
|
5
|
-
"
|
|
6
|
-
|
|
3
|
+
"version": "0.1.1",
|
|
4
|
+
"description": "Locates files by glob patterns, exclusions and filters such as .gitignore.",
|
|
5
|
+
"type": "module",
|
|
6
|
+
"main": "dist/index.js",
|
|
7
|
+
"types": "dist/index.d.ts",
|
|
8
|
+
"exports": {
|
|
9
|
+
".": {
|
|
10
|
+
"types": "./dist/index.d.ts",
|
|
11
|
+
"default": "./dist/index.js"
|
|
12
|
+
}
|
|
13
|
+
},
|
|
14
|
+
"files": [
|
|
15
|
+
"dist/**",
|
|
16
|
+
"README.md",
|
|
17
|
+
"LICENSE.md"
|
|
18
|
+
],
|
|
19
|
+
"scripts": {
|
|
20
|
+
"flint": "toolkit flint",
|
|
21
|
+
"clean": "toolkit clean",
|
|
22
|
+
"build": "tsc -p tsconfig.build.json",
|
|
23
|
+
"build:dist": "tsc -p tsconfig.dist.json",
|
|
24
|
+
"typecheck": "tsc -p tsconfig.build.json --noEmit",
|
|
25
|
+
"guard:clean-git": "toolkit ensure-clean-working-directory",
|
|
26
|
+
"prepack": "npm run clean && npm run build && npm run test && npm run build:dist && npm run guard:clean-git",
|
|
27
|
+
"postpublish": "toolkit tag-release-revision",
|
|
28
|
+
"test": "node --test --enable-source-maps build/**/*.test.js",
|
|
29
|
+
"test:watch": "node --watch --test build/**/*.test.js",
|
|
30
|
+
"release:patch": "toolkit release-patch",
|
|
31
|
+
"all": "npm i && npm run clean && npm run build:dist && npm run flint && npm run typecheck && npm run build && npm run test"
|
|
32
|
+
},
|
|
33
|
+
"keywords": [
|
|
34
|
+
"glob",
|
|
35
|
+
"gitignore",
|
|
36
|
+
"files",
|
|
37
|
+
"nodejs",
|
|
38
|
+
"locator"
|
|
39
|
+
],
|
|
40
|
+
"homepage": "https://github.com/AlexandriteSoftware/asljs#readme",
|
|
41
|
+
"bugs": {
|
|
42
|
+
"url": "https://github.com/AlexandriteSoftware/asljs/issues"
|
|
43
|
+
},
|
|
44
|
+
"repository": {
|
|
45
|
+
"type": "git",
|
|
46
|
+
"url": "git+https://github.com/AlexandriteSoftware/asljs.git"
|
|
47
|
+
},
|
|
48
|
+
"author": "\"Alex Netkachov\" <alex.netkachov@gmail.com>",
|
|
49
|
+
"license": "MIT",
|
|
50
|
+
"dependencies": {
|
|
51
|
+
"asljs-logging": "^0.1.1",
|
|
52
|
+
"glob": "^13.0.6",
|
|
53
|
+
"ignore": "^7.0.6",
|
|
54
|
+
"minimatch": "^10.2.6"
|
|
55
|
+
},
|
|
56
|
+
"devDependencies": {
|
|
57
|
+
"asljs-testing": "^0.1.0",
|
|
58
|
+
"asljs-tmpdir": "^0.1.13",
|
|
59
|
+
"asljs-toolkit": "^0.1.0"
|
|
60
|
+
}
|
|
61
|
+
}
|