Matt (pactflow.io / pact-js / pact-go)
state is not a property in StateFunc or StateFuncWithSetup. The state is the key to the function.
so:
stateHandlers: {
'Customers are available': (params) => Promise.resolve(),
} as StateHandlers,
Should work.
If you don’t need the params, that’s optional alsoÉdouard Lopez
01/16/2023, 12:57 PMTimothy Jones
01/16/2023, 9:41 PMas StateHandlersTimothy Jones
01/16/2023, 9:41 PMTimothy Jones
01/16/2023, 9:47 PMStateHandlers, one for messages and one for the verifier. They’re both interfaces, and so they’re being merged.Timothy Jones
01/16/2023, 9:48 PMas StateHandlers is the wrong StateHandlers.Timothy Jones
01/16/2023, 9:49 PMas StateHandlers?Timothy Jones
01/16/2023, 9:50 PMStateHandlers needs to be removed or renamed, as the definitions are still being inappropriately merged even just within the pact-js code.Édouard Lopez
01/17/2023, 10:19 AMVerifierOptions and as StateHandlers, from below code, I don't have any errors, but…:
const opts: VerifierOptions = {
provider: 'ms.pact-provider-example-for-typescript',
providerVersion: packageJson.version,
providerBaseUrl: '<http://localhost:8081>',
pactUrls: [path.resolve('./pact/pacts/')],
pactBrokerUrl:
process.env.PACT_BROKER_BASE_URL || 'BROKER URL IS UNDEFINED',
publishVerificationResult:
!!<http://process.env.CI|process.env.CI> ||
!!process.env.PACT_BROKER_PUBLISH_VERIFICATION_RESULTS,
stateHandlers: {
'Customers are available': (params) =>
Promise.reject({ reason: `params: ${params}` }),
'Customers orders are available': (params) =>
Promise.reject({ reason: `params: ${params}` }),
} as StateHandlers,
logLevel: (LOG_LEVEL as LogLevel) || 'debug',
}Édouard Lopez
01/17/2023, 10:20 AMas StateHandlers I have indeed different errors:
Import from @pact_foundation/pact/src/dsl/verifier/proxy/types.js
import { StateHandlers } from '@pact-foundation/pact/src/dsl/verifier/proxy/types.js'
Type 'StateHandlers' is not assignable to type 'StateHandlers & StateHandlers'.
Type 'import("/workspaces/ms.pact-provider-example-for-typescript/node_modules/@pact-foundation/pact/src/dsl/verifier/proxy/types").StateHandlers' is not assignable to type 'import("/workspaces/ms.pact-provider-example-for-typescript/node_modules/@pact-foundation/pact/src/dsl/message").StateHandlers'.
'string' index signatures are incompatible.
Type 'StateHandler' is not assignable to type '(state: string, params?: { [name: string]: string; } | undefined) => Promise<unknown>'.
Type 'StateFuncWithSetup' is not assignable to type '(state: string, params?: { [name: string]: string; } | undefined) => Promise<unknown>'.
Type 'StateFuncWithSetup' provides no match for the signature '(state: string, params?: { [name: string]: string; } | undefined): Promise<unknown>'.Édouard Lopez
01/17/2023, 10:20 AM@pact-foundation/pact
import { LogLevel, StateHandlers, Verifier, VerifierOptions } from '@pact-foundation/pact'
Type 'StateHandlers' is not assignable to type 'StateHandlers & StateHandlers'.
Type 'import("/workspaces/ms.pact-provider-example-for-typescript/node_modules/@pact-foundation/pact/src/dsl/message").StateHandlers' is not assignable to type 'import("/workspaces/ms.pact-provider-example-for-typescript/node_modules/@pact-foundation/pact/src/dsl/verifier/proxy/types").StateHandlers'.
'string' index signatures are incompatible.
Type '(state: string, params?: { [name: string]: string; } | undefined) => Promise<unknown>' is not assignable to type 'StateHandler'.
Type '(state: string, params?: { [name: string]: string; } | undefined) => Promise<unknown>' is not assignable to type 'StateFunc'.
Types of parameters 'state' and 'parameters' are incompatible.
Type 'AnyJson | undefined' is not assignable to type 'string'.
Type 'undefined' is not assignable to type 'string'.Timothy Jones
01/17/2023, 10:20 AMas in your code. Ideally, you should use this sparinglyTimothy Jones
01/17/2023, 10:21 AMas, you’re telling the compiler not to believe what it knows, and overriding its ability to reason about the types.Timothy Jones
01/17/2023, 10:21 AMlogLevel: (LOG_LEVEL as LogLevel) || 'debug', <-- this is definitely not right, for example.Timothy Jones
01/17/2023, 10:22 AMstateHandlers: {
'Customers are available': (params) =>
Promise.reject({ reason: `params: ${params}` }),
'Customers orders are available': (params) =>
Promise.reject({ reason: `params: ${params}` }),
} as StateHandlers,
^ To fix this, replace with:
stateHandlers: {
'Customers are available': (params) =>
Promise.reject({ reason: `params: ${params}` }),
'Customers orders are available': (params) =>
Promise.reject({ reason: `params: ${params}` }),
},Timothy Jones
01/17/2023, 10:23 AMLOG_LEVEL line without seeing how it is defined, but probably you want something like:
const LOG_LEVEL = 'debug' as const;
(as const is different to the type assertion)Timothy Jones
01/17/2023, 10:24 AMas const means “this is a constant string”, so the type of LOG_LEVEL will be 'debug' and not stringTimothy Jones
01/17/2023, 10:25 AMas <Type> is only for use sparingly, in situations where typescript can’t reason about the types. Usually this happens only if someone is converting code from JS that “happened to work” rather than was well-designed. Like relying on falsy values, or convoluted array operationsTimothy Jones
01/17/2023, 10:26 AMconst opts: VerifierOptions = {
provider: 'ms.pact-provider-example-for-typescript',
providerVersion: packageJson.version,
providerBaseUrl: '<http://localhost:8081>',
pactUrls: [path.resolve('./pact/pacts/')],
pactBrokerUrl:
process.env.PACT_BROKER_BASE_URL || 'BROKER URL IS UNDEFINED',
publishVerificationResult:
!!<http://process.env.CI|process.env.CI> ||
!!process.env.PACT_BROKER_PUBLISH_VERIFICATION_RESULTS,
stateHandlers: {
'Customers are available': (params) =>
Promise.reject({ reason: `params: ${params}` }),
'Customers orders are available': (params) =>
Promise.reject({ reason: `params: ${params}` }),
},
logLevel: LOG_LEVEL || 'debug',
}Timothy Jones
01/17/2023, 10:26 AMTimothy Jones
01/17/2023, 10:26 AMTimothy Jones
01/17/2023, 10:26 AM!!Timothy Jones
01/17/2023, 10:27 AMTimothy Jones
01/17/2023, 10:27 AMTimothy Jones
01/17/2023, 10:28 AMÉdouard Lopez
01/17/2023, 10:29 AMVerifierOptions trigger an error on stateHandlers and remove the as LogLevel trigger one on logLevel field
It's defined like this
const LOG_LEVEL = process.env.LOG_LEVEL || 'trace'Timothy Jones
01/17/2023, 10:29 AMTimothy Jones
01/17/2023, 10:30 AMTimothy Jones
01/17/2023, 10:30 AMas LogLevel but you shouldn’t, because then you’re just turning off typescriptTimothy Jones
01/17/2023, 10:31 AMTimothy Jones
01/17/2023, 10:34 AMconst pactLogLevel = (
maybeLogLevel: string | undefined,
defaultLevel: LogLevel = 'info'
): LogLevel => {
if (
(maybeLogLevel !== undefined && maybeLogLevel === 'trace') ||
maybeLogLevel === 'debug' ||
maybeLogLevel === 'info' ||
maybeLogLevel === 'warn' ||
maybeLogLevel === 'error'
)
return maybeLogLevel;
return defaultLevel;
};
const LOG_LEVEL = pactLogLevel(process.env.LOG_LEVEL, 'trace');Timothy Jones
01/17/2023, 10:34 AMTimothy Jones
01/17/2023, 10:36 AMconst pactLogLevel = (
maybeLogLevel: string | undefined,
defaultLevel: LogLevel = 'info'
): LogLevel => {
if (
(maybeLogLevel !== undefined && maybeLogLevel === 'trace') ||
maybeLogLevel === 'debug' ||
maybeLogLevel === 'info' ||
maybeLogLevel === 'warn' ||
maybeLogLevel === 'error'
)
return maybeLogLevel;
return defaultLevel;
};
const LOG_LEVEL = pactLogLevel(process.env.LOG_LEVEL, 'trace');
const opts: VerifierOptions = {
provider: 'ms.pact-provider-example-for-typescript',
providerVersion: 'packageJson.version',
providerBaseUrl: '<http://localhost:8081>',
pactUrls: [path.resolve('./pact/pacts/')],
pactBrokerUrl: process.env.PACT_BROKER_BASE_URL || 'BROKER URL IS UNDEFINED',
publishVerificationResult:
!!<http://process.env.CI|process.env.CI> || !!process.env.PACT_BROKER_PUBLISH_VERIFICATION_RESULTS,
stateHandlers: {
'Customers are available': (params) =>
Promise.reject({ reason: `params: ${params}` }),
'Customers orders are available': (params) =>
Promise.reject({ reason: `params: ${params}` }),
},
logLevel: LOG_LEVEL || 'debug',
};Timothy Jones
01/17/2023, 10:36 AMpackageJson.version, because I don’t have that defined)Édouard Lopez
01/17/2023, 10:37 AMpactLogLevel method, consider normalizing the string as you have example in uppercaseTimothy Jones
01/17/2023, 10:38 AMTimothy Jones
01/17/2023, 10:38 AMTimothy Jones
01/17/2023, 10:39 AMas constÉdouard Lopez
01/17/2023, 10:40 AMstateHandlersTimothy Jones
01/17/2023, 10:40 AMTimothy Jones
01/17/2023, 10:40 AMas StateHandlers present. I’d like to see it without that line, because that line is definitely causing the error that you have sent.Édouard Lopez
01/17/2023, 10:41 AMType '{ 'Customers are available': (params: string) => Promise<unknown>; 'Customers orders are available': (params: string) => Promise<unknown>; }' is not assignable to type 'StateHandlers & StateHandlers'.
Type '{ 'Customers are available': (params: string) => Promise<unknown>; 'Customers orders are available': (params: string) => Promise<unknown>; }' is not assignable to type 'StateHandlers'.
Property ''Customers are available'' is incompatible with index signature.
Type '(params: string) => Promise<unknown>' is not assignable to type 'StateHandler'.
Type '(params: string) => Promise<unknown>' is not assignable to type 'StateFunc'.
Types of parameters 'params' and 'parameters' are incompatible.
Type 'AnyJson | undefined' is not assignable to type 'string'.
Type 'undefined' is not assignable to type 'string'.
types.d.ts(42, 5): The expected type comes from property 'stateHandlers' which is declared here on type 'VerifierOptions'Timothy Jones
01/17/2023, 10:42 AMStateHandlers?Timothy Jones
01/17/2023, 10:42 AMTimothy Jones
01/17/2023, 10:42 AMTimothy Jones
01/17/2023, 10:43 AMÉdouard Lopez
01/17/2023, 10:43 AMÉdouard Lopez
01/17/2023, 10:43 AM"typescript": "^4.9.4" and "@pact-foundation/pact": "^10.4.0",Timothy Jones
01/17/2023, 10:44 AMTimothy Jones
01/17/2023, 10:45 AMTimothy Jones
01/17/2023, 10:46 AMTimothy Jones
01/17/2023, 10:46 AMTimothy Jones
01/17/2023, 10:47 AMTimothy Jones
01/17/2023, 10:47 AMTimothy Jones
01/17/2023, 10:47 AMÉdouard Lopez
01/17/2023, 10:50 AMTimothy Jones
01/17/2023, 10:50 AMF1 then “Select Typescript Version” you can choose which version it’s using. Usually you want “Project”Timothy Jones
01/17/2023, 10:50 AMÉdouard Lopez
01/17/2023, 10:51 AM5.0.0 but select the one from the project I still get the errorTimothy Jones
01/17/2023, 10:52 AMparamsÉdouard Lopez
01/17/2023, 10:53 AMTimothy Jones
01/17/2023, 10:53 AMTimothy Jones
01/17/2023, 10:53 AMÉdouard Lopez
01/17/2023, 10:55 AMVerifierOptions on the opts declaration remove the errorTimothy Jones
01/17/2023, 10:55 AMTimothy Jones
01/17/2023, 10:55 AMTimothy Jones
01/17/2023, 10:55 AMÉdouard Lopez
01/17/2023, 10:56 AMTimothy Jones
01/17/2023, 10:57 AMPromise.rejectTimothy Jones
01/17/2023, 10:57 AMPromise<unknown> which Pact doesn’t accept.Timothy Jones
01/17/2023, 10:57 AMTimothy Jones
01/17/2023, 10:58 AMstateHandlers: {
'Customers are available': (params: Record<string, string> | string) =>
Promise.reject<void>({
reason: `params: ${params}`,
}),
'Customers orders are available': (
params: Record<string, string> | string
) => Promise.reject<void>({ reason: `params: ${params}` }),
},Timothy Jones
01/17/2023, 10:58 AMTimothy Jones
01/17/2023, 10:58 AMTimothy Jones
01/17/2023, 10:58 AMStateHandler definitions. Frankly I can’t see how this ever worked.Timothy Jones
01/17/2023, 10:59 AMunknown)Édouard Lopez
01/17/2023, 10:59 AMÉdouard Lopez
01/17/2023, 11:00 AMstateHandlers: {
'Customers are available': (params: Record<string, string> | string) =>
Promise.reject<void>({
reason: `params: ${params}`,
}),
'Customers orders are available': (
params: Record<string, string> | string
) => Promise.reject<void>({ reason: `params: ${params}` }),
},
fails
Type '{ 'Customers are available': (params: Record<string, string> | string) => Promise<void>; 'Customers orders are available': (params: Record<string, string> | string) => Promise<void>; }' is not assignable to type 'StateHandlers & StateHandlers'.
Type '{ 'Customers are available': (params: Record<string, string> | string) => Promise<void>; 'Customers orders are available': (params: Record<string, string> | string) => Promise<void>; }' is not assignable to type 'StateHandlers'.
Property ''Customers are available'' is incompatible with index signature.
Type '(params: Record<string, string> | string) => Promise<void>' is not assignable to type 'StateHandler'.
Type '(params: Record<string, string> | string) => Promise<void>' is not assignable to type 'StateFunc'.
Types of parameters 'params' and 'parameters' are incompatible.
Type 'AnyJson | undefined' is not assignable to type 'string | Record<string, string>'.
Type 'undefined' is not assignable to type 'string | Record<string, string>'.Timothy Jones
01/17/2023, 11:00 AMTimothy Jones
01/17/2023, 11:02 AMTimothy Jones
01/17/2023, 11:02 AMTimothy Jones
01/17/2023, 11:04 AMAnyJson. I brought that in when I was a maintainer - I thought it was a good idea (designed to stop people putting non-json things in a body), but it turns out to be more trouble than it was worth.
I don’t think it’s the problem here - I think the problem is the inappropriately merged declaration.Timothy Jones
01/17/2023, 11:04 AMTimothy Jones
01/17/2023, 11:06 AMconst customersAreAvailable: StateFunc = (params) =>
Promise.reject<void>({
reason: `params: ${params}`,
});
const customerOrdersAreAvailable: StateFunc = (params) =>
Promise.reject({
reason: `params: ${params}`,
});
it('verify our app can provide responses expected by ALL our consumers', () => {
const opts: VerifierOptions = {
provider: 'ms.pact-provider-example-for-typescript',
providerVersion: packageJson.version,
providerBaseUrl: '<http://localhost:8081>',
pactUrls: [path.resolve('./pact/pacts/')],
pactBrokerUrl:
process.env.PACT_BROKER_BASE_URL || 'BROKER URL IS UNDEFINED',
publishVerificationResult:
!!<http://process.env.CI|process.env.CI> ||
!!process.env.PACT_BROKER_PUBLISH_VERIFICATION_RESULTS,
stateHandlers: {
'Customers are available': customersAreAvailable,
'Customers orders are available': customerOrdersAreAvailable,
},
logLevel: LOG_LEVEL || 'debug',
};Timothy Jones
01/17/2023, 11:06 AMÉdouard Lopez
01/17/2023, 11:13 AMÉdouard Lopez
01/17/2023, 11:18 AMTimothy Jones
01/17/2023, 11:23 AM