Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions CLAUDE.md
Original file line number Diff line number Diff line change
Expand Up @@ -127,6 +127,7 @@ Yarn provides "prefixed" scripts using the `<scope>:<action>` pattern. Scripts l
- Test mocks: `packages/tests/src/_jest/helpers/mocks`
- More utilities exist in `@dd/core/helpers/` and `packages/tests/src/_jest/helpers/` — search these directories before writing new helpers.
- **No unnecessary optionality**: Don't make parameters optional (`?`) when they are always provided. If a value must exist at the call site, make the type reflect that.
- **No nested function calls as arguments**: Don't inline a function call, especially an awaited call, directly as an argument to another function. Assign the inner result to a well-named local variable first, then pass that variable.
- **DRY with existing code**: Before writing a new implementation, search for existing code that does the same thing. Reuse and extend rather than duplicate.
- **Consistent dependency versions**: When adding a new dependency, check what version is already used elsewhere in the monorepo (`grep` across `package.json` files) and use the same version. Don't introduce a second version of a package that already exists in the repo.

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,9 @@
// This product includes software developed at Datadog (https://www.datadoghq.com/).
// Copyright 2019-Present Datadog, Inc.

import type { BaseNode, Program } from 'estree';
import type { Program } from 'estree';

import { isTypeOnly } from './type-guards';

const ACTION_CATALOG_PACKAGE = '@datadog/action-catalog';

Expand All @@ -11,8 +13,6 @@ export interface ActionCatalogImports {
namespaces: Set<string>;
}

type NodeWithOptionalImportKind = BaseNode & { importKind?: string };

export function collectActionCatalogImports(ast: Program): ActionCatalogImports {
const functions = new Set<string>();
const namespaces = new Set<string>();
Expand Down Expand Up @@ -51,7 +51,3 @@ function isActionCatalogSource(source: unknown): boolean {
(source === ACTION_CATALOG_PACKAGE || source.startsWith(`${ACTION_CATALOG_PACKAGE}/`))
);
}

function isTypeOnly(node: NodeWithOptionalImportKind): boolean {
return node.importKind === 'type';
}
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@

import type { BaseNode, Declaration, Expression, Program } from 'estree';

import { isProgramNode } from './type-guards';
import { ensureProgram } from './type-guards';
import type { BackendExport } from './types';

/**
Expand All @@ -23,17 +23,13 @@ export function extractExportedFunctions(ast: BaseNode, filePath: string): strin
}

export function enumerateBackendExports(ast: BaseNode, filePath: string): BackendExport[] {
if (!isProgramNode(ast)) {
throw new Error(
`Expected a Program node from this.parse() for ${filePath}, got ${ast.type}`,
);
}
const program = ensureProgram(ast, filePath);

// Build a map of top-level declarations so we can validate export specifiers.
const declarations = buildDeclarationMap(ast);
const declarations = buildDeclarationMap(program);

const backendExports: BackendExport[] = [];
for (const node of ast.body) {
for (const node of program.body) {
// handles: export default ...
if (node.type === 'ExportDefaultDeclaration') {
throw new Error(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,30 +8,22 @@ import {
analyzeActionCatalogScopes,
findActionCatalogCallSites,
} from './action-catalog-call-sites';
import { collectActionCatalogImports, hasActionCatalogImports } from './action-catalog-imports';
import { collectActionCatalogImports } from './action-catalog-imports';
import {
collectSameModuleConnectionIdBindings,
extractConnectionIdFromActionCall,
} from './connection-id-values';
import { isProgramNode } from './type-guards';
import { ensureProgram } from './type-guards';

export function extractConnectionIds(ast: BaseNode, filePath: string): string[] {
if (!isProgramNode(ast)) {
throw new Error(
`Expected a Program node from this.parse() for ${filePath}, got ${ast.type}`,
);
}

const imports = collectActionCatalogImports(ast);
if (!hasActionCatalogImports(imports)) {
return [];
}
const program = ensureProgram(ast, filePath);

const scopeAnalysis = analyzeActionCatalogScopes(ast, imports);
const bindings = collectSameModuleConnectionIdBindings(ast, scopeAnalysis);
const imports = collectActionCatalogImports(program);
const scopeAnalysis = analyzeActionCatalogScopes(program, imports);
const bindings = collectSameModuleConnectionIdBindings(program, scopeAnalysis);
const connectionIds = new Set<string>();

for (const callSite of findActionCatalogCallSites(ast, scopeAnalysis, filePath)) {
for (const callSite of findActionCatalogCallSites(program, scopeAnalysis, filePath)) {
const connectionId = extractConnectionIdFromActionCall(
callSite,
bindings,
Expand Down
Loading
Loading