@google/gemini-cli-core 0.1.10 → 0.1.11-nightly.250713.4442e893

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (101) hide show
  1. package/README.md +1 -1
  2. package/dist/google-gemini-cli-core-0.1.11.tgz +0 -0
  3. package/dist/src/code_assist/codeAssist.d.ts +2 -1
  4. package/dist/src/code_assist/codeAssist.js +2 -2
  5. package/dist/src/code_assist/codeAssist.js.map +1 -1
  6. package/dist/src/code_assist/oauth2.d.ts +2 -8
  7. package/dist/src/code_assist/oauth2.js +92 -73
  8. package/dist/src/code_assist/oauth2.js.map +1 -1
  9. package/dist/src/code_assist/oauth2.test.js +75 -33
  10. package/dist/src/code_assist/oauth2.test.js.map +1 -1
  11. package/dist/src/code_assist/server.d.ts +4 -0
  12. package/dist/src/code_assist/server.js +33 -0
  13. package/dist/src/code_assist/server.js.map +1 -1
  14. package/dist/src/config/config.d.ts +8 -0
  15. package/dist/src/config/config.js +17 -0
  16. package/dist/src/config/config.js.map +1 -1
  17. package/dist/src/config/config.test.js +23 -23
  18. package/dist/src/config/config.test.js.map +1 -1
  19. package/dist/src/core/client.d.ts +3 -1
  20. package/dist/src/core/client.js +13 -3
  21. package/dist/src/core/client.js.map +1 -1
  22. package/dist/src/core/client.test.js +90 -12
  23. package/dist/src/core/client.test.js.map +1 -1
  24. package/dist/src/core/contentGenerator.d.ts +4 -1
  25. package/dist/src/core/contentGenerator.js +2 -2
  26. package/dist/src/core/contentGenerator.js.map +1 -1
  27. package/dist/src/core/contentGenerator.test.js +3 -2
  28. package/dist/src/core/contentGenerator.test.js.map +1 -1
  29. package/dist/src/core/coreToolScheduler.js +24 -3
  30. package/dist/src/core/coreToolScheduler.js.map +1 -1
  31. package/dist/src/core/geminiChat.js +2 -2
  32. package/dist/src/core/geminiChat.js.map +1 -1
  33. package/dist/src/core/nonInteractiveToolExecutor.js +8 -2
  34. package/dist/src/core/nonInteractiveToolExecutor.js.map +1 -1
  35. package/dist/src/core/prompts.js +9 -8
  36. package/dist/src/core/prompts.js.map +1 -1
  37. package/dist/src/core/turn.d.ts +6 -2
  38. package/dist/src/core/turn.js +1 -0
  39. package/dist/src/core/turn.js.map +1 -1
  40. package/dist/src/telemetry/clearcut-logger/clearcut-logger.d.ts +3 -2
  41. package/dist/src/telemetry/clearcut-logger/clearcut-logger.js +50 -28
  42. package/dist/src/telemetry/clearcut-logger/clearcut-logger.js.map +1 -1
  43. package/dist/src/telemetry/clearcut-logger/event-metadata-key.d.ts +3 -1
  44. package/dist/src/telemetry/clearcut-logger/event-metadata-key.js +4 -0
  45. package/dist/src/telemetry/clearcut-logger/event-metadata-key.js.map +1 -1
  46. package/dist/src/telemetry/constants.d.ts +1 -0
  47. package/dist/src/telemetry/constants.js +1 -0
  48. package/dist/src/telemetry/constants.js.map +1 -1
  49. package/dist/src/telemetry/index.d.ts +2 -2
  50. package/dist/src/telemetry/index.js +2 -2
  51. package/dist/src/telemetry/index.js.map +1 -1
  52. package/dist/src/telemetry/loggers.d.ts +2 -1
  53. package/dist/src/telemetry/loggers.js +18 -1
  54. package/dist/src/telemetry/loggers.js.map +1 -1
  55. package/dist/src/telemetry/loggers.test.js +27 -7
  56. package/dist/src/telemetry/loggers.test.js.map +1 -1
  57. package/dist/src/telemetry/types.d.ts +13 -4
  58. package/dist/src/telemetry/types.js +19 -3
  59. package/dist/src/telemetry/types.js.map +1 -1
  60. package/dist/src/tools/grep.test.js +1 -1
  61. package/dist/src/tools/grep.test.js.map +1 -1
  62. package/dist/src/tools/mcp-client.js +8 -11
  63. package/dist/src/tools/mcp-client.js.map +1 -1
  64. package/dist/src/tools/mcp-client.test.js +46 -1
  65. package/dist/src/tools/mcp-client.test.js.map +1 -1
  66. package/dist/src/tools/read-file.js +1 -2
  67. package/dist/src/tools/read-file.js.map +1 -1
  68. package/dist/src/tools/read-many-files.js +1 -1
  69. package/dist/src/tools/read-many-files.js.map +1 -1
  70. package/dist/src/tools/read-many-files.test.js +21 -10
  71. package/dist/src/tools/read-many-files.test.js.map +1 -1
  72. package/dist/src/tools/shell.js +3 -1
  73. package/dist/src/tools/shell.js.map +1 -1
  74. package/dist/src/tools/tool-registry.js +3 -1
  75. package/dist/src/tools/tool-registry.js.map +1 -1
  76. package/dist/src/tools/tools.d.ts +19 -1
  77. package/dist/src/tools/tools.js +8 -1
  78. package/dist/src/tools/tools.js.map +1 -1
  79. package/dist/src/utils/paths.d.ts +1 -0
  80. package/dist/src/utils/paths.js +1 -0
  81. package/dist/src/utils/paths.js.map +1 -1
  82. package/dist/src/utils/summarizer.d.ts +25 -0
  83. package/dist/src/utils/summarizer.js +79 -0
  84. package/dist/src/utils/summarizer.js.map +1 -0
  85. package/dist/src/utils/summarizer.test.d.ts +6 -0
  86. package/dist/src/utils/summarizer.test.js +131 -0
  87. package/dist/src/utils/summarizer.test.js.map +1 -0
  88. package/dist/src/utils/user_account.d.ts +9 -0
  89. package/dist/src/utils/user_account.js +99 -0
  90. package/dist/src/utils/user_account.js.map +1 -0
  91. package/dist/src/utils/user_account.test.d.ts +6 -0
  92. package/dist/src/utils/user_account.test.js +153 -0
  93. package/dist/src/utils/user_account.test.js.map +1 -0
  94. package/dist/src/utils/user_id.d.ts +0 -6
  95. package/dist/src/utils/user_id.js +0 -21
  96. package/dist/src/utils/user_id.js.map +1 -1
  97. package/dist/src/utils/user_id.test.js +1 -22
  98. package/dist/src/utils/user_id.test.js.map +1 -1
  99. package/dist/tsconfig.tsbuildinfo +1 -1
  100. package/package.json +2 -2
  101. package/dist/google-gemini-cli-core-0.1.9.tgz +0 -0
@@ -0,0 +1,79 @@
1
+ /**
2
+ * @license
3
+ * Copyright 2025 Google LLC
4
+ * SPDX-License-Identifier: Apache-2.0
5
+ */
6
+ import { DEFAULT_GEMINI_FLASH_MODEL } from '../config/models.js';
7
+ /**
8
+ * The default summarizer for tool results.
9
+ *
10
+ * @param result The result of the tool execution.
11
+ * @param geminiClient The Gemini client to use for summarization.
12
+ * @param abortSignal The abort signal to use for summarization.
13
+ * @returns The summary of the result.
14
+ */
15
+ export const defaultSummarizer = (result, _geminiClient, _abortSignal) => Promise.resolve(JSON.stringify(result.llmContent));
16
+ // TODO: Move both these functions to utils
17
+ function partToString(part) {
18
+ if (!part) {
19
+ return '';
20
+ }
21
+ if (typeof part === 'string') {
22
+ return part;
23
+ }
24
+ if (Array.isArray(part)) {
25
+ return part.map(partToString).join('');
26
+ }
27
+ if ('text' in part) {
28
+ return part.text ?? '';
29
+ }
30
+ return '';
31
+ }
32
+ function getResponseText(response) {
33
+ if (response.candidates && response.candidates.length > 0) {
34
+ const candidate = response.candidates[0];
35
+ if (candidate.content &&
36
+ candidate.content.parts &&
37
+ candidate.content.parts.length > 0) {
38
+ return candidate.content.parts
39
+ .filter((part) => part.text)
40
+ .map((part) => part.text)
41
+ .join('');
42
+ }
43
+ }
44
+ return null;
45
+ }
46
+ const toolOutputSummarizerModel = DEFAULT_GEMINI_FLASH_MODEL;
47
+ const toolOutputSummarizerConfig = {
48
+ maxOutputTokens: 2000,
49
+ };
50
+ const SUMMARIZE_TOOL_OUTPUT_PROMPT = `Summarize the following tool output to be a maximum of {maxLength} characters. The summary should be concise and capture the main points of the tool output.
51
+
52
+ The summarization should be done based on the content that is provided. Here are the basic rules to follow:
53
+ 1. If the text is a directory listing or any output that is structural, use the history of the conversation to understand the context. Using this context try to understand what information we need from the tool output and return that as a response.
54
+ 2. If the text is text content and there is nothing structural that we need, summarize the text.
55
+ 3. If the text is the output of a shell command, use the history of the conversation to understand the context. Using this context try to understand what information we need from the tool output and return a summarization along with the stack trace of any error within the <error></error> tags. The stack trace should be complete and not truncated. If there are warnings, you should include them in the summary within <warning></warning> tags.
56
+
57
+
58
+ Text to summarize:
59
+ "{textToSummarize}"
60
+
61
+ Return the summary string which should first contain an overall summarization of text followed by the full stack trace of errors and warnings in the tool output.
62
+ `;
63
+ export const llmSummarizer = (result, geminiClient, abortSignal) => summarizeToolOutput(partToString(result.llmContent), geminiClient, abortSignal);
64
+ export async function summarizeToolOutput(textToSummarize, geminiClient, abortSignal, maxLength = 2000) {
65
+ if (!textToSummarize || textToSummarize.length < maxLength) {
66
+ return textToSummarize;
67
+ }
68
+ const prompt = SUMMARIZE_TOOL_OUTPUT_PROMPT.replace('{maxLength}', String(maxLength)).replace('{textToSummarize}', textToSummarize);
69
+ const contents = [{ role: 'user', parts: [{ text: prompt }] }];
70
+ try {
71
+ const parsedResponse = (await geminiClient.generateContent(contents, toolOutputSummarizerConfig, abortSignal, toolOutputSummarizerModel));
72
+ return getResponseText(parsedResponse) || textToSummarize;
73
+ }
74
+ catch (error) {
75
+ console.error('Failed to summarize tool output.', error);
76
+ return textToSummarize;
77
+ }
78
+ }
79
+ //# sourceMappingURL=summarizer.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"summarizer.js","sourceRoot":"","sources":["../../../src/utils/summarizer.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AASH,OAAO,EAAE,0BAA0B,EAAE,MAAM,qBAAqB,CAAC;AAejE;;;;;;;GAOG;AACH,MAAM,CAAC,MAAM,iBAAiB,GAAe,CAC3C,MAAkB,EAClB,aAA2B,EAC3B,YAAyB,EACzB,EAAE,CAAC,OAAO,CAAC,OAAO,CAAC,IAAI,CAAC,SAAS,CAAC,MAAM,CAAC,UAAU,CAAC,CAAC,CAAC;AAExD,2CAA2C;AAC3C,SAAS,YAAY,CAAC,IAAmB;IACvC,IAAI,CAAC,IAAI,EAAE,CAAC;QACV,OAAO,EAAE,CAAC;IACZ,CAAC;IACD,IAAI,OAAO,IAAI,KAAK,QAAQ,EAAE,CAAC;QAC7B,OAAO,IAAI,CAAC;IACd,CAAC;IACD,IAAI,KAAK,CAAC,OAAO,CAAC,IAAI,CAAC,EAAE,CAAC;QACxB,OAAO,IAAI,CAAC,GAAG,CAAC,YAAY,CAAC,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;IACzC,CAAC;IACD,IAAI,MAAM,IAAI,IAAI,EAAE,CAAC;QACnB,OAAO,IAAI,CAAC,IAAI,IAAI,EAAE,CAAC;IACzB,CAAC;IACD,OAAO,EAAE,CAAC;AACZ,CAAC;AAED,SAAS,eAAe,CAAC,QAAiC;IACxD,IAAI,QAAQ,CAAC,UAAU,IAAI,QAAQ,CAAC,UAAU,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;QAC1D,MAAM,SAAS,GAAG,QAAQ,CAAC,UAAU,CAAC,CAAC,CAAC,CAAC;QACzC,IACE,SAAS,CAAC,OAAO;YACjB,SAAS,CAAC,OAAO,CAAC,KAAK;YACvB,SAAS,CAAC,OAAO,CAAC,KAAK,CAAC,MAAM,GAAG,CAAC,EAClC,CAAC;YACD,OAAO,SAAS,CAAC,OAAO,CAAC,KAAK;iBAC3B,MAAM,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,IAAI,CAAC,IAAI,CAAC;iBAC3B,GAAG,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,IAAI,CAAC,IAAI,CAAC;iBACxB,IAAI,CAAC,EAAE,CAAC,CAAC;QACd,CAAC;IACH,CAAC;IACD,OAAO,IAAI,CAAC;AACd,CAAC;AAED,MAAM,yBAAyB,GAAG,0BAA0B,CAAC;AAC7D,MAAM,0BAA0B,GAA0B;IACxD,eAAe,EAAE,IAAI;CACtB,CAAC;AAEF,MAAM,4BAA4B,GAAG;;;;;;;;;;;;CAYpC,CAAC;AAEF,MAAM,CAAC,MAAM,aAAa,GAAe,CAAC,MAAM,EAAE,YAAY,EAAE,WAAW,EAAE,EAAE,CAC7E,mBAAmB,CACjB,YAAY,CAAC,MAAM,CAAC,UAAU,CAAC,EAC/B,YAAY,EACZ,WAAW,CACZ,CAAC;AAEJ,MAAM,CAAC,KAAK,UAAU,mBAAmB,CACvC,eAAuB,EACvB,YAA0B,EAC1B,WAAwB,EACxB,YAAoB,IAAI;IAExB,IAAI,CAAC,eAAe,IAAI,eAAe,CAAC,MAAM,GAAG,SAAS,EAAE,CAAC;QAC3D,OAAO,eAAe,CAAC;IACzB,CAAC;IACD,MAAM,MAAM,GAAG,4BAA4B,CAAC,OAAO,CACjD,aAAa,EACb,MAAM,CAAC,SAAS,CAAC,CAClB,CAAC,OAAO,CAAC,mBAAmB,EAAE,eAAe,CAAC,CAAC;IAEhD,MAAM,QAAQ,GAAc,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,KAAK,EAAE,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,CAAC,EAAE,CAAC,CAAC;IAE1E,IAAI,CAAC;QACH,MAAM,cAAc,GAAG,CAAC,MAAM,YAAY,CAAC,eAAe,CACxD,QAAQ,EACR,0BAA0B,EAC1B,WAAW,EACX,yBAAyB,CAC1B,CAAuC,CAAC;QACzC,OAAO,eAAe,CAAC,cAAc,CAAC,IAAI,eAAe,CAAC;IAC5D,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACf,OAAO,CAAC,KAAK,CAAC,kCAAkC,EAAE,KAAK,CAAC,CAAC;QACzD,OAAO,eAAe,CAAC;IACzB,CAAC;AACH,CAAC"}
@@ -0,0 +1,6 @@
1
+ /**
2
+ * @license
3
+ * Copyright 2025 Google LLC
4
+ * SPDX-License-Identifier: Apache-2.0
5
+ */
6
+ export {};
@@ -0,0 +1,131 @@
1
+ /**
2
+ * @license
3
+ * Copyright 2025 Google LLC
4
+ * SPDX-License-Identifier: Apache-2.0
5
+ */
6
+ import { describe, it, expect, vi, beforeEach, afterEach } from 'vitest';
7
+ import { GeminiClient } from '../core/client.js';
8
+ import { Config } from '../config/config.js';
9
+ import { summarizeToolOutput, llmSummarizer, defaultSummarizer, } from './summarizer.js';
10
+ // Mock GeminiClient and Config constructor
11
+ vi.mock('../core/client.js');
12
+ vi.mock('../config/config.js');
13
+ describe('summarizers', () => {
14
+ let mockGeminiClient;
15
+ let MockConfig;
16
+ const abortSignal = new AbortController().signal;
17
+ beforeEach(() => {
18
+ MockConfig = vi.mocked(Config);
19
+ const mockConfigInstance = new MockConfig('test-api-key', 'gemini-pro', false, '.', false, undefined, false, undefined, undefined, undefined);
20
+ mockGeminiClient = new GeminiClient(mockConfigInstance);
21
+ mockGeminiClient.generateContent = vi.fn();
22
+ vi.spyOn(console, 'error').mockImplementation(() => { });
23
+ });
24
+ afterEach(() => {
25
+ vi.clearAllMocks();
26
+ console.error.mockRestore();
27
+ });
28
+ describe('summarizeToolOutput', () => {
29
+ it('should return original text if it is shorter than maxLength', async () => {
30
+ const shortText = 'This is a short text.';
31
+ const result = await summarizeToolOutput(shortText, mockGeminiClient, abortSignal, 2000);
32
+ expect(result).toBe(shortText);
33
+ expect(mockGeminiClient.generateContent).not.toHaveBeenCalled();
34
+ });
35
+ it('should return original text if it is empty', async () => {
36
+ const emptyText = '';
37
+ const result = await summarizeToolOutput(emptyText, mockGeminiClient, abortSignal, 2000);
38
+ expect(result).toBe(emptyText);
39
+ expect(mockGeminiClient.generateContent).not.toHaveBeenCalled();
40
+ });
41
+ it('should call generateContent if text is longer than maxLength', async () => {
42
+ const longText = 'This is a very long text.'.repeat(200);
43
+ const summary = 'This is a summary.';
44
+ mockGeminiClient.generateContent.mockResolvedValue({
45
+ candidates: [{ content: { parts: [{ text: summary }] } }],
46
+ });
47
+ const result = await summarizeToolOutput(longText, mockGeminiClient, abortSignal, 2000);
48
+ expect(mockGeminiClient.generateContent).toHaveBeenCalledTimes(1);
49
+ expect(result).toBe(summary);
50
+ });
51
+ it('should return original text if generateContent throws an error', async () => {
52
+ const longText = 'This is a very long text.'.repeat(200);
53
+ const error = new Error('API Error');
54
+ mockGeminiClient.generateContent.mockRejectedValue(error);
55
+ const result = await summarizeToolOutput(longText, mockGeminiClient, abortSignal, 2000);
56
+ expect(mockGeminiClient.generateContent).toHaveBeenCalledTimes(1);
57
+ expect(result).toBe(longText);
58
+ expect(console.error).toHaveBeenCalledWith('Failed to summarize tool output.', error);
59
+ });
60
+ it('should construct the correct prompt for summarization', async () => {
61
+ const longText = 'This is a very long text.'.repeat(200);
62
+ const summary = 'This is a summary.';
63
+ mockGeminiClient.generateContent.mockResolvedValue({
64
+ candidates: [{ content: { parts: [{ text: summary }] } }],
65
+ });
66
+ await summarizeToolOutput(longText, mockGeminiClient, abortSignal, 1000);
67
+ const expectedPrompt = `Summarize the following tool output to be a maximum of 1000 characters. The summary should be concise and capture the main points of the tool output.
68
+
69
+ The summarization should be done based on the content that is provided. Here are the basic rules to follow:
70
+ 1. If the text is a directory listing or any output that is structural, use the history of the conversation to understand the context. Using this context try to understand what information we need from the tool output and return that as a response.
71
+ 2. If the text is text content and there is nothing structural that we need, summarize the text.
72
+ 3. If the text is the output of a shell command, use the history of the conversation to understand the context. Using this context try to understand what information we need from the tool output and return a summarization along with the stack trace of any error within the <error></error> tags. The stack trace should be complete and not truncated. If there are warnings, you should include them in the summary within <warning></warning> tags.
73
+
74
+
75
+ Text to summarize:
76
+ "${longText}"
77
+
78
+ Return the summary string which should first contain an overall summarization of text followed by the full stack trace of errors and warnings in the tool output.
79
+ `;
80
+ const calledWith = mockGeminiClient.generateContent.mock
81
+ .calls[0];
82
+ const contents = calledWith[0];
83
+ expect(contents[0].parts[0].text).toBe(expectedPrompt);
84
+ });
85
+ });
86
+ describe('llmSummarizer', () => {
87
+ it('should summarize tool output using summarizeToolOutput', async () => {
88
+ const toolResult = {
89
+ llmContent: 'This is a very long text.'.repeat(200),
90
+ returnDisplay: '',
91
+ };
92
+ const summary = 'This is a summary.';
93
+ mockGeminiClient.generateContent.mockResolvedValue({
94
+ candidates: [{ content: { parts: [{ text: summary }] } }],
95
+ });
96
+ const result = await llmSummarizer(toolResult, mockGeminiClient, abortSignal);
97
+ expect(mockGeminiClient.generateContent).toHaveBeenCalledTimes(1);
98
+ expect(result).toBe(summary);
99
+ });
100
+ it('should handle different llmContent types', async () => {
101
+ const longText = 'This is a very long text.'.repeat(200);
102
+ const toolResult = {
103
+ llmContent: [{ text: longText }],
104
+ returnDisplay: '',
105
+ };
106
+ const summary = 'This is a summary.';
107
+ mockGeminiClient.generateContent.mockResolvedValue({
108
+ candidates: [{ content: { parts: [{ text: summary }] } }],
109
+ });
110
+ const result = await llmSummarizer(toolResult, mockGeminiClient, abortSignal);
111
+ expect(mockGeminiClient.generateContent).toHaveBeenCalledTimes(1);
112
+ const calledWith = mockGeminiClient.generateContent.mock
113
+ .calls[0];
114
+ const contents = calledWith[0];
115
+ expect(contents[0].parts[0].text).toContain(`"${longText}"`);
116
+ expect(result).toBe(summary);
117
+ });
118
+ });
119
+ describe('defaultSummarizer', () => {
120
+ it('should stringify the llmContent', async () => {
121
+ const toolResult = {
122
+ llmContent: { text: 'some data' },
123
+ returnDisplay: '',
124
+ };
125
+ const result = await defaultSummarizer(toolResult, mockGeminiClient, abortSignal);
126
+ expect(result).toBe(JSON.stringify({ text: 'some data' }));
127
+ expect(mockGeminiClient.generateContent).not.toHaveBeenCalled();
128
+ });
129
+ });
130
+ });
131
+ //# sourceMappingURL=summarizer.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"summarizer.test.js","sourceRoot":"","sources":["../../../src/utils/summarizer.test.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,9 @@
1
+ /**
2
+ * @license
3
+ * Copyright 2025 Google LLC
4
+ * SPDX-License-Identifier: Apache-2.0
5
+ */
6
+ export declare function cacheGoogleAccount(email: string): Promise<void>;
7
+ export declare function getCachedGoogleAccount(): string | null;
8
+ export declare function getLifetimeGoogleAccounts(): number;
9
+ export declare function clearCachedGoogleAccount(): Promise<void>;
@@ -0,0 +1,99 @@
1
+ /**
2
+ * @license
3
+ * Copyright 2025 Google LLC
4
+ * SPDX-License-Identifier: Apache-2.0
5
+ */
6
+ import path from 'node:path';
7
+ import { promises as fsp, existsSync, readFileSync } from 'node:fs';
8
+ import * as os from 'os';
9
+ import { GEMINI_DIR, GOOGLE_ACCOUNTS_FILENAME } from './paths.js';
10
+ function getGoogleAccountsCachePath() {
11
+ return path.join(os.homedir(), GEMINI_DIR, GOOGLE_ACCOUNTS_FILENAME);
12
+ }
13
+ async function readAccounts(filePath) {
14
+ try {
15
+ const content = await fsp.readFile(filePath, 'utf-8');
16
+ if (!content.trim()) {
17
+ return { active: null, old: [] };
18
+ }
19
+ return JSON.parse(content);
20
+ }
21
+ catch (error) {
22
+ if (error instanceof Error && 'code' in error && error.code === 'ENOENT') {
23
+ // File doesn't exist, which is fine.
24
+ return { active: null, old: [] };
25
+ }
26
+ // File is corrupted or not valid JSON, start with a fresh object.
27
+ console.debug('Could not parse accounts file, starting fresh.', error);
28
+ return { active: null, old: [] };
29
+ }
30
+ }
31
+ export async function cacheGoogleAccount(email) {
32
+ const filePath = getGoogleAccountsCachePath();
33
+ await fsp.mkdir(path.dirname(filePath), { recursive: true });
34
+ const accounts = await readAccounts(filePath);
35
+ if (accounts.active && accounts.active !== email) {
36
+ if (!accounts.old.includes(accounts.active)) {
37
+ accounts.old.push(accounts.active);
38
+ }
39
+ }
40
+ // If the new email was in the old list, remove it
41
+ accounts.old = accounts.old.filter((oldEmail) => oldEmail !== email);
42
+ accounts.active = email;
43
+ await fsp.writeFile(filePath, JSON.stringify(accounts, null, 2), 'utf-8');
44
+ }
45
+ export function getCachedGoogleAccount() {
46
+ try {
47
+ const filePath = getGoogleAccountsCachePath();
48
+ if (existsSync(filePath)) {
49
+ const content = readFileSync(filePath, 'utf-8').trim();
50
+ if (!content) {
51
+ return null;
52
+ }
53
+ const accounts = JSON.parse(content);
54
+ return accounts.active;
55
+ }
56
+ return null;
57
+ }
58
+ catch (error) {
59
+ console.debug('Error reading cached Google Account:', error);
60
+ return null;
61
+ }
62
+ }
63
+ export function getLifetimeGoogleAccounts() {
64
+ try {
65
+ const filePath = getGoogleAccountsCachePath();
66
+ if (!existsSync(filePath)) {
67
+ return 0;
68
+ }
69
+ const content = readFileSync(filePath, 'utf-8').trim();
70
+ if (!content) {
71
+ return 0;
72
+ }
73
+ const accounts = JSON.parse(content);
74
+ let count = accounts.old.length;
75
+ if (accounts.active) {
76
+ count++;
77
+ }
78
+ return count;
79
+ }
80
+ catch (error) {
81
+ console.debug('Error reading lifetime Google Accounts:', error);
82
+ return 0;
83
+ }
84
+ }
85
+ export async function clearCachedGoogleAccount() {
86
+ const filePath = getGoogleAccountsCachePath();
87
+ if (!existsSync(filePath)) {
88
+ return;
89
+ }
90
+ const accounts = await readAccounts(filePath);
91
+ if (accounts.active) {
92
+ if (!accounts.old.includes(accounts.active)) {
93
+ accounts.old.push(accounts.active);
94
+ }
95
+ accounts.active = null;
96
+ }
97
+ await fsp.writeFile(filePath, JSON.stringify(accounts, null, 2), 'utf-8');
98
+ }
99
+ //# sourceMappingURL=user_account.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"user_account.js","sourceRoot":"","sources":["../../../src/utils/user_account.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,6 @@
1
+ /**
2
+ * @license
3
+ * Copyright 2025 Google LLC
4
+ * SPDX-License-Identifier: Apache-2.0
5
+ */
6
+ export {};
@@ -0,0 +1,153 @@
1
+ /**
2
+ * @license
3
+ * Copyright 2025 Google LLC
4
+ * SPDX-License-Identifier: Apache-2.0
5
+ */
6
+ import { vi, describe, it, expect, beforeEach, afterEach } from 'vitest';
7
+ import { cacheGoogleAccount, getCachedGoogleAccount, clearCachedGoogleAccount, getLifetimeGoogleAccounts, } from './user_account.js';
8
+ import * as fs from 'node:fs';
9
+ import * as os from 'node:os';
10
+ import path from 'node:path';
11
+ vi.mock('os', async (importOriginal) => {
12
+ const os = await importOriginal();
13
+ return {
14
+ ...os,
15
+ homedir: vi.fn(),
16
+ };
17
+ });
18
+ describe('user_account', () => {
19
+ let tempHomeDir;
20
+ const accountsFile = () => path.join(tempHomeDir, '.gemini', 'google_accounts.json');
21
+ beforeEach(() => {
22
+ tempHomeDir = fs.mkdtempSync(path.join(os.tmpdir(), 'gemini-cli-test-home-'));
23
+ os.homedir.mockReturnValue(tempHomeDir);
24
+ });
25
+ afterEach(() => {
26
+ fs.rmSync(tempHomeDir, { recursive: true, force: true });
27
+ vi.clearAllMocks();
28
+ });
29
+ describe('cacheGoogleAccount', () => {
30
+ it('should create directory and write initial account file', async () => {
31
+ await cacheGoogleAccount('test1@google.com');
32
+ // Verify Google Account ID was cached
33
+ expect(fs.existsSync(accountsFile())).toBe(true);
34
+ expect(fs.readFileSync(accountsFile(), 'utf-8')).toBe(JSON.stringify({ active: 'test1@google.com', old: [] }, null, 2));
35
+ });
36
+ it('should update active account and move previous to old', async () => {
37
+ fs.mkdirSync(path.dirname(accountsFile()), { recursive: true });
38
+ fs.writeFileSync(accountsFile(), JSON.stringify({ active: 'test2@google.com', old: ['test1@google.com'] }, null, 2));
39
+ await cacheGoogleAccount('test3@google.com');
40
+ expect(fs.readFileSync(accountsFile(), 'utf-8')).toBe(JSON.stringify({
41
+ active: 'test3@google.com',
42
+ old: ['test1@google.com', 'test2@google.com'],
43
+ }, null, 2));
44
+ });
45
+ it('should not add a duplicate to the old list', async () => {
46
+ fs.mkdirSync(path.dirname(accountsFile()), { recursive: true });
47
+ fs.writeFileSync(accountsFile(), JSON.stringify({ active: 'test1@google.com', old: ['test2@google.com'] }, null, 2));
48
+ await cacheGoogleAccount('test2@google.com');
49
+ await cacheGoogleAccount('test1@google.com');
50
+ expect(fs.readFileSync(accountsFile(), 'utf-8')).toBe(JSON.stringify({ active: 'test1@google.com', old: ['test2@google.com'] }, null, 2));
51
+ });
52
+ it('should handle corrupted JSON by starting fresh', async () => {
53
+ fs.mkdirSync(path.dirname(accountsFile()), { recursive: true });
54
+ fs.writeFileSync(accountsFile(), 'not valid json');
55
+ const consoleDebugSpy = vi
56
+ .spyOn(console, 'debug')
57
+ .mockImplementation(() => { });
58
+ await cacheGoogleAccount('test1@google.com');
59
+ expect(consoleDebugSpy).toHaveBeenCalled();
60
+ expect(JSON.parse(fs.readFileSync(accountsFile(), 'utf-8'))).toEqual({
61
+ active: 'test1@google.com',
62
+ old: [],
63
+ });
64
+ });
65
+ });
66
+ describe('getCachedGoogleAccount', () => {
67
+ it('should return the active account if file exists and is valid', () => {
68
+ fs.mkdirSync(path.dirname(accountsFile()), { recursive: true });
69
+ fs.writeFileSync(accountsFile(), JSON.stringify({ active: 'active@google.com', old: [] }, null, 2));
70
+ const account = getCachedGoogleAccount();
71
+ expect(account).toBe('active@google.com');
72
+ });
73
+ it('should return null if file does not exist', () => {
74
+ const account = getCachedGoogleAccount();
75
+ expect(account).toBeNull();
76
+ });
77
+ it('should return null if file is empty', () => {
78
+ fs.mkdirSync(path.dirname(accountsFile()), { recursive: true });
79
+ fs.writeFileSync(accountsFile(), '');
80
+ const account = getCachedGoogleAccount();
81
+ expect(account).toBeNull();
82
+ });
83
+ it('should return null and log if file is corrupted', () => {
84
+ fs.mkdirSync(path.dirname(accountsFile()), { recursive: true });
85
+ fs.writeFileSync(accountsFile(), '{ "active": "test@google.com"'); // Invalid JSON
86
+ const consoleDebugSpy = vi
87
+ .spyOn(console, 'debug')
88
+ .mockImplementation(() => { });
89
+ const account = getCachedGoogleAccount();
90
+ expect(account).toBeNull();
91
+ expect(consoleDebugSpy).toHaveBeenCalled();
92
+ });
93
+ });
94
+ describe('clearCachedGoogleAccount', () => {
95
+ it('should set active to null and move it to old', async () => {
96
+ fs.mkdirSync(path.dirname(accountsFile()), { recursive: true });
97
+ fs.writeFileSync(accountsFile(), JSON.stringify({ active: 'active@google.com', old: ['old1@google.com'] }, null, 2));
98
+ await clearCachedGoogleAccount();
99
+ const stored = JSON.parse(fs.readFileSync(accountsFile(), 'utf-8'));
100
+ expect(stored.active).toBeNull();
101
+ expect(stored.old).toEqual(['old1@google.com', 'active@google.com']);
102
+ });
103
+ it('should handle empty file gracefully', async () => {
104
+ fs.mkdirSync(path.dirname(accountsFile()), { recursive: true });
105
+ fs.writeFileSync(accountsFile(), '');
106
+ await clearCachedGoogleAccount();
107
+ const stored = JSON.parse(fs.readFileSync(accountsFile(), 'utf-8'));
108
+ expect(stored.active).toBeNull();
109
+ expect(stored.old).toEqual([]);
110
+ });
111
+ });
112
+ describe('getLifetimeGoogleAccounts', () => {
113
+ it('should return 0 if the file does not exist', () => {
114
+ expect(getLifetimeGoogleAccounts()).toBe(0);
115
+ });
116
+ it('should return 0 if the file is empty', () => {
117
+ fs.mkdirSync(path.dirname(accountsFile()), { recursive: true });
118
+ fs.writeFileSync(accountsFile(), '');
119
+ expect(getLifetimeGoogleAccounts()).toBe(0);
120
+ });
121
+ it('should return 0 if the file is corrupted', () => {
122
+ fs.mkdirSync(path.dirname(accountsFile()), { recursive: true });
123
+ fs.writeFileSync(accountsFile(), 'invalid json');
124
+ const consoleDebugSpy = vi
125
+ .spyOn(console, 'debug')
126
+ .mockImplementation(() => { });
127
+ expect(getLifetimeGoogleAccounts()).toBe(0);
128
+ expect(consoleDebugSpy).toHaveBeenCalled();
129
+ });
130
+ it('should return 1 if there is only an active account', () => {
131
+ fs.mkdirSync(path.dirname(accountsFile()), { recursive: true });
132
+ fs.writeFileSync(accountsFile(), JSON.stringify({ active: 'test1@google.com', old: [] }));
133
+ expect(getLifetimeGoogleAccounts()).toBe(1);
134
+ });
135
+ it('should correctly count old accounts when active is null', () => {
136
+ fs.mkdirSync(path.dirname(accountsFile()), { recursive: true });
137
+ fs.writeFileSync(accountsFile(), JSON.stringify({
138
+ active: null,
139
+ old: ['test1@google.com', 'test2@google.com'],
140
+ }));
141
+ expect(getLifetimeGoogleAccounts()).toBe(2);
142
+ });
143
+ it('should correctly count both active and old accounts', () => {
144
+ fs.mkdirSync(path.dirname(accountsFile()), { recursive: true });
145
+ fs.writeFileSync(accountsFile(), JSON.stringify({
146
+ active: 'test3@google.com',
147
+ old: ['test1@google.com', 'test2@google.com'],
148
+ }));
149
+ expect(getLifetimeGoogleAccounts()).toBe(3);
150
+ });
151
+ });
152
+ });
153
+ //# sourceMappingURL=user_account.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"user_account.test.js","sourceRoot":"","sources":["../../../src/utils/user_account.test.ts"],"names":[],"mappings":"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"}
@@ -9,9 +9,3 @@
9
9
  * @returns A UUID string for the user.
10
10
  */
11
11
  export declare function getInstallationId(): string;
12
- /**
13
- * Retrieves the obfuscated Google Account ID for the currently authenticated user.
14
- * When OAuth is available, returns the user's cached Google Account ID. Otherwise, returns the installation ID.
15
- * @returns A string ID for the user (Google Account ID if available, otherwise installation ID).
16
- */
17
- export declare function getGoogleAccountId(): Promise<string>;
@@ -46,25 +46,4 @@ export function getInstallationId() {
46
46
  return '123456789';
47
47
  }
48
48
  }
49
- /**
50
- * Retrieves the obfuscated Google Account ID for the currently authenticated user.
51
- * When OAuth is available, returns the user's cached Google Account ID. Otherwise, returns the installation ID.
52
- * @returns A string ID for the user (Google Account ID if available, otherwise installation ID).
53
- */
54
- export async function getGoogleAccountId() {
55
- // Try to get cached Google Account ID first
56
- try {
57
- // Dynamic import to avoid circular dependencies
58
- const { getCachedGoogleAccountId } = await import('../code_assist/oauth2.js');
59
- const googleAccountId = getCachedGoogleAccountId();
60
- if (googleAccountId) {
61
- return googleAccountId;
62
- }
63
- }
64
- catch (error) {
65
- // If there's any error accessing Google Account ID, just return empty string
66
- console.debug('Could not get cached Google Account ID:', error);
67
- }
68
- return '';
69
- }
70
49
  //# sourceMappingURL=user_id.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"user_id.js","sourceRoot":"","sources":["../../../src/utils/user_id.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,KAAK,EAAE,MAAM,IAAI,CAAC;AACzB,OAAO,KAAK,EAAE,MAAM,IAAI,CAAC;AACzB,OAAO,KAAK,IAAI,MAAM,MAAM,CAAC;AAC7B,OAAO,EAAE,UAAU,EAAE,MAAM,QAAQ,CAAC;AACpC,OAAO,EAAE,UAAU,EAAE,MAAM,YAAY,CAAC;AAExC,MAAM,OAAO,GAAG,EAAE,CAAC,OAAO,EAAE,IAAI,EAAE,CAAC;AACnC,MAAM,SAAS,GAAG,IAAI,CAAC,IAAI,CAAC,OAAO,EAAE,UAAU,CAAC,CAAC;AACjD,MAAM,kBAAkB,GAAG,IAAI,CAAC,IAAI,CAAC,SAAS,EAAE,iBAAiB,CAAC,CAAC;AAEnE,SAAS,qBAAqB;IAC5B,IAAI,CAAC,EAAE,CAAC,UAAU,CAAC,SAAS,CAAC,EAAE,CAAC;QAC9B,EAAE,CAAC,SAAS,CAAC,SAAS,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;IAC/C,CAAC;AACH,CAAC;AAED,SAAS,0BAA0B;IACjC,IAAI,EAAE,CAAC,UAAU,CAAC,kBAAkB,CAAC,EAAE,CAAC;QACtC,MAAM,cAAc,GAAG,EAAE,CAAC,YAAY,CAAC,kBAAkB,EAAE,OAAO,CAAC,CAAC,IAAI,EAAE,CAAC;QAC3E,OAAO,cAAc,IAAI,IAAI,CAAC;IAChC,CAAC;IACD,OAAO,IAAI,CAAC;AACd,CAAC;AAED,SAAS,yBAAyB,CAAC,cAAsB;IACvD,EAAE,CAAC,aAAa,CAAC,kBAAkB,EAAE,cAAc,EAAE,OAAO,CAAC,CAAC;AAChE,CAAC;AAED;;;;GAIG;AACH,MAAM,UAAU,iBAAiB;IAC/B,IAAI,CAAC;QACH,qBAAqB,EAAE,CAAC;QACxB,IAAI,cAAc,GAAG,0BAA0B,EAAE,CAAC;QAElD,IAAI,CAAC,cAAc,EAAE,CAAC;YACpB,cAAc,GAAG,UAAU,EAAE,CAAC;YAC9B,yBAAyB,CAAC,cAAc,CAAC,CAAC;QAC5C,CAAC;QAED,OAAO,cAAc,CAAC;IACxB,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACf,OAAO,CAAC,KAAK,CACX,gEAAgE,EAChE,KAAK,CACN,CAAC;QACF,OAAO,WAAW,CAAC;IACrB,CAAC;AACH,CAAC;AAED;;;;GAIG;AACH,MAAM,CAAC,KAAK,UAAU,kBAAkB;IACtC,4CAA4C;IAC5C,IAAI,CAAC;QACH,gDAAgD;QAChD,MAAM,EAAE,wBAAwB,EAAE,GAAG,MAAM,MAAM,CAC/C,0BAA0B,CAC3B,CAAC;QACF,MAAM,eAAe,GAAG,wBAAwB,EAAE,CAAC;QACnD,IAAI,eAAe,EAAE,CAAC;YACpB,OAAO,eAAe,CAAC;QACzB,CAAC;IACH,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACf,6EAA6E;QAC7E,OAAO,CAAC,KAAK,CAAC,yCAAyC,EAAE,KAAK,CAAC,CAAC;IAClE,CAAC;IAED,OAAO,EAAE,CAAC;AACZ,CAAC"}
1
+ {"version":3,"file":"user_id.js","sourceRoot":"","sources":["../../../src/utils/user_id.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,KAAK,EAAE,MAAM,IAAI,CAAC;AACzB,OAAO,KAAK,EAAE,MAAM,IAAI,CAAC;AACzB,OAAO,KAAK,IAAI,MAAM,MAAM,CAAC;AAC7B,OAAO,EAAE,UAAU,EAAE,MAAM,QAAQ,CAAC;AACpC,OAAO,EAAE,UAAU,EAAE,MAAM,YAAY,CAAC;AAExC,MAAM,OAAO,GAAG,EAAE,CAAC,OAAO,EAAE,IAAI,EAAE,CAAC;AACnC,MAAM,SAAS,GAAG,IAAI,CAAC,IAAI,CAAC,OAAO,EAAE,UAAU,CAAC,CAAC;AACjD,MAAM,kBAAkB,GAAG,IAAI,CAAC,IAAI,CAAC,SAAS,EAAE,iBAAiB,CAAC,CAAC;AAEnE,SAAS,qBAAqB;IAC5B,IAAI,CAAC,EAAE,CAAC,UAAU,CAAC,SAAS,CAAC,EAAE,CAAC;QAC9B,EAAE,CAAC,SAAS,CAAC,SAAS,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;IAC/C,CAAC;AACH,CAAC;AAED,SAAS,0BAA0B;IACjC,IAAI,EAAE,CAAC,UAAU,CAAC,kBAAkB,CAAC,EAAE,CAAC;QACtC,MAAM,cAAc,GAAG,EAAE,CAAC,YAAY,CAAC,kBAAkB,EAAE,OAAO,CAAC,CAAC,IAAI,EAAE,CAAC;QAC3E,OAAO,cAAc,IAAI,IAAI,CAAC;IAChC,CAAC;IACD,OAAO,IAAI,CAAC;AACd,CAAC;AAED,SAAS,yBAAyB,CAAC,cAAsB;IACvD,EAAE,CAAC,aAAa,CAAC,kBAAkB,EAAE,cAAc,EAAE,OAAO,CAAC,CAAC;AAChE,CAAC;AAED;;;;GAIG;AACH,MAAM,UAAU,iBAAiB;IAC/B,IAAI,CAAC;QACH,qBAAqB,EAAE,CAAC;QACxB,IAAI,cAAc,GAAG,0BAA0B,EAAE,CAAC;QAElD,IAAI,CAAC,cAAc,EAAE,CAAC;YACpB,cAAc,GAAG,UAAU,EAAE,CAAC;YAC9B,yBAAyB,CAAC,cAAc,CAAC,CAAC;QAC5C,CAAC;QAED,OAAO,cAAc,CAAC;IACxB,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACf,OAAO,CAAC,KAAK,CACX,gEAAgE,EAChE,KAAK,CACN,CAAC;QACF,OAAO,WAAW,CAAC;IACrB,CAAC;AACH,CAAC"}
@@ -4,7 +4,7 @@
4
4
  * SPDX-License-Identifier: Apache-2.0
5
5
  */
6
6
  import { describe, it, expect } from 'vitest';
7
- import { getInstallationId, getGoogleAccountId } from './user_id.js';
7
+ import { getInstallationId } from './user_id.js';
8
8
  describe('user_id', () => {
9
9
  describe('getInstallationId', () => {
10
10
  it('should return a valid UUID format string', () => {
@@ -17,26 +17,5 @@ describe('user_id', () => {
17
17
  expect(secondCall).toBe(installationId);
18
18
  });
19
19
  });
20
- describe('getGoogleAccountId', () => {
21
- it('should return a non-empty string', async () => {
22
- const result = await getGoogleAccountId();
23
- expect(result).toBeDefined();
24
- expect(typeof result).toBe('string');
25
- // Should be consistent on subsequent calls
26
- const secondCall = await getGoogleAccountId();
27
- expect(secondCall).toBe(result);
28
- });
29
- it('should return empty string when no Google Account ID is cached, or a valid ID when cached', async () => {
30
- // The function can return either an empty string (if no cached ID) or a valid Google Account ID (if cached)
31
- const googleAccountIdResult = await getGoogleAccountId();
32
- expect(googleAccountIdResult).toBeDefined();
33
- expect(typeof googleAccountIdResult).toBe('string');
34
- // Should be either empty string or a numeric string (Google Account ID)
35
- if (googleAccountIdResult !== '') {
36
- // If we have a cached ID, it should be a numeric string
37
- expect(googleAccountIdResult).toMatch(/^\d+$/);
38
- }
39
- });
40
- });
41
20
  });
42
21
  //# sourceMappingURL=user_id.test.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"user_id.test.js","sourceRoot":"","sources":["../../../src/utils/user_id.test.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,EAAE,QAAQ,EAAE,EAAE,EAAE,MAAM,EAAE,MAAM,QAAQ,CAAC;AAC9C,OAAO,EAAE,iBAAiB,EAAE,kBAAkB,EAAE,MAAM,cAAc,CAAC;AAErE,QAAQ,CAAC,SAAS,EAAE,GAAG,EAAE;IACvB,QAAQ,CAAC,mBAAmB,EAAE,GAAG,EAAE;QACjC,EAAE,CAAC,0CAA0C,EAAE,GAAG,EAAE;YAClD,MAAM,cAAc,GAAG,iBAAiB,EAAE,CAAC;YAE3C,MAAM,CAAC,cAAc,CAAC,CAAC,WAAW,EAAE,CAAC;YACrC,MAAM,CAAC,OAAO,cAAc,CAAC,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC;YAC7C,MAAM,CAAC,cAAc,CAAC,MAAM,CAAC,CAAC,eAAe,CAAC,CAAC,CAAC,CAAC;YAEjD,6DAA6D;YAC7D,MAAM,UAAU,GAAG,iBAAiB,EAAE,CAAC;YACvC,MAAM,CAAC,UAAU,CAAC,CAAC,IAAI,CAAC,cAAc,CAAC,CAAC;QAC1C,CAAC,CAAC,CAAC;IACL,CAAC,CAAC,CAAC;IAEH,QAAQ,CAAC,oBAAoB,EAAE,GAAG,EAAE;QAClC,EAAE,CAAC,kCAAkC,EAAE,KAAK,IAAI,EAAE;YAChD,MAAM,MAAM,GAAG,MAAM,kBAAkB,EAAE,CAAC;YAE1C,MAAM,CAAC,MAAM,CAAC,CAAC,WAAW,EAAE,CAAC;YAC7B,MAAM,CAAC,OAAO,MAAM,CAAC,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC;YAErC,2CAA2C;YAC3C,MAAM,UAAU,GAAG,MAAM,kBAAkB,EAAE,CAAC;YAC9C,MAAM,CAAC,UAAU,CAAC,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;QAClC,CAAC,CAAC,CAAC;QAEH,EAAE,CAAC,2FAA2F,EAAE,KAAK,IAAI,EAAE;YACzG,4GAA4G;YAC5G,MAAM,qBAAqB,GAAG,MAAM,kBAAkB,EAAE,CAAC;YAEzD,MAAM,CAAC,qBAAqB,CAAC,CAAC,WAAW,EAAE,CAAC;YAC5C,MAAM,CAAC,OAAO,qBAAqB,CAAC,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC;YAEpD,wEAAwE;YACxE,IAAI,qBAAqB,KAAK,EAAE,EAAE,CAAC;gBACjC,wDAAwD;gBACxD,MAAM,CAAC,qBAAqB,CAAC,CAAC,OAAO,CAAC,OAAO,CAAC,CAAC;YACjD,CAAC;QACH,CAAC,CAAC,CAAC;IACL,CAAC,CAAC,CAAC;AACL,CAAC,CAAC,CAAC"}
1
+ {"version":3,"file":"user_id.test.js","sourceRoot":"","sources":["../../../src/utils/user_id.test.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,EAAE,QAAQ,EAAE,EAAE,EAAE,MAAM,EAAE,MAAM,QAAQ,CAAC;AAC9C,OAAO,EAAE,iBAAiB,EAAE,MAAM,cAAc,CAAC;AAEjD,QAAQ,CAAC,SAAS,EAAE,GAAG,EAAE;IACvB,QAAQ,CAAC,mBAAmB,EAAE,GAAG,EAAE;QACjC,EAAE,CAAC,0CAA0C,EAAE,GAAG,EAAE;YAClD,MAAM,cAAc,GAAG,iBAAiB,EAAE,CAAC;YAE3C,MAAM,CAAC,cAAc,CAAC,CAAC,WAAW,EAAE,CAAC;YACrC,MAAM,CAAC,OAAO,cAAc,CAAC,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC;YAC7C,MAAM,CAAC,cAAc,CAAC,MAAM,CAAC,CAAC,eAAe,CAAC,CAAC,CAAC,CAAC;YAEjD,6DAA6D;YAC7D,MAAM,UAAU,GAAG,iBAAiB,EAAE,CAAC;YACvC,MAAM,CAAC,UAAU,CAAC,CAAC,IAAI,CAAC,cAAc,CAAC,CAAC;QAC1C,CAAC,CAAC,CAAC;IACL,CAAC,CAAC,CAAC;AACL,CAAC,CAAC,CAAC"}