convex-devtools 1.0.1 → 1.1.1

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.
package/README.md CHANGED
@@ -6,18 +6,21 @@
6
6
  <img src="https://img.shields.io/npm/dt/convex-devtools" alt="downloads">
7
7
  </p>
8
8
 
9
- A standalone development tool for testing Convex queries, mutations, and actions with identity mocking, request saving, and auto-reloading schema discovery.
9
+ A standalone development tool for testing Convex functions and exploring data with identity mocking, request saving, schema discovery, and a schema‑driven Data Explorer.
10
10
 
11
- > 💡 **Note**: This tool is designed for **development and testing**. A deploy key is optional but enables identity mocking features.
11
+ > 💡 **Note**: This tool is designed for **development and testing**. A deploy key is required for Data Explorer queries.
12
12
 
13
13
  ## Features
14
14
 
15
15
  - 🔍 **Function Explorer** - Browse all your Convex queries, mutations, and actions in a tree view
16
16
  - 🎭 **Identity Mocking** - Test functions as different users with custom roles and claims
17
17
  - 💾 **Request Collections** - Save and organize requests like Postman
18
- - 📜 **History** - View and replay previous function calls
18
+ - 📜 **History** - View and replay previous function calls and schema queries
19
19
  - 🔄 **Auto-reload** - Schema updates automatically when your Convex files change
20
20
  - 📤 **Import/Export** - Share collections with your team
21
+ - 🧭 **Data Explorer** - Schema‑driven table view, column picker, pagination, and JSON view
22
+ - 🧱 **Query Builder** - Build filters/order via UI or switch to raw JSON
23
+ - 🗂️ **Query Tabs** - Recent tabs for functions and schema queries
21
24
 
22
25
  ## Quick Start
23
26
 
@@ -75,6 +78,19 @@ convex-devtools --no-open
75
78
 
76
79
  The tool will automatically open in your browser at `http://localhost:5173`.
77
80
 
81
+ ## Data Explorer (Schema Queries)
82
+
83
+ The Data Explorer lets you run read‑only schema queries against `ctx.db.query()` in your Convex project:
84
+
85
+ - **Builder**: pick table, order, and filters with a UI
86
+ - **JSON**: edit the query payload directly
87
+ - **Table view**: column picker, pagination, and search
88
+ - **JSON view**: raw response with search
89
+ - **Resizable panes**: adjust the Data Explorer/Response split
90
+ - **Recent tabs**: quickly jump between recent schema queries
91
+
92
+ The helper query uses Convex pagination (cursor + page size). The deploy key is required to run these queries.
93
+
78
94
  ## CLI Options
79
95
 
80
96
  | Option | Description | Default |
@@ -138,7 +154,7 @@ The export format is a simple JSON structure:
138
154
 
139
155
  ```json
140
156
  {
141
- "version": "1.0",
157
+ "version": "1.1.1",
142
158
  "exportedAt": "2025-01-29T10:00:00.000Z",
143
159
  "collections": [
144
160
  {
@@ -3,6 +3,11 @@ import chokidar from "chokidar";
3
3
  import { EventEmitter } from "events";
4
4
  import fs from "fs";
5
5
  import path from "path";
6
+ import {
7
+ Node,
8
+ Project,
9
+ SyntaxKind
10
+ } from "ts-morph";
6
11
  var SchemaWatcher = class extends EventEmitter {
7
12
  projectDir;
8
13
  watcher = null;
@@ -56,7 +61,7 @@ var SchemaWatcher = class extends EventEmitter {
56
61
  this.schemaInfo = {
57
62
  modules,
58
63
  tables,
59
- lastUpdated: /* @__PURE__ */ new Date()
64
+ lastUpdated: (/* @__PURE__ */ new Date()).toISOString()
60
65
  };
61
66
  const funcCount = this.countFunctions(modules);
62
67
  console.log(
@@ -333,13 +338,48 @@ var SchemaWatcher = class extends EventEmitter {
333
338
  }
334
339
  try {
335
340
  const content = fs.readFileSync(schemaPath, "utf-8");
336
- const tablePattern = /(\w+):\s*defineTable\(/g;
337
- let match;
338
- while ((match = tablePattern.exec(content)) !== null) {
341
+ const project = new Project({ useInMemoryFileSystem: true });
342
+ const sourceFile = project.createSourceFile(
343
+ "schema.ts",
344
+ content,
345
+ { overwrite: true }
346
+ );
347
+ const defineSchemaCall = sourceFile.getDescendantsOfKind(SyntaxKind.CallExpression).find(
348
+ (call) => call.getExpression().getText() === "defineSchema"
349
+ );
350
+ if (!defineSchemaCall) {
351
+ return tables;
352
+ }
353
+ const schemaArg = defineSchemaCall.getArguments()[0];
354
+ if (!schemaArg || !Node.isObjectLiteralExpression(schemaArg)) {
355
+ return tables;
356
+ }
357
+ for (const prop of schemaArg.getProperties()) {
358
+ if (!Node.isPropertyAssignment(prop)) continue;
359
+ const tableName = this.normalizePropertyName(prop.getName());
360
+ const initializer = prop.getInitializer();
361
+ if (!initializer) continue;
362
+ const defineTableCall = this.findDefineTableCall(initializer);
363
+ if (!defineTableCall) continue;
364
+ const fieldsArg = defineTableCall.getArguments()[0];
365
+ const fields = [];
366
+ if (fieldsArg && Node.isObjectLiteralExpression(fieldsArg)) {
367
+ for (const fieldProp of fieldsArg.getProperties()) {
368
+ if (!Node.isPropertyAssignment(fieldProp)) continue;
369
+ const fieldName = this.normalizePropertyName(fieldProp.getName());
370
+ const fieldInit = fieldProp.getInitializer();
371
+ if (!fieldInit) continue;
372
+ const parsedField = this.parseFieldInfo(fieldInit);
373
+ fields.push({
374
+ name: fieldName,
375
+ type: parsedField.type,
376
+ optional: parsedField.optional
377
+ });
378
+ }
379
+ }
339
380
  tables.push({
340
- name: match[1],
341
- fields: []
342
- // Could parse fields but keeping simple for now
381
+ name: tableName,
382
+ fields
343
383
  });
344
384
  }
345
385
  } catch (error) {
@@ -347,9 +387,54 @@ var SchemaWatcher = class extends EventEmitter {
347
387
  }
348
388
  return tables;
349
389
  }
390
+ findDefineTableCall(expr) {
391
+ if (Node.isCallExpression(expr)) {
392
+ const callee = expr.getExpression();
393
+ if (Node.isIdentifier(callee) && callee.getText() === "defineTable") {
394
+ return expr;
395
+ }
396
+ if (Node.isPropertyAccessExpression(callee)) {
397
+ const inner = callee.getExpression();
398
+ if (Node.isCallExpression(inner)) {
399
+ return this.findDefineTableCall(inner);
400
+ }
401
+ if (Node.isPropertyAccessExpression(inner)) {
402
+ return this.findDefineTableCall(inner.getExpression());
403
+ }
404
+ }
405
+ }
406
+ if (Node.isPropertyAccessExpression(expr)) {
407
+ return this.findDefineTableCall(expr.getExpression());
408
+ }
409
+ return null;
410
+ }
411
+ parseFieldInfo(expr) {
412
+ let optional = false;
413
+ let typeExpr = expr;
414
+ if (Node.isCallExpression(expr)) {
415
+ const calleeText = expr.getExpression().getText();
416
+ if (calleeText === "v.optional") {
417
+ optional = true;
418
+ const inner = expr.getArguments()[0];
419
+ if (inner && Node.isExpression(inner)) {
420
+ typeExpr = inner;
421
+ }
422
+ }
423
+ }
424
+ return {
425
+ type: typeExpr?.getText() ?? "unknown",
426
+ optional
427
+ };
428
+ }
429
+ normalizePropertyName(name) {
430
+ if (name.startsWith("'") && name.endsWith("'") || name.startsWith('"') && name.endsWith('"')) {
431
+ return name.slice(1, -1);
432
+ }
433
+ return name;
434
+ }
350
435
  };
351
436
 
352
437
  export {
353
438
  SchemaWatcher
354
439
  };
355
- //# sourceMappingURL=chunk-6H4WSVWY.js.map
440
+ //# sourceMappingURL=chunk-7LFMAA6L.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../src/server/schema-watcher.ts"],"sourcesContent":["import chokidar from 'chokidar';\nimport { EventEmitter } from 'events';\nimport fs from 'fs';\nimport path from 'path';\nimport {\n CallExpression,\n Expression,\n Node,\n Project,\n SyntaxKind,\n} from 'ts-morph';\n\nexport interface FunctionInfo {\n name: string;\n path: string; // Full path like \"products/products:list\"\n type: 'query' | 'mutation' | 'action';\n args: ArgInfo[];\n returns?: string;\n}\n\nexport interface ArgInfo {\n name: string;\n type: string;\n optional: boolean;\n description?: string;\n enumValues?: string[];\n}\n\nexport interface ModuleInfo {\n name: string;\n path: string;\n functions: FunctionInfo[];\n children: ModuleInfo[];\n}\n\nexport interface SchemaInfo {\n modules: ModuleInfo[];\n tables: TableInfo[];\n lastUpdated: string;\n}\n\nexport interface TableInfo {\n name: string;\n fields: FieldInfo[];\n}\n\nexport interface FieldInfo {\n name: string;\n type: string;\n optional: boolean;\n}\n\nexport class SchemaWatcher extends EventEmitter {\n private projectDir: string;\n private watcher: chokidar.FSWatcher | null = null;\n private schemaInfo: SchemaInfo | null = null;\n\n constructor(projectDir: string) {\n super();\n this.projectDir = projectDir;\n }\n\n async start(): Promise<void> {\n // Initial parse\n await this.parseSchema();\n\n // Watch for changes\n const convexDir = path.join(this.projectDir, 'convex');\n\n this.watcher = chokidar.watch(convexDir, {\n persistent: true,\n ignoreInitial: true,\n ignored: [\n '**/node_modules/**',\n '**/_generated/**',\n '**/test.setup.ts',\n '**/*.test.ts',\n ],\n });\n\n this.watcher.on('change', async (filePath) => {\n if (filePath.endsWith('.ts') && !filePath.includes('_generated')) {\n console.log(`[SchemaWatcher] File changed: ${filePath}`);\n await this.parseSchema();\n this.emit('schema-updated', this.schemaInfo);\n }\n });\n\n this.watcher.on('add', async (filePath) => {\n if (filePath.endsWith('.ts') && !filePath.includes('_generated')) {\n console.log(`[SchemaWatcher] File added: ${filePath}`);\n await this.parseSchema();\n this.emit('schema-updated', this.schemaInfo);\n }\n });\n }\n\n stop(): void {\n if (this.watcher) {\n this.watcher.close();\n this.watcher = null;\n }\n }\n\n getSchema(): SchemaInfo | null {\n return this.schemaInfo;\n }\n\n private async parseSchema(): Promise<void> {\n try {\n const convexDir = path.join(this.projectDir, 'convex');\n const modules = await this.parseConvexDirectory(convexDir);\n const tables = await this.parseSchemaFile(convexDir);\n\n this.schemaInfo = {\n modules,\n tables,\n lastUpdated: new Date().toISOString(),\n };\n\n const funcCount = this.countFunctions(modules);\n console.log(\n `[SchemaWatcher] Parsed ${funcCount} functions from ${modules.length} modules`\n );\n } catch (error) {\n console.error('[SchemaWatcher] Error parsing schema:', error);\n }\n }\n\n private countFunctions(modules: ModuleInfo[]): number {\n let count = 0;\n for (const mod of modules) {\n count += mod.functions.length;\n count += this.countFunctions(mod.children);\n }\n return count;\n }\n\n private async parseConvexDirectory(convexDir: string): Promise<ModuleInfo[]> {\n const modules: ModuleInfo[] = [];\n\n // Read convex directory structure\n const entries = fs.readdirSync(convexDir, { withFileTypes: true });\n\n for (const entry of entries) {\n // Skip hidden, generated, and test files\n if (\n entry.name.startsWith('.') ||\n entry.name.startsWith('_') ||\n entry.name === 'node_modules' ||\n entry.name.endsWith('.test.ts') ||\n entry.name === 'test.setup.ts'\n ) {\n continue;\n }\n\n if (entry.isDirectory()) {\n // Parse subdirectory as module\n const subModule = await this.parseSubdirectory(\n path.join(convexDir, entry.name),\n entry.name\n );\n if (subModule.functions.length > 0 || subModule.children.length > 0) {\n modules.push(subModule);\n }\n } else if (entry.isFile() && entry.name.endsWith('.ts')) {\n // Parse root-level file\n const filePath = path.join(convexDir, entry.name);\n const moduleName = entry.name.replace('.ts', '');\n const functions = await this.parseFile(filePath, moduleName);\n\n if (functions.length > 0) {\n modules.push({\n name: moduleName,\n path: moduleName,\n functions,\n children: [],\n });\n }\n }\n }\n\n return modules;\n }\n\n private async parseSubdirectory(\n dirPath: string,\n parentPath: string\n ): Promise<ModuleInfo> {\n const module: ModuleInfo = {\n name: path.basename(dirPath),\n path: parentPath,\n functions: [],\n children: [],\n };\n\n const entries = fs.readdirSync(dirPath, { withFileTypes: true });\n\n for (const entry of entries) {\n // Skip tests directory and test files\n if (\n entry.name === 'tests' ||\n entry.name.endsWith('.test.ts') ||\n entry.name.startsWith('.')\n ) {\n continue;\n }\n\n if (entry.isDirectory()) {\n const subModule = await this.parseSubdirectory(\n path.join(dirPath, entry.name),\n `${parentPath}/${entry.name}`\n );\n if (subModule.functions.length > 0 || subModule.children.length > 0) {\n module.children.push(subModule);\n }\n } else if (entry.isFile() && entry.name.endsWith('.ts')) {\n const filePath = path.join(dirPath, entry.name);\n const moduleName = entry.name.replace('.ts', '');\n const modulePath = `${parentPath}/${moduleName}`;\n const functions = await this.parseFile(filePath, modulePath);\n\n // Create a child module for each file (group by file)\n if (functions.length > 0) {\n module.children.push({\n name: moduleName,\n path: modulePath,\n functions,\n children: [],\n });\n }\n }\n }\n\n return module;\n }\n\n private async parseFile(\n filePath: string,\n modulePath: string\n ): Promise<FunctionInfo[]> {\n const functions: FunctionInfo[] = [];\n\n try {\n const content = fs.readFileSync(filePath, 'utf-8');\n\n // Parse exported functions using regex\n // Match patterns like: export const functionName = query({ or mutation({ or action({\n const exportPattern =\n /export\\s+const\\s+(\\w+)\\s*=\\s*(query|mutation|action|internalQuery|internalMutation|internalAction)\\s*\\(\\s*\\{/g;\n\n let match;\n while ((match = exportPattern.exec(content)) !== null) {\n const [, funcName, funcType] = match;\n\n // Normalize internal functions to their base type\n let normalizedType = funcType as 'query' | 'mutation' | 'action';\n if (funcType.startsWith('internal')) {\n normalizedType = funcType.replace('internal', '').toLowerCase() as\n | 'query'\n | 'mutation'\n | 'action';\n }\n\n // Extract JSDoc comment above the function\n const jsdocComment = this.extractJSDocAbove(content, match.index);\n\n // Extract args from the function definition\n const args = this.extractArgsFromPosition(\n content,\n match.index,\n jsdocComment\n );\n\n functions.push({\n name: funcName,\n path: `${modulePath}:${funcName}`,\n type: normalizedType,\n args,\n });\n }\n } catch (error) {\n console.error(`[SchemaWatcher] Error parsing file ${filePath}:`, error);\n }\n\n return functions;\n }\n\n private extractJSDocAbove(content: string, position: number): string {\n // Look backwards from position to find JSDoc comment\n // Allow some whitespace and newlines between the JSDoc and the export\n const beforePosition = content.slice(0, position);\n // Match JSDoc that ends with */ followed by optional whitespace before the export\n const jsdocMatch = beforePosition.match(/\\/\\*\\*([\\s\\S]*?)\\*\\/\\s*$/);\n if (jsdocMatch) {\n return jsdocMatch[1];\n }\n\n // Also try to find JSDoc within the last 500 chars (in case there's space between)\n const last500 = beforePosition.slice(-500);\n const jsdocMatch2 = last500.match(/\\/\\*\\*([\\s\\S]*?)\\*\\//);\n return jsdocMatch2 ? jsdocMatch2[1] : '';\n }\n\n private parseJSDocParams(\n jsdoc: string\n ): Map<string, { description: string; enumValues?: string[] }> {\n const params = new Map<\n string,\n { description: string; enumValues?: string[] }\n >();\n\n // Match @param patterns like: @param sortBy - Sort order: 'newest', 'oldest'\n const paramPattern = /@param\\s+(\\w+)\\s*-?\\s*([^@]*)/g;\n let match;\n while ((match = paramPattern.exec(jsdoc)) !== null) {\n const [, paramName, description] = match;\n const trimmedDesc = description.trim();\n\n // Extract enum values from description (quoted strings like 'value1', 'value2')\n const enumMatches = trimmedDesc.match(/'([^']+)'/g);\n const enumValues = enumMatches\n ? enumMatches.map((e) => e.replace(/'/g, ''))\n : undefined;\n\n params.set(paramName, {\n description: trimmedDesc,\n enumValues:\n enumValues && enumValues.length > 0 ? enumValues : undefined,\n });\n }\n\n return params;\n }\n\n private extractArgsFromPosition(\n content: string,\n startIndex: number,\n jsdocComment: string = ''\n ): ArgInfo[] {\n const args: ArgInfo[] = [];\n const jsdocParams = this.parseJSDocParams(jsdocComment);\n\n // Limit parsing to the current function block to avoid false positives\n const functionBlock = this.extractFunctionBlock(content, startIndex);\n\n // Find the args: { ... } section\n const argsMatch = functionBlock.match(/args:\\s*\\{([^}]*)\\}/s);\n\n if (argsMatch) {\n const argsContent = argsMatch[1];\n\n // Parse individual args\n // Matches patterns like: argName: v.string(), argName: v.optional(v.id('users'))\n const argPattern = /(\\w+):\\s*(v\\.optional\\()?v\\.(\\w+)/g;\n\n let argMatch;\n while ((argMatch = argPattern.exec(argsContent)) !== null) {\n const [, argName, isOptional, argType] = argMatch;\n const jsdocInfo = jsdocParams.get(argName);\n\n args.push({\n name: argName,\n type: argType,\n optional: !!isOptional,\n description: jsdocInfo?.description,\n enumValues: jsdocInfo?.enumValues,\n });\n }\n }\n\n // Check for paginationOpts (built-in Convex pagination)\n const hasPaginationOpts = functionBlock.match(/paginationOptsValidator/s);\n if (hasPaginationOpts) {\n // Add paginationOpts as a synthetic argument\n args.push({\n name: 'paginationOpts',\n type: 'PaginationOptions',\n optional: false,\n description: 'Pagination options with cursor and numItems',\n });\n }\n\n return args;\n }\n\n private extractFunctionBlock(content: string, startIndex: number): string {\n const afterStart = content.slice(startIndex);\n const openIndex = afterStart.indexOf('{');\n if (openIndex === -1) {\n return afterStart;\n }\n\n let depth = 0;\n let inSingle = false;\n let inDouble = false;\n let inTemplate = false;\n let inLineComment = false;\n let inBlockComment = false;\n let escape = false;\n\n for (let i = openIndex; i < afterStart.length; i += 1) {\n const char = afterStart[i];\n const next = afterStart[i + 1];\n\n if (inLineComment) {\n if (char === '\\n') {\n inLineComment = false;\n }\n continue;\n }\n\n if (inBlockComment) {\n if (char === '*' && next === '/') {\n inBlockComment = false;\n i += 1;\n }\n continue;\n }\n\n if (inSingle) {\n if (escape) {\n escape = false;\n } else if (char === '\\\\') {\n escape = true;\n } else if (char === \"'\") {\n inSingle = false;\n }\n continue;\n }\n\n if (inDouble) {\n if (escape) {\n escape = false;\n } else if (char === '\\\\') {\n escape = true;\n } else if (char === '\"') {\n inDouble = false;\n }\n continue;\n }\n\n if (inTemplate) {\n if (escape) {\n escape = false;\n } else if (char === '\\\\') {\n escape = true;\n } else if (char === '`') {\n inTemplate = false;\n }\n continue;\n }\n\n if (char === '/' && next === '/') {\n inLineComment = true;\n i += 1;\n continue;\n }\n\n if (char === '/' && next === '*') {\n inBlockComment = true;\n i += 1;\n continue;\n }\n\n if (char === \"'\") {\n inSingle = true;\n escape = false;\n continue;\n }\n\n if (char === '\"') {\n inDouble = true;\n escape = false;\n continue;\n }\n\n if (char === '`') {\n inTemplate = true;\n escape = false;\n continue;\n }\n\n if (char === '{') {\n depth += 1;\n } else if (char === '}') {\n depth -= 1;\n if (depth === 0) {\n return afterStart.slice(openIndex, i + 1);\n }\n }\n }\n\n return afterStart;\n }\n\n private async parseSchemaFile(convexDir: string): Promise<TableInfo[]> {\n const tables: TableInfo[] = [];\n const schemaPath = path.join(convexDir, 'schema.ts');\n\n if (!fs.existsSync(schemaPath)) {\n return tables;\n }\n\n try {\n const content = fs.readFileSync(schemaPath, 'utf-8');\n const project = new Project({ useInMemoryFileSystem: true });\n const sourceFile = project.createSourceFile(\n 'schema.ts',\n content,\n { overwrite: true }\n );\n\n const defineSchemaCall = sourceFile\n .getDescendantsOfKind(SyntaxKind.CallExpression)\n .find(\n (call) => call.getExpression().getText() === 'defineSchema'\n );\n\n if (!defineSchemaCall) {\n return tables;\n }\n\n const schemaArg = defineSchemaCall.getArguments()[0];\n if (!schemaArg || !Node.isObjectLiteralExpression(schemaArg)) {\n return tables;\n }\n\n for (const prop of schemaArg.getProperties()) {\n if (!Node.isPropertyAssignment(prop)) continue;\n\n const tableName = this.normalizePropertyName(prop.getName());\n const initializer = prop.getInitializer();\n if (!initializer) continue;\n\n const defineTableCall = this.findDefineTableCall(initializer);\n if (!defineTableCall) continue;\n\n const fieldsArg = defineTableCall.getArguments()[0];\n const fields: FieldInfo[] = [];\n\n if (fieldsArg && Node.isObjectLiteralExpression(fieldsArg)) {\n for (const fieldProp of fieldsArg.getProperties()) {\n if (!Node.isPropertyAssignment(fieldProp)) continue;\n const fieldName = this.normalizePropertyName(fieldProp.getName());\n const fieldInit = fieldProp.getInitializer();\n if (!fieldInit) continue;\n\n const parsedField = this.parseFieldInfo(fieldInit);\n fields.push({\n name: fieldName,\n type: parsedField.type,\n optional: parsedField.optional,\n });\n }\n }\n\n tables.push({\n name: tableName,\n fields,\n });\n }\n } catch (error) {\n console.error('[SchemaWatcher] Error parsing schema file:', error);\n }\n\n return tables;\n }\n\n private findDefineTableCall(\n expr: Expression\n ): CallExpression | null {\n if (Node.isCallExpression(expr)) {\n const callee = expr.getExpression();\n if (Node.isIdentifier(callee) && callee.getText() === 'defineTable') {\n return expr;\n }\n if (Node.isPropertyAccessExpression(callee)) {\n const inner = callee.getExpression();\n if (Node.isCallExpression(inner)) {\n return this.findDefineTableCall(inner);\n }\n if (Node.isPropertyAccessExpression(inner)) {\n return this.findDefineTableCall(inner.getExpression());\n }\n }\n }\n\n if (Node.isPropertyAccessExpression(expr)) {\n return this.findDefineTableCall(expr.getExpression());\n }\n\n return null;\n }\n\n private parseFieldInfo(\n expr: Expression\n ): { type: string; optional: boolean } {\n let optional = false;\n let typeExpr: Expression | undefined = expr;\n\n if (Node.isCallExpression(expr)) {\n const calleeText = expr.getExpression().getText();\n if (calleeText === 'v.optional') {\n optional = true;\n const inner = expr.getArguments()[0];\n if (inner && Node.isExpression(inner)) {\n typeExpr = inner;\n }\n }\n }\n\n return {\n type: typeExpr?.getText() ?? 'unknown',\n optional,\n };\n }\n\n private normalizePropertyName(name: string): string {\n if (\n (name.startsWith(\"'\") && name.endsWith(\"'\")) ||\n (name.startsWith('\"') && name.endsWith('\"'))\n ) {\n return name.slice(1, -1);\n }\n return name;\n }\n}\n"],"mappings":"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","names":[]}