Repository navigation
Keep reading every old environment variable name, deprecated - #88
Merged
Merged
Conversation
The cloud request engine, the 51Did client and the creator context example must read _51DEGREES_CLOUD_ENDPOINT first and, when that is unset or empty, FOD_CLOUD_API_URL, reporting once that the old name is deprecated. These tests say so and fail until the old name is read again. The environment variable name check now allows the old name in the files that will read or document it, and fails while a listed file does not name it.
The rename of the cloud endpoint variable to _51DEGREES_CLOUD_ENDPOINT stopped reading FOD_CLOUD_API_URL, which the last release read. A patch release must not drop a name a caller may have set, so the old name is read again for this release, deprecated. The cloud request engine and the 51Did client read _51DEGREES_CLOUD_ENDPOINT first. When that is unset or empty they read FOD_CLOUD_API_URL and say once that it is deprecated. The engine logs a warn message to its Pipeline on the first process, because it has no Pipeline when it is built. The 51Did package has no logger, so the client raises one Node DeprecationWarning for the process. The creator context example no longer reads the variable itself. It builds its client with no endpoint and gives the page the base the client settled on, so it follows the same rule. Neither package held the variable name in a public constant, so there is no constant to restore.
The variable name check said every variable has one name with nothing behind it, which is no longer true of the cloud endpoint, so the comment now speaks of the resource key and the licence key alone. The title of its old name test said the name appears only where it is still read, when four of the six listed files word or document it without reading it. The header of the creator context server test described only the /redeem route. It now also says the endpoint tests start the example as its own process and ask for its page over the loopback address. No code or test behaviour changes.
Tests, test helpers and examples read their keys and data file paths from names such as RESOURCE_KEY, LICENSE_KEY, the TEST_ key names and names starting with the digit, until those names were aligned on the _51DEGREES_ prefix. Every such name is public, so each must still be read, deprecated, when the name that replaced it is unset or empty. The new tests set only the old name and check that the value is used and that the deprecation is printed once, naming the new name. They cover the key helpers of the pipeline, device detection and IP Intelligence tests, the example helpers, the constants that held an old name and each example that reads a variable itself. They fail until the old names are read again. The environment variable name check now allows a digit-initial name and a read of a bare key name in the files that will read them as fallbacks, and fails while a listed file does not carry one.
…d it Every environment variable name that a package, a test, an example or a CI script reads is a public name, and a patch release never removes or renames one. The alignment on the _51DEGREES_ prefix dropped these names, which the last release read: - RESOURCE_KEY, behind _51DEGREES_RESOURCE_KEY - LICENSE_KEY, behind _51DEGREES_LICENSE_KEY - 51DEGREES_RESOURCE_KEY, 51DEGREES_DD_PATH and 51DEGREES_IPI_PATH, behind the same names with a leading underscore - TEST_SUPER_RESOURCE_KEY, TEST_PLATFORM_RESOURCE_KEY, TEST_HARDWARE_RESOURCE_KEY, TEST_BROWSER_RESOURCE_KEY and TEST_NO_SETHEADER_RESOURCE_KEY, behind the _51DEGREES_RESOURCE_KEY_ names Each is read again, only when the name that replaced it is unset or empty, and the first read that finds a value there prints once that the old name is deprecated and which name replaces it. The test key helpers and the example helpers do this in one place each, and the examples and tests that read a variable themselves do it where they read. The constants that held an old name are back under their old names with their old values, marked deprecated: legacyEnvVars and licenseKeyEnvVar in the device detection test constants, ipiResourceKeyEnvVar and licenseKeyEnvVar in the IP Intelligence test constants, and LEGACY_RESOURCE_KEY_ENV_VAR and LEGACY_DATA_FILE_PATH_ENV_VAR in the example helpers. The messages that tell a reader which variable to set still name only the _51DEGREES_ names.
Five exported constants kept their names when the variable they name was renamed, and now hold the new name. Code that passes one of them to the environment would no longer read the variable it read before, so each must hold its old value again, with a new constant for the name in use. These tests say so for superResourceKeyEnvVar in the IP Intelligence test constants, RESOURCE_KEY_ENV_VAR in the IP Intelligence cloud example helper, DATA_FILE_PATH_ENV_VAR in the device detection on-premise example helper, and IPI_DATA_FILE_ENV_VAR and DD_DATA_FILE_ENV_VAR in the IP Intelligence on-premise example helper. They fail until the values are restored.
Five exported constants kept their names when the variable they name was renamed, and held the new name. Code that passes one of them to the environment would no longer read the variable it read before, so each holds its old value again, marked deprecated, and a new constant beside it holds the name in use: - superResourceKeyEnvVar in the IP Intelligence test constants is TEST_SUPER_RESOURCE_KEY again, with superResourceKeyVariable - RESOURCE_KEY_ENV_VAR in the IP Intelligence cloud example helper is 51DEGREES_RESOURCE_KEY again, with RESOURCE_KEY_VARIABLE - DATA_FILE_PATH_ENV_VAR in the device detection on-premise example helper is 51DEGREES_DD_PATH again, with DATA_FILE_PATH_VARIABLE - IPI_DATA_FILE_ENV_VAR and DD_DATA_FILE_ENV_VAR in the IP Intelligence on-premise example helper are 51DEGREES_IPI_PATH and 51DEGREES_DD_PATH again, with IPI_DATA_FILE_VARIABLE and DD_DATA_FILE_VARIABLE The examples and tests that used those constants to read a variable, or to tell a reader which variable to set, use the new constants, so what is read first and what is printed do not change.
jwrosewell
marked this pull request as ready for review
November 12, 2026 19:24
Draft
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
The problem
The last published release, 4.5.102, was built from
main384bff2d (the tagsfiftyone.pipeline.cloudrequestengine/4.5.102andfiftyone.pipeline.did/4.5.102both point at it). Its packages, tests and examples read environment variables under names thatrca32301da no longer reads. #77 renamed the cloud endpoint variable and #70 gave every other variable one_51DEGREES_name with nothing behind it. Neither has been published. A deployment, a test set-up or a person running an example who sets one of the old names would, after this patch release, find it ignored with no error and no message. For the endpoint that means calls go tohttps://cloud.51degrees.com/api/v4/and not to the private host that was set.The rules
James Rosewell said, at about 11:40 UTC on 12 November 2026
Asked at about 12:05 UTC whether that covers an environment variable name a package reads as well as names in code, he answered
Asked at about 16:55 UTC whether the rule covers environment variable names that tests and examples read, he answered
So every environment variable name that a package, a test, an example or a CI script in this repository reads is a public name. This draft began with the cloud endpoint alone and now covers every such name, in one draft.
The specification does not name any of these variables. A code search of the default branch of specifications at 6570727d finds neither
FOD_CLOUD_API_URLnor_51DEGREES_CLOUD_ENDPOINT, so the rules above are what this draft follows.What was checked
Every read of an environment variable (
process.env.NAME,process.env[...],$env:NAMEand${env:NAME}) in every.js,.ps1and.ymlfile atmain384bff2 and atrca32301d, and the constants that hold a variable name. The namesmainread thatrcdoes not are these.mainread the old nameFOD_CLOUD_API_URL_51DEGREES_CLOUD_ENDPOINTRESOURCE_KEY_51DEGREES_RESOURCE_KEYlegacyEnvVars, and the IP Intelligence example and tests below. As the only name in the four geolocation examples (for example gettingStarted.js line 115) and geoLocationCloud.test.js line 26LICENSE_KEY_51DEGREES_LICENSE_KEY51DEGREES_RESOURCE_KEY_51DEGREES_RESOURCE_KEYfiftyone.ipintelligencetest at line 35, thefiftyone.ipintelligence.cloudtest at line 3751DEGREES_DD_PATH_51DEGREES_DD_PATH51DEGREES_IPI_PATH_51DEGREES_IPI_PATHTEST_SUPER_RESOURCE_KEY,TEST_PLATFORM_RESOURCE_KEY,TEST_HARDWARE_RESOURCE_KEY,TEST_BROWSER_RESOURCE_KEY,TEST_NO_SETHEADER_RESOURCE_KEY_51DEGREES_RESOURCE_KEY_SUPERand the matching_PLATFORM,_HARDWARE,_BROWSERand_NO_SETHEADERnameslegacyEnvVars. The IP Intelligence example tests readTEST_SUPER_RESOURCE_KEYthroughsuperResourceKeyEnvVarTEST_IPI_RESOURCE_KEYandTEST_LICENSE_KEYwere held in constants onmainand read by nothing, so their constants come back and there is no read to restore. The CI scripts onmainset some old names and read none of them, so no CI script changes, and CI goes on setting only the_51DEGREES_names.No package held
FOD_CLOUD_API_URLin a public constant, member or setting. The constants that held one of the other names are listed under "Constants" below.What changed
Every old name above is read again, only when the name that replaced it is unset or empty, and the first read that finds a value there says once that the old name is deprecated and which name replaces it. When both are set the new name wins. Everything that tells a reader which variable to set still names only the
_51DEGREES_name.The cloud endpoint
Cloud Request Engine. The constructor reads
_51DEGREES_CLOUD_ENDPOINTfirst, thenFOD_CLOUD_API_URL(cloudRequestEngine.js lines 163 to 178). ThebaseURLoption still wins over both. An engine whose endpoint came from the old name logs onewarnmessage to its Pipeline (lines 54 to 70, called fromprocessat line 283). The message is in errorMessages.js lines 38 to 44 and reads51Did client.
environmentEndpointreads the two names in the same order (didClient.js lines 1012 to 1040). Theendpointoption still wins over both, and the environment is not read when it is given. The first client that takes its endpoint from the old name raises one NodeDeprecationWarningfor the process, with the same wording (lines 37 to 44).Creator context example. The server no longer reads the endpoint variable itself. It builds its client with no endpoint and gives the page the base the client settled on (server.js lines 250 to 267).
Documents. The engine's readme (lines 70 to 73) and the 51Did readme (lines 462 to 469 and line 848) say the old endpoint name is deprecated and still read. The comments on the
endpointoption and onDEFAULT_ENDPOINTsay the same, indidClient.jsand in the matching lines of types/didClient.d.ts, and types/errorMessages.d.ts gains the new message name. Both type files were edited by hand to match what the type generator copies from the comments.The keys and data file paths of tests and examples
The message each of these prints, once for each old name in a process, is "The
<old name>environment variable is deprecated and<new name>replaces it. Set<new name>instead."findKeyin the twoliveCloudKeys.jshelpers readsRESOURCE_KEYlast inRESOURCE_KEY_NAMES(liveCloudKeys.js lines 38 to 83, liveCloudKeys.js lines 38 to 92). The 51Did helper gainsLICENCE_KEY_NAMES, ending inLICENSE_KEY(lines 72 to 76), which didClient.integration.test.js line 37 now reads the licence key throughgetResourceKeyreads the namelegacyEnvVarsgives for each key (keyUtils.js lines 66 to 90). The two cloud tests that read the key themselves readRESOURCE_KEYbehind it (deviceDetectionCloud.test.js lines 34 to 42, deviceDetectionCloud.test.js lines 54 to 62)resourceKeyNamesputs the deprecated names of the names it is given last, being51DEGREES_RESOURCE_KEY,RESOURCE_KEYandTEST_SUPER_RESOURCE_KEY, andgetResourceKeysays when one is used (keyUtils.js lines 33 to 124)getResourceKeyFromEnvin device detection (RESOURCE_KEY) and IP Intelligence (51DEGREES_RESOURCE_KEY, thenRESOURCE_KEY)getDataFilePathFromEnvin device detection (51DEGREES_DD_PATH), andgetDataFilePathFromEnvandfindDeviceDataFilein IP Intelligence (51DEGREES_IPI_PATHand51DEGREES_DD_PATH).updatedatafile.jsnow reads the path through the helpergettingStarted.jsexamples (device detection, IP Intelligence), the four geolocation examples (for example gettingStarted.js lines 115 to 123), the six automatic update examples (for example updateOnStartUp.js lines 62 to 72) and the creator context example (server.js lines 214 to 230)The two tests that run the on-premise examples with no settings also remove the old names from the environment they give the examples.
Constants
Removed constants are back under their old names with their old values, each marked
@deprecatedand pointing at the name in use.legacyEnvVarsandenvVars.licenseKeyEnvVarin the device detection test constants (testConstants.js lines 36 to 53), whichfiftyone.devicedetection.sharedexports, with their types.envVars.ipiResourceKeyEnvVarandenvVars.licenseKeyEnvVarin the IP Intelligence test constants (testConstants.js lines 25 to 44), whichfiftyone.ipintelligence.sharedexports, with their types.LEGACY_RESOURCE_KEY_ENV_VARin both cloud example helpers andLEGACY_DATA_FILE_PATH_ENV_VARin the device detection on-premise example helper.Five constants kept their names and had their values changed to the new name. Each holds its old value again, marked
@deprecated, and a new constant beside it holds the name in use.main, restoredenvVars.superResourceKeyEnvVar, IP Intelligence test constantsTEST_SUPER_RESOURCE_KEYenvVars.superResourceKeyVariableRESOURCE_KEY_ENV_VAR, IP Intelligence cloud example helper51DEGREES_RESOURCE_KEYRESOURCE_KEY_VARIABLEDATA_FILE_PATH_ENV_VAR, device detection on-premise example helper51DEGREES_DD_PATHDATA_FILE_PATH_VARIABLEIPI_DATA_FILE_ENV_VAR, IP Intelligence on-premise example helper51DEGREES_IPI_PATHIPI_DATA_FILE_VARIABLEDD_DATA_FILE_ENV_VAR, IP Intelligence on-premise example helper51DEGREES_DD_PATHDD_DATA_FILE_VARIABLEThe examples and tests that used those five to read a variable, or to tell a reader which variable to set, use the new constants, so what is read first and what is printed do not change.
The variable name check
ci/tests/environmentVariableNames.test.js failed on a digit-initial name, a read of a bare
RESOURCE_KEYorLICENSE_KEY, or the old endpoint name, anywhere in the repository. It now allows each only in the files that read it as a deprecated fallback or document it (five files, 16 files and six files), still fails on it anywhere else, and fails when a listed file no longer carries it (lines 195 to 229), so no list can outlast the deprecated names.Decisions made in this draft, for review
consolecall in its package code), so the client usesprocess.emitWarningwith the typeDeprecationWarning, which is Node's own route for a deprecation. Node writes it to standard error once, passes it to anyprocess.on('warning')listener and leaves it out under--no-deprecation. A browser has no environment variables, so nothing is read or reported there.warnlistener drops the message, as it drops every other warning the engine logs (pipeline.js lines 222 to 229).console.warn. A test helper or an example has no logger, so each prints the message to standard error, once for each old name in a process.mainthe geolocation examples and test and the automatic update examples read only the old name, and the device detection on-premise helper read51DEGREES_DD_PATHbefore_51DEGREES_DD_PATH. Here the_51DEGREES_name is always read first, as the rule says the new name wins.exampleUtils.jsfile exports. The rule speaks of a public constant, and James's words make what tests and examples read public, so the four are restored as the exported test constants are. If a constant that only an example's helper file exports is not public, the four and their new_VARIABLEconstants can go back to howrchas them with no change in what is read.Tests
Each change was tested first, with the tests pushed alone and built before the fix.
baseURLis used, or for the defaultDeprecationWarningnaming both names. None is raised when the old name is not usedThere is no test that an old endpoint constant still holds
"FOD_CLOUD_API_URL", because Node never had such a constant.Red runs. Each is the full build on a tests-only commit, and in each the Ubuntu_ARM_Node_22 job failed and the other five build jobs were cancelled when it failed.
DidClient construction › endpoint reads the old variable name when the new one is not set(expectedhttps://old.example/api/v4/, receivedhttps://cloud.51degrees.com/api/v4/) andcustom end point - old variable name logged once(expected one warning, received none).deprecatedVariableNames.test.jsand the two list tests inenvironmentVariableNames.test.js, for examplecloud request engine tests (0) › reads RESOURCE_KEY when _51DEGREES_RESOURCE_KEY is not set, and says once that it is deprecated(expectedold-value, received an empty string).constants that held an old name › hold their old values in the cloud example helpers(expected51DEGREES_RESOURCE_KEY, received_51DEGREES_RESOURCE_KEY).Green run. Run 43279049770, the full build on the head 0dced2b, finished with success. All seven
Setting 'PullRequestSha'lines, one in Configure and one in each of the six build jobs, read 0dced2b. Configure printed "Left out 2 macOS entries". Each of the six build jobs (Ubuntu, Ubuntu ARM and Windows, on Node 22 and Node 24) reports 1342 unit tests passed and 2 skipped of 1344, and 132 integration tests passed and 4 skipped of 136. Lint reports 0 errors. The Complete job printed "Dry run - not merging". Two earlier heads also had green full builds, 66937e3 in run 43260670425 and 74e8fa3 in run 43273805487.macOS was left out of this draft's full build under the 9 November decision. The rc head is built with macOS before it merges into main.
What remains