1 // Package lduser defines the older LaunchDarkly SDK model for user properties. 2 // 3 // The SDK now uses the type [ldcontext.Context] to represent an evaluation context that might 4 // represent a user, or some other kind of entity, or multiple kinds. But in older SDK versions, 5 // this was limited to one kind and was represented by the type lduser.User. This differed from 6 // [ldcontext.Context] in several ways: 7 // - There was always a single implicit context kind of "user" ([ldcontext.DefaultKind]). 8 // - Unlike Context where only a few attributes such as Key and Name have special behavior, the 9 // user model defined many other built-in attributes such as Email which, like Name, were constrained 10 // to only allow string values. These had specific setter methods in [UserBuilder]. Non-built-in 11 // attributes were considered "custom" attributes, and were enclosed in a "custom" object in JSON 12 // representations. 13 // 14 // # The User type 15 // 16 // The SDK now operates only on Contexts, but the former [User] type is now an alias for 17 // [ldcontext.Context], so that some code written for the older SDK that referenced the User type 18 // can still work-- as long as it is treating the user as an opaque value and not trying to call 19 // methods of the old User type on it. For instance, the old User type had attribute accessors like 20 // GetEmail() which do not exist in [ldcontext.Context]. 21 // 22 // # Updating code while still using UserBuilder 23 // 24 // The [UserBuilder] type has been retained and modified to be a wrapper for [ldcontext.Builder], 25 // allowing code that used the older model for building users to still work with minor adjustments. 26 // 27 // For any code that still uses UserBuilder, the significant differences from older SDK versions are: 28 // 1. The Build method of UserBuilder now returns an [ldcontext.Context], so you will need to update 29 // any part of your code that referred to the lduser.User type by name. 30 // 2. The SDK no longer supports setting the key to an empty string. If you do this, the returned 31 // Context will be invalid (as indicated by its [ldcontext.Context.Err] method returning an error) and the 32 // SDK will refuse to use it for evaluations or events. 33 // 3. The SDK no longer supports setting the Secondary meta-attribute. 34 // 4. Previously, the Anonymous attribute of a user had three states: true, false, or undefined/null. 35 // Undefined/null and false were functionally the same in terms of the LaunchDarkly 36 // dashboard/indexing behavior, but they were represented differently in JSON and could behave 37 // differently if referenced in a flag rule (an undefined/null value would not match "anonymous is 38 // false"). Now, the prattributeoperty is a simple boolean defaulting to false, and the undefined state is 39 // the same as false. 40 // 41 // # Migrating from User/UserBuilder to the ldcontext API 42 // 43 // It is preferable to update existing code to use the ldcontext package directly, rather than the 44 // [User] type alias and the [UserBuilder] wrapper. Here are the kinds of changes you may need to make: 45 // 46 // - Code that previously created a simple User with only a key should now use [ldcontext.New]. 47 // 48 // // old 49 // user := lduser.NewUser("my-user-key") 50 // 51 // // new 52 // user := ldcontext.New("my-user-key") 53 // 54 // - Code that previously created a User with an empty string key ("") must be changed to use a 55 // non-empty key instead. If you do not care about the value of the key, use an arbitrary value. 56 // If you do not want the key to appear on your LaunchDarkly dashboard, set the Anonymous attribute. 57 // 58 // - Code that previously used UserBuilder should now use [ldcontext.NewBuilder]. 59 // 60 // - The [ldcontext.Builder] has fewer attribute-name-specific setter methods: [ldcontext.Builder.Name] is 61 // still a built-in attribute with its own setter, but for all other optional attributes such as Email 62 // that you are setting to a string value, you should instead call [ldcontext.Builder.SetString] and 63 // specify the attribute name as the first parameter. 64 // 65 // // old 66 // user := lduser.NewUserBuilder("my-user-key"). 67 // Name("my-name"). 68 // Email("my-email"). 69 // Build() 70 // 71 // // new 72 // user := ldcontext.NewBuilder("my-user-key"). 73 // Name("my-name"). 74 // SetString("email", "my-email"). 75 // Build() 76 // 77 // - The SetCustom method has been replaced by several Set methods for specific value types, 78 // and the [ldcontext.Builder.SetValue] method which takes an ldvalue.Value representing a value of any 79 // type (boolean, number, string, array, or object). 80 // 81 // // old 82 // user := lduser.NewUserBuilder("my-user-key"). 83 // Custom("my-string-attr", ldvalue.String("value")). 84 // Custom("my-array-attr", ldvalue.ArrayOf(ldvalue.String("a"), ldvalue.String("b"))). 85 // Build() 86 // 87 // // new 88 // user := ldcontext.NewBuilder("my-user-key"). 89 // SetString("my-string-attr", "value"). 90 // Set("my-array-attr", ldvalue.ArrayOf(ldvalue.String("a"), ldvalue.String("b"))). 91 // Build() 92 // 93 // - Private attributes are now designated by attribute name with [ldcontext.Builder.Private], 94 // instead of chaining a call to AsPrivateAttribute() after calling the setter. 95 // 96 // // old 97 // user := lduser.NewUserBuilder("my-user-key"). 98 // Name("my-name").AsPrivateAttribute(). 99 // Email("my-email").AsPrivateAttribute(). 100 // Build() 101 // 102 // // new 103 // user := ldcontext.NewBuilder("my-user-key"). 104 // Name("my-name"). 105 // SetString("email", "my-email"). 106 // Private("name", "email"). 107 // Build() 108 package lduser 109