CodeSampleX

Exemple

typescript 7.0.2: Construct and validate TypeScript function declarations using createFunctionDeclaration and createParameterDeclaration

Échantillon vérifié pour npm typescript 7.0.2: Construct and validate TypeScript function declarations using createFunctionDeclaration and…

sha256:4d51681d44d875cd68e1e2602763c0e34a22531d69d29994a25fe897cdb411a1

Ce réseau offre une seule chose : un échantillon qui compile. Il l'a exécuté dans un bac à sable et conservé le reçu signé. Il ne note rien et ne garantit rien : si le même code compile chez vous, il ne l'a pas mesuré. Combien de clés de signature distinctes ont déposé un reçu de contrat réussi. Une seule, c'est l'auteur ; plus d'une signifie que quelqu'un d'autre l'a compilé aussi. Une clé est auto-générée sans identité enregistrée derrière, donc on compte des clés, pas des personnes. MIT-0

Preuves d'exécution

L'environnement déclaré et les exécutions signées sont séparés, pour que vous voyiez exactement ce que cet échantillon a exécuté et où.

Base de preuve
Contrat signé réussi
Reçus de vérification
1
Clés de signature qui l’ont compilé
1
Environnement déclaré linux 24 · ubuntu · glibc 2.39 x64 npm

Environnements des exécutions de vérification

Environnement Contrat Étapes Exécution
node 22 · linux alpine/x64 · docker ed25519:d91480838ac982c9 PASS compile:SKIPPED · contract:PASS · load:PASS · resolve:PASS
CONTAINER_RUN · node-typescript@1
2026-08-20

Cas

HOW
Objectif
Construct and validate TypeScript function declarations using createFunctionDeclaration and createParameterDeclaration
Paquets
Symboles
  • createFunctionDeclaration
  • createParameterDeclaration
Créé
2026-08-20T04:54:35Z

Contrat

  1. buildFunctionDeclaration constructs a function declaration with parameters and return type and validates it with isFunctionDeclaration
  2. buildAsyncFunctionDeclaration constructs an async function declaration returning a Promise type
  3. buildFunctionParameter constructs parameter declarations with optional tokens and initializers
  4. inspectFunctionDeclaration extracts structural function metadata using AST type guards

Fichiers

  • PROMPT.md
  • csx.json
  • package-lock.json
  • package.json
  • spec.json
  • src/index.mjs
  • test/contract.mjs

Télécharger l’artefact source (tar.gz)

Code source

PROMPT.md
Clean-room public code sample — generation instructions

Write a brand-new, minimal, self-contained code sample in this clean-room directory.
Do not copy, paraphrase, or reference any existing project source. Work only from this spec.

A csx.json manifest scaffold already exists. Do not recreate it from memory. Preserve its case.goal, packages and symbols; fill its empty case.contract with exact assertions and correct its environment, commands and verifierAdapter for the files you generate.

Goal: Construct and validate TypeScript function declarations using createFunctionDeclaration and createParameterDeclaration
Kind: HOW

Use EXACTLY these public packages and versions:
  - pkg:npm/typescript@7.0.2
Demonstrate these symbols/APIs:
  - createFunctionDeclaration
  - createParameterDeclaration

Rules:
  - One focused purpose; the smallest project that proves the goal.
  - Include a contract test (test/contract.*) that runs OFFLINE and exits 0 exactly when the goal behavior works.
  - Pin every dependency with a lockfile so resolution is reproducible.
  - No secrets, credentials, or tokens. No real URLs (only example.com or localhost). No absolute paths.
  - No personal names, emails, company names, or project identifiers of any kind.
  - No binaries and no generated output (node_modules, dist, target, venv, .git, .env).
  - Keep it under 200 files and 256KB packed.
csx.json
{"case":{"caseId":"case:sha256:0acfd48a74c984e597d7c6b27bea4b52ecbc3dfa873ed98bf8f4e8f3ea8243de","contract":["buildFunctionDeclaration constructs a function declaration with parameters and return type and validates it with isFunctionDeclaration","buildAsyncFunctionDeclaration constructs an async function declaration returning a Promise type","buildFunctionParameter constructs parameter declarations with optional tokens and initializers","inspectFunctionDeclaration extracts structural function metadata using AST type guards"],"goal":"Construct and validate TypeScript function declarations using createFunctionDeclaration and createParameterDeclaration","kind":"HOW","packages":["pkg:npm/typescript@7.0.2"],"schemaVersion":1,"symbols":["createFunctionDeclaration","createParameterDeclaration"]},"contractCommand":["node","test/contract.mjs"],"environment":{"arch":"x64","distro":"ubuntu","ecosystem":"npm","libc":"glibc","libcVersion":"2.39","os":"linux","osVersionBucket":"24","packageManager":"npm","schemaVersion":1},"license":"MIT-0","packages":["pkg:npm/typescript@7.0.2"],"schemaVersion":1,"symbols":["createFunctionDeclaration","createParameterDeclaration"],"verifierAdapter":"node-typescript@1"}
package-lock.json
{
  "name": "typescript-function-declaration-sample",
  "version": "1.0.0",
  "lockfileVersion": 3,
  "requires": true,
  "packages": {
    "": {
      "name": "typescript-function-declaration-sample",
      "version": "1.0.0",
      "license": "MIT-0",
      "dependencies": {
        "typescript": "7.0.2"
      }
    },
    "node_modules/@typescript/typescript-aix-ppc64": {
      "version": "7.0.2",
      "resolved": "https://registry.npmjs.org/@typescript/typescript-aix-ppc64/-/typescript-aix-ppc64-7.0.2.tgz",
      "integrity": "sha512-MTKKkWB7p/0E9xi1d1tHtZ5PiLkGEMIq88pK2CubZjOsLtYTLqhgIgi6zepFa+9GHZ6h05NMCkQxGKiPXMxXtQ==",
      "cpu": [
        "ppc64"
      ],
      "license": "Apache-2.0",
      "optional": true,
      "os": [
        "aix"
      ],
      "engines": {
        "node": ">=16.20.0"
      }
    },
    "node_modules/@typescript/typescript-darwin-arm64": {
      "version": "7.0.2",
      "resolved": "https://registry.npmjs.org/@typescript/typescript-darwin-arm64/-/typescript-darwin-arm64-7.0.2.tgz",
      "integrity": "sha512-gowzar9MwS/aRWp6f3a4KUqzRjAZjOsmGNCM6LcTgXum+dBfgsBVMN+AgvOCCbguXyick6LJhpBszxMebJ8syA==",
      "cpu": [
        "arm64"
      ],
      "license": "Apache-2.0",
      "optional": true,
      "os": [
        "darwin"
      ],
      "engines": {
        "node": ">=16.20.0"
      }
    },
    "node_modules/@typescript/typescript-darwin-x64": {
      "version": "7.0.2",
      "resolved": "https://registry.npmjs.org/@typescript/typescript-darwin-x64/-/typescript-darwin-x64-7.0.2.tgz",
      "integrity": "sha512-SZ9xZInqApNlNGc9s0W1VSsktYSOe9cFqNOIqmN1Gs8SmkjKZYFt017G4VwPxASInODuAdbTW7sXiFUf893RgA==",
      "cpu": [
        "x64"
      ],
      "license": "Apache-2.0",
      "optional": true,
      "os": [
        "darwin"
      ],
      "engines": {
        "node": ">=16.20.0"
      }
    },
    "node_modules/@typescript/typescript-freebsd-arm64": {
      "version": "7.0.2",
      "resolved": "https://registry.npmjs.org/@typescript/typescript-freebsd-arm64/-/typescript-freebsd-arm64-7.0.2.tgz",
      "integrity": "sha512-W5NH4y/J0plIIS5b2xvTEkU7JFxyqdMAOgf+Ilhl0vHQXKO5dZoxd+C/jEtq56c4F3wk71RB4BMRQ2XdI+bwYQ==",
      "cpu": [
        "arm64"
      ],
      "license": "Apache-2.0",
      "optional": true,
      "os": [
        "freebsd"
      ],
      "engines": {
        "node": ">=16.20.0"
      }
    },
    "node_modules/@typescript/typescript-freebsd-x64": {
      "version": "7.0.2",
      "resolved": "https://registry.npmjs.org/@typescript/typescript-freebsd-x64/-/typescript-freebsd-x64-7.0.2.tgz",
      "integrity": "sha512-UMGDx5sTpzNw3WiPebH7l90IWfJggEd+egHt/q6p7/Cm3zqoV7VxkGXt+3DxPIw8CcmvAB0j3sVVfbhX+M4Tpw==",
      "cpu": [
        "x64"
      ],
      "license": "Apache-2.0",
      "optional": true,
      "os": [
        "freebsd"
      ],
      "engines": {
        "node": ">=16.20.0"
      }
    },
    "node_modules/@typescript/typescript-linux-arm": {
      "version": "7.0.2",
      "resolved": "https://registry.npmjs.org/@typescript/typescript-linux-arm/-/typescript-linux-arm-7.0.2.tgz",
      "integrity": "sha512-gffT3xPz9sR7j/YJExkyPntrI0P2EP9XbOyWzth2/Gs0RstK+90RBcO0ncXoXy/beYll1SXw846Nf2zdnEz0QQ==",
      "cpu": [
        "arm"
      ],
      "license": "Apache-2.0",
      "optional": true,
      "os": [
        "linux"
      ],
      "engines": {
        "node": ">=16.20.0"
      }
    },
    "node_modules/@typescript/typescript-linux-arm64": {
      "version": "7.0.2",
      "resolved": "https://registry.npmjs.org/@typescript/typescript-linux-arm64/-/typescript-linux-arm64-7.0.2.tgz",
      "integrity": "sha512-Qh4eU4/y3yDjnfjjyPYihMj5/ODIlmt+Bzu17OI+fiSRDW57QmU5SiN63exPRNJPKUzcc1INa1NXdrJ+MqHjUQ==",
      "cpu": [
        "arm64"
      ],
      "license": "Apache-2.0",
      "optional": true,
      "os": [
        "linux"
      ],
      "engines": {
        "node": ">=16.20.0"
      }
    },
    "node_modules/@typescript/typescript-linux-loong64": {
      "version": "7.0.2",
      "resolved": "https://registry.npmjs.org/@typescript/typescript-linux-loong64/-/typescript-linux-loong64-7.0.2.tgz",
      "integrity": "sha512-uEHck9i8hoAzXPiYRib1O7miOnz23SxIeVl6F4LXox+qov1K35jHcEW6VHKvZI+pyvl7fZEP4MCU5LYvIq1GuQ==",
      "cpu": [
        "loong64"
      ],
      "license": "Apache-2.0",
      "optional": true,
      "os": [
        "linux"
      ],
      "engines": {
        "node": ">=16.20.0"
      }
    },
    "node_modules/@typescript/typescript-linux-mips64el": {
      "version": "7.0.2",
      "resolved": "https://registry.npmjs.org/@typescript/typescript-linux-mips64el/-/typescript-linux-mips64el-7.0.2.tgz",
      "integrity": "sha512-R4KvAMnE43W5Qeqb0Ly56O3mWMWIAgsMyz36DCaycd5nbg/9kzm0liw3JocfRqyJY0KPmzFjbswozXyW0DnIYA==",
      "cpu": [
        "mips64el"
      ],
      "license": "Apache-2.0",
      "optional": true,
      "os": [
        "linux"
      ],
      "engines": {
        "node": ">=16.20.0"
      }
    },
    "node_modules/@typescript/typescript-linux-ppc64": {
      "version": "7.0.2",
      "resolved": "https://registry.npmjs.org/@typescript/typescript-linux-ppc64/-/typescript-linux-ppc64-7.0.2.tgz",
      "integrity": "sha512-DORx5b3sd/4S7eayxm4FQv+A7CrkUIGRaHiwI8oiHTAI1fAPWhF4J0vAlkC8biAlHSVVwxMQ3tjZ2/DVbnQiiA==",
      "cpu": [
        "ppc64"
      ],
      "license": "Apache-2.0",
      "optional": true,
      "os": [
        "linux"
      ],
      "engines": {
        "node": ">=16.20.0"
      }
    },
    "node_modules/@typescript/typescript-linux-riscv64": {
      "version": "7.0.2",
      "resolved": "https://registry.npmjs.org/@typescript/typescript-linux-riscv64/-/typescript-linux-riscv64-7.0.2.tgz",
      "integrity": "sha512-wf0jqEDOjrPRnKwYRyyJDRo11KMbvMFrU+q4zqKyChODBzvlkbhNQfKvLxQCcwTpdDaXSHZTVuh0JoCrKCUMHQ==",
      "cpu": [
        "riscv64"
      ],
      "license": "Apache-2.0",
      "optional": true,
      "os": [
        "linux"
      ],
      "engines": {
        "node": ">=16.20.0"
      }
    },
    "node_modules/@typescript/typescript-linux-s390x": {
      "version": "7.0.2",
      "resolved": "https://registry.npmjs.org/@typescript/typescript-linux-s390x/-/typescript-linux-s390x-7.0.2.tgz",
      "integrity": "sha512-IkwJc3L7yhytWd/ewjyxNDfOmswCm9GWMJT/ue/dU4aZNbwZeYAetq42VyLmsmSjvoX7z74X6ZaYCtzAr0EuGw==",
      "cpu": [
        "s390x"
      ],
      "license": "Apache-2.0",
      "optional": true,
      "os": [
        "linux"
      ],
      "engines": {
        "node": ">=16.20.0"
      }
    },
    "node_modules/@typescript/typescript-linux-x64": {
      "version": "7.0.2",
      "resolved": "https://registry.npmjs.org/@typescript/typescript-linux-x64/-/typescript-linux-x64-7.0.2.tgz",
      "integrity": "sha512-EYdf2cNg7rgCWJnxCdJ+F3V39O8ihb37eHAu1LK8oAFizgTQbPOK7zHHXbPt8rX24COqODXeI3sIf0fCXG7H/A==",
      "cpu": [
        "x64"
      ],
      "license": "Apache-2.0",
      "optional": true,
      "os": [
        "linux"
      ],
      "engines": {
        "node": ">=16.20.0"
      }
    },
    "node_modules/@typescript/typescript-netbsd-arm64": {
      "version": "7.0.2",
      "resolved": "https://registry.npmjs.org/@typescript/typescript-netbsd-arm64/-/typescript-netbsd-arm64-7.0.2.tgz",
      "integrity": "sha512-+polYF4MF04aPpO5FTkHran9yUQDSXqy5GiSDKpsll5jy3l3+g9QLhpf39T+ePtefhXLOGrLl0QIjkQP6VnelA==",
      "cpu": [
        "arm64"
      ],
      "license": "Apache-2.0",
      "optional": true,
      "os": [
        "netbsd"
      ],
      "engines": {
        "node": ">=16.20.0"
      }
    },
    "node_modules/@typescript/typescript-netbsd-x64": {
      "version": "7.0.2",
      "resolved": "https://registry.npmjs.org/@typescript/typescript-netbsd-x64/-/typescript-netbsd-x64-7.0.2.tgz",
      "integrity": "sha512-8YIT0EHM/3dq10ZOVF/A7pc/YSMtbcecct4rWtexrnSCHOPcpC2KTLXfTCR6vDpnSiY12heNb1GiN/wu+T/FyA==",
      "cpu": [
        "x64"
      ],
      "license": "Apache-2.0",
      "optional": true,
      "os": [
        "netbsd"
      ],
      "engines": {
        "node": ">=16.20.0"
      }
    },
    "node_modules/@typescript/typescript-openbsd-arm64": {
      "version": "7.0.2",
      "resolved": "https://registry.npmjs.org/@typescript/typescript-openbsd-arm64/-/typescript-openbsd-arm64-7.0.2.tgz",
      "integrity": "sha512-APT8+ClYnuYm1u9+kgGXoMj2VzWzcymwh2gNSQVySHfkRDGOTVkoWLjCmOQSaO+PoqQ57B0flRp9SA+7GnnkzQ==",
      "cpu": [
        "arm64"
      ],
      "license": "Apache-2.0",
      "optional": true,
      "os": [
        "openbsd"
      ],
      "engines": {
        "node": ">=16.20.0"
      }
    },
    "node_modules/@typescript/typescript-openbsd-x64": {
      "version": "7.0.2",
      "resolved": "https://registry.npmjs.org/@typescript/typescript-openbsd-x64/-/typescript-openbsd-x64-7.0.2.tgz",
      "integrity": "sha512-yX7s+Q0Dln0Dt9tEzZsAjXXR/+ytBM7AlglaqyeMPxQszJ1JhlJdZ6jLA+IzldHtflX81em7lDao1xXu+aRRkg==",
      "cpu": [
        "x64"
      ],
      "license": "Apache-2.0",
      "optional": true,
      "os": [
        "openbsd"
      ],
      "engines": {
        "node": ">=16.20.0"
      }
    },
    "node_modules/@typescript/typescript-sunos-x64": {
      "version": "7.0.2",
      "resolved": "https://registry.npmjs.org/@typescript/typescript-sunos-x64/-/typescript-sunos-x64-7.0.2.tgz",
      "integrity": "sha512-dLJDGaLZ1D4HPQn62u1n8mBDkJREwMsAkCdkwd4Ieqw+x3TUyTsqY0YiBCtE6H6OzzgGk3iuZ3vFWRS+E8/d1g==",
      "cpu": [
        "x64"
      ],
      "license": "Apache-2.0",
      "optional": true,
      "os": [
        "sunos"
      ],
      "engines": {
        "node": ">=16.20.0"
      }
    },
    "node_modules/@typescript/typescript-win32-arm64": {
      "version": "7.0.2",
      "resolved": "https://registry.npmjs.org/@typescript/typescript-win32-arm64/-/typescript-win32-arm64-7.0.2.tgz",
      "integrity": "sha512-Gyl1Vy6OsWesLzmq+EP0Fb7b4Nid5232AvcA2SFcdYreldpNtYFFofPjnt62y9hQy7VTaZp65ICJjuAQRaVcIQ==",
      "cpu": [
        "arm64"
      ],
      "license": "Apache-2.0",
      "optional": true,
      "os": [
        "win32"
      ],
      "engines": {
        "node": ">=16.20.0"
      }
    },
    "node_modules/@typescript/typescript-win32-x64": {
      "version": "7.0.2",
      "resolved": "https://registry.npmjs.org/@typescript/typescript-win32-x64/-/typescript-win32-x64-7.0.2.tgz",
      "integrity": "sha512-0BQ3HkAHHlKLSp1qRvf3SUhGpGsDuhB/jgFw75guyqbxJqEaS0Cw/VFO8i2nHglJUzQCRtMMR/IBAKE3ETMC4g==",
      "cpu": [
        "x64"
      ],
      "license": "Apache-2.0",
      "optional": true,
      "os": [
        "win32"
      ],
      "engines": {
        "node": ">=16.20.0"
      }
    },
    "node_modules/typescript": {
      "version": "7.0.2",
      "resolved": "https://registry.npmjs.org/typescript/-/typescript-7.0.2.tgz",
      "integrity": "sha512-8FYau96o3NKOhbjKi/qNvG/W5jhzxkbdm5sj9AbZ/5T5sWqn3hJgLfGx27sRKZWTvyzCP8dLRBTf5tBTSRVUNA==",
      "license": "Apache-2.0",
      "bin": {
        "tsc": "bin/tsc"
      },
      "engines": {
        "node": ">=16.20.0"
      },
      "optionalDependencies": {
        "@typescript/typescript-aix-ppc64": "7.0.2",
        "@typescript/typescript-darwin-arm64": "7.0.2",
        "@typescript/typescript-darwin-x64": "7.0.2",
        "@typescript/typescript-freebsd-arm64": "7.0.2",
        "@typescript/typescript-freebsd-x64": "7.0.2",
        "@typescript/typescript-linux-arm": "7.0.2",
        "@typescript/typescript-linux-arm64": "7.0.2",
        "@typescript/typescript-linux-loong64": "7.0.2",
        "@typescript/typescript-linux-mips64el": "7.0.2",
        "@typescript/typescript-linux-ppc64": "7.0.2",
        "@typescript/typescript-linux-riscv64": "7.0.2",
        "@typescript/typescript-linux-s390x": "7.0.2",
        "@typescript/typescript-linux-x64": "7.0.2",
        "@typescript/typescript-netbsd-arm64": "7.0.2",
        "@typescript/typescript-netbsd-x64": "7.0.2",
        "@typescript/typescript-openbsd-arm64": "7.0.2",
        "@typescript/typescript-openbsd-x64": "7.0.2",
        "@typescript/typescript-sunos-x64": "7.0.2",
        "@typescript/typescript-win32-arm64": "7.0.2",
        "@typescript/typescript-win32-x64": "7.0.2"
      }
    }
  }
}
package.json
{
  "name": "typescript-function-declaration-sample",
  "version": "1.0.0",
  "description": "Construct and validate TypeScript function declarations using createFunctionDeclaration and createParameterDeclaration",
  "type": "module",
  "main": "src/index.mjs",
  "scripts": {
    "test": "node test/contract.mjs"
  },
  "dependencies": {
    "typescript": "7.0.2"
  },
  "license": "MIT-0"
}
spec.json
{
  "schemaVersion": 1,
  "goal": "Construct and validate TypeScript function declarations using createFunctionDeclaration and createParameterDeclaration",
  "kind": "HOW",
  "packages": [
    "pkg:npm/typescript@7.0.2"
  ],
  "symbols": [
    "createFunctionDeclaration",
    "createParameterDeclaration"
  ]
}
src/index.mjs
import {
  createFunctionDeclaration,
  createParameterDeclaration,
  createReturnStatement,
  createBlock,
  createIdentifier,
  createToken,
  createTypeReferenceNode,
  createNumericLiteral,
  createStringLiteral,
  createBinaryExpression,
  createCallExpression,
} from 'typescript/unstable/ast/factory';

import {
  isFunctionDeclaration,
  isParameterDeclaration,
  isReturnStatement,
  isBlock,
  isIdentifier,
  isToken,
  isBinaryExpression,
  isCallExpression,
  isStringLiteral,
  isNumericLiteral,
  isTypeReferenceNode,
  SyntaxKind,
  formatSyntaxKind,
} from 'typescript/unstable/ast';

/**
 * Builds a ParameterDeclaration AST node using createParameterDeclaration.
 *
 * @param {string | object} name - Parameter name identifier or string.
 * @param {string | object} [typeName] - Type name or TypeNode.
 * @param {object} [options={}] - Optional parameter configuration.
 * @param {boolean} [options.isOptional=false] - Whether the parameter has a question token.
 * @param {object} [options.initializer] - Default expression initializer.
 * @returns {object} ParameterDeclaration AST node.
 */
export function buildFunctionParameter(name, typeName, options = {}) {
  const nameIdentifier = typeof name === 'string' ? createIdentifier(name) : name;
  const typeNode = typeName
    ? typeof typeName === 'string'
      ? createTypeReferenceNode(createIdentifier(typeName), undefined)
      : typeName
    : undefined;
  const initializer = options.initializer !== undefined ? options.initializer : undefined;
  const questionToken = options.isOptional ? createToken(SyntaxKind.QuestionToken) : undefined;

  return createParameterDeclaration(
    undefined,
    undefined,
    nameIdentifier,
    questionToken,
    typeNode,
    initializer
  );
}

/**
 * Builds a FunctionDeclaration AST node using createFunctionDeclaration.
 *
 * @param {string | object} name - Function name identifier or string.
 * @param {Array<object>} [parameters=[]] - Parameter declaration list.
 * @param {string | object} [returnType] - Return type name or TypeNode.
 * @param {Array<object>} [bodyStatements=[]] - Statements for the function body.
 * @param {object} [options={}] - Optional configuration.
 * @param {boolean} [options.isExported=false] - Whether to include an ExportKeyword modifier.
 * @param {boolean} [options.isDefault=false] - Whether to include a DefaultKeyword modifier.
 * @param {boolean} [options.isAsync=false] - Whether to include an AsyncKeyword modifier.
 * @param {boolean} [options.hasNoBody=false] - Whether this is an ambient/signature declaration without a body.
 * @returns {object} FunctionDeclaration AST node.
 */
export function buildFunctionDeclaration(name, parameters = [], returnType = undefined, bodyStatements = [], options = {}) {
  const nameIdentifier = typeof name === 'string' ? createIdentifier(name) : name;
  const modifiers = [];
  if (options.isExported) {
    modifiers.push(createToken(SyntaxKind.ExportKeyword));
  }
  if (options.isDefault) {
    modifiers.push(createToken(SyntaxKind.DefaultKeyword));
  }
  if (options.isAsync) {
    modifiers.push(createToken(SyntaxKind.AsyncKeyword));
  }

  const paramNodes = parameters.map((p) => {
    if (p && isParameterDeclaration(p)) {
      return p;
    }
    return buildFunctionParameter(p.name, p.type, p);
  });

  const returnTypeNode = returnType
    ? typeof returnType === 'string'
      ? createTypeReferenceNode(createIdentifier(returnType), undefined)
      : returnType
    : undefined;

  const body = options.hasNoBody ? undefined : createBlock(bodyStatements, true);

  return createFunctionDeclaration(
    modifiers.length > 0 ? modifiers : undefined,
    undefined,
    nameIdentifier,
    undefined,
    paramNodes,
    returnTypeNode,
    body
  );
}

/**
 * Builds an async FunctionDeclaration AST node returning a Promise type.
 *
 * @param {string | object} name - Function name.
 * @param {Array<object>} [parameters=[]] - Parameters.
 * @param {string | object} [returnInnerType] - Inner type of Promise<T>.
 * @param {Array<object>} [bodyStatements=[]] - Body statements.
 * @param {object} [options={}] - Options.
 * @returns {object} Async FunctionDeclaration AST node.
 */
export function buildAsyncFunctionDeclaration(name, parameters = [], returnInnerType = undefined, bodyStatements = [], options = {}) {
  const returnTypeNode = returnInnerType
    ? createTypeReferenceNode(createIdentifier('Promise'), [
        typeof returnInnerType === 'string'
          ? createTypeReferenceNode(createIdentifier(returnInnerType), undefined)
          : returnInnerType,
      ])
    : createTypeReferenceNode(createIdentifier('Promise'), [
        createTypeReferenceNode(createIdentifier('void'), undefined),
      ]);

  return buildFunctionDeclaration(name, parameters, returnTypeNode, bodyStatements, {
    ...options,
    isAsync: true,
  });
}

/**
 * Inspects a FunctionDeclaration node and returns structured metadata using AST type guards.
 *
 * @param {object} node - AST node to inspect.
 * @returns {{
 *   kind: number,
 *   kindName: string,
 *   isFunctionDeclaration: boolean,
 *   name: string,
 *   isExported: boolean,
 *   isAsync: boolean,
 *   parameterCount: number,
 *   parameters: Array<{ name: string, isOptional: boolean, hasInitializer: boolean }>,
 *   hasBody: boolean
 * }}
 */
export function inspectFunctionDeclaration(node) {
  if (!node || typeof node !== 'object') {
    throw new TypeError('Expected an AST node object');
  }

  const isFn = isFunctionDeclaration(node);
  if (!isFn) {
    return {
      kind: node.kind,
      kindName: formatSyntaxKind(node.kind),
      isFunctionDeclaration: false,
      name: '',
      isExported: false,
      isAsync: false,
      parameterCount: 0,
      parameters: [],
      hasBody: false,
    };
  }

  const modifiers = node.modifiers || [];
  const isExported = Array.isArray(modifiers) && modifiers.some((m) => m.kind === SyntaxKind.ExportKeyword);
  const isAsync = Array.isArray(modifiers) && modifiers.some((m) => m.kind === SyntaxKind.AsyncKeyword);

  const rawName = node.name ? (node.name._data?.text ?? node.name.text ?? '') : '';

  const rawParams = node.parameters || [];
  const parameters = rawParams.map((p) => ({
    name: p.name ? (p.name._data?.text ?? p.name.text ?? '') : '',
    isOptional: p.questionToken !== undefined,
    hasInitializer: p.initializer !== undefined,
  }));

  return {
    kind: node.kind,
    kindName: formatSyntaxKind(node.kind),
    isFunctionDeclaration: true,
    name: rawName,
    isExported,
    isAsync,
    parameterCount: parameters.length,
    parameters,
    hasBody: node.body !== undefined && isBlock(node.body),
  };
}

export {
  createFunctionDeclaration,
  createParameterDeclaration,
  createReturnStatement,
  createBlock,
  createIdentifier,
  createToken,
  createTypeReferenceNode,
  createNumericLiteral,
  createStringLiteral,
  createBinaryExpression,
  createCallExpression,
  isFunctionDeclaration,
  isParameterDeclaration,
  isReturnStatement,
  isBlock,
  isIdentifier,
  isToken,
  isBinaryExpression,
  isCallExpression,
  isStringLiteral,
  isNumericLiteral,
  isTypeReferenceNode,
  SyntaxKind,
  formatSyntaxKind,
};
test/contract.mjs
import assert from 'node:assert/strict';
import {
  buildFunctionDeclaration,
  buildAsyncFunctionDeclaration,
  buildFunctionParameter,
  inspectFunctionDeclaration,
  createReturnStatement,
  createIdentifier,
  createNumericLiteral,
  createStringLiteral,
  createBinaryExpression,
  createToken,
  isFunctionDeclaration,
  isParameterDeclaration,
  isReturnStatement,
  isBlock,
  isTypeReferenceNode,
  isNumericLiteral,
  isStringLiteral,
  SyntaxKind,
  formatSyntaxKind,
} from '../src/index.mjs';

// Contract 1: buildFunctionDeclaration constructs a function declaration with parameters and return type and validates it with isFunctionDeclaration
{
  const paramA = buildFunctionParameter('a', 'number');
  const paramB = buildFunctionParameter('b', 'number');
  const returnStmt = createReturnStatement(
    createBinaryExpression(
      createIdentifier('a'),
      createToken(SyntaxKind.PlusToken),
      createIdentifier('b')
    )
  );

  const fnNode = buildFunctionDeclaration('add', [paramA, paramB], 'number', [returnStmt], { isExported: true });

  assert.ok(fnNode, 'Function declaration should be created');
  assert.strictEqual(isFunctionDeclaration(fnNode), true, 'Node should satisfy isFunctionDeclaration');
  assert.strictEqual(formatSyntaxKind(fnNode.kind), 'FunctionDeclaration', 'Kind name should be FunctionDeclaration');
  assert.strictEqual(fnNode.parameters.length, 2, 'Should have 2 parameters');
  assert.strictEqual(isParameterDeclaration(fnNode.parameters[0]), true, 'First parameter should be ParameterDeclaration');
  assert.strictEqual(isParameterDeclaration(fnNode.parameters[1]), true, 'Second parameter should be ParameterDeclaration');
  assert.strictEqual(isBlock(fnNode.body), true, 'Body should be a Block statement');
  assert.strictEqual(isReturnStatement(fnNode.body.statements[0]), true, 'Inner statement should be ReturnStatement');
}

// Contract 2: buildAsyncFunctionDeclaration constructs an async function declaration returning a Promise type
{
  const paramId = buildFunctionParameter('userId', 'string');
  const returnStmt = createReturnStatement(createStringLiteral('"user-data"'));

  const asyncFn = buildAsyncFunctionDeclaration('fetchUser', [paramId], 'string', [returnStmt], { isExported: true });

  assert.ok(asyncFn, 'Async function should be created');
  assert.strictEqual(isFunctionDeclaration(asyncFn), true, 'Should satisfy isFunctionDeclaration');
  assert.ok(asyncFn.modifiers.some((m) => m.kind === SyntaxKind.AsyncKeyword), 'Should contain AsyncKeyword modifier');
  assert.ok(asyncFn.modifiers.some((m) => m.kind === SyntaxKind.ExportKeyword), 'Should contain ExportKeyword modifier');
  assert.strictEqual(isTypeReferenceNode(asyncFn.type), true, 'Return type should be TypeReferenceNode');
  assert.strictEqual(asyncFn.type.typeName.text, 'Promise', 'Return typeName should be Promise');
}

// Contract 3: buildFunctionParameter constructs parameter declarations with optional tokens and initializers
{
  const optParam = buildFunctionParameter('prefix', 'string', { isOptional: true });
  assert.strictEqual(isParameterDeclaration(optParam), true, 'Should be ParameterDeclaration');
  assert.strictEqual(optParam.name.text, 'prefix', 'Name should be prefix');
  assert.strictEqual(optParam.questionToken.kind, SyntaxKind.QuestionToken, 'Should have QuestionToken');

  const defaultParam = buildFunctionParameter('count', 'number', { initializer: createNumericLiteral('10') });
  assert.strictEqual(isParameterDeclaration(defaultParam), true, 'Should be ParameterDeclaration');
  assert.strictEqual(defaultParam.name.text, 'count', 'Name should be count');
  assert.strictEqual(isNumericLiteral(defaultParam.initializer), true, 'Initializer should be NumericLiteral');
}

// Contract 4: inspectFunctionDeclaration extracts structural function metadata using AST type guards
{
  const fn = buildFunctionDeclaration(
    'calculateTotal',
    [
      { name: 'price', type: 'number' },
      { name: 'taxRate', type: 'number', isOptional: true },
    ],
    'number',
    [createReturnStatement(createNumericLiteral('0'))],
    { isExported: true }
  );

  const info = inspectFunctionDeclaration(fn);
  assert.strictEqual(info.isFunctionDeclaration, true, 'isFunctionDeclaration should be true');
  assert.strictEqual(info.kindName, 'FunctionDeclaration', 'kindName should be FunctionDeclaration');
  assert.strictEqual(info.name, 'calculateTotal', 'name should match calculateTotal');
  assert.strictEqual(info.isExported, true, 'isExported should be true');
  assert.strictEqual(info.isAsync, false, 'isAsync should be false');
  assert.strictEqual(info.parameterCount, 2, 'parameterCount should be 2');
  assert.strictEqual(info.parameters[0].name, 'price', 'First param name should be price');
  assert.strictEqual(info.parameters[1].isOptional, true, 'Second param should be optional');
  assert.strictEqual(info.hasBody, true, 'hasBody should be true');

  assert.throws(
    () => inspectFunctionDeclaration(null),
    { name: 'TypeError' },
    'inspectFunctionDeclaration should throw TypeError on null input'
  );
}

console.log('All pkg:npm/typescript@7.0.2 contracts passed successfully.');

Seeder d'origine

anonyme