UNPKG

@servicenow/sdk

Version:
178 lines (139 loc) 5.3 kB
--- sidebar_label: Keys File sidebar_position: 5 tags: [keys-file, keys, keys.ts, Now.ID, sys_id, record identity, coalesce, composite key, explicit key] --- # The keys.ts File Every Fluent project has an auto-generated `keys.ts` file that maps human-readable identifiers to ServiceNow sys_ids. It's the registry that makes `Now.ID['my-record']` work. ## Location ``` src/fluent/generated/keys.ts ``` This file is **auto-generated by the build system** — you should not normally need to edit it by hand. ## Purpose ServiceNow identifies every record by a 32-character sys_id (e.g., `4103297d12554b488d489c0bf1ceff19`). Working with raw sys_ids in source code is error-prone and unreadable. The keys file solves this by mapping meaningful names to sys_ids: ```typescript fluent $id: Now.ID['validate-on-insert'] // readable // resolves to sys_id: '4103297d12554b488d489c0bf1ceff19' ``` ## Structure ```typescript fluent import '@servicenow/sdk/global' declare global { namespace Now { namespace Internal { interface Keys extends KeysRegistry { explicit: { 'validate-on-insert': { table: 'sys_script' id: '4103297d12554b488d489c0bf1ceff19' } 'my-acl': { table: 'sys_security_acl' id: 'a3a4966e8c38446d8e1c25620e4e73f4' } } composite: [ { table: 'sys_documentation' id: '00e80b3ed0124620a32c6f9ac0472cf4' key: { name: 'x_myapp_table' element: 'name' language: 'en' } } ] deleted: {} } } } } ``` ## Key types ### Explicit keys Direct mappings from a developer-chosen name to a table and sys_id. These are created when you use `$id: Now.ID['some-name']` in your Fluent code. ```typescript fluent explicit: { 'my-business-rule': { table: 'sys_script' id: '4103297d12554b488d489c0bf1ceff19' } } ``` - **You choose the key name** — it can be any string (`'my-rule'`, `'validate-on-insert'`, `'1'`) - **The sys_id is auto-generated** on first build and stable thereafter - IDE autocomplete suggests existing keys when you type `Now.ID['` ### Composite keys For records identified by a combination of field values (coalesce keys) rather than a single developer-chosen name. These are auto-generated for child and descendant records like table columns, documentation entries, and choice values. ```typescript fluent composite: [ { table: 'sys_choice' id: 'ae25f03b01c14366942460e8cfeec032' key: { name: 'x_myapp_task' element: 'state' value: 'todo' } } ] ``` You don't interact with composite keys directly — they're managed by the build system. ### Deleted keys Tracks records that have been removed from the project. This prevents sys_id reuse and enables clean uninstall. ## How Now.ID works ### First build — key is new ```typescript fluent // In your .now.ts file: BusinessRule({ $id: Now.ID['my-new-rule'], // Key doesn't exist yet ... }) ``` The build system: 1. Sees `'my-new-rule'` is not in keys.ts 2. Generates a new sys_id 3. Adds the entry to keys.ts 4. Uses that sys_id in the XML output ### Subsequent builds — key exists ```typescript fluent // In your .now.ts file: BusinessRule({ $id: Now.ID['my-new-rule'], // Key exists in keys.ts ... }) ``` The build system: 1. Looks up `'my-new-rule'` in keys.ts 2. Finds the existing sys_id 3. Uses the **same** sys_id — ensuring the record is updated, not duplicated ## Where Now.ID resolves `Now.ID['key']` only resolves to a hashed sys_id when used in the `$id` property. It does **not** resolve inside `data` fields — the literal key string is written to the database instead, causing reference fields to appear blank. ```typescript fluent import { Record } from '@servicenow/sdk/core' export const vendorAcme = Record({ $id: Now.ID['vendor-acme'], // CORRECT: Now.ID resolves here table: 'x_snc_vendor_man_vendor', data: { name: 'Acme Corp', }, }) export const contractAcme = Record({ $id: Now.ID['contract-acme-1'], table: 'x_snc_vendor_man_vendor_contract', data: { vendor: vendorAcme, // CORRECT: pass the record variable directly // vendor: Now.ID['vendor-acme'], // WRONG: writes literal "vendor-acme" to DB }, }) ``` | Scenario | Pattern | |----------|---------| | Same-app record reference | `exportedRecord` (pass the variable directly) | | Platform record not in your app | sys_id string (e.g., `'77ad8176731313005754660c4cf6a7de'`) | ## Best practices - **Don't edit keys.ts manually** unless you need to fix a specific mapping - **Do commit keys.ts to version control** — it's the source of truth for record identity - **Use meaningful key names** — `'validate-priority-on-insert'` is better than `'1'` - **Don't worry about composite keys** — they're fully automatic