-
Notifications
You must be signed in to change notification settings - Fork 3.9k
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
Tokens: be able to represent as numbers #1455
Tokens: be able to represent as numbers #1455
Comments
Agreed. This requires VERY careful thought and testing at the jsii serialization border. For example, numbers are PROBABLY represented as My original (most future-proofed) idea was to store the token identifier in the unused bits of a NaN, but that definitely requires additional JSII implementation effort on both sides (to detect the case of special NaNs, extract and transport the hidden bits explicitly, on both sides), so just picking a decimal number that "just" happens to stringify and parse correctly may be a more expedient solution. |
Use case: @mipearson for example wants to use a CloudFormation parameter as the input to This would also require changing the source of ASG to check for "real" values and only do the validation then. |
So .. this isn't a real use case, so much as something I thought would work but didn't. I was working out how to integrate CDK with existing tooling that can use external tools to compile CFN templates. What I ended up doing instead was using that tool's "compile time parameters" feature to pass the parameters in via JSON to javascript. IMO properly supporting this use case would complicate most constructs - what I'd prefer is that the construct instead insist on "real" values and throw a descriptive error if it's passed references when it can't work with them. |
In my own code I'm going to be optimising for providers instead and writing my own - eg if |
Sure, but I think we can add some utilities to make this easier to write for TypeScript construct authors. Something like: cdk.validate(props.minSize, props.maxSize, (minSize, maxSize) => {
// Callback only executed if neither minSize nor maxSize are unresolved
if (!(minSize <= maxSize)) {
throw new Error('...');
}
}); Or even this: cdk.validate('minSize should be <= maxSize', props.minSize, props.maxSize, (minSize, maxSize) =>minSize <= maxSize);
});
// Will throw something like:
// "minSize should be <= maxSize, got: 23, 5" |
Now that we can represent attributes as native strings and string lists, this covers the majority of resource attributes in CloudFormation. This change: * String attributes are represented as `string` (like before). * String list attribute are now represented as `string[]`. * Any other attribute types are represented as `cdk.Token`. Attributes that are represented as Tokens as of this change: * amazonmq has a bunch of `Integer` attributes (will be solved by #1455) * iot1click has a bunch of `Boolean` attributes * cloudformation has a JSON attribute * That's all. A few improvements to cfn2ts: * Auto-detect cfn2ts scope from package.json so it is more self-contained and doesn't rely on cdk-build-tools to run. * Added a "cfn2ts" npm script to all modules so it is now possible to regenerate all L1 via "lerna run cfn2ts". * Removed the premature optimization for avoiding code regeneration (it saved about 0.5ms). Fixes #1406
Now that we can represent attributes as native strings and string lists, this covers the majority of resource attributes in CloudFormation. This change: * String attributes are represented as `string` (like before). * String list attribute are now represented as `string[]`. * Any other attribute types are represented as `cdk.Token`. Attributes that are represented as Tokens as of this change: * amazonmq has a bunch of `Integer` attributes (will be solved by #1455) * iot1click has a bunch of `Boolean` attributes * cloudformation has a JSON attribute * That's all. A few improvements to cfn2ts: * Auto-detect cfn2ts scope from package.json so it is more self-contained and doesn't rely on cdk-build-tools to run. * Added a "cfn2ts" npm script to all modules so it is now possible to regenerate all L1 via "lerna run cfn2ts". * Removed the premature optimization for avoiding code regeneration (it saved about 0.5ms). Fixes #1406 BREAKING CHANGE: any `CfnXxx` resource attributes that represented a list of strings are now typed as `string[]`s (via #1144). Attributes that represent strings, are still typed as `string` (#712) and all other attribute types are represented as `cdk.Token`.
This does bring up a more general concern around input validation which exists not only for numbers and I suspect we are violating already in a few places. |
var buf = new ArrayBuffer(8);
var bytes = new Uint8Array(buf);
// IEEE double in LE
// [mmmmmmm][mmmmmmm][mmmmmmm][mmmmmmm][mmmmmmm][mmmmmmm][eeeeemm][Seeeeee]
// \------------------- mantissa 52 bits ------------------/\----expo---/^sign
bytes[7] = 0x80;
bytes[6] = 0x04;
bytes[5] = 0x01;
const f = (new Float64Array(buf))[0];
const fs = JSON.stringify(f);
console.log(fs);
g = JSON.parse(fs);
console.log(f == g);
|
Java: Double f = Double.parseDouble("-5.568116955492875e-309");
System.out.println(f);
|
Python
|
A finite binary number can never need an infinite decimal representation, says someone smarter than me on StackExchange: |
By the way, I just realized something. We should make the number VERY LARGE as opposed to VERY SMALL, so that if users manipulate it by accident it'll reduce the opportunity for it to break the token: tiny_token + 1 === 1
huge_token + 1 === huge_token |
Numbers can now be encoded into a set of (hugely negative) numbers, and the encoding can be reversed. This allows APIs that take numbers to take lazy values and intrinsics that evaluate to numbers. This change only introduces the capability, it does not use it in any of the construct libraries yet. Fixes #1455.
Numbers can now be encoded into a set of (hugely negative) numbers, and the encoding can be reversed. This allows APIs that take numbers to take lazy values and intrinsics that evaluate to numbers. This change only introduces the capability, it does not use it in any of the construct libraries yet. Fixes #1455.
Numbers can now be encoded into a set of (hugely negative) numbers, and the encoding can be reversed. This allows APIs that take numbers to take lazy values and intrinsics that evaluate to numbers. This change only introduces the capability, it does not use it in any of the construct libraries yet. Fixes #1455.
We are able to represent tokens as strings (
token.toString()
) and as string arrays (token.toList()
), but in certain cases, there's a need to represent them as numbers. Introducetoken.toNumber()
.We need to somehow encode the fact that this is a token into a number. It's not going to be elegant (e.g.
-66737346654.<random>
can be the key to the token map).Related to #744
Related to #1453
The text was updated successfully, but these errors were encountered: