-
Notifications
You must be signed in to change notification settings - Fork 28
feat(api): codegen'd sdks now look a little bit nicer #769
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
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -230,20 +230,19 @@ export default class TSGenerator extends CodeGenerator { | |
| let filePath = sourceFile.getFilePath().toString(); | ||
| filePath = filePath.substring(1); | ||
|
|
||
| /** | ||
| * It's not Prettier-level of nice but `ts-morph` offers a method of using the TS | ||
| * formatter for formatting code which we can use to make our generated SDK not look like | ||
| * total garbage. | ||
| * | ||
| * @see {@link https://ts-morph.com/manipulation/formatting} | ||
| */ | ||
| sourceFile.formatText(); | ||
|
|
||
| return { | ||
| [filePath]: sourceFile.getFullText(), | ||
| }; | ||
| }), | ||
|
|
||
| // Because we're returning the raw source files for TS generation we also need to separately | ||
| // emit out our declaration files so we can put those into a separate file in the installed | ||
| // SDK directory. | ||
| ...this.project | ||
| .emitToMemory({ emitOnlyDtsFiles: true }) | ||
| .getFiles() | ||
| .map(sourceFile => ({ | ||
| [path.basename(sourceFile.filePath)]: sourceFile.text, | ||
| })), | ||
|
Comment on lines
-238
to
-246
Member
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This is no longer used and is safe to be removed. It was a remaining artifact of the previous CJS and (attempted) ESM export work where we were generating |
||
| ].reduce((prev, next) => Object.assign(prev, next)); | ||
| } | ||
|
|
||
|
|
@@ -383,7 +382,7 @@ sdk.server('https://eu.api.example.com/v14');`), | |
| name: 'createSDK', | ||
| initializer: writer => { | ||
| // `ts-morph` doesn't have any way to cleanly create an IIFE. | ||
| writer.writeLine('(() => { return new SDK(); })()'); | ||
| writer.write('(() => { return new SDK(); })()'); | ||
|
Member
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Changing this from const createSDK = (() => { return new SDK(); })()
;and now const createSDK = (() => { return new SDK(); })();it's the little things |
||
| return writer; | ||
| }, | ||
| }, | ||
|
|
@@ -519,7 +518,9 @@ sdk.server('https://eu.api.example.com/v14');`), | |
| moduleSpecifier: `./schemas/${schemaName}`, | ||
| }); | ||
|
|
||
| let str = JSON.stringify(schema); | ||
| // Though we aren't using Prettier to make these generated SDKs look amazing we should at | ||
| // least make the schema files we generate not look like completely unreadable garbage. | ||
| let str = JSON.stringify(schema, null, 2); | ||
| let referencedSchemas = str.match(REF_PLACEHOLDER_REGEX)?.map(s => s.replace(REF_PLACEHOLDER_REGEX, '$1')); | ||
| if (referencedSchemas) { | ||
| referencedSchemas.sort(); | ||
|
|
@@ -549,7 +550,7 @@ sdk.server('https://eu.api.example.com/v14');`), | |
| // need to clean them up. | ||
| str = str.replace(REF_PLACEHOLDER_REGEX, '$1'); | ||
|
|
||
| writer.writeLine(`${str} as const`); | ||
| writer.write(`${str} as const`); | ||
|
Member
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Same as the other semicolon fix. These schemas were getting generated like the following: const schema = {"type": "string"} as const
;They're now this: const schema = {"type": "string"} as const; |
||
| return writer; | ||
| }, | ||
| }, | ||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1,5 +1,92 @@ | ||
| import RuleSource from './RuleSource'; | ||
|
|
||
| const AmqpExternalRulePatch = {"additionalProperties":false,"properties":{"requestMode":{"description":"Single request mode sends each event separately to the endpoint specified by the rule. You can read more about single request mode events in the <a href=\"https://ably.com/documentation/general/events#batching\">Ably documentation</a>.","enum":["single"],"type":"string","examples":["single"]},"ruleType":{"description":"The type of rule. In this case AMQP external (using Firehose). See the <a href=\"https://ably.com/documentation/general/firehose\">Ably documentation</a> for further information.","enum":["amqp/external"],"type":"string"},"source":RuleSource,"status":{"description":"The status of the rule. Rules can be enabled or disabled.","enum":["enabled","disabled"],"type":"string","examples":["enabled"]},"target":{"additionalProperties":false,"properties":{"enveloped":{"description":"Messages delivered through Reactor are wrapped in an Ably envelope by default that contains metadata about the message and its payload. The form of the envelope depends on whether it is part of a Webhook/Function or a Queue/Firehose rule. For everything besides Webhooks, you can ensure you only get the raw payload by unchecking \"Enveloped\" when setting up the rule.","type":["boolean","null"]},"format":{"type":"string"},"headers":{"description":"If you have additional information to send, you'll need to include the relevant headers.","items":{"properties":{"name":{"description":"The name of the header.","type":"string"},"value":{"description":"The value of the header.","type":"string"}},"type":"object"},"type":"array"},"mandatoryRoute":{"description":"Reject delivery of the message if the route does not exist, otherwise fail silently.","type":"boolean"},"messageTtl":{"description":"You can optionally override the default TTL on a queue and specify a TTL in minutes for messages to be persisted. It is unusual to change the default TTL, so if this field is left empty, the default TTL for the queue will be used.","type":"integer"},"persistentMessages":{"description":"Marks the message as persistent, instructing the broker to write it to disk if it is in a durable queue.","type":"boolean"},"routingKey":{"description":"The AMQP routing key. See this <a href=\"https://knowledge.ably.com/what-is-the-format-of-the-routingkey-for-an-amqp-or-kinesis-reactor-rule\">Ably knowledge base article</a> for details.","type":"string"},"url":{"type":"string"}},"type":"object"}},"type":"object","title":"amqp_external_rule_patch","x-readme-ref-name":"amqp_external_rule_patch"} as const | ||
| ; | ||
| const AmqpExternalRulePatch = { | ||
| "additionalProperties": false, | ||
| "properties": { | ||
| "requestMode": { | ||
| "description": "Single request mode sends each event separately to the endpoint specified by the rule. You can read more about single request mode events in the <a href=\"https://ably.com/documentation/general/events#batching\">Ably documentation</a>.", | ||
| "enum": [ | ||
| "single" | ||
| ], | ||
| "type": "string", | ||
| "examples": [ | ||
| "single" | ||
| ] | ||
| }, | ||
| "ruleType": { | ||
| "description": "The type of rule. In this case AMQP external (using Firehose). See the <a href=\"https://ably.com/documentation/general/firehose\">Ably documentation</a> for further information.", | ||
| "enum": [ | ||
| "amqp/external" | ||
| ], | ||
| "type": "string" | ||
| }, | ||
| "source": RuleSource, | ||
| "status": { | ||
| "description": "The status of the rule. Rules can be enabled or disabled.", | ||
| "enum": [ | ||
| "enabled", | ||
| "disabled" | ||
| ], | ||
| "type": "string", | ||
| "examples": [ | ||
| "enabled" | ||
| ] | ||
| }, | ||
| "target": { | ||
| "additionalProperties": false, | ||
| "properties": { | ||
| "enveloped": { | ||
| "description": "Messages delivered through Reactor are wrapped in an Ably envelope by default that contains metadata about the message and its payload. The form of the envelope depends on whether it is part of a Webhook/Function or a Queue/Firehose rule. For everything besides Webhooks, you can ensure you only get the raw payload by unchecking \"Enveloped\" when setting up the rule.", | ||
| "type": [ | ||
| "boolean", | ||
| "null" | ||
| ] | ||
| }, | ||
| "format": { | ||
| "type": "string" | ||
| }, | ||
| "headers": { | ||
| "description": "If you have additional information to send, you'll need to include the relevant headers.", | ||
| "items": { | ||
| "properties": { | ||
| "name": { | ||
| "description": "The name of the header.", | ||
| "type": "string" | ||
| }, | ||
| "value": { | ||
| "description": "The value of the header.", | ||
| "type": "string" | ||
| } | ||
| }, | ||
| "type": "object" | ||
| }, | ||
| "type": "array" | ||
| }, | ||
| "mandatoryRoute": { | ||
| "description": "Reject delivery of the message if the route does not exist, otherwise fail silently.", | ||
| "type": "boolean" | ||
| }, | ||
| "messageTtl": { | ||
| "description": "You can optionally override the default TTL on a queue and specify a TTL in minutes for messages to be persisted. It is unusual to change the default TTL, so if this field is left empty, the default TTL for the queue will be used.", | ||
| "type": "integer" | ||
| }, | ||
| "persistentMessages": { | ||
| "description": "Marks the message as persistent, instructing the broker to write it to disk if it is in a durable queue.", | ||
| "type": "boolean" | ||
| }, | ||
| "routingKey": { | ||
| "description": "The AMQP routing key. See this <a href=\"https://knowledge.ably.com/what-is-the-format-of-the-routingkey-for-an-amqp-or-kinesis-reactor-rule\">Ably knowledge base article</a> for details.", | ||
| "type": "string" | ||
| }, | ||
| "url": { | ||
| "type": "string" | ||
| } | ||
| }, | ||
| "type": "object" | ||
| } | ||
| }, | ||
| "type": "object", | ||
| "title": "amqp_external_rule_patch", | ||
| "x-readme-ref-name": "amqp_external_rule_patch" | ||
| } as const; | ||
| export default AmqpExternalRulePatch |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1,5 +1,93 @@ | ||
| import RuleSource from './RuleSource'; | ||
|
|
||
| const AmqpExternalRulePost = {"additionalProperties":false,"properties":{"requestMode":{"description":"Single request mode sends each event separately to the endpoint specified by the rule. You can read more about single request mode events in the <a href=\"https://ably.com/documentation/general/events#batching\">Ably documentation</a>.","enum":["single"],"type":"string","examples":["single"]},"ruleType":{"description":"The type of rule. In this case AMQP external (using Firehose). See the <a href=\"https://ably.com/documentation/general/firehose\">documentation</a> for further information.","enum":["amqp/external"],"type":"string"},"source":RuleSource,"target":{"additionalProperties":false,"properties":{"enveloped":{"description":"Messages delivered through Reactor are wrapped in an Ably envelope by default that contains metadata about the message and its payload. The form of the envelope depends on whether it is part of a Webhook/Function or a Queue/Firehose rule. For everything besides Webhooks, you can ensure you only get the raw payload by unchecking \"Enveloped\" when setting up the rule.","type":["boolean","null"]},"format":{"type":"string"},"headers":{"description":"If you have additional information to send, you'll need to include the relevant headers.","items":{"properties":{"name":{"description":"The name of the header.","type":"string"},"value":{"description":"The value of the header.","type":"string"}},"type":"object"},"type":"array"},"mandatoryRoute":{"description":"Reject delivery of the message if the route does not exist, otherwise fail silently.","type":"boolean"},"messageTtl":{"description":"You can optionally override the default TTL on a queue and specify a TTL in minutes for messages to be persisted. It is unusual to change the default TTL, so if this field is left empty, the default TTL for the queue will be used.","type":"integer"},"persistentMessages":{"description":"Marks the message as persistent, instructing the broker to write it to disk if it is in a durable queue.","type":"boolean"},"routingKey":{"description":"The AMQP routing key. See this <a href=\"https://knowledge.ably.com/what-is-the-format-of-the-routingkey-for-an-amqp-or-kinesis-reactor-rule\">Ably knowledge base article</a> for details.","type":"string"},"url":{"type":"string"}},"required":["url","routingKey","mandatoryRoute","persistentMessages"],"type":"object"}},"required":["ruleType","requestMode","source","target"],"type":"object","title":"amqp_external_rule_post","x-readme-ref-name":"amqp_external_rule_post"} as const | ||
| ; | ||
| const AmqpExternalRulePost = { | ||
| "additionalProperties": false, | ||
| "properties": { | ||
| "requestMode": { | ||
| "description": "Single request mode sends each event separately to the endpoint specified by the rule. You can read more about single request mode events in the <a href=\"https://ably.com/documentation/general/events#batching\">Ably documentation</a>.", | ||
| "enum": [ | ||
| "single" | ||
| ], | ||
| "type": "string", | ||
| "examples": [ | ||
| "single" | ||
| ] | ||
| }, | ||
| "ruleType": { | ||
| "description": "The type of rule. In this case AMQP external (using Firehose). See the <a href=\"https://ably.com/documentation/general/firehose\">documentation</a> for further information.", | ||
| "enum": [ | ||
| "amqp/external" | ||
| ], | ||
| "type": "string" | ||
| }, | ||
| "source": RuleSource, | ||
| "target": { | ||
| "additionalProperties": false, | ||
| "properties": { | ||
| "enveloped": { | ||
| "description": "Messages delivered through Reactor are wrapped in an Ably envelope by default that contains metadata about the message and its payload. The form of the envelope depends on whether it is part of a Webhook/Function or a Queue/Firehose rule. For everything besides Webhooks, you can ensure you only get the raw payload by unchecking \"Enveloped\" when setting up the rule.", | ||
| "type": [ | ||
| "boolean", | ||
| "null" | ||
| ] | ||
| }, | ||
| "format": { | ||
| "type": "string" | ||
| }, | ||
| "headers": { | ||
| "description": "If you have additional information to send, you'll need to include the relevant headers.", | ||
| "items": { | ||
| "properties": { | ||
| "name": { | ||
| "description": "The name of the header.", | ||
| "type": "string" | ||
| }, | ||
| "value": { | ||
| "description": "The value of the header.", | ||
| "type": "string" | ||
| } | ||
| }, | ||
| "type": "object" | ||
| }, | ||
| "type": "array" | ||
| }, | ||
| "mandatoryRoute": { | ||
| "description": "Reject delivery of the message if the route does not exist, otherwise fail silently.", | ||
| "type": "boolean" | ||
| }, | ||
| "messageTtl": { | ||
| "description": "You can optionally override the default TTL on a queue and specify a TTL in minutes for messages to be persisted. It is unusual to change the default TTL, so if this field is left empty, the default TTL for the queue will be used.", | ||
| "type": "integer" | ||
| }, | ||
| "persistentMessages": { | ||
| "description": "Marks the message as persistent, instructing the broker to write it to disk if it is in a durable queue.", | ||
| "type": "boolean" | ||
| }, | ||
| "routingKey": { | ||
| "description": "The AMQP routing key. See this <a href=\"https://knowledge.ably.com/what-is-the-format-of-the-routingkey-for-an-amqp-or-kinesis-reactor-rule\">Ably knowledge base article</a> for details.", | ||
| "type": "string" | ||
| }, | ||
| "url": { | ||
| "type": "string" | ||
| } | ||
| }, | ||
| "required": [ | ||
| "url", | ||
| "routingKey", | ||
| "mandatoryRoute", | ||
| "persistentMessages" | ||
| ], | ||
| "type": "object" | ||
| } | ||
| }, | ||
| "required": [ | ||
| "ruleType", | ||
| "requestMode", | ||
| "source", | ||
| "target" | ||
| ], | ||
| "type": "object", | ||
| "title": "amqp_external_rule_post", | ||
| "x-readme-ref-name": "amqp_external_rule_post" | ||
| } as const; | ||
| export default AmqpExternalRulePost |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
nice, TIL! kinda curious about the performance of this vs prettier vs others (but don't think we need to investigate that any time soon)