apcore-toolkit 0.1.0 → 0.3.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +68 -0
- package/README.md +29 -1
- package/dist/ai-enhancer.d.ts +43 -0
- package/dist/ai-enhancer.d.ts.map +1 -0
- package/dist/ai-enhancer.js +313 -0
- package/dist/ai-enhancer.js.map +1 -0
- package/dist/flatten-params.d.ts +16 -0
- package/dist/flatten-params.d.ts.map +1 -0
- package/dist/flatten-params.js +18 -0
- package/dist/flatten-params.js.map +1 -0
- package/dist/index.d.ts +8 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +6 -1
- package/dist/index.js.map +1 -1
- package/dist/openapi.d.ts +7 -0
- package/dist/openapi.d.ts.map +1 -1
- package/dist/openapi.js +49 -8
- package/dist/openapi.js.map +1 -1
- package/dist/output/errors.d.ts +6 -0
- package/dist/output/errors.d.ts.map +1 -0
- package/dist/output/errors.js +11 -0
- package/dist/output/errors.js.map +1 -0
- package/dist/output/index.d.ts +4 -0
- package/dist/output/index.d.ts.map +1 -1
- package/dist/output/index.js +3 -0
- package/dist/output/index.js.map +1 -1
- package/dist/output/registry-writer.d.ts +5 -1
- package/dist/output/registry-writer.d.ts.map +1 -1
- package/dist/output/registry-writer.js +21 -4
- package/dist/output/registry-writer.js.map +1 -1
- package/dist/output/types.d.ts +15 -0
- package/dist/output/types.d.ts.map +1 -0
- package/dist/output/types.js +4 -0
- package/dist/output/types.js.map +1 -0
- package/dist/output/typescript-writer.d.ts +4 -1
- package/dist/output/typescript-writer.d.ts.map +1 -1
- package/dist/output/typescript-writer.js +36 -10
- package/dist/output/typescript-writer.js.map +1 -1
- package/dist/output/verifiers.d.ts +26 -0
- package/dist/output/verifiers.d.ts.map +1 -0
- package/dist/output/verifiers.js +103 -0
- package/dist/output/verifiers.js.map +1 -0
- package/dist/output/yaml-writer.d.ts +4 -1
- package/dist/output/yaml-writer.d.ts.map +1 -1
- package/dist/output/yaml-writer.js +48 -23
- package/dist/output/yaml-writer.js.map +1 -1
- package/dist/resolve-target.d.ts +7 -1
- package/dist/resolve-target.d.ts.map +1 -1
- package/dist/resolve-target.js +17 -1
- package/dist/resolve-target.js.map +1 -1
- package/dist/scanner.d.ts +5 -0
- package/dist/scanner.d.ts.map +1 -1
- package/dist/scanner.js +50 -5
- package/dist/scanner.js.map +1 -1
- package/package.json +5 -5
|
@@ -2,9 +2,14 @@ import yaml from 'js-yaml';
|
|
|
2
2
|
import { writeFileSync, mkdirSync, existsSync } from 'node:fs';
|
|
3
3
|
import { resolve, join } from 'node:path';
|
|
4
4
|
import { annotationsToDict } from '../serializers.js';
|
|
5
|
+
import { createWriteResult } from './types.js';
|
|
6
|
+
import { WriteError } from './errors.js';
|
|
7
|
+
import { YAMLVerifier, runVerifierChain } from './verifiers.js';
|
|
5
8
|
export class YAMLWriter {
|
|
6
9
|
write(modules, outputDir, options) {
|
|
7
10
|
const dryRun = options?.dryRun ?? false;
|
|
11
|
+
const shouldVerify = options?.verify ?? false;
|
|
12
|
+
const verifiers = options?.verifiers ?? [];
|
|
8
13
|
if (modules.length === 0) {
|
|
9
14
|
return [];
|
|
10
15
|
}
|
|
@@ -16,29 +21,49 @@ export class YAMLWriter {
|
|
|
16
21
|
const timestamp = new Date().toISOString();
|
|
17
22
|
for (const module of modules) {
|
|
18
23
|
const bindingData = this._buildBinding(module);
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
24
|
+
if (dryRun) {
|
|
25
|
+
results.push(createWriteResult(module.moduleId, null));
|
|
26
|
+
continue;
|
|
27
|
+
}
|
|
28
|
+
let safeId = module.moduleId.replace(/[^a-zA-Z0-9._-]/g, '_');
|
|
29
|
+
safeId = safeId.replace(/\.{2,}/g, '_');
|
|
30
|
+
const filename = `${safeId}.binding.yaml`;
|
|
31
|
+
const filePath = resolve(join(outputPath, filename));
|
|
32
|
+
// Path traversal protection
|
|
33
|
+
if (!filePath.startsWith(outputPath)) {
|
|
34
|
+
console.warn('Skipping file outside output directory: %s', filePath);
|
|
35
|
+
continue;
|
|
36
|
+
}
|
|
37
|
+
if (existsSync(filePath)) {
|
|
38
|
+
console.warn('Overwriting existing file: %s', filePath);
|
|
39
|
+
}
|
|
40
|
+
const header = `# Auto-generated by apcore-toolkit scanner\n` +
|
|
41
|
+
`# Generated: ${timestamp}\n` +
|
|
42
|
+
`# Do not edit manually unless you intend to customize schemas.\n\n`;
|
|
43
|
+
const yamlContent = yaml.dump(bindingData, {
|
|
44
|
+
flowLevel: -1,
|
|
45
|
+
sortKeys: false,
|
|
46
|
+
});
|
|
47
|
+
try {
|
|
48
|
+
writeFileSync(filePath, header + yamlContent, 'utf-8');
|
|
49
|
+
}
|
|
50
|
+
catch (err) {
|
|
51
|
+
throw new WriteError(filePath, err);
|
|
52
|
+
}
|
|
53
|
+
let result = createWriteResult(module.moduleId, filePath);
|
|
54
|
+
if (shouldVerify) {
|
|
55
|
+
const builtinResult = new YAMLVerifier().verify(filePath, module.moduleId);
|
|
56
|
+
if (!builtinResult.ok) {
|
|
57
|
+
result = createWriteResult(module.moduleId, filePath, false, builtinResult.error ?? null);
|
|
29
58
|
}
|
|
30
|
-
|
|
31
|
-
|
|
59
|
+
}
|
|
60
|
+
if (result.verified && verifiers.length > 0) {
|
|
61
|
+
const vResult = runVerifierChain(verifiers, filePath, module.moduleId);
|
|
62
|
+
if (!vResult.ok) {
|
|
63
|
+
result = createWriteResult(module.moduleId, filePath, false, vResult.error ?? null);
|
|
32
64
|
}
|
|
33
|
-
const header = `# Auto-generated by apcore-toolkit scanner\n` +
|
|
34
|
-
`# Generated: ${timestamp}\n` +
|
|
35
|
-
`# Do not edit manually unless you intend to customize schemas.\n\n`;
|
|
36
|
-
const yamlContent = yaml.dump(bindingData, {
|
|
37
|
-
flowLevel: -1,
|
|
38
|
-
sortKeys: false,
|
|
39
|
-
});
|
|
40
|
-
writeFileSync(filePath, header + yamlContent, 'utf-8');
|
|
41
65
|
}
|
|
66
|
+
results.push(result);
|
|
42
67
|
}
|
|
43
68
|
return results;
|
|
44
69
|
}
|
|
@@ -56,9 +81,9 @@ export class YAMLWriter {
|
|
|
56
81
|
examples: module.examples.length > 0
|
|
57
82
|
? module.examples.map((e) => ({ ...e }))
|
|
58
83
|
: [],
|
|
59
|
-
metadata:
|
|
60
|
-
input_schema:
|
|
61
|
-
output_schema:
|
|
84
|
+
metadata: structuredClone(module.metadata),
|
|
85
|
+
input_schema: structuredClone(module.inputSchema),
|
|
86
|
+
output_schema: structuredClone(module.outputSchema),
|
|
62
87
|
},
|
|
63
88
|
],
|
|
64
89
|
};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"yaml-writer.js","sourceRoot":"","sources":["../../src/output/yaml-writer.ts"],"names":[],"mappings":"AAAA,OAAO,IAAI,MAAM,SAAS,CAAC;AAC3B,OAAO,EAAE,aAAa,EAAE,SAAS,EAAE,UAAU,EAAE,MAAM,SAAS,CAAC;AAC/D,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AAE1C,OAAO,EAAE,iBAAiB,EAAE,MAAM,mBAAmB,CAAC;AAEtD,MAAM,OAAO,UAAU;IACrB,KAAK,CACH,OAAwB,EACxB,SAAiB,EACjB,
|
|
1
|
+
{"version":3,"file":"yaml-writer.js","sourceRoot":"","sources":["../../src/output/yaml-writer.ts"],"names":[],"mappings":"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"}
|
package/dist/resolve-target.d.ts
CHANGED
|
@@ -4,6 +4,12 @@
|
|
|
4
4
|
* Target format: `"module/path:exportName"`.
|
|
5
5
|
* The LAST `:` is used as the separator so that Node.js built-in prefixes
|
|
6
6
|
* like `node:path` are supported (e.g. `"node:path:join"`).
|
|
7
|
+
*
|
|
8
|
+
* @param target - The target string in "module:export" format.
|
|
9
|
+
* @param allowedPrefixes - Optional list of allowed directory prefixes for
|
|
10
|
+
* absolute/relative paths. If provided, file-path imports must resolve
|
|
11
|
+
* under one of these directories. Package-name imports (no leading `.` or `/`)
|
|
12
|
+
* are always allowed.
|
|
7
13
|
*/
|
|
8
|
-
export declare function resolveTarget(target: string): Promise<unknown>;
|
|
14
|
+
export declare function resolveTarget(target: string, allowedPrefixes?: string[]): Promise<unknown>;
|
|
9
15
|
//# sourceMappingURL=resolve-target.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"resolve-target.d.ts","sourceRoot":"","sources":["../src/resolve-target.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"resolve-target.d.ts","sourceRoot":"","sources":["../src/resolve-target.ts"],"names":[],"mappings":"AAEA;;;;;;;;;;;;GAYG;AACH,wBAAsB,aAAa,CACjC,MAAM,EAAE,MAAM,EACd,eAAe,CAAC,EAAE,MAAM,EAAE,GACzB,OAAO,CAAC,OAAO,CAAC,CAwClB"}
|
package/dist/resolve-target.js
CHANGED
|
@@ -1,17 +1,33 @@
|
|
|
1
|
+
import { resolve, isAbsolute } from 'node:path';
|
|
1
2
|
/**
|
|
2
3
|
* Dynamically imports a module and resolves a named export.
|
|
3
4
|
*
|
|
4
5
|
* Target format: `"module/path:exportName"`.
|
|
5
6
|
* The LAST `:` is used as the separator so that Node.js built-in prefixes
|
|
6
7
|
* like `node:path` are supported (e.g. `"node:path:join"`).
|
|
8
|
+
*
|
|
9
|
+
* @param target - The target string in "module:export" format.
|
|
10
|
+
* @param allowedPrefixes - Optional list of allowed directory prefixes for
|
|
11
|
+
* absolute/relative paths. If provided, file-path imports must resolve
|
|
12
|
+
* under one of these directories. Package-name imports (no leading `.` or `/`)
|
|
13
|
+
* are always allowed.
|
|
7
14
|
*/
|
|
8
|
-
export async function resolveTarget(target) {
|
|
15
|
+
export async function resolveTarget(target, allowedPrefixes) {
|
|
9
16
|
const lastColon = target.lastIndexOf(":");
|
|
10
17
|
if (lastColon === -1) {
|
|
11
18
|
throw new Error(`Invalid target format: "${target}". Expected "module/path:exportName".`);
|
|
12
19
|
}
|
|
13
20
|
const modulePath = target.slice(0, lastColon);
|
|
14
21
|
const exportName = target.slice(lastColon + 1);
|
|
22
|
+
// Validate file-path imports against allowedPrefixes
|
|
23
|
+
const isFilePath = modulePath.startsWith('.') || isAbsolute(modulePath);
|
|
24
|
+
if (isFilePath && allowedPrefixes != null && allowedPrefixes.length > 0) {
|
|
25
|
+
const resolved = resolve(modulePath);
|
|
26
|
+
const allowed = allowedPrefixes.some((prefix) => resolved.startsWith(resolve(prefix)));
|
|
27
|
+
if (!allowed) {
|
|
28
|
+
throw new Error(`Import path "${modulePath}" is not under any allowed prefix: ${allowedPrefixes.join(', ')}`);
|
|
29
|
+
}
|
|
30
|
+
}
|
|
15
31
|
let mod;
|
|
16
32
|
try {
|
|
17
33
|
mod = (await import(modulePath));
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"resolve-target.js","sourceRoot":"","sources":["../src/resolve-target.ts"],"names":[],"mappings":"AAAA
|
|
1
|
+
{"version":3,"file":"resolve-target.js","sourceRoot":"","sources":["../src/resolve-target.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,UAAU,EAAE,MAAM,WAAW,CAAC;AAEhD;;;;;;;;;;;;GAYG;AACH,MAAM,CAAC,KAAK,UAAU,aAAa,CACjC,MAAc,EACd,eAA0B;IAE1B,MAAM,SAAS,GAAG,MAAM,CAAC,WAAW,CAAC,GAAG,CAAC,CAAC;IAC1C,IAAI,SAAS,KAAK,CAAC,CAAC,EAAE,CAAC;QACrB,MAAM,IAAI,KAAK,CACb,2BAA2B,MAAM,uCAAuC,CACzE,CAAC;IACJ,CAAC;IAED,MAAM,UAAU,GAAG,MAAM,CAAC,KAAK,CAAC,CAAC,EAAE,SAAS,CAAC,CAAC;IAC9C,MAAM,UAAU,GAAG,MAAM,CAAC,KAAK,CAAC,SAAS,GAAG,CAAC,CAAC,CAAC;IAE/C,qDAAqD;IACrD,MAAM,UAAU,GAAG,UAAU,CAAC,UAAU,CAAC,GAAG,CAAC,IAAI,UAAU,CAAC,UAAU,CAAC,CAAC;IACxE,IAAI,UAAU,IAAI,eAAe,IAAI,IAAI,IAAI,eAAe,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;QACxE,MAAM,QAAQ,GAAG,OAAO,CAAC,UAAU,CAAC,CAAC;QACrC,MAAM,OAAO,GAAG,eAAe,CAAC,IAAI,CAAC,CAAC,MAAM,EAAE,EAAE,CAC9C,QAAQ,CAAC,UAAU,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC,CACrC,CAAC;QACF,IAAI,CAAC,OAAO,EAAE,CAAC;YACb,MAAM,IAAI,KAAK,CACb,gBAAgB,UAAU,sCAAsC,eAAe,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAC7F,CAAC;QACJ,CAAC;IACH,CAAC;IAED,IAAI,GAA4B,CAAC;IACjC,IAAI,CAAC;QACH,GAAG,GAAG,CAAC,MAAM,MAAM,CAAC,UAAU,CAAC,CAA4B,CAAC;IAC9D,CAAC;IAAC,OAAO,GAAY,EAAE,CAAC;QACtB,MAAM,OAAO,GAAG,GAAG,YAAY,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC;QACjE,MAAM,IAAI,KAAK,CAAC,4BAA4B,UAAU,MAAM,OAAO,EAAE,CAAC,CAAC;IACzE,CAAC;IAED,IAAI,GAAG,CAAC,UAAU,CAAC,KAAK,SAAS,EAAE,CAAC;QAClC,MAAM,IAAI,KAAK,CACb,WAAW,UAAU,0BAA0B,UAAU,IAAI,CAC9D,CAAC;IACJ,CAAC;IAED,OAAO,GAAG,CAAC,UAAU,CAAC,CAAC;AACzB,CAAC"}
|
package/dist/scanner.d.ts
CHANGED
|
@@ -3,6 +3,11 @@ import type { ScannedModule } from './types.js';
|
|
|
3
3
|
export declare abstract class BaseScanner {
|
|
4
4
|
abstract scan(...args: unknown[]): ScannedModule[] | Promise<ScannedModule[]>;
|
|
5
5
|
abstract getSourceName(): string;
|
|
6
|
+
extractDocstring(func: unknown): {
|
|
7
|
+
description: string | null;
|
|
8
|
+
documentation: string | null;
|
|
9
|
+
params: Record<string, string>;
|
|
10
|
+
};
|
|
6
11
|
filterModules(modules: ScannedModule[], options?: {
|
|
7
12
|
include?: string;
|
|
8
13
|
exclude?: string;
|
package/dist/scanner.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"scanner.d.ts","sourceRoot":"","sources":["../src/scanner.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,WAAW,CAAC;AAEnD,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,YAAY,CAAC;
|
|
1
|
+
{"version":3,"file":"scanner.d.ts","sourceRoot":"","sources":["../src/scanner.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,WAAW,CAAC;AAEnD,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,YAAY,CAAC;AAYhD,8BAAsB,WAAW;IAC/B,QAAQ,CAAC,IAAI,CAAC,GAAG,IAAI,EAAE,OAAO,EAAE,GAAG,aAAa,EAAE,GAAG,OAAO,CAAC,aAAa,EAAE,CAAC;IAC7E,QAAQ,CAAC,aAAa,IAAI,MAAM;IAEhC,gBAAgB,CAAC,IAAI,EAAE,OAAO,GAAG;QAC/B,WAAW,EAAE,MAAM,GAAG,IAAI,CAAC;QAC3B,aAAa,EAAE,MAAM,GAAG,IAAI,CAAC;QAC7B,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;KAChC;IAwCD,aAAa,CACX,OAAO,EAAE,aAAa,EAAE,EACxB,OAAO,CAAC,EAAE;QAAE,OAAO,CAAC,EAAE,MAAM,CAAC;QAAC,OAAO,CAAC,EAAE,MAAM,CAAA;KAAE,GAC/C,aAAa,EAAE;IAgBlB,MAAM,CAAC,0BAA0B,CAAC,MAAM,EAAE,MAAM,GAAG,iBAAiB;IAgBpE,cAAc,CAAC,OAAO,EAAE,aAAa,EAAE,GAAG,aAAa,EAAE;CA2B1D"}
|
package/dist/scanner.js
CHANGED
|
@@ -1,22 +1,67 @@
|
|
|
1
1
|
import { DEFAULT_ANNOTATIONS } from 'apcore-js';
|
|
2
2
|
import { cloneModule } from './types.js';
|
|
3
|
+
function safeRegExp(pattern) {
|
|
4
|
+
try {
|
|
5
|
+
return new RegExp(pattern);
|
|
6
|
+
}
|
|
7
|
+
catch {
|
|
8
|
+
// If the pattern is invalid regex, treat it as a literal string
|
|
9
|
+
return new RegExp(pattern.replace(/[.*+?^${}()|[\]\\]/g, '\\$&'));
|
|
10
|
+
}
|
|
11
|
+
}
|
|
3
12
|
export class BaseScanner {
|
|
13
|
+
extractDocstring(func) {
|
|
14
|
+
if (func == null || typeof func !== 'function') {
|
|
15
|
+
return { description: null, documentation: null, params: {} };
|
|
16
|
+
}
|
|
17
|
+
// Extract JSDoc-style documentation from function's toString representation
|
|
18
|
+
const source = func.toString();
|
|
19
|
+
const jsdocMatch = source.match(/\/\*\*([\s\S]*?)\*\//);
|
|
20
|
+
if (!jsdocMatch) {
|
|
21
|
+
return { description: null, documentation: null, params: {} };
|
|
22
|
+
}
|
|
23
|
+
const raw = jsdocMatch[1];
|
|
24
|
+
const lines = raw
|
|
25
|
+
.split('\n')
|
|
26
|
+
.map((l) => l.replace(/^\s*\*\s?/, '').trim())
|
|
27
|
+
.filter((l) => l.length > 0);
|
|
28
|
+
const descLines = [];
|
|
29
|
+
const params = {};
|
|
30
|
+
let hitTag = false;
|
|
31
|
+
for (const line of lines) {
|
|
32
|
+
if (line.startsWith('@param')) {
|
|
33
|
+
hitTag = true;
|
|
34
|
+
const m = line.match(/@param\s+\{?\w*\}?\s*(\w+)\s*(.*)/);
|
|
35
|
+
if (m)
|
|
36
|
+
params[m[1]] = m[2].replace(/^-\s*/, '').trim();
|
|
37
|
+
}
|
|
38
|
+
else if (line.startsWith('@')) {
|
|
39
|
+
hitTag = true;
|
|
40
|
+
}
|
|
41
|
+
else if (!hitTag) {
|
|
42
|
+
descLines.push(line);
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
const description = descLines.length > 0 ? descLines[0] : null;
|
|
46
|
+
const documentation = descLines.length > 1 ? descLines.join('\n') : null;
|
|
47
|
+
return { description, documentation, params };
|
|
48
|
+
}
|
|
4
49
|
filterModules(modules, options) {
|
|
5
50
|
let result = modules;
|
|
6
51
|
if (options?.include != null) {
|
|
7
|
-
const
|
|
8
|
-
result = result.filter((m) =>
|
|
52
|
+
const re = safeRegExp(options.include);
|
|
53
|
+
result = result.filter((m) => re.test(m.moduleId));
|
|
9
54
|
}
|
|
10
55
|
if (options?.exclude != null) {
|
|
11
|
-
const
|
|
12
|
-
result = result.filter((m) => !
|
|
56
|
+
const re = safeRegExp(options.exclude);
|
|
57
|
+
result = result.filter((m) => !re.test(m.moduleId));
|
|
13
58
|
}
|
|
14
59
|
return result;
|
|
15
60
|
}
|
|
16
61
|
static inferAnnotationsFromMethod(method) {
|
|
17
62
|
const upper = method.toUpperCase();
|
|
18
63
|
if (upper === 'GET') {
|
|
19
|
-
return { ...DEFAULT_ANNOTATIONS, readonly: true };
|
|
64
|
+
return { ...DEFAULT_ANNOTATIONS, readonly: true, cacheable: true };
|
|
20
65
|
}
|
|
21
66
|
if (upper === 'DELETE') {
|
|
22
67
|
return { ...DEFAULT_ANNOTATIONS, destructive: true };
|
package/dist/scanner.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"scanner.js","sourceRoot":"","sources":["../src/scanner.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,mBAAmB,EAAE,MAAM,WAAW,CAAC;AAEhD,OAAO,EAAE,WAAW,EAAE,MAAM,YAAY,CAAC;AAEzC,MAAM,OAAgB,WAAW;IAI/B,aAAa,
|
|
1
|
+
{"version":3,"file":"scanner.js","sourceRoot":"","sources":["../src/scanner.ts"],"names":[],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "apcore-toolkit",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.3.0",
|
|
4
4
|
"description": "Shared scanner, schema extraction, and output toolkit for apcore framework adapters",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "./dist/index.js",
|
|
@@ -50,17 +50,17 @@
|
|
|
50
50
|
"clean": "rm -rf dist"
|
|
51
51
|
},
|
|
52
52
|
"dependencies": {
|
|
53
|
-
"apcore-js": "
|
|
53
|
+
"apcore-js": "^0.13.0",
|
|
54
54
|
"js-yaml": "^4.1.0"
|
|
55
55
|
},
|
|
56
56
|
"devDependencies": {
|
|
57
57
|
"@types/js-yaml": "^4.0.9",
|
|
58
58
|
"@types/node": "^22.0.0",
|
|
59
|
+
"@vitest/coverage-v8": "^3.0.0",
|
|
59
60
|
"apdev-js": "^0.2.0",
|
|
61
|
+
"eslint": "^9.0.0",
|
|
60
62
|
"typescript": "^5.5.0",
|
|
61
|
-
"vitest": "^3.0.0"
|
|
62
|
-
"@vitest/coverage-v8": "^3.0.0",
|
|
63
|
-
"eslint": "^9.0.0"
|
|
63
|
+
"vitest": "^3.0.0"
|
|
64
64
|
},
|
|
65
65
|
"engines": {
|
|
66
66
|
"node": ">=20.0.0"
|