@posthog/hogql-parser 0.0.1 → 0.0.3

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
@@ -1,45 +1,98 @@
1
- # @posthog/hogql-parser
1
+ # HogQL Parser
2
2
 
3
- ## ⚠️ IMPORTANT NOTICE ⚠️
3
+ ANTLR4-based parser for [HogQL](https://posthog.com/docs/hogql) and [Hog](https://posthog.com/docs/hog),
4
+ available as both a Python C++ extension and a WebAssembly module for JavaScript/TypeScript.
4
5
 
5
- **This package is created solely for the purpose of setting up OIDC (OpenID Connect) trusted publishing with npm.**
6
+ ## Packages
6
7
 
7
- This is **NOT** a functional package and contains **NO** code or functionality beyond the OIDC setup configuration.
8
+ | Package | Runtime | Registry |
9
+ | ----------------------- | -------------------------------- | ---------------------------------------------------------- |
10
+ | `hogql_parser` | CPython (native C++ extension) | [PyPI](https://pypi.org/project/hogql-parser/) |
11
+ | `@posthog/hogql-parser` | Any JS environment (WebAssembly) | [npm](https://www.npmjs.com/package/@posthog/hogql-parser) |
8
12
 
9
- ## Purpose
13
+ Both packages share the same C++ parser core and ANTLR4 grammar,
14
+ so they produce identical ASTs.
10
15
 
11
- This package exists to:
12
- 1. Configure OIDC trusted publishing for the package name `@posthog/hogql-parser`
13
- 2. Enable secure, token-less publishing from CI/CD workflows
14
- 3. Establish provenance for packages published under this name
16
+ ## npm package (`@posthog/hogql-parser`)
15
17
 
16
- ## What is OIDC Trusted Publishing?
18
+ ### Installation
17
19
 
18
- OIDC trusted publishing allows package maintainers to publish packages directly from their CI/CD workflows without needing to manage npm access tokens. Instead, it uses OpenID Connect to establish trust between the CI/CD provider (like GitHub Actions) and npm.
20
+ ```bash
21
+ npm install @posthog/hogql-parser
22
+ ```
19
23
 
20
- ## Setup Instructions
24
+ ### Usage
21
25
 
22
- To properly configure OIDC trusted publishing for this package:
26
+ ```typescript
27
+ import createHogQLParser from '@posthog/hogql-parser'
23
28
 
24
- 1. Go to [npmjs.com](https://www.npmjs.com/) and navigate to your package settings
25
- 2. Configure the trusted publisher (e.g., GitHub Actions)
26
- 3. Specify the repository and workflow that should be allowed to publish
27
- 4. Use the configured workflow to publish your actual package
29
+ const parser = await createHogQLParser()
28
30
 
29
- ## DO NOT USE THIS PACKAGE
31
+ // Parse a HogQL expression
32
+ const exprAST = JSON.parse(parser.parseExpr('1 + 2'))
30
33
 
31
- This package is a placeholder for OIDC configuration only. It:
32
- - Contains no executable code
33
- - Provides no functionality
34
- - Should not be installed as a dependency
35
- - Exists only for administrative purposes
34
+ // Parse a SELECT statement
35
+ const selectAST = JSON.parse(parser.parseSelect('SELECT event FROM events WHERE timestamp > now()'))
36
36
 
37
- ## More Information
37
+ // Parse a Hog program
38
+ const programAST = JSON.parse(parser.parseProgram('let x := 42; return x;'))
39
+ ```
38
40
 
39
- For more details about npm's trusted publishing feature, see:
40
- - [npm Trusted Publishing Documentation](https://docs.npmjs.com/generating-provenance-statements)
41
- - [GitHub Actions OIDC Documentation](https://docs.github.com/en/actions/deployment/security-hardening-your-deployments/about-security-hardening-with-openid-connect)
41
+ All parse functions return JSON strings.
42
+ On failure they return a JSON error object instead of throwing:
42
43
 
43
- ---
44
+ ```typescript
45
+ const result = JSON.parse(parser.parseExpr('!!!'))
46
+ if ('error' in result) {
47
+ console.error(result.type, result.message) // e.g. "SyntaxError ..."
48
+ }
49
+ ```
44
50
 
45
- **Maintained for OIDC setup purposes only**
51
+ ### API
52
+
53
+ | Method | Description |
54
+ | --------------------------------------------- | ---------------------------------- |
55
+ | `parseExpr(input, isInternal?)` | Parse a HogQL expression |
56
+ | `parseSelect(input, isInternal?)` | Parse a SELECT statement |
57
+ | `parseOrderExpr(input, isInternal?)` | Parse an ORDER BY expression |
58
+ | `parseProgram(input, isInternal?)` | Parse a Hog program |
59
+ | `parseFullTemplateString(input, isInternal?)` | Parse a template string (`f'...'`) |
60
+ | `parseStringLiteralText(input)` | Unquote a string literal |
61
+
62
+ Setting `isInternal` to `true` omits position information from the AST.
63
+
64
+ ## Python package (`hogql_parser`)
65
+
66
+ ### Installation
67
+
68
+ ```bash
69
+ pip install hogql_parser
70
+ ```
71
+
72
+ The Python package is a native C++ extension and requires a platform with prebuilt wheels
73
+ (macOS and Linux, x86_64 and arm64).
74
+
75
+ ### Local development
76
+
77
+ ```bash
78
+ pip install ./common/hogql_parser
79
+ ```
80
+
81
+ ## Building from source
82
+
83
+ ### Python
84
+
85
+ ```bash
86
+ pip install ./common/hogql_parser
87
+ ```
88
+
89
+ ### WebAssembly
90
+
91
+ Requires the [Emscripten](https://emscripten.org/) toolchain and [Ninja](https://ninja-build.org/).
92
+
93
+ ```bash
94
+ cd common/hogql_parser
95
+ npm run build
96
+ ```
97
+
98
+ This compiles the parser to WASM and places the output in `dist/`.
Binary file
package/dist/index.cjs ADDED
@@ -0,0 +1,5 @@
1
+ // CommonJS wrapper for the ES module WASM build
2
+ // This allows Jest and other CommonJS environments to import the module
3
+
4
+ module.exports = () => import('./hogql_parser_wasm.js').then(m => m.default);
5
+ module.exports.default = module.exports;
@@ -0,0 +1,157 @@
1
+ /**
2
+ * HogQL Parser WebAssembly Module
3
+ *
4
+ * High-performance HogQL parser compiled to WebAssembly.
5
+ * All parse functions return JSON strings that should be parsed with JSON.parse().
6
+ */
7
+
8
+ /**
9
+ * AST Position information
10
+ */
11
+ export interface Position {
12
+ line: number
13
+ column: number
14
+ offset: number
15
+ }
16
+
17
+ /**
18
+ * Base AST node with position information
19
+ */
20
+ export interface ASTNode {
21
+ node: string
22
+ start: Position
23
+ end: Position
24
+ [key: string]: any
25
+ }
26
+
27
+ /**
28
+ * Parse error object
29
+ */
30
+ export interface ParseError {
31
+ error: true
32
+ type: 'SyntaxError' | 'ParsingError' | 'NotImplementedError'
33
+ message: string
34
+ start: Position
35
+ end: Position
36
+ }
37
+
38
+ /**
39
+ * Parse result - either an AST node or an error
40
+ */
41
+ export type ParseResult = ASTNode | ParseError
42
+
43
+ /**
44
+ * HogQL Parser instance
45
+ */
46
+ export interface HogQLParser {
47
+ /**
48
+ * Parse a HogQL expression
49
+ *
50
+ * @param input - The HogQL expression string to parse
51
+ * @param isInternal - If true, omits position information from the AST (default: false)
52
+ * @returns JSON string representing the AST or error
53
+ *
54
+ * @example
55
+ * ```typescript
56
+ * const result = parser.parseExpr('user_id + 100');
57
+ * const ast = JSON.parse(result);
58
+ * ```
59
+ */
60
+ parseExpr(input: string, isInternal?: boolean): string
61
+
62
+ /**
63
+ * Parse a complete SELECT statement
64
+ *
65
+ * @param input - The SELECT statement string to parse
66
+ * @param isInternal - If true, omits position information from the AST (default: false)
67
+ * @returns JSON string representing the AST or error
68
+ *
69
+ * @example
70
+ * ```typescript
71
+ * const result = parser.parseSelect('SELECT * FROM events WHERE timestamp > now()');
72
+ * const ast = JSON.parse(result);
73
+ * ```
74
+ */
75
+ parseSelect(input: string, isInternal?: boolean): string
76
+
77
+ /**
78
+ * Parse an ORDER BY expression
79
+ *
80
+ * @param input - The ORDER BY expression string to parse
81
+ * @param isInternal - If true, omits position information from the AST (default: false)
82
+ * @returns JSON string representing the AST or error
83
+ *
84
+ * @example
85
+ * ```typescript
86
+ * const result = parser.parseOrderExpr('timestamp DESC, user_id ASC');
87
+ * const ast = JSON.parse(result);
88
+ * ```
89
+ */
90
+ parseOrderExpr(input: string, isInternal?: boolean): string
91
+
92
+ /**
93
+ * Parse a complete Hog program
94
+ *
95
+ * @param input - The Hog program string to parse
96
+ * @param isInternal - If true, omits position information from the AST (default: false)
97
+ * @returns JSON string representing the AST or error
98
+ *
99
+ * @example
100
+ * ```typescript
101
+ * const result = parser.parseProgram('let x := 42; return x;');
102
+ * const ast = JSON.parse(result);
103
+ * ```
104
+ */
105
+ parseProgram(input: string, isInternal?: boolean): string
106
+
107
+ /**
108
+ * Parse a Hog template string (f'...' syntax)
109
+ *
110
+ * @param input - The template string to parse
111
+ * @param isInternal - If true, omits position information from the AST (default: false)
112
+ * @returns JSON string representing the AST or error
113
+ *
114
+ * @example
115
+ * ```typescript
116
+ * const result = parser.parseFullTemplateString("f'Hello {name}'");
117
+ * const ast = JSON.parse(result);
118
+ * ```
119
+ */
120
+ parseFullTemplateString(input: string, isInternal?: boolean): string
121
+
122
+ /**
123
+ * Unquote a string literal
124
+ *
125
+ * @param input - The quoted string literal
126
+ * @returns The unquoted string content
127
+ *
128
+ * @example
129
+ * ```typescript
130
+ * const text = parser.parseStringLiteralText("'hello world'");
131
+ * // Returns: "hello world"
132
+ * ```
133
+ */
134
+ parseStringLiteralText(input: string): string
135
+ }
136
+
137
+ /**
138
+ * Factory function to create a HogQL Parser instance
139
+ *
140
+ * @returns Promise that resolves to a HogQLParser instance
141
+ *
142
+ * @example
143
+ * ```typescript
144
+ * import createHogQLParser from '@posthog/hogql-parser';
145
+ *
146
+ * const parser = await createHogQLParser();
147
+ * const result = parser.parseExpr('1 + 2');
148
+ * const ast: ParseResult = JSON.parse(result);
149
+ *
150
+ * if ('error' in ast) {
151
+ * console.error('Parse error:', ast.message);
152
+ * } else {
153
+ * console.log('Parsed successfully:', ast);
154
+ * }
155
+ * ```
156
+ */
157
+ export default function createHogQLParser(): Promise<HogQLParser>
package/package.json CHANGED
@@ -1,10 +1,44 @@
1
1
  {
2
- "name": "@posthog/hogql-parser",
3
- "version": "0.0.1",
4
- "description": "OIDC trusted publishing setup package for @posthog/hogql-parser",
5
- "keywords": [
6
- "oidc",
7
- "trusted-publishing",
8
- "setup"
9
- ]
2
+ "name": "@posthog/hogql-parser",
3
+ "version": "0.0.3",
4
+ "description": "WebAssembly HogQL Parser - Parse HogQL queries in JavaScript/TypeScript",
5
+ "type": "module",
6
+ "main": "dist/index.cjs",
7
+ "module": "dist/hogql_parser_wasm.js",
8
+ "types": "dist/index.d.ts",
9
+ "exports": {
10
+ ".": {
11
+ "types": "./dist/index.d.ts",
12
+ "import": "./dist/hogql_parser_wasm.js",
13
+ "require": "./dist/index.cjs"
14
+ }
15
+ },
16
+ "files": [
17
+ "dist/hogql_parser_wasm.js",
18
+ "dist/index.cjs",
19
+ "dist/index.d.ts"
20
+ ],
21
+ "scripts": {
22
+ "build:compile": "emmake cmake --build build_wasm --config Release && cmake --install build_wasm",
23
+ "build:make": "emcmake cmake -S . -B build_wasm -DCMAKE_BUILD_TYPE=Release && npm run build:compile || echo 'Warning: hogql-parser build failed, skipping'",
24
+ "build": "emcmake cmake -S . -B build_wasm -G Ninja -DCMAKE_BUILD_TYPE=Release && npm run build:compile || echo 'Warning: hogql-parser build failed, skipping'"
25
+ },
26
+ "keywords": [
27
+ "hogql",
28
+ "parser",
29
+ "wasm",
30
+ "webassembly",
31
+ "antlr4"
32
+ ],
33
+ "author": "PostHog Inc.",
34
+ "license": "MIT",
35
+ "repository": {
36
+ "type": "git",
37
+ "url": "https://github.com/PostHog/posthog.git",
38
+ "directory": "common/hogql_parser"
39
+ },
40
+ "bugs": {
41
+ "url": "https://github.com/PostHog/posthog/issues"
42
+ },
43
+ "homepage": "https://github.com/PostHog/posthog/tree/master/common/hogql_parser"
10
44
  }