Download packages/cli/src/config/extensions/variables.ts from SaylorTwift/gemini-cli: direct link, hf CLI and curl.
- Browser
- Download file 2.68 kB
-
https://huggingface.co/SaylorTwift/gemini-cli/resolve/main/packages/cli/src/config/extensions/variables.ts
- Command line
-
hf download hf://SaylorTwift/gemini-cli/packages/cli/src/config/extensions/variables.ts
-
curl -L -o variables.ts https://huggingface.co/SaylorTwift/gemini-cli/resolve/main/packages/cli/src/config/extensions/variables.ts
2.68 kB
| /** | |
| * @license | |
| * Copyright 2025 Google LLC | |
| * SPDX-License-Identifier: Apache-2.0 | |
| */ | |
| import * as path from 'node:path'; | |
| import { type VariableSchema, VARIABLE_SCHEMA } from './variableSchema.js'; | |
| import { GEMINI_DIR } from '@google/gemini-cli-core'; | |
| /** | |
| * Represents a set of keys that will be considered invalid while unmarshalling | |
| * JSON in recursivelyHydrateStrings. | |
| */ | |
| const UNMARSHALL_KEY_IGNORE_LIST: Set<string> = new Set<string>([ | |
| '__proto__', | |
| 'constructor', | |
| 'prototype', | |
| ]); | |
| export const EXTENSIONS_DIRECTORY_NAME = path.join(GEMINI_DIR, 'extensions'); | |
| export const EXTENSIONS_CONFIG_FILENAME = 'gemini-extension.json'; | |
| export const INSTALL_METADATA_FILENAME = '.gemini-extension-install.json'; | |
| export const EXTENSION_SETTINGS_FILENAME = '.env'; | |
| export type JsonObject = { [key: string]: JsonValue }; | |
| export type JsonArray = JsonValue[]; | |
| export type JsonValue = | |
| | string | |
| | number | |
| | boolean | |
| | null | |
| | JsonObject | |
| | JsonArray; | |
| export type VariableContext = { | |
| [key: string]: string | undefined; | |
| }; | |
| export function validateVariables( | |
| variables: VariableContext, | |
| schema: VariableSchema, | |
| ) { | |
| for (const key in schema) { | |
| const definition = schema[key]; | |
| if (definition.required && !variables[key]) { | |
| throw new Error(`Missing required variable: ${key}`); | |
| } | |
| } | |
| } | |
| export function hydrateString(str: string, context: VariableContext): string { | |
| validateVariables(context, VARIABLE_SCHEMA); | |
| const regex = /\${(.*?)}/g; | |
| return str.replace(regex, (match, key) => { | |
| const val = context[key]; | |
| return val == null ? match : String(val); | |
| }); | |
| } | |
| export function recursivelyHydrateStrings<T>( | |
| obj: T, | |
| values: VariableContext, | |
| ): T { | |
| if (typeof obj === 'string') { | |
| // eslint-disable-next-line @typescript-eslint/no-unsafe-type-assertion | |
| return hydrateString(obj, values) as unknown as T; | |
| } | |
| if (Array.isArray(obj)) { | |
| // eslint-disable-next-line @typescript-eslint/no-unsafe-type-assertion | |
| return (obj as unknown[]).map((item) => | |
| recursivelyHydrateStrings(item, values), | |
| ) as unknown as T; | |
| } | |
| if (typeof obj === 'object' && obj !== null) { | |
| const newObj: Record<string, unknown> = {}; | |
| for (const key in obj) { | |
| if ( | |
| !UNMARSHALL_KEY_IGNORE_LIST.has(key) && | |
| Object.prototype.hasOwnProperty.call(obj, key) | |
| ) { | |
| newObj[key] = recursivelyHydrateStrings( | |
| // eslint-disable-next-line @typescript-eslint/no-unsafe-type-assertion | |
| (obj as Record<string, unknown>)[key], | |
| values, | |
| ); | |
| } | |
| } | |
| // eslint-disable-next-line @typescript-eslint/no-unsafe-type-assertion | |
| return newObj as T; | |
| } | |
| return obj; | |
| } | |