{"_id":"@bakes/dastardly-core","name":"@bakes/dastardly-core","dist-tags":{"latest":"1.0.0"},"versions":{"1.0.0":{"name":"@bakes/dastardly-core","version":"1.0.0","description":"Core AST types and utilities for dASTardly","main":"dist/index.js","types":"dist/index.d.ts","type":"module","exports":{".":{"types":"./dist/index.d.ts","import":"./dist/index.js","default":"./dist/index.js"}},"keywords":["ast","parser","tree"],"author":{"name":"The Software Bakery"},"license":"MIT","repository":{"type":"git","url":"git+https://github.com/thesoftwarebakery/dastardly.git","directory":"packages/core"},"homepage":"https://github.com/thesoftwarebakery/dastardly#readme","bugs":{"url":"https://github.com/thesoftwarebakery/dastardly/issues"},"publishConfig":{"access":"public"},"dependencies":{"json-pointer":"^0.6.2","object-hash":"^3.0.0"},"devDependencies":{"@types/json-pointer":"^1.0.34","@types/object-hash":"^3.0.6","@vitest/ui":"^4.0.8","typescript":"^5.3.0","vitest":"^1.6.1"},"scripts":{"build":"tsc","typecheck":"tsc --noEmit","test":"vitest run","test:watch":"vitest"},"_id":"@bakes/dastardly-core@1.0.0","_integrity":"sha512-0rg0hlt2GX3wBpE/xo64uB57D5Bw8E5NLDfuYay+Y/7jVj5sbcc3IacFJDjZcvSPEPleeq2O13LftqUQ7e8OOA==","_resolved":"/tmp/894d0da355655c69d384bc51721a20bc/bakes-dastardly-core-1.0.0.tgz","_from":"file:bakes-dastardly-core-1.0.0.tgz","_nodeVersion":"20.19.5","_npmVersion":"10.8.2","dist":{"integrity":"sha512-0rg0hlt2GX3wBpE/xo64uB57D5Bw8E5NLDfuYay+Y/7jVj5sbcc3IacFJDjZcvSPEPleeq2O13LftqUQ7e8OOA==","shasum":"e8724e1f95d380c1b6c451fae6643ba7f4b8409f","tarball":"https://registry.npmjs.org/@bakes/dastardly-core/-/dastardly-core-1.0.0.tgz","fileCount":43,"unpackedSize":74417,"attestations":{"url":"https://registry.npmjs.org/-/npm/v1/attestations/@bakes%2fdastardly-core@1.0.0","provenance":{"predicateType":"https://slsa.dev/provenance/v1"}},"signatures":[{"keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U","sig":"MEUCIHFL5vxJiR8N8SFOBP4zms0LicQ62c6FfXZ9AvnGX5pZAiEAhG3lifXmyncrzud5HV/jseO72x4m/J3P0alzYrO/iNg="}]},"_npmUser":{"name":"georgewaters","email":"george@bakes.software"},"directories":{},"maintainers":[{"name":"georgewaters","email":"george@bakes.software"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages-npm-production","tmp":"tmp/dastardly-core_1.0.0_1763161239091_0.29300227368878784"},"_hasShrinkwrap":false}},"time":{"created":"2025-11-14T23:00:39.028Z","1.0.0":"2025-11-14T23:00:39.321Z","modified":"2025-11-14T23:00:40.633Z"},"maintainers":[{"name":"georgewaters","email":"george@bakes.software"}],"description":"Core AST types and utilities for dASTardly","homepage":"https://github.com/thesoftwarebakery/dastardly#readme","keywords":["ast","parser","tree"],"repository":{"type":"git","url":"git+https://github.com/thesoftwarebakery/dastardly.git","directory":"packages/core"},"author":{"name":"The Software Bakery"},"bugs":{"url":"https://github.com/thesoftwarebakery/dastardly/issues"},"license":"MIT","readme":"# @bakes/dastardly-core\n\nCore AST types and utilities for dASTardly - a high-performance, format-agnostic Abstract Syntax Tree for data interchange formats.\n\n## Installation\n\n```bash\nnpm install @bakes/dastardly-core\n```\n\n```bash\npnpm add @bakes/dastardly-core\n```\n\n## Overview\n\n`@bakes/dastardly-core` provides the foundational types and utilities for building and working with dASTardly ASTs. It defines a format-agnostic representation of structured data that can be used across JSON, YAML, XML, CSV, and other formats.\n\n**Key Features:**\n- **Format-agnostic AST types** - Common representation for all data formats\n- **Position tracking** - Every node tracks source location (line, column, offset)\n- **Type-safe** - Full TypeScript support with discriminated unions\n- **Builder functions** - Convenient constructors for AST nodes\n- **Type guards** - Runtime type checking utilities\n- **Traversal utilities** - Visitor pattern for AST manipulation\n- **Immutable** - All nodes use readonly properties\n\n## Quick Start\n\n```typescript\nimport {\n  documentNode,\n  objectNode,\n  propertyNode,\n  stringNode,\n  numberNode,\n  position,\n  sourceLocation,\n} from '@bakes/dastardly-core';\n\n// Create a simple AST\nconst loc = sourceLocation(\n  position(1, 0, 0),\n  position(1, 20, 20),\n  'json'\n);\n\nconst ast = documentNode(\n  objectNode([\n    propertyNode(\n      stringNode('name', loc),\n      stringNode('Alice', loc),\n      loc\n    ),\n    propertyNode(\n      stringNode('age', loc),\n      numberNode(30, loc),\n      loc\n    ),\n  ], loc),\n  loc\n);\n\nconsole.log(ast.body.type); // 'Object'\nconsole.log(ast.body.properties[0].key.value); // 'name'\n```\n\n## API Reference\n\n### Types\n\n#### Position\n\nRepresents a position in source text:\n\n```typescript\ninterface Position {\n  readonly line: number;   // 1-indexed line number\n  readonly column: number; // 0-indexed column number\n  readonly offset: number; // Byte offset from start\n}\n```\n\n#### SourceLocation\n\nRepresents a range in source text:\n\n```typescript\ninterface SourceLocation {\n  readonly start: Position;\n  readonly end: Position;\n  readonly source?: string; // Source format (e.g., 'json', 'yaml')\n}\n```\n\n#### AST Node Types\n\nAll AST nodes extend the base `ASTNode` interface:\n\n```typescript\ninterface ASTNode {\n  readonly type: string;\n  readonly loc: SourceLocation;\n}\n```\n\n**Value Nodes:**\n- `StringNode` - String values\n- `NumberNode` - Numeric values\n- `BooleanNode` - Boolean values\n- `NullNode` - Null values\n\n**Container Nodes:**\n- `ObjectNode` - Key-value pairs (objects/maps)\n- `ArrayNode` - Ordered lists\n- `PropertyNode` - Object property (key-value pair)\n\n**Document:**\n- `DocumentNode` - Root document node containing a single data value\n\n**Type Aliases:**\n- `ValueNode` - Union of primitive value nodes\n- `DataNode` - Union of all value and container nodes\n- `ContainerNode` - Union of Object and Array nodes\n\n### Builder Functions\n\nBuilder functions provide a convenient way to create AST nodes:\n\n#### `position(line, column, offset)`\n\nCreate a Position:\n\n```typescript\nconst pos = position(1, 0, 0);\n```\n\n#### `sourceLocation(start, end, source?)`\n\nCreate a SourceLocation:\n\n```typescript\nconst loc = sourceLocation(\n  position(1, 0, 0),\n  position(1, 10, 10),\n  'json'\n);\n```\n\n#### Value Node Builders\n\n```typescript\n// String node\nconst str = stringNode('hello', loc);\nconst strWithRaw = stringNode('hello', loc, '\"hello\"');\n\n// Number node\nconst num = numberNode(42, loc);\nconst numWithRaw = numberNode(3.14, loc, '3.14');\n\n// Boolean node\nconst bool = booleanNode(true, loc);\nconst boolWithRaw = booleanNode(false, loc, 'false');\n\n// Null node\nconst nil = nullNode(loc);\nconst nilWithRaw = nullNode(loc, 'null');\n```\n\nAll value nodes accept an optional third `raw` parameter to preserve the original source representation.\n\n#### Container Node Builders\n\n```typescript\n// Property node (key-value pair)\nconst prop = propertyNode(\n  stringNode('key', loc),\n  stringNode('value', loc),\n  loc\n);\n\n// Object node\nconst obj = objectNode([prop1, prop2], loc);\n\n// Array node\nconst arr = arrayNode([str, num, bool], loc);\n```\n\n#### Document Node\n\n```typescript\nconst doc = documentNode(obj, loc);\n```\n\n### Type Guards\n\nType guards provide runtime type checking for AST nodes:\n\n```typescript\nimport {\n  isObjectNode,\n  isArrayNode,\n  isStringNode,\n  isNumberNode,\n  isBooleanNode,\n  isNullNode,\n  isValueNode,\n  isContainerNode,\n  isDocumentNode,\n  isPropertyNode,\n} from '@bakes/dastardly-core';\n\nif (isObjectNode(node)) {\n  // TypeScript knows node is ObjectNode\n  console.log(node.properties);\n}\n\nif (isValueNode(node)) {\n  // node is StringNode | NumberNode | BooleanNode | NullNode\n}\n\nif (isContainerNode(node)) {\n  // node is ObjectNode | ArrayNode\n}\n```\n\n### Traversal\n\nTraverse and manipulate AST nodes using the visitor pattern:\n\n#### `visit(node, visitor)`\n\nVisit nodes with a visitor object:\n\n```typescript\nimport { visit } from '@bakes/dastardly-core';\n\nvisit(ast, {\n  String(node) {\n    console.log('Found string:', node.value);\n  },\n  Number(node) {\n    console.log('Found number:', node.value);\n  },\n});\n```\n\n#### `traverse(node, callback)`\n\nTraverse all nodes with a callback:\n\n```typescript\nimport { traverse } from '@bakes/dastardly-core';\n\ntraverse(ast, (node) => {\n  console.log(node.type, node.loc);\n});\n```\n\n#### `findAll(node, predicate)`\n\nFind all nodes matching a predicate:\n\n```typescript\nimport { findAll, isStringNode } from '@bakes/dastardly-core';\n\nconst stringNodes = findAll(ast, isStringNode);\n```\n\n#### `findFirst(node, predicate)`\n\nFind the first node matching a predicate:\n\n```typescript\nimport { findFirst, isNumberNode } from '@bakes/dastardly-core';\n\nconst firstNumber = findFirst(ast, isNumberNode);\n```\n\n#### `getChildren(node)`\n\nGet direct children of a node:\n\n```typescript\nimport { getChildren } from '@bakes/dastardly-core';\n\nconst children = getChildren(objectNode);\n// Returns array of PropertyNodes\n```\n\n### Utilities\n\n#### `toNative(node)`\n\nConvert AST to native JavaScript values:\n\n```typescript\nimport { toNative } from '@bakes/dastardly-core';\n\nconst obj = objectNode([\n  propertyNode(\n    stringNode('name', loc),\n    stringNode('Alice', loc),\n    loc\n  ),\n], loc);\n\nconst native = toNative(obj);\n// { name: 'Alice' }\n```\n\nConverts:\n- `ObjectNode` → Plain JavaScript object\n- `ArrayNode` → JavaScript array\n- `StringNode` → string\n- `NumberNode` → number\n- `BooleanNode` → boolean\n- `NullNode` → null\n\n## Type Safety\n\nAll AST types use TypeScript discriminated unions for proper type narrowing:\n\n```typescript\nfunction processNode(node: DataNode) {\n  switch (node.type) {\n    case 'Object':\n      // TypeScript knows node is ObjectNode\n      node.properties.forEach(prop => {\n        console.log(prop.key.value);\n      });\n      break;\n    case 'Array':\n      // TypeScript knows node is ArrayNode\n      node.elements.forEach(el => {\n        console.log(el.type);\n      });\n      break;\n    case 'String':\n      // TypeScript knows node is StringNode\n      console.log(node.value);\n      break;\n    // ... handle other types\n  }\n}\n```\n\n## Position Tracking\n\nEvery node includes precise source location information:\n\n```typescript\nconst node = stringNode('hello', sourceLocation(\n  position(1, 5, 5),   // line 1, column 5, offset 5\n  position(1, 12, 12), // line 1, column 12, offset 12\n  'json'\n));\n\nconsole.log(node.loc.start.line);    // 1\nconsole.log(node.loc.start.column);  // 5\nconsole.log(node.loc.source);        // 'json'\n```\n\nThis enables:\n- Precise error reporting with line/column numbers\n- Source maps for transformations\n- Cross-format error mapping\n\n## Examples\n\n### Building Complex AST\n\n```typescript\nimport {\n  documentNode,\n  objectNode,\n  arrayNode,\n  propertyNode,\n  stringNode,\n  numberNode,\n  booleanNode,\n  position,\n  sourceLocation,\n} from '@bakes/dastardly-core';\n\nconst loc = sourceLocation(\n  position(1, 0, 0),\n  position(10, 0, 100),\n  'json'\n);\n\nconst ast = documentNode(\n  objectNode([\n    propertyNode(\n      stringNode('users', loc),\n      arrayNode([\n        objectNode([\n          propertyNode(stringNode('name', loc), stringNode('Alice', loc), loc),\n          propertyNode(stringNode('age', loc), numberNode(30, loc), loc),\n          propertyNode(stringNode('active', loc), booleanNode(true, loc), loc),\n        ], loc),\n        objectNode([\n          propertyNode(stringNode('name', loc), stringNode('Bob', loc), loc),\n          propertyNode(stringNode('age', loc), numberNode(25, loc), loc),\n          propertyNode(stringNode('active', loc), booleanNode(false, loc), loc),\n        ], loc),\n      ], loc),\n      loc\n    ),\n  ], loc),\n  loc\n);\n```\n\n### Traversing and Transforming\n\n```typescript\nimport { visit, isStringNode } from '@bakes/dastardly-core';\n\n// Collect all string values\nconst strings: string[] = [];\nvisit(ast, {\n  String(node) {\n    strings.push(node.value);\n  },\n});\n\n// Find all objects with a specific property\nconst usersWithAge = findAll(ast, (node) => {\n  if (!isObjectNode(node)) return false;\n  return node.properties.some(\n    prop => isStringNode(prop.key) && prop.key.value === 'age'\n  );\n});\n```\n\n### Converting to Native Values\n\n```typescript\nimport { toNative, parseValue } from '@bakes/dastardly-json';\n\nconst ast = parseValue('{\"name\": \"Alice\", \"age\": 30}');\nconst obj = toNative(ast);\n\nconsole.log(obj.name); // 'Alice'\nconsole.log(obj.age);  // 30\n```\n\n## Related Packages\n\n- **[@bakes/dastardly-json](https://www.npmjs.com/package/@bakes/dastardly-json)** - JSON parser and serializer\n- **[@bakes/dastardly-tree-sitter-runtime](https://www.npmjs.com/package/@bakes/dastardly-tree-sitter-runtime)** - Tree-sitter runtime abstraction\n- **[@bakes/dastardly-yaml](https://www.npmjs.com/package/@bakes/dastardly-yaml)** - YAML parser and serializer (coming soon)\n\n## Documentation\n\nFor more information:\n- [Main Repository](https://github.com/thesoftwarebakery/dastardly)\n- [Architecture Documentation](https://github.com/thesoftwarebakery/dastardly/blob/main/ARCHITECTURE.md)\n- [Contributing Guide](https://github.com/thesoftwarebakery/dastardly/blob/main/CONTRIBUTING.md)\n\n## License\n\nMIT\n","readmeFilename":"README.md","_rev":"1-3f7df455f053ad8c09587d312ef37c14"}