@ls-apis/cli 0.0.6 → 0.0.7
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/data/apis.json +1 -1
- package/package.json +1 -1
- package/dist/config.js +0 -36
- package/dist/packages/cli/src/categories.js +0 -13
- package/dist/packages/cli/src/colors.js +0 -19
- package/dist/packages/cli/src/config.js +0 -36
- package/dist/packages/cli/src/formatter.js +0 -73
- package/dist/packages/cli/src/index.js +0 -178
- package/dist/packages/cli/src/providers.js +0 -21
- package/dist/packages/cli/src/qa.js +0 -14
- package/dist/packages/cli/src/search.js +0 -50
- package/dist/packages/cli/src/types.js +0 -1
- package/dist/search.js +0 -50
- package/dist/types.js +0 -1
package/data/apis.json
CHANGED
package/package.json
CHANGED
package/dist/config.js
DELETED
|
@@ -1,36 +0,0 @@
|
|
|
1
|
-
import { readFile, writeFile, access } from 'node:fs/promises';
|
|
2
|
-
import { homedir } from 'node:os';
|
|
3
|
-
import { join } from 'node:path';
|
|
4
|
-
export const CONFIG_PATH = join(homedir(), '.ls-apis');
|
|
5
|
-
const DEFAULTS = {
|
|
6
|
-
limit: 20,
|
|
7
|
-
descriptionMaxLength: 250,
|
|
8
|
-
colors: true,
|
|
9
|
-
};
|
|
10
|
-
export async function loadConfig() {
|
|
11
|
-
try {
|
|
12
|
-
const raw = await readFile(CONFIG_PATH, 'utf-8');
|
|
13
|
-
const parsed = JSON.parse(raw);
|
|
14
|
-
return {
|
|
15
|
-
limit: parsed.limit ?? DEFAULTS.limit,
|
|
16
|
-
descriptionMaxLength: parsed.descriptionMaxLength ?? DEFAULTS.descriptionMaxLength,
|
|
17
|
-
colors: parsed.colors ?? DEFAULTS.colors,
|
|
18
|
-
};
|
|
19
|
-
}
|
|
20
|
-
catch {
|
|
21
|
-
await ensureConfigExists();
|
|
22
|
-
return DEFAULTS;
|
|
23
|
-
}
|
|
24
|
-
}
|
|
25
|
-
async function ensureConfigExists() {
|
|
26
|
-
try {
|
|
27
|
-
await access(CONFIG_PATH);
|
|
28
|
-
}
|
|
29
|
-
catch {
|
|
30
|
-
await writeFile(CONFIG_PATH, JSON.stringify(DEFAULTS, null, 2) + '\n');
|
|
31
|
-
}
|
|
32
|
-
}
|
|
33
|
-
export async function getConfig() {
|
|
34
|
-
const config = await loadConfig();
|
|
35
|
-
return { config, filePath: CONFIG_PATH };
|
|
36
|
-
}
|
|
@@ -1,13 +0,0 @@
|
|
|
1
|
-
import { getCategories } from './search.js';
|
|
2
|
-
import { formatList } from './formatter.js';
|
|
3
|
-
import { initColors } from './colors.js';
|
|
4
|
-
export function handleCategories(apis, argv, config) {
|
|
5
|
-
const noColor = argv.color === false;
|
|
6
|
-
initColors(noColor ?? !config.colors);
|
|
7
|
-
const categories = getCategories(apis);
|
|
8
|
-
const output = formatList(categories, 'categories', {
|
|
9
|
-
sort: argv.sort,
|
|
10
|
-
output: argv.output,
|
|
11
|
-
});
|
|
12
|
-
console.log(output);
|
|
13
|
-
}
|
|
@@ -1,19 +0,0 @@
|
|
|
1
|
-
import chalk from 'chalk';
|
|
2
|
-
let useColor = false;
|
|
3
|
-
export function initColors(noColor) {
|
|
4
|
-
if (noColor === true || process.env.NO_COLOR) {
|
|
5
|
-
useColor = false;
|
|
6
|
-
}
|
|
7
|
-
else {
|
|
8
|
-
useColor = true;
|
|
9
|
-
}
|
|
10
|
-
chalk.level = useColor ? 3 : 0;
|
|
11
|
-
}
|
|
12
|
-
export const color = {
|
|
13
|
-
bold: (text) => (useColor ? chalk.bold(text) : text),
|
|
14
|
-
dim: (text) => (useColor ? chalk.dim(text) : text),
|
|
15
|
-
cyan: (text) => (useColor ? chalk.cyan(text) : text),
|
|
16
|
-
green: (text) => (useColor ? chalk.green(text) : text),
|
|
17
|
-
yellow: (text) => (useColor ? chalk.yellow(text) : text),
|
|
18
|
-
red: (text) => (useColor ? chalk.red(text) : text),
|
|
19
|
-
};
|
|
@@ -1,36 +0,0 @@
|
|
|
1
|
-
import { readFile, writeFile, access } from 'node:fs/promises';
|
|
2
|
-
import { homedir } from 'node:os';
|
|
3
|
-
import { join } from 'node:path';
|
|
4
|
-
export const CONFIG_PATH = join(homedir(), '.ls-apis');
|
|
5
|
-
const DEFAULTS = {
|
|
6
|
-
limit: 20,
|
|
7
|
-
descriptionMaxLength: 250,
|
|
8
|
-
colors: true,
|
|
9
|
-
};
|
|
10
|
-
export async function loadConfig() {
|
|
11
|
-
try {
|
|
12
|
-
const raw = await readFile(CONFIG_PATH, 'utf-8');
|
|
13
|
-
const parsed = JSON.parse(raw);
|
|
14
|
-
return {
|
|
15
|
-
limit: parsed.limit ?? DEFAULTS.limit,
|
|
16
|
-
descriptionMaxLength: parsed.descriptionMaxLength ?? DEFAULTS.descriptionMaxLength,
|
|
17
|
-
colors: parsed.colors ?? DEFAULTS.colors,
|
|
18
|
-
};
|
|
19
|
-
}
|
|
20
|
-
catch {
|
|
21
|
-
await ensureConfigExists();
|
|
22
|
-
return DEFAULTS;
|
|
23
|
-
}
|
|
24
|
-
}
|
|
25
|
-
async function ensureConfigExists() {
|
|
26
|
-
try {
|
|
27
|
-
await access(CONFIG_PATH);
|
|
28
|
-
}
|
|
29
|
-
catch {
|
|
30
|
-
await writeFile(CONFIG_PATH, JSON.stringify(DEFAULTS, null, 2) + '\n');
|
|
31
|
-
}
|
|
32
|
-
}
|
|
33
|
-
export async function getConfig() {
|
|
34
|
-
const config = await loadConfig();
|
|
35
|
-
return { config, filePath: CONFIG_PATH };
|
|
36
|
-
}
|
|
@@ -1,73 +0,0 @@
|
|
|
1
|
-
import { color } from './colors.js';
|
|
2
|
-
function truncate(text, maxLength) {
|
|
3
|
-
if (text.length <= maxLength) {
|
|
4
|
-
return text;
|
|
5
|
-
}
|
|
6
|
-
return text.slice(0, maxLength) + '...';
|
|
7
|
-
}
|
|
8
|
-
function formatText(results, total, limit, options) {
|
|
9
|
-
const maxLen = options.descriptionMaxLength ?? 250;
|
|
10
|
-
const lines = [];
|
|
11
|
-
lines.push(color.bold(`Found ${total} APIs:`));
|
|
12
|
-
for (const api of results.slice(0, limit)) {
|
|
13
|
-
lines.push(color.cyan(` ${api.name}`));
|
|
14
|
-
lines.push(` ${color.dim('Description:')} ${truncate(api.description ?? 'No description', maxLen)}`);
|
|
15
|
-
lines.push(` ${color.dim('Link:')} ${api.link}`);
|
|
16
|
-
// Test missing braces - should trigger ESLint error
|
|
17
|
-
if (api.auth !== undefined && api.auth !== null) {
|
|
18
|
-
lines.push(` ${color.dim('Auth:')} ${color.yellow(api.auth)}`);
|
|
19
|
-
}
|
|
20
|
-
if (api.categories.length > 0) {
|
|
21
|
-
lines.push(` ${color.dim('Categories:')} ${color.green(api.categories.join(', '))}`);
|
|
22
|
-
}
|
|
23
|
-
if (api.openapiSpec !== undefined && api.openapiSpec !== null) {
|
|
24
|
-
lines.push(` ${color.dim('OpenAPI Spec:')} ${api.openapiSpec}`);
|
|
25
|
-
}
|
|
26
|
-
if (api.sources.length > 0) {
|
|
27
|
-
lines.push(` ${color.dim('Sources:')} ${api.sources.join(', ')}`);
|
|
28
|
-
}
|
|
29
|
-
lines.push('');
|
|
30
|
-
}
|
|
31
|
-
if (results.length > limit) {
|
|
32
|
-
lines.push(` ${color.dim('... and ' + (results.length - limit) + ' more')}`);
|
|
33
|
-
}
|
|
34
|
-
return lines.join('\n');
|
|
35
|
-
}
|
|
36
|
-
function formatJson(results, limit) {
|
|
37
|
-
return JSON.stringify(results.slice(0, limit), null, 2);
|
|
38
|
-
}
|
|
39
|
-
export function formatResults(results, total, limit, options) {
|
|
40
|
-
if (options.output === 'json') {
|
|
41
|
-
return formatJson(results, limit);
|
|
42
|
-
}
|
|
43
|
-
return formatText(results, total, limit, options);
|
|
44
|
-
}
|
|
45
|
-
export function formatList(items, label, options) {
|
|
46
|
-
const sorted = [...items.entries()].sort((a, b) => a[0].localeCompare(b[0]));
|
|
47
|
-
if (options.sort === 'count') {
|
|
48
|
-
sorted.sort((a, b) => b[1] - a[1]);
|
|
49
|
-
}
|
|
50
|
-
if (options.output === 'json') {
|
|
51
|
-
return JSON.stringify(sorted.map(([name, count]) => ({ name, count })), null, 2);
|
|
52
|
-
}
|
|
53
|
-
const lines = [`Found ${sorted.length} ${label}:`];
|
|
54
|
-
for (const [name, count] of sorted) {
|
|
55
|
-
lines.push(` ${name.padEnd(20)} (${count} APIs)`);
|
|
56
|
-
}
|
|
57
|
-
return lines.join('\n');
|
|
58
|
-
}
|
|
59
|
-
export function formatProviders(providers, options) {
|
|
60
|
-
const sorted = [...providers].sort((a, b) => a.name.localeCompare(b.name));
|
|
61
|
-
if (options.sort === 'count') {
|
|
62
|
-
sorted.sort((a, b) => (b.count ?? 0) - (a.count ?? 0));
|
|
63
|
-
}
|
|
64
|
-
if (options.output === 'json') {
|
|
65
|
-
return JSON.stringify(sorted, null, 2);
|
|
66
|
-
}
|
|
67
|
-
const lines = [`Found ${sorted.length} providers:`];
|
|
68
|
-
for (const provider of sorted) {
|
|
69
|
-
const countStr = provider.count !== undefined ? ` (${provider.count} APIs)` : '';
|
|
70
|
-
lines.push(` ${provider.name.padEnd(20)} ${color.dim(provider.url)}${countStr}`);
|
|
71
|
-
}
|
|
72
|
-
return lines.join('\n');
|
|
73
|
-
}
|
|
@@ -1,178 +0,0 @@
|
|
|
1
|
-
#!/usr/bin/env node
|
|
2
|
-
import { readFile } from 'node:fs/promises';
|
|
3
|
-
import { join, dirname } from 'node:path';
|
|
4
|
-
import { fileURLToPath } from 'node:url';
|
|
5
|
-
import yargs from 'yargs';
|
|
6
|
-
import { hideBin } from 'yargs/helpers';
|
|
7
|
-
import { initColors } from './colors.js';
|
|
8
|
-
import { loadConfig, getConfig } from './config.js';
|
|
9
|
-
import { search } from './search.js';
|
|
10
|
-
import { formatResults } from './formatter.js';
|
|
11
|
-
import { handleCategories } from './categories.js';
|
|
12
|
-
import { handleProviders } from './providers.js';
|
|
13
|
-
import { runQa } from './qa.js';
|
|
14
|
-
let version;
|
|
15
|
-
async function getVersion() {
|
|
16
|
-
if (!version) {
|
|
17
|
-
const packageJsonPath = join(dirname(fileURLToPath(import.meta.url)), '../package.json');
|
|
18
|
-
const pkg = JSON.parse(await readFile(packageJsonPath, 'utf-8'));
|
|
19
|
-
version = pkg.version;
|
|
20
|
-
}
|
|
21
|
-
return version;
|
|
22
|
-
}
|
|
23
|
-
export async function run(argv) {
|
|
24
|
-
const config = await loadConfig();
|
|
25
|
-
const ver = await getVersion();
|
|
26
|
-
const dataFile = join(dirname(fileURLToPath(import.meta.url)), '../data/apis.json');
|
|
27
|
-
const data = await readFile(dataFile, 'utf-8');
|
|
28
|
-
const { apis, providers } = JSON.parse(data);
|
|
29
|
-
let exitEarly = false;
|
|
30
|
-
const args = await yargs(argv)
|
|
31
|
-
.scriptName('ls-apis')
|
|
32
|
-
.strict()
|
|
33
|
-
.version(ver)
|
|
34
|
-
.alias('version', 'V')
|
|
35
|
-
.alias('version', 'v')
|
|
36
|
-
.usage('$0 <command> [options]')
|
|
37
|
-
.usage('$0 [options]')
|
|
38
|
-
.example('$0 -q weather', 'Search for weather APIs')
|
|
39
|
-
.example('$0 -c weather', 'Filter by weather category')
|
|
40
|
-
.example('$0 -q weather -c storage', 'Search weather in storage category')
|
|
41
|
-
.example('$0 -a oauth', 'Filter by OAuth auth')
|
|
42
|
-
.example('$0 -q weather -l 50', 'Limit results to 50')
|
|
43
|
-
.example('$0 -q weather -o json', 'Output as JSON')
|
|
44
|
-
.example('$0 -q weather -s name', 'Sort results by name')
|
|
45
|
-
.command({
|
|
46
|
-
command: 'categories',
|
|
47
|
-
describe: 'List all API categories',
|
|
48
|
-
builder: (yargs) => {
|
|
49
|
-
return yargs
|
|
50
|
-
.option('sort', {
|
|
51
|
-
alias: 's',
|
|
52
|
-
type: 'string',
|
|
53
|
-
choices: ['name', 'count'],
|
|
54
|
-
default: 'name',
|
|
55
|
-
describe: 'Sort by name or count',
|
|
56
|
-
})
|
|
57
|
-
.option('output', {
|
|
58
|
-
alias: 'o',
|
|
59
|
-
type: 'string',
|
|
60
|
-
choices: ['text', 'json'],
|
|
61
|
-
default: 'text',
|
|
62
|
-
describe: 'Output format',
|
|
63
|
-
});
|
|
64
|
-
},
|
|
65
|
-
handler: (argv) => {
|
|
66
|
-
handleCategories(apis, argv, config);
|
|
67
|
-
exitEarly = true;
|
|
68
|
-
},
|
|
69
|
-
})
|
|
70
|
-
.command({
|
|
71
|
-
command: 'providers',
|
|
72
|
-
describe: 'List all data providers',
|
|
73
|
-
builder: (yargs) => {
|
|
74
|
-
return yargs
|
|
75
|
-
.option('sort', {
|
|
76
|
-
alias: 's',
|
|
77
|
-
type: 'string',
|
|
78
|
-
choices: ['name', 'count'],
|
|
79
|
-
default: 'name',
|
|
80
|
-
describe: 'Sort by name or count',
|
|
81
|
-
})
|
|
82
|
-
.option('output', {
|
|
83
|
-
alias: 'o',
|
|
84
|
-
type: 'string',
|
|
85
|
-
choices: ['text', 'json'],
|
|
86
|
-
default: 'text',
|
|
87
|
-
describe: 'Output format',
|
|
88
|
-
});
|
|
89
|
-
},
|
|
90
|
-
handler: (argv) => {
|
|
91
|
-
handleProviders(providers, apis, argv, config);
|
|
92
|
-
exitEarly = true;
|
|
93
|
-
},
|
|
94
|
-
})
|
|
95
|
-
.command({
|
|
96
|
-
command: 'config',
|
|
97
|
-
describe: 'Show config settings',
|
|
98
|
-
handler: async () => {
|
|
99
|
-
const { config, filePath } = await getConfig();
|
|
100
|
-
console.log(`Config file: ${filePath}`);
|
|
101
|
-
console.log(JSON.stringify(config, null, 2));
|
|
102
|
-
exitEarly = true;
|
|
103
|
-
},
|
|
104
|
-
})
|
|
105
|
-
.command({
|
|
106
|
-
command: 'qa',
|
|
107
|
-
describe: 'Run QA validation on apis.json',
|
|
108
|
-
builder: (yargs) => {
|
|
109
|
-
return yargs.option('file', {
|
|
110
|
-
alias: 'f',
|
|
111
|
-
type: 'string',
|
|
112
|
-
describe: 'Custom output file path (default: qa-output/issues.json)',
|
|
113
|
-
});
|
|
114
|
-
},
|
|
115
|
-
handler: async (argv) => {
|
|
116
|
-
await runQa(config.descriptionMaxLength, argv.file);
|
|
117
|
-
exitEarly = true;
|
|
118
|
-
},
|
|
119
|
-
})
|
|
120
|
-
.option('query', {
|
|
121
|
-
alias: 'q',
|
|
122
|
-
type: 'string',
|
|
123
|
-
describe: 'Search query (filters name, description)',
|
|
124
|
-
})
|
|
125
|
-
.option('category', { alias: 'c', type: 'string', describe: 'Filter by category' })
|
|
126
|
-
.option('auth', {
|
|
127
|
-
alias: 'a',
|
|
128
|
-
type: 'string',
|
|
129
|
-
describe: 'Filter by auth (apiKey, OAuth, no)',
|
|
130
|
-
})
|
|
131
|
-
.option('limit', {
|
|
132
|
-
alias: 'l',
|
|
133
|
-
type: 'number',
|
|
134
|
-
default: config.limit,
|
|
135
|
-
describe: 'Max results to show',
|
|
136
|
-
})
|
|
137
|
-
.option('output', {
|
|
138
|
-
alias: 'o',
|
|
139
|
-
type: 'string',
|
|
140
|
-
choices: ['text', 'json'],
|
|
141
|
-
default: 'text',
|
|
142
|
-
describe: 'Output format',
|
|
143
|
-
})
|
|
144
|
-
.option('sort', {
|
|
145
|
-
alias: 's',
|
|
146
|
-
type: 'string',
|
|
147
|
-
choices: ['name', 'category', 'auth'],
|
|
148
|
-
describe: 'Sort results by field',
|
|
149
|
-
})
|
|
150
|
-
.option('no-color', { type: 'boolean', describe: 'Disable colors in output' })
|
|
151
|
-
.help()
|
|
152
|
-
.alias('help', 'h')
|
|
153
|
-
.alias('help', '?')
|
|
154
|
-
.parse();
|
|
155
|
-
if (exitEarly) {
|
|
156
|
-
return;
|
|
157
|
-
}
|
|
158
|
-
const noColor = args.color === false;
|
|
159
|
-
initColors(noColor ?? !config.colors);
|
|
160
|
-
const results = search(apis, {
|
|
161
|
-
query: args.query,
|
|
162
|
-
category: args.category,
|
|
163
|
-
auth: args.auth,
|
|
164
|
-
sort: args.sort,
|
|
165
|
-
limit: args.limit,
|
|
166
|
-
});
|
|
167
|
-
const output = formatResults(results, results.length, args.limit, {
|
|
168
|
-
output: args.output,
|
|
169
|
-
descriptionMaxLength: config.descriptionMaxLength,
|
|
170
|
-
});
|
|
171
|
-
console.log(output);
|
|
172
|
-
}
|
|
173
|
-
if (process.argv[1] && !process.argv[1].includes('vitest')) {
|
|
174
|
-
run(hideBin(process.argv)).catch((err) => {
|
|
175
|
-
console.error('Error:', err.message);
|
|
176
|
-
process.exit(1);
|
|
177
|
-
});
|
|
178
|
-
}
|
|
@@ -1,21 +0,0 @@
|
|
|
1
|
-
import { formatProviders } from './formatter.js';
|
|
2
|
-
import { initColors } from './colors.js';
|
|
3
|
-
export function handleProviders(providers, apis, argv, config) {
|
|
4
|
-
const noColor = argv.color === false;
|
|
5
|
-
initColors(noColor ?? !config.colors);
|
|
6
|
-
const counts = new Map();
|
|
7
|
-
for (const api of apis) {
|
|
8
|
-
for (const source of api.sources) {
|
|
9
|
-
counts.set(source, (counts.get(source) ?? 0) + 1);
|
|
10
|
-
}
|
|
11
|
-
}
|
|
12
|
-
const providersWithCounts = providers.map((p) => ({
|
|
13
|
-
...p,
|
|
14
|
-
count: counts.get(p.name) ?? 0,
|
|
15
|
-
}));
|
|
16
|
-
const output = formatProviders(providersWithCounts, {
|
|
17
|
-
sort: argv.sort,
|
|
18
|
-
output: argv.output,
|
|
19
|
-
});
|
|
20
|
-
console.log(output);
|
|
21
|
-
}
|
|
@@ -1,14 +0,0 @@
|
|
|
1
|
-
import { execSync } from 'node:child_process';
|
|
2
|
-
import { join, dirname } from 'node:path';
|
|
3
|
-
import { fileURLToPath } from 'node:url';
|
|
4
|
-
import { realpathSync } from 'node:fs';
|
|
5
|
-
export async function runQa(descriptionMaxLength, outputFile) {
|
|
6
|
-
const currentDir = dirname(realpathSync(fileURLToPath(import.meta.url)));
|
|
7
|
-
const projectRoot = join(currentDir, '../../..');
|
|
8
|
-
const script = join(projectRoot, 'packages/aggregator/src/qa/index.ts');
|
|
9
|
-
const args = ['npx', 'tsx', script];
|
|
10
|
-
if (outputFile) {
|
|
11
|
-
args.push('--output', outputFile);
|
|
12
|
-
}
|
|
13
|
-
execSync(args.join(' '), { cwd: projectRoot, stdio: 'inherit' });
|
|
14
|
-
}
|
|
@@ -1,50 +0,0 @@
|
|
|
1
|
-
export function search(apis, options) {
|
|
2
|
-
let results = apis;
|
|
3
|
-
if (options.query) {
|
|
4
|
-
const q = options.query.toLowerCase();
|
|
5
|
-
results = results.filter((api) => api.name.toLowerCase().includes(q) || api.description?.toLowerCase().includes(q));
|
|
6
|
-
}
|
|
7
|
-
if (options.category) {
|
|
8
|
-
const cat = options.category.toLowerCase();
|
|
9
|
-
results = results.filter((api) => api.categories.some((c) => c.toLowerCase().includes(cat)));
|
|
10
|
-
}
|
|
11
|
-
if (options.auth) {
|
|
12
|
-
const auth = options.auth.toLowerCase();
|
|
13
|
-
results = results.filter((api) => {
|
|
14
|
-
if (auth === 'no') {
|
|
15
|
-
return !api.auth;
|
|
16
|
-
}
|
|
17
|
-
return api.auth?.toLowerCase().includes(auth);
|
|
18
|
-
});
|
|
19
|
-
}
|
|
20
|
-
if (options.sort) {
|
|
21
|
-
results = [...results].sort((a, b) => {
|
|
22
|
-
switch (options.sort) {
|
|
23
|
-
case 'name':
|
|
24
|
-
return a.name.localeCompare(b.name);
|
|
25
|
-
case 'category': {
|
|
26
|
-
const catA = a.categories[0] ?? '';
|
|
27
|
-
const catB = b.categories[0] ?? '';
|
|
28
|
-
return catA.localeCompare(catB);
|
|
29
|
-
}
|
|
30
|
-
case 'auth': {
|
|
31
|
-
const authA = a.auth ?? '';
|
|
32
|
-
const authB = b.auth ?? '';
|
|
33
|
-
return authA.localeCompare(authB);
|
|
34
|
-
}
|
|
35
|
-
default:
|
|
36
|
-
return 0;
|
|
37
|
-
}
|
|
38
|
-
});
|
|
39
|
-
}
|
|
40
|
-
return results;
|
|
41
|
-
}
|
|
42
|
-
export function getCategories(apis) {
|
|
43
|
-
const map = new Map();
|
|
44
|
-
for (const api of apis) {
|
|
45
|
-
for (const cat of api.categories) {
|
|
46
|
-
map.set(cat, (map.get(cat) ?? 0) + 1);
|
|
47
|
-
}
|
|
48
|
-
}
|
|
49
|
-
return map;
|
|
50
|
-
}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
export {};
|
package/dist/search.js
DELETED
|
@@ -1,50 +0,0 @@
|
|
|
1
|
-
export function search(apis, options) {
|
|
2
|
-
let results = apis;
|
|
3
|
-
if (options.query) {
|
|
4
|
-
const q = options.query.toLowerCase();
|
|
5
|
-
results = results.filter((api) => api.name.toLowerCase().includes(q) || api.description?.toLowerCase().includes(q));
|
|
6
|
-
}
|
|
7
|
-
if (options.category) {
|
|
8
|
-
const cat = options.category.toLowerCase();
|
|
9
|
-
results = results.filter((api) => api.categories.some((c) => c.toLowerCase().includes(cat)));
|
|
10
|
-
}
|
|
11
|
-
if (options.auth) {
|
|
12
|
-
const auth = options.auth.toLowerCase();
|
|
13
|
-
results = results.filter((api) => {
|
|
14
|
-
if (auth === 'no') {
|
|
15
|
-
return !api.auth;
|
|
16
|
-
}
|
|
17
|
-
return api.auth?.toLowerCase().includes(auth);
|
|
18
|
-
});
|
|
19
|
-
}
|
|
20
|
-
if (options.sort) {
|
|
21
|
-
results = [...results].sort((a, b) => {
|
|
22
|
-
switch (options.sort) {
|
|
23
|
-
case 'name':
|
|
24
|
-
return a.name.localeCompare(b.name);
|
|
25
|
-
case 'category': {
|
|
26
|
-
const catA = a.categories[0] ?? '';
|
|
27
|
-
const catB = b.categories[0] ?? '';
|
|
28
|
-
return catA.localeCompare(catB);
|
|
29
|
-
}
|
|
30
|
-
case 'auth': {
|
|
31
|
-
const authA = a.auth ?? '';
|
|
32
|
-
const authB = b.auth ?? '';
|
|
33
|
-
return authA.localeCompare(authB);
|
|
34
|
-
}
|
|
35
|
-
default:
|
|
36
|
-
return 0;
|
|
37
|
-
}
|
|
38
|
-
});
|
|
39
|
-
}
|
|
40
|
-
return results;
|
|
41
|
-
}
|
|
42
|
-
export function getCategories(apis) {
|
|
43
|
-
const map = new Map();
|
|
44
|
-
for (const api of apis) {
|
|
45
|
-
for (const cat of api.categories) {
|
|
46
|
-
map.set(cat, (map.get(cat) ?? 0) + 1);
|
|
47
|
-
}
|
|
48
|
-
}
|
|
49
|
-
return map;
|
|
50
|
-
}
|
package/dist/types.js
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
export {};
|