Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion docs/guides/examples.md
Original file line number Diff line number Diff line change
Expand Up @@ -99,7 +99,7 @@ Service factories must accept a typed config and return a typed service:
"exportFunctions": [
{
"name": "create${serviceName.toPascalCase()}Service",
"receiveParamOfType": "${serviceName.toPascalCase()}Config",
"receiveParamsOfTypes": ["${serviceName.toPascalCase()}Config"],
"returnValueOfType": "${serviceName.toPascalCase()}Service"
}
]
Expand Down
4 changes: 3 additions & 1 deletion docs/reference/path-patterns.md
Original file line number Diff line number Diff line change
Expand Up @@ -107,7 +107,9 @@ Templates work anywhere a string appears in `must` or `mustNot`:
"exportFunctions": [
{
"name": "create${adapterName.toPascalCase()}Adapter",
"receiveParamOfType": "${adapterName.toPascalCase()}AdapterConfig",
"receiveParamsOfTypes": [
"${adapterName.toPascalCase()}AdapterConfig"
],
"returnValueOfType": "${adapterName.toPascalCase()}Adapter"
}
]
Expand Down
11 changes: 6 additions & 5 deletions docs/reference/predicates.md
Original file line number Diff line number Diff line change
Expand Up @@ -108,14 +108,14 @@ Assert local `const` declarations.

### `declareFunctions`

Assert local function declarations. Optionally validate parameter and return type, using the same fields as `exportFunctions`.
Assert local function declarations. Optionally validate parameters and return type, using the same fields as `exportFunctions`.

```json
"must": {
"declareFunctions": [
{
"name": "createInternalClient",
"receiveParamOfType": "ClientConfig",
"receiveParamsOfTypes": ["ClientConfig"],
"returnValueOfType": "Client"
}
]
Expand Down Expand Up @@ -222,14 +222,14 @@ Assert `const` exports specifically. Stricter than `export` — a `function` or

### `exportFunctions`

Assert function exports. Optionally validate the parameter and return type.
Assert function exports. Optionally validate parameters and return type.

```json
"must": {
"exportFunctions": [
{
"name": "create${serviceName.toPascalCase()}Service",
"receiveParamOfType": "${serviceName.toPascalCase()}Config",
"receiveParamsOfTypes": ["${serviceName.toPascalCase()}Config"],
"returnValueOfType": "${serviceName.toPascalCase()}Service"
}
]
Expand All @@ -239,7 +239,8 @@ Assert function exports. Optionally validate the parameter and return type.
| Field | Type | Description |
| --- | --- | --- |
| `name` | string | The function name. Templates allowed. |
| `receiveParamOfType` | string | Optional. Type the first parameter must have. |
| `receiveParamsOfTypes` | string[] | Optional. Ordered parameter types to enforce by index. Extra function parameters are allowed. |
| `receiveParamOfType` | string | Deprecated. Optional type at least one parameter must have. Use `receiveParamsOfTypes` instead. |
| `returnValueOfType` | string | Optional. Type the return value must have. |

The bare-string form (`"exportFunctions": ["myFunction"]`) checks existence only.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,9 @@
"exportFunctions": [
{
"name": "create${adapterName.toPascalCase()}Adapter",
"receiveParamOfType": "${adapterName.toPascalCase()}AdapterConfig",
"receiveParamsOfTypes": [
"${adapterName.toPascalCase()}AdapterConfig"
],
"returnValueOfType": "${adapterName.toPascalCase()}Adapter"
}
],
Expand Down
4 changes: 3 additions & 1 deletion e2e/fixtures/class-and-function-contracts/konsistent.json
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,9 @@
"exportFunctions": [
{
"name": "create${adapterName.toPascalCase()}Adapter",
"receiveParamOfType": "${adapterName.toPascalCase()}AdapterConfig",
"receiveParamsOfTypes": [
"${adapterName.toPascalCase()}AdapterConfig"
],
"returnValueOfType": "${adapterName.toPascalCase()}Adapter"
}
],
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@
"declareFunctions": [
{
"name": "createLocal",
"receiveParamOfType": "LocalConfig",
"receiveParamsOfTypes": ["LocalConfig"],
"returnValueOfType": "LocalResult"
}
],
Expand Down
2 changes: 1 addition & 1 deletion e2e/fixtures/declaration-predicates-broken/konsistent.json
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@
"declareFunctions": [
{
"name": "createLocal",
"receiveParamOfType": "LocalConfig",
"receiveParamsOfTypes": ["LocalConfig"],
"returnValueOfType": "LocalResult"
}
],
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@
"declareFunctions": [
{
"name": "createLocal",
"receiveParamOfType": "LocalConfig",
"receiveParamsOfTypes": ["LocalConfig"],
"returnValueOfType": "LocalResult"
}
],
Expand Down
2 changes: 1 addition & 1 deletion e2e/fixtures/declaration-predicates/konsistent.json
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@
"declareFunctions": [
{
"name": "createLocal",
"receiveParamOfType": "LocalConfig",
"receiveParamsOfTypes": ["LocalConfig"],
"returnValueOfType": "LocalResult"
}
],
Expand Down
16 changes: 16 additions & 0 deletions e2e/fixtures/deprecated-function-param/konsistent.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
{
"version": "v1",
"conventions": [
{
"paths": "index.ts",
"must": {
"exportFunctions": [
{
"name": "createThing",
"receiveParamOfType": "ThingConfig"
}
]
}
}
]
}
5 changes: 4 additions & 1 deletion e2e/fixtures/function-signatures-broken/konsistent.json
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,10 @@
"exportFunctions": [
{
"name": "create${serviceName.toPascalCase()}Service",
"receiveParamOfType": "${serviceName.toPascalCase()}Config",
"receiveParamsOfTypes": [
"${serviceName.toPascalCase()}Config",
"${serviceName.toPascalCase()}Logger"
],
"returnValueOfType": "${serviceName.toPascalCase()}Service"
}
]
Expand Down
14 changes: 13 additions & 1 deletion e2e/fixtures/function-signatures-broken/services/auth/index.ts
Original file line number Diff line number Diff line change
@@ -1,9 +1,21 @@
export interface Options {
apiKey: string;
}
export interface AuthConfig {
apiKey: string;
}
export interface AuthService {
authenticate(): Promise<void>;
}
export function createAuthService(config: Options): AuthService {
export interface AuthLogger {
info(message: string): void;
}
export function createAuthService(
config: AuthConfig,
logger: Options,
retryCount: number
): AuthService {
logger.apiKey;
retryCount;
return { authenticate: async () => {} };
}
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,13 @@ export interface PaymentsConfig {
export interface PaymentsService {
charge(): Promise<void>;
}
export function createPaymentsService(config: PaymentsConfig): any {
export interface PaymentsLogger {
info(message: string): void;
}
export function createPaymentsService(
config: PaymentsConfig,
logger: PaymentsLogger
): any {
logger.info(config.apiKey);
return { charge: async () => {} };
}
5 changes: 4 additions & 1 deletion e2e/fixtures/function-signatures/konsistent.json
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,10 @@
"exportFunctions": [
{
"name": "create${serviceName.toPascalCase()}Service",
"receiveParamOfType": "${serviceName.toPascalCase()}Config",
"receiveParamsOfTypes": [
"${serviceName.toPascalCase()}Config",
"${serviceName.toPascalCase()}Logger"
],
"returnValueOfType": "${serviceName.toPascalCase()}Service"
}
]
Expand Down
10 changes: 9 additions & 1 deletion e2e/fixtures/function-signatures/services/auth/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,14 @@ export interface AuthConfig {
export interface AuthService {
authenticate(): Promise<void>;
}
export function createAuthService(config: AuthConfig): AuthService {
export interface AuthLogger {
info(message: string): void;
}
export function createAuthService(
config: AuthConfig,
logger: AuthLogger,
retryCount: number
): AuthService {
logger.info(`auth retries: ${retryCount}`);
return { authenticate: async () => {} };
}
8 changes: 7 additions & 1 deletion e2e/fixtures/function-signatures/services/payments/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,14 @@ export interface PaymentsService<T> {
client: T;
charge(): Promise<void>;
}
export interface PaymentsLogger {
info(message: string): void;
}
export function createPaymentsService(
config: PaymentsConfig<string>
config: PaymentsConfig<string>,
logger: PaymentsLogger,
timeoutMs: number
): PaymentsService<string> {
logger.info(`payments timeout: ${timeoutMs}`);
return { client: config.client, charge: async () => {} };
}
17 changes: 15 additions & 2 deletions e2e/placeholder.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -201,7 +201,7 @@ describe("function-signatures-broken fixture", () => {
};
expect(error.code ?? error.status).toBe(1);
expect(error.stdout).toContain(
'Function "createAuthService" must receive a parameter of type "AuthConfig"'
'Function "createAuthService" parameter 2 must be of type "AuthLogger"'
);
expect(error.stdout).toContain(
'Function "createPaymentsService" must return value of type "PaymentsService"'
Expand All @@ -212,6 +212,19 @@ describe("function-signatures-broken fixture", () => {
});
});

describe("deprecated-function-param fixture", () => {
const cwd = resolve(fixturesDir, "deprecated-function-param");

it("konsistent validate exits 0 and warns for receiveParamOfType", async () => {
const { stdout, stderr } = await runCli({ args: ["validate"], cwd });
expect(stdout).toContain("Configuration is valid");
expect(stderr).toContain('"receiveParamOfType" is deprecated');
expect(stderr).toContain(
"conventions[0].must.exportFunctions[0].receiveParamOfType"
);
});
});

describe("ai-toolkit-broken-exports fixture", () => {
const cwd = resolve(fixturesDir, "ai-toolkit-broken-exports");

Expand Down Expand Up @@ -300,7 +313,7 @@ describe("class-and-function-contracts-broken fixture", () => {
'Class "DatabaseAdapter" must extend "BaseAdapter"'
);
expect(error.stdout).toContain(
'Function "createDatabaseAdapter" must receive a parameter of type "DatabaseAdapterConfig"'
'Function "createDatabaseAdapter" parameter 1 must be of type "DatabaseAdapterConfig"'
);
expect(error.stdout).toContain(
'Function "createDatabaseAdapter" must return value of type "DatabaseAdapter"'
Expand Down
48 changes: 48 additions & 0 deletions packages/convention/reusable-convention-package.schema.json
Original file line number Diff line number Diff line change
Expand Up @@ -156,6 +156,12 @@
"receiveParamOfType": {
"type": "string"
},
"receiveParamsOfTypes": {
"type": "array",
"items": {
"type": "string"
}
},
"returnValueOfType": {
"type": "string"
}
Expand Down Expand Up @@ -354,6 +360,12 @@
"receiveParamOfType": {
"type": "string"
},
"receiveParamsOfTypes": {
"type": "array",
"items": {
"type": "string"
}
},
"returnValueOfType": {
"type": "string"
}
Expand Down Expand Up @@ -603,6 +615,12 @@
"receiveParamOfType": {
"type": "string"
},
"receiveParamsOfTypes": {
"type": "array",
"items": {
"type": "string"
}
},
"returnValueOfType": {
"type": "string"
}
Expand Down Expand Up @@ -801,6 +819,12 @@
"receiveParamOfType": {
"type": "string"
},
"receiveParamsOfTypes": {
"type": "array",
"items": {
"type": "string"
}
},
"returnValueOfType": {
"type": "string"
}
Expand Down Expand Up @@ -1131,6 +1155,12 @@
"receiveParamOfType": {
"type": "string"
},
"receiveParamsOfTypes": {
"type": "array",
"items": {
"type": "string"
}
},
"returnValueOfType": {
"type": "string"
}
Expand Down Expand Up @@ -1329,6 +1359,12 @@
"receiveParamOfType": {
"type": "string"
},
"receiveParamsOfTypes": {
"type": "array",
"items": {
"type": "string"
}
},
"returnValueOfType": {
"type": "string"
}
Expand Down Expand Up @@ -1578,6 +1614,12 @@
"receiveParamOfType": {
"type": "string"
},
"receiveParamsOfTypes": {
"type": "array",
"items": {
"type": "string"
}
},
"returnValueOfType": {
"type": "string"
}
Expand Down Expand Up @@ -1776,6 +1818,12 @@
"receiveParamOfType": {
"type": "string"
},
"receiveParamsOfTypes": {
"type": "array",
"items": {
"type": "string"
}
},
"returnValueOfType": {
"type": "string"
}
Expand Down
1 change: 1 addition & 0 deletions packages/convention/src/index.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,7 @@ describe("ReusableConventionV1Schema", () => {
{
name: "createLocal",
receiveParamOfType: "LocalConfig",
receiveParamsOfTypes: ["LocalConfig"],
returnValueOfType: "Local",
},
],
Expand Down
4 changes: 4 additions & 0 deletions packages/convention/src/schemas.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,11 @@ export const ImportDefinitionV1Schema = z.strictObject({

export const FunctionDefinitionV1Schema = z.strictObject({
name: z.string(),
/**
* Deprecated: use receiveParamsOfTypes instead.
*/
receiveParamOfType: z.string().optional(),
receiveParamsOfTypes: z.array(z.string()).optional(),
returnValueOfType: z.string().optional(),
});

Expand Down
Loading