fix: 使用规范化插件入口路径
This commit is contained in:
parent
3a941d8a6d
commit
8b50b57f27
@ -54,14 +54,13 @@ export class QqbotPluginPackageSourceService {
|
|||||||
}
|
}
|
||||||
|
|
||||||
const manifestLike = JSON.parse(readFileSync(manifestFile, 'utf8'));
|
const manifestLike = JSON.parse(readFileSync(manifestFile, 'utf8'));
|
||||||
const entry = this.readManifestEntry(manifestLike);
|
|
||||||
const entryFile = this.pathPolicy.resolveEntryFile(
|
|
||||||
controlledPackageRoot,
|
|
||||||
entry,
|
|
||||||
);
|
|
||||||
const manifest = parseQqbotPluginManifest(manifestLike, {
|
const manifest = parseQqbotPluginManifest(manifestLike, {
|
||||||
pluginRoot: controlledPackageRoot,
|
pluginRoot: controlledPackageRoot,
|
||||||
});
|
});
|
||||||
|
const entryFile = this.pathPolicy.resolveEntryFile(
|
||||||
|
controlledPackageRoot,
|
||||||
|
manifest.entry,
|
||||||
|
);
|
||||||
const pluginKey = manifest.key;
|
const pluginKey = manifest.key;
|
||||||
|
|
||||||
return {
|
return {
|
||||||
@ -83,23 +82,4 @@ export class QqbotPluginPackageSourceService {
|
|||||||
.filter((entry) => entry.isDirectory())
|
.filter((entry) => entry.isDirectory())
|
||||||
.map((entry) => join(root, entry.name));
|
.map((entry) => join(root, entry.name));
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Reads the raw entry string before parser normalization so path policy errors stay explicit.
|
|
||||||
* @param manifestLike - Parsed `plugin.json` content whose entry path belongs to the package.
|
|
||||||
* @returns Raw entry path or an empty value that the manifest parser will reject.
|
|
||||||
*/
|
|
||||||
private readManifestEntry(manifestLike: unknown): string {
|
|
||||||
if (!this.isRecord(manifestLike)) return '';
|
|
||||||
return typeof manifestLike.entry === 'string' ? manifestLike.entry : '';
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Narrows JSON values to object records before reading manifest fields.
|
|
||||||
* @param value - Parsed JSON value from a QQBot plugin package manifest.
|
|
||||||
* @returns Whether the value is a non-array object record.
|
|
||||||
*/
|
|
||||||
private isRecord(value: unknown): value is Record<string, unknown> {
|
|
||||||
return !!value && typeof value === 'object' && !Array.isArray(value);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,4 +1,10 @@
|
|||||||
import { mkdtempSync, mkdirSync, rmSync, writeFileSync } from 'node:fs';
|
import {
|
||||||
|
mkdtempSync,
|
||||||
|
mkdirSync,
|
||||||
|
readFileSync,
|
||||||
|
rmSync,
|
||||||
|
writeFileSync,
|
||||||
|
} from 'node:fs';
|
||||||
import { tmpdir } from 'node:os';
|
import { tmpdir } from 'node:os';
|
||||||
import { join, sep } from 'node:path';
|
import { join, sep } from 'node:path';
|
||||||
|
|
||||||
@ -88,7 +94,62 @@ describe('QqbotPluginPackageSourceService', () => {
|
|||||||
);
|
);
|
||||||
|
|
||||||
await expect(source.discoverPackages()).rejects.toThrow(
|
await expect(source.discoverPackages()).rejects.toThrow(
|
||||||
'Plugin entry must stay inside the package root',
|
'PATH_OUTSIDE_PLUGIN_ROOT',
|
||||||
|
);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('resolves entry files from parser-normalized package paths', async () => {
|
||||||
|
const packageRoot = join(tempRoot, 'windows-entry');
|
||||||
|
mkdirSync(join(packageRoot, 'src'), { recursive: true });
|
||||||
|
writeFileSync(
|
||||||
|
join(packageRoot, 'plugin.json'),
|
||||||
|
JSON.stringify({
|
||||||
|
key: 'windows-entry',
|
||||||
|
name: 'Windows Entry',
|
||||||
|
version: '1.0.0',
|
||||||
|
entry: 'src\\\\index.ts',
|
||||||
|
runtime: {
|
||||||
|
workerType: 'thread',
|
||||||
|
timeoutMs: 5000,
|
||||||
|
memoryMb: 128,
|
||||||
|
maxConcurrency: 1,
|
||||||
|
},
|
||||||
|
operations: [],
|
||||||
|
}),
|
||||||
|
'utf8',
|
||||||
|
);
|
||||||
|
|
||||||
|
const pathPolicy = new QqbotPluginPackagePathPolicyService([tempRoot]);
|
||||||
|
const resolveEntryFileSpy = jest.spyOn(pathPolicy, 'resolveEntryFile');
|
||||||
|
const source = new QqbotPluginPackageSourceService(pathPolicy);
|
||||||
|
|
||||||
|
await expect(source.discoverPackages()).resolves.toEqual([
|
||||||
|
expect.objectContaining({
|
||||||
|
entry: 'src/index.ts',
|
||||||
|
entryFile: join(packageRoot, 'src', 'index.ts'),
|
||||||
|
pluginKey: 'windows-entry',
|
||||||
|
}),
|
||||||
|
]);
|
||||||
|
expect(resolveEntryFileSpy).toHaveBeenCalledWith(
|
||||||
|
packageRoot,
|
||||||
|
'src/index.ts',
|
||||||
|
);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('does not keep platform-side manifest transfer shims', () => {
|
||||||
|
const source = readFileSync(
|
||||||
|
join(
|
||||||
|
process.cwd(),
|
||||||
|
'src/modules/qqbot/plugin-platform/infrastructure/integration/package/plugin-package-source.service.ts',
|
||||||
|
),
|
||||||
|
'utf8',
|
||||||
|
);
|
||||||
|
|
||||||
|
expect(source).not.toMatch(
|
||||||
|
/normalizeManifestForCurrentParser|attachPackageKeyAlias|readPackageKey/,
|
||||||
|
);
|
||||||
|
expect(source).not.toMatch(
|
||||||
|
/thread[\s\S]{0,80}node-worker|node-worker[\s\S]{0,80}thread/,
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user