import { ts, Plugin, type Source, type Record, ElementAccessExpressionShape } from '@servicenow/sdk-build-core' export class NowIdShape extends ElementAccessExpressionShape { constructor({ source, id }: { source: Source; id: string | number }) { super({ source, callee: 'Now.ID', arg: id }) } override getValue(): string | number { return this.getArg().getValue() } static override from(record: Record): NowIdShape { const id = record.getId().getNowIdKey() ?? record.getId().getValue() return new NowIdShape({ source: record, id }) } override getCode(): string { return `Now.ID[${this.getArg().getCode()}]` } } export const NowIdPlugin = Plugin.create({ name: 'NowIdPlugin', noTelemetry: true, shapes: [ { shape: ElementAccessExpressionShape, fileTypes: ['fluent'], toSubclass(expression, { diagnostics }) { if (expression.getCallee() !== 'Now.ID') { return { success: false } } const arg = expression.getArg() if (!arg.isString() && !arg.isNumber()) { diagnostics.error(arg, 'Now.ID argument must be a string or number') return { success: false } } return { success: true, value: new NowIdShape({ source: expression, id: arg.getValue().toString() }), } }, }, ], nodes: [ { node: 'PropertyAccessExpression', fileTypes: ['fluent'], async toShape(node, { transform }) { if (node.getName() !== '$id') { return { success: false } } const identifier = node.getExpressionIfKind(ts.SyntaxKind.Identifier) if (!identifier) { return { success: false } } const result = await transform.toShape(identifier) if (!result.success || !result.value.isIdentifier()) { return { success: false } } const record = result.value.resolve() if (!record.isRecord()) { return { success: false } } return { success: true, value: record.getId(), } }, }, ], })