Merge branch 'main' into next

This commit is contained in:
nocobase[bot]
2026-07-10 05:40:42 +00:00
2 changed files with 77 additions and 2 deletions
@@ -0,0 +1,69 @@
/**
* This file is part of the NocoBase (R) project.
* Copyright (c) 2020-2024 NocoBase Co., Ltd.
* Authors: NocoBase Team.
*
* This project is dual-licensed under AGPL-3.0 and NocoBase Commercial License.
* For more information, please refer to: https://www.nocobase.com/agreement.
*/
import type { ResourcerContext } from '@nocobase/resourcer';
import { beforeAll, describe, expect, it, vi } from 'vitest';
import { resolveVariablesTemplate } from '../variables/resolve';
import { resetVariablesRegistryForTest } from './test-utils';
describe('variables:resolve external data source records', () => {
beforeAll(() => {
resetVariablesRegistryForTest();
});
it('resolves a popup record field when the repository returns plain JSON', async () => {
const findOne = vi.fn(async () => ({ id: 'lead-1', email: 'acme@example.test' }));
const repository = { findOne };
const collection = {
filterTargetKey: 'id',
model: {
primaryKeyAttribute: 'id',
},
};
const getDataSource = vi.fn((key: string) => {
expect(key).toBe('crm_external');
return {
collectionManager: {
db: {
getCollection: () => collection,
getRepository: () => repository,
},
},
};
});
const koaContext = {
app: {
dataSourceManager: { get: getDataSource },
environment: { getVariables: () => ({}) },
logger: { child: () => ({ debug: vi.fn(), warn: vi.fn() }) },
},
state: {},
} as unknown as ResourcerContext;
const result = await resolveVariablesTemplate(
koaContext,
{ value: '{{ ctx.popup.record.email }}' },
{
'popup.record': {
dataSourceKey: 'crm_external',
collection: 'leads',
filterByTk: 'lead-1',
},
},
);
expect(result).toEqual({ value: 'acme@example.test' });
expect(findOne).toHaveBeenCalledTimes(1);
expect(findOne).toHaveBeenCalledWith({
filterByTk: 'lead-1',
fields: undefined,
appends: undefined,
});
});
});
@@ -77,9 +77,15 @@ export function mergeFieldsWithExtras(fields?: string[], extras: string[] = []):
return uniqStrings([...fields, ...extras]);
}
function toJsonRecord(record: unknown): unknown {
if (!record || typeof record !== 'object') return record;
const toJSON = (record as { toJSON?: () => unknown }).toJSON;
return typeof toJSON === 'function' ? toJSON.call(record) : record;
}
function toJsonArray(rows: unknown): any[] {
if (!Array.isArray(rows)) return [];
return rows.map((r: any) => (r?.toJSON ? r.toJSON() : r));
return rows.map(toJsonRecord);
}
/**
@@ -158,5 +164,5 @@ export async function fetchRecordOrRecordsJson(
const rec = await repo.findOne(
preferFullRecord ? { filterByTk: filterByTk as any } : { filterByTk: filterByTk as any, fields, appends },
);
return rec ? rec.toJSON() : undefined;
return rec ? toJsonRecord(rec) : undefined;
}