Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Typescript zod (and effect) language uses block scoped variables before they've been declared #2414

Closed
kriswest opened this issue Sep 29, 2023 · 1 comment · Fixed by #2419

Comments

@kriswest
Copy link
Contributor

kriswest commented Sep 29, 2023

While attempting to generate zod schemas from a fairly large set of JSON Schemas we've noted multiple places where a block-scoped variable representing one of the schemas is used before its been declared, meaning the source file generated is unusable

export const RaiseIntentResultBridgeResponsePayloadSchema = z.object({
    "intentResult": IntentResultSchema,
});

...

export const IntentResultSchema = z.object({
    "context": z.union([ContextElementSchema, z.null()]).optional(),
    "channel": z.union([ChannelSchema, z.null()]).optional(),
});

The same happens in the Typescript generator, but it doesn't matter there as the interfaces aren't variables

 * The message payload typically contains return values for FDC3 API functions.
 */
export interface RaiseIntentResultAgentResponsePayload {
  intentResult: IntentResult;
}

...

export interface IntentResult {
  context?: ContextElement;
  channel?: Channel;
}

Presumably, this occurs due to a logical error in this code:

mapKey.forEach((_, index) => {
// assume first
let ordinal = 0;
// pull out all names
const source = mapValue[index];
const names = source.filter(value => value as Name);
// must be behind all these names
for (let i = 0; i < names.length; i++) {
const depName = names[i];
// find this name's ordinal, if it has already been added
for (let j = 0; j < order.length; j++) {
const depIndex = order[j];
if (mapKey[depIndex] === depName) {
// this is the index of the dependency, so make sure we come after it
ordinal = Math.max(ordinal, depIndex + 1);
}
}
}
// insert index
order.splice(ordinal, 0, index);
});
// now emit ordered source
order.forEach(i => this.emitGatheredSource(mapValue[i]));

I assume the issue also affects the TypeScript effect schema language as it uses the same code.

@ryoid @Southclaws @dvdsgl

@kriswest
Copy link
Contributor Author

I instrumented the above code and determined that it outputs in the same order as the input as the comparison mapKey[depIndex] === depName is never true.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
1 participant