mirror of
https://github.com/Abdulazizzn/n8n-enterprise-unlocked.git
synced 2025-12-18 02:21:13 +00:00
feat(API): Add route for schema static files (#12770)
This commit is contained in:
@@ -211,4 +211,44 @@ describe('LoadNodesAndCredentials', () => {
|
||||
expect(result.description.displayName).toBe('Special @#$% Node Tool');
|
||||
});
|
||||
});
|
||||
|
||||
describe('resolveSchema', () => {
|
||||
let instance: LoadNodesAndCredentials;
|
||||
|
||||
beforeEach(() => {
|
||||
instance = new LoadNodesAndCredentials(mock(), mock(), mock(), mock());
|
||||
instance.knownNodes['n8n-nodes-base.test'] = {
|
||||
className: 'Test',
|
||||
sourcePath: '/nodes-base/dist/nodes/Test/Test.node.js',
|
||||
};
|
||||
});
|
||||
|
||||
it('should return undefined if the node is not known', () => {
|
||||
const result = instance.resolveSchema({
|
||||
node: 'n8n-nodes-base.doesNotExist',
|
||||
version: '1.0.0',
|
||||
resource: 'account',
|
||||
operation: 'get',
|
||||
});
|
||||
expect(result).toBeUndefined();
|
||||
});
|
||||
|
||||
it('should return the correct path if the node is known', () => {
|
||||
const result = instance.resolveSchema({
|
||||
node: 'n8n-nodes-base.test',
|
||||
version: '1.0.0',
|
||||
resource: 'account',
|
||||
operation: 'get',
|
||||
});
|
||||
expect(result).toEqual('/nodes-base/dist/nodes/Test/__schema__/v1.0.0/account/get.json');
|
||||
});
|
||||
|
||||
it('should return the correct path if there is no resource or operation', () => {
|
||||
const result = instance.resolveSchema({
|
||||
node: 'n8n-nodes-base.test',
|
||||
version: '1.0.0',
|
||||
});
|
||||
expect(result).toEqual('/nodes-base/dist/nodes/Test/__schema__/v1.0.0.json');
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
@@ -174,6 +174,29 @@ export class LoadNodesAndCredentials {
|
||||
return isContainedWithin(loader.directory, filePath) ? filePath : undefined;
|
||||
}
|
||||
|
||||
resolveSchema({
|
||||
node,
|
||||
version,
|
||||
resource,
|
||||
operation,
|
||||
}: {
|
||||
node: string;
|
||||
version: string;
|
||||
resource?: string;
|
||||
operation?: string;
|
||||
}): string | undefined {
|
||||
const nodePath = this.known.nodes[node]?.sourcePath;
|
||||
if (!nodePath) {
|
||||
return undefined;
|
||||
}
|
||||
|
||||
const nodeParentPath = path.dirname(nodePath);
|
||||
const schemaPath = ['__schema__', `v${version}`, resource, operation].filter(Boolean).join('/');
|
||||
const filePath = path.resolve(nodeParentPath, schemaPath + '.json');
|
||||
|
||||
return isContainedWithin(nodeParentPath, filePath) ? filePath : undefined;
|
||||
}
|
||||
|
||||
getCustomDirectories(): string[] {
|
||||
const customDirectories = [this.instanceSettings.customExtensionDir];
|
||||
|
||||
|
||||
@@ -322,8 +322,27 @@ export class Server extends AbstractServer {
|
||||
res.sendStatus(404);
|
||||
};
|
||||
|
||||
const serveSchemas: express.RequestHandler = async (req, res) => {
|
||||
const { node, version, resource, operation } = req.params;
|
||||
const filePath = this.loadNodesAndCredentials.resolveSchema({
|
||||
node,
|
||||
resource,
|
||||
operation,
|
||||
version,
|
||||
});
|
||||
|
||||
if (filePath) {
|
||||
try {
|
||||
await fsAccess(filePath);
|
||||
return res.sendFile(filePath, cacheOptions);
|
||||
} catch {}
|
||||
}
|
||||
res.sendStatus(404);
|
||||
};
|
||||
|
||||
this.app.use('/icons/@:scope/:packageName/*/*.(svg|png)', serveIcons);
|
||||
this.app.use('/icons/:packageName/*/*.(svg|png)', serveIcons);
|
||||
this.app.use('/schemas/:node/:version/:resource?/:operation?.json', serveSchemas);
|
||||
|
||||
const isTLSEnabled =
|
||||
this.globalConfig.protocol === 'https' && !!(this.sslKey && this.sslCert);
|
||||
|
||||
Reference in New Issue
Block a user