aws-cloudformation / aws-cloudformation/cloudformation-cli-typescript-plugin

Migrate away from class-transfomer

Ouverte
#100 1 commentaire 0 réactions 0 personnes assignées Voir sur GitHub
Langage dominant
TypeScript
Étoiles
46
Forks
18
Métriques de merge des PR
Aucune PR mergée en 30 j

Description

This is a rethought version of my previous ticket https://github.com/aws-cloudformation/cloudformation-cli-typescript-plugin/issues/68

To resummarize the issues with `class-transformer`:

* The serialization breaks down in the face of unsupported CloudFormation JSON Schema Features, and increases complexity since JSON Schema features must be manually mapped to the Class Transformer equivalent.
* It ties the implementation to TypeScript's decorators which are soon to be completely deprecated and redesigned entirely, and results in a data model that might be foreign to a lot of JavaScript developers today (outside angular and nestjs)
* Because of the above, it prevents JavaScript from working (though I'd personally always encourage TS over JS) (https://github.com/aws-cloudformation/cloudformation-cli-typescript-plugin/issues/8)
* ~The project isn't also super alive right now: https://github.com/typestack/class-transformer/issues/1272~ Possibly no longer as valid, it looks like the projects might be getting new maintainers.

The updated proposal proposes swapping `class-transformer` with three components:

* The package [camelcase-keys](https://www.npmjs.com/package/camelcase-keys) to handle the CloudFormation-to-JS object key camelcasing.
* The package [AJV](https://www.npmjs.com/package/ajv) to handle validating the incoming event properties, provide friendly(er) error messages, as well as [automatic type conversion](https://ajv.js.org/coercion.html)
* The package [json-schema-to-typescript](https://www.npmjs.com/package/json-schema-to-typescript) to handle consuming the resource definition and outputting type information for a richer experience.

While a very large change, it would uncouple this plugin from TypeScript and an unmaintained library while hopefully simplifying the Dev UX of developing a resource in typescript.

For example, a simple handler like the template default would become (example greatly appreviated):

```typescript
// handlers.ts
import { Resource, TypeConfiguration } from "./.generated/models";
import { createResource, ProgressEvent, exceptions } from '@amazon-web-services-cloudformation/cloudformation-cli-typescript-lib';

const { entrypoint, testEntrypoint } = createResource({
typeName: Resource.TypeName,
schema: Resource.Schema,
// Type information for all the below is automatically infered
async create({ session, properties, request, logger, typeConfiguration }) {
// Example:
try {
const { apiKey } = typeConfiguration;
const response = await fetch(`https://api.someservice.com`, {
method: 'POST',
headers: { 'x-api-key': apiKey },
body: { ...properties },
});
const { id } = await response.json();
properties.id = id;
// else handle error
} catch(err) {
logger.log(err);
// exceptions module lets CloudFormation know the type of failure that occurred
throw new exceptions.InternalFailure(err.message);
// this can also be done by returning a failed progress event
// return ProgressEvent.failed(HandlerErrorCode.InternalFailure, err.message);
}
return properties;
},
/* more handlers.... */
async list({ properties, typeConfiguration }) {
/* ...some list code... */
// Just return a plain array of models, validate via typescript & ajv
return [/* list of plain old javascript models */];
},
});

export { entrypoint, testEntrypoint };

```

This also externalizes a lot of concerns unnecessary to the user code, infers a lot more of type information automatically, and makes developing resource types much less mentally onerous allowing developers to focus on business logic.

It would require more work with the SDK and generated code however.

Guide de contribution

Ouvrir le guide de contribution

Piste de recherche

Examinez d’abord l’issue 68 et l’exemple handlers.ts proposé, puis inspectez le SDK et le code généré qui, d’après l’issue, nécessiteraient des modifications. Retracez l’intégration actuelle de class-transformer et identifiez les points d’entrée concernés avant d’évaluer camelcase-keys, AJV et json-schema-to-typescript. La tâche est terminée lorsque le plugin ne dépend plus de class-transformer, prend en charge le workflow JavaScript et TypeScript proposé et inclut les modifications requises du SDK et du code généré.

Rédigé par le modèle d'indexation à partir du texte de l'issue.

Évaluation

Stack technique
javascript, nodejs, typescript
Domaine
developer-experience, tooling
Type d'issue
Fonctionnalité
Difficulté
5/5
Temps estimé
Plus d'une semaine
Activité
À l'abandon
Clarté
À clarifier
Accessibilité débutants
25/100

Recevez les nouvelles issues par e-mail

Un résumé court des issues GitHub adaptées aux débutants.