typebars 1.0.0

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.
Files changed (87) hide show
  1. package/README.md +1582 -0
  2. package/dist/analyzer.d.ts +59 -0
  3. package/dist/analyzer.js +4 -0
  4. package/dist/analyzer.js.map +9 -0
  5. package/dist/chunk-1gm6cf0e.js +5 -0
  6. package/dist/chunk-1gm6cf0e.js.map +10 -0
  7. package/dist/chunk-1qwj7pjc.js +4 -0
  8. package/dist/chunk-1qwj7pjc.js.map +10 -0
  9. package/dist/chunk-4zv02svp.js +7 -0
  10. package/dist/chunk-4zv02svp.js.map +10 -0
  11. package/dist/chunk-60gk3q7z.js +5 -0
  12. package/dist/chunk-60gk3q7z.js.map +10 -0
  13. package/dist/chunk-6955jpr7.js +5 -0
  14. package/dist/chunk-6955jpr7.js.map +10 -0
  15. package/dist/chunk-6c0pw73w.js +7 -0
  16. package/dist/chunk-6c0pw73w.js.map +10 -0
  17. package/dist/chunk-7j6q1e3z.js +5 -0
  18. package/dist/chunk-7j6q1e3z.js.map +14 -0
  19. package/dist/chunk-8g0d6h85.js +5 -0
  20. package/dist/chunk-8g0d6h85.js.map +10 -0
  21. package/dist/chunk-9mg6qfrs.js +5 -0
  22. package/dist/chunk-9mg6qfrs.js.map +10 -0
  23. package/dist/chunk-a37yzqra.js +5 -0
  24. package/dist/chunk-a37yzqra.js.map +11 -0
  25. package/dist/chunk-awgj10qg.js +4 -0
  26. package/dist/chunk-awgj10qg.js.map +10 -0
  27. package/dist/chunk-fhvf5y4x.js +7 -0
  28. package/dist/chunk-fhvf5y4x.js.map +10 -0
  29. package/dist/chunk-ggdfaqhe.js +5 -0
  30. package/dist/chunk-ggdfaqhe.js.map +10 -0
  31. package/dist/chunk-hc1jnqaw.js +5 -0
  32. package/dist/chunk-hc1jnqaw.js.map +10 -0
  33. package/dist/chunk-kznb0bev.js +5 -0
  34. package/dist/chunk-kznb0bev.js.map +10 -0
  35. package/dist/chunk-mx8neh7q.js +5 -0
  36. package/dist/chunk-mx8neh7q.js.map +10 -0
  37. package/dist/chunk-p3xzf1ew.js +5 -0
  38. package/dist/chunk-p3xzf1ew.js.map +10 -0
  39. package/dist/chunk-qh2r1pa1.js +5 -0
  40. package/dist/chunk-qh2r1pa1.js.map +10 -0
  41. package/dist/chunk-qpzzr2rd.js +5 -0
  42. package/dist/chunk-qpzzr2rd.js.map +10 -0
  43. package/dist/chunk-vka4e61h.js +7 -0
  44. package/dist/chunk-vka4e61h.js.map +10 -0
  45. package/dist/chunk-xbvk4ygq.js +5 -0
  46. package/dist/chunk-xbvk4ygq.js.map +11 -0
  47. package/dist/chunk-ybh51hbe.js +7 -0
  48. package/dist/chunk-ybh51hbe.js.map +10 -0
  49. package/dist/chunk-yczpjh73.js +4 -0
  50. package/dist/chunk-yczpjh73.js.map +10 -0
  51. package/dist/chunk-yraqh2tz.js +5 -0
  52. package/dist/chunk-yraqh2tz.js.map +10 -0
  53. package/dist/chunk-z6yh5qvc.js +5 -0
  54. package/dist/chunk-z6yh5qvc.js.map +10 -0
  55. package/dist/compiled-template.d.ts +130 -0
  56. package/dist/compiled-template.js +4 -0
  57. package/dist/compiled-template.js.map +9 -0
  58. package/dist/errors.d.ts +93 -0
  59. package/dist/errors.js +4 -0
  60. package/dist/errors.js.map +9 -0
  61. package/dist/executor.d.ts +55 -0
  62. package/dist/executor.js +4 -0
  63. package/dist/executor.js.map +9 -0
  64. package/dist/helpers/helper-factory.d.ts +56 -0
  65. package/dist/helpers/index.d.ts +4 -0
  66. package/dist/helpers/logical-helpers.d.ts +15 -0
  67. package/dist/helpers/math-helpers.d.ts +13 -0
  68. package/dist/helpers/utils.d.ts +19 -0
  69. package/dist/index.d.ts +2 -0
  70. package/dist/index.js +4 -0
  71. package/dist/index.js.map +9 -0
  72. package/dist/parser.d.ts +146 -0
  73. package/dist/parser.js +4 -0
  74. package/dist/parser.js.map +9 -0
  75. package/dist/schema-resolver.d.ts +50 -0
  76. package/dist/schema-resolver.js +4 -0
  77. package/dist/schema-resolver.js.map +9 -0
  78. package/dist/typebars.d.ts +130 -0
  79. package/dist/typebars.js +4 -0
  80. package/dist/typebars.js.map +9 -0
  81. package/dist/types.d.ts +334 -0
  82. package/dist/types.js +4 -0
  83. package/dist/types.js.map +9 -0
  84. package/dist/utils.d.ts +113 -0
  85. package/dist/utils.js +4 -0
  86. package/dist/utils.js.map +9 -0
  87. package/package.json +42 -0
@@ -0,0 +1,93 @@
1
+ import type { TemplateDiagnostic } from "./types.ts";
2
+ export declare class TemplateError extends Error {
3
+ constructor(message: string);
4
+ /**
5
+ * Serializes the error into a JSON-compatible object, suitable for sending
6
+ * to a frontend or a structured logging system.
7
+ */
8
+ toJSON(): Record<string, unknown>;
9
+ }
10
+ export declare class TemplateParseError extends TemplateError {
11
+ /** Approximate position of the error in the source */
12
+ readonly loc?: {
13
+ line: number;
14
+ column: number;
15
+ } | undefined;
16
+ /** Fragment of the template source around the error */
17
+ readonly source?: string | undefined;
18
+ constructor(message: string,
19
+ /** Approximate position of the error in the source */
20
+ loc?: {
21
+ line: number;
22
+ column: number;
23
+ } | undefined,
24
+ /** Fragment of the template source around the error */
25
+ source?: string | undefined);
26
+ toJSON(): Record<string, unknown>;
27
+ }
28
+ export declare class TemplateAnalysisError extends TemplateError {
29
+ /** Full list of diagnostics (errors + warnings) */
30
+ readonly diagnostics: TemplateDiagnostic[];
31
+ /** Only diagnostics with "error" severity */
32
+ readonly errors: TemplateDiagnostic[];
33
+ /** Only diagnostics with "warning" severity */
34
+ readonly warnings: TemplateDiagnostic[];
35
+ /** Total number of errors */
36
+ readonly errorCount: number;
37
+ /** Total number of warnings */
38
+ readonly warningCount: number;
39
+ constructor(diagnostics: TemplateDiagnostic[]);
40
+ /**
41
+ * Serializes the analysis error into a JSON-compatible object.
42
+ *
43
+ * Designed for direct use in API responses:
44
+ * ```
45
+ * res.status(400).json(error.toJSON());
46
+ * ```
47
+ *
48
+ * Returned structure:
49
+ * ```
50
+ * {
51
+ * name: "TemplateAnalysisError",
52
+ * message: "Static analysis failed with 2 error(s): ...",
53
+ * errorCount: 2,
54
+ * warningCount: 0,
55
+ * diagnostics: [
56
+ * {
57
+ * severity: "error",
58
+ * code: "UNKNOWN_PROPERTY",
59
+ * message: "Property \"foo\" does not exist...",
60
+ * loc: { start: { line: 1, column: 0 }, end: { line: 1, column: 7 } },
61
+ * source: "{{foo}}",
62
+ * details: { path: "foo", availableProperties: ["name", "age"] }
63
+ * }
64
+ * ]
65
+ * }
66
+ * ```
67
+ */
68
+ toJSON(): Record<string, unknown>;
69
+ }
70
+ export declare class TemplateRuntimeError extends TemplateError {
71
+ constructor(message: string);
72
+ }
73
+ /**
74
+ * Creates a structured diagnostic message for a missing property.
75
+ * Used by the analyzer to produce enriched error messages with suggestions.
76
+ */
77
+ export declare function createPropertyNotFoundMessage(path: string, availableProperties: string[]): string;
78
+ /**
79
+ * Creates a message for a type mismatch on a block helper.
80
+ */
81
+ export declare function createTypeMismatchMessage(helperName: string, expected: string, actual: string): string;
82
+ /**
83
+ * Creates a message for a missing argument on a block helper.
84
+ */
85
+ export declare function createMissingArgumentMessage(helperName: string): string;
86
+ /**
87
+ * Creates a message for an unknown block helper.
88
+ */
89
+ export declare function createUnknownHelperMessage(helperName: string): string;
90
+ /**
91
+ * Creates a message for an expression that cannot be statically analyzed.
92
+ */
93
+ export declare function createUnanalyzableMessage(nodeType: string): string;
package/dist/errors.js ADDED
@@ -0,0 +1,4 @@
1
+ import{A as b,B as c,C as d,D as e,E as f,F as g,G as h,H as i,z as a}from"./chunk-ybh51hbe.js";export{h as createUnknownHelperMessage,i as createUnanalyzableMessage,f as createTypeMismatchMessage,e as createPropertyNotFoundMessage,g as createMissingArgumentMessage,d as TemplateRuntimeError,b as TemplateParseError,a as TemplateError,c as TemplateAnalysisError};
2
+
3
+ //# debugId=043280437018AA4064756E2164756E21
4
+ //# sourceMappingURL=errors.js.map
@@ -0,0 +1,9 @@
1
+ {
2
+ "version": 3,
3
+ "sources": [],
4
+ "sourcesContent": [
5
+ ],
6
+ "mappings": "",
7
+ "debugId": "043280437018AA4064756E2164756E21",
8
+ "names": []
9
+ }
@@ -0,0 +1,55 @@
1
+ import Handlebars from "handlebars";
2
+ import type { TemplateInput } from "./types.ts";
3
+ import { LRUCache } from "./utils.ts";
4
+ /** Optional context for execution (used by Typebars/CompiledTemplate) */
5
+ export interface ExecutorContext {
6
+ /** Data by identifier `{ [id]: { key: value } }` */
7
+ identifierData?: Record<number, Record<string, unknown>>;
8
+ /** Pre-compiled Handlebars template (for CompiledTemplate) */
9
+ compiledTemplate?: HandlebarsTemplateDelegate;
10
+ /** Isolated Handlebars environment (for custom helpers) */
11
+ hbs?: typeof Handlebars;
12
+ /** Compilation cache shared by the engine */
13
+ compilationCache?: LRUCache<string, HandlebarsTemplateDelegate>;
14
+ }
15
+ /**
16
+ * Executes a template with the provided data and returns the result.
17
+ *
18
+ * The return type depends on the template structure:
19
+ * - Single expression `{{expr}}` → raw value (any)
20
+ * - Single block → coerced value (number, boolean, null, or string)
21
+ * - Mixed template → `string`
22
+ *
23
+ * @param template - The template string
24
+ * @param data - The main context data
25
+ * @param identifierData - (optional) Data by identifier `{ [id]: { key: value } }`
26
+ */
27
+ export declare function execute(template: TemplateInput, data: Record<string, unknown>, identifierData?: Record<number, Record<string, unknown>>): unknown;
28
+ /**
29
+ * Executes a template from an already-parsed AST.
30
+ *
31
+ * This function is the core of execution. It is used by:
32
+ * - `execute()` (backward-compatible wrapper)
33
+ * - `CompiledTemplate.execute()` (with pre-parsed AST and cache)
34
+ * - `Typebars.execute()` (with cache and helpers)
35
+ *
36
+ * @param ast - The already-parsed Handlebars AST
37
+ * @param template - The template source (for Handlebars compilation if needed)
38
+ * @param data - The main context data
39
+ * @param ctx - Optional execution context
40
+ */
41
+ export declare function executeFromAst(ast: hbs.AST.Program, template: string, data: Record<string, unknown>, ctx?: ExecutorContext): unknown;
42
+ /**
43
+ * Navigates through a data object by following a path of segments.
44
+ *
45
+ * @param data - The data object
46
+ * @param segments - The path segments (e.g. `["user", "address", "city"]`)
47
+ * @returns The value at the end of the path, or `undefined` if an
48
+ * intermediate segment is null/undefined
49
+ */
50
+ export declare function resolveDataPath(data: unknown, segments: string[]): unknown;
51
+ /**
52
+ * Clears the global Handlebars compilation cache.
53
+ * Useful for tests or to free memory.
54
+ */
55
+ export declare function clearCompilationCache(): void;
@@ -0,0 +1,4 @@
1
+ import{f as a,g as b,h as c,i as d}from"./chunk-qpzzr2rd.js";import"./chunk-6955jpr7.js";import"./chunk-1gm6cf0e.js";import"./chunk-ybh51hbe.js";import"./chunk-4zv02svp.js";export{c as resolveDataPath,b as executeFromAst,a as execute,d as clearCompilationCache};
2
+
3
+ //# debugId=E439EBF232D2886264756E2164756E21
4
+ //# sourceMappingURL=executor.js.map
@@ -0,0 +1,9 @@
1
+ {
2
+ "version": 3,
3
+ "sources": [],
4
+ "sourcesContent": [
5
+ ],
6
+ "mappings": "",
7
+ "debugId": "E439EBF232D2886264756E2164756E21",
8
+ "names": []
9
+ }
@@ -0,0 +1,56 @@
1
+ import type { HelperDefinition } from "../types.ts";
2
+ /** Minimal registration interface — avoids tight coupling with Typebars */
3
+ export interface HelperRegistry {
4
+ registerHelper(name: string, definition: HelperDefinition): unknown;
5
+ unregisterHelper(name: string): unknown;
6
+ }
7
+ export declare abstract class HelperFactory {
8
+ private _definitions;
9
+ private _helperNames;
10
+ private _helperNamesSet;
11
+ /**
12
+ * Populates the `defs` map with all helper definitions.
13
+ *
14
+ * Subclasses implement this method to register their helpers:
15
+ * ```
16
+ * protected buildDefinitions(defs: Map<string, HelperDefinition>): void {
17
+ * defs.set("myHelper", {
18
+ * fn: (a: unknown) => String(a).toUpperCase(),
19
+ * params: [{ name: "a", type: { type: "string" } }],
20
+ * returnType: { type: "string" },
21
+ * description: "Converts to uppercase",
22
+ * });
23
+ * }
24
+ * ```
25
+ *
26
+ * @param defs - The map to populate with `[name, HelperDefinition]` entries
27
+ */
28
+ protected abstract buildDefinitions(defs: Map<string, HelperDefinition>): void;
29
+ /**
30
+ * Returns all definitions as a `Map<name, HelperDefinition>`.
31
+ * The map is lazily built and cached on first access.
32
+ */
33
+ getDefinitions(): Map<string, HelperDefinition>;
34
+ /**
35
+ * Returns the list of all helper names provided by this factory.
36
+ */
37
+ getHelperNames(): readonly string[];
38
+ /**
39
+ * Checks whether a helper name belongs to this factory.
40
+ *
41
+ * @param name - The helper name to check
42
+ */
43
+ isHelper(name: string): boolean;
44
+ /**
45
+ * Registers all helpers from this factory on the given registry.
46
+ *
47
+ * @param registry - The engine or target registry
48
+ */
49
+ register(registry: HelperRegistry): void;
50
+ /**
51
+ * Removes all helpers from this factory from the given registry.
52
+ *
53
+ * @param registry - The engine or target registry
54
+ */
55
+ unregister(registry: HelperRegistry): void;
56
+ }
@@ -0,0 +1,4 @@
1
+ export { HelperFactory, type HelperRegistry } from "./helper-factory.ts";
2
+ export { LogicalHelpers } from "./logical-helpers.ts";
3
+ export { MathHelpers } from "./math-helpers.ts";
4
+ export { toNumber } from "./utils.ts";
@@ -0,0 +1,15 @@
1
+ import type { HelperDefinition } from "../types.ts";
2
+ import { HelperFactory } from "./helper-factory.ts";
3
+ export declare class LogicalHelpers extends HelperFactory {
4
+ protected buildDefinitions(defs: Map<string, HelperDefinition>): void;
5
+ /** Registers eq, ne / neq */
6
+ private registerEquality;
7
+ /** Registers lt, lte / le, gt, gte / ge */
8
+ private registerComparison;
9
+ /** Registers not, and, or */
10
+ private registerLogicalOperators;
11
+ /** Registers contains, in */
12
+ private registerCollectionHelpers;
13
+ /** Registers the generic `compare` helper with operator as a parameter */
14
+ private registerGenericCompare;
15
+ }
@@ -0,0 +1,13 @@
1
+ import type { HelperDefinition } from "../types.ts";
2
+ import { HelperFactory } from "./helper-factory.ts";
3
+ export declare class MathHelpers extends HelperFactory {
4
+ protected buildDefinitions(defs: Map<string, HelperDefinition>): void;
5
+ /** Registers add, subtract/sub, multiply/mul, divide/div, modulo/mod, pow */
6
+ private registerBinaryOperators;
7
+ /** Registers abs, ceil, floor, round, sqrt */
8
+ private registerUnaryFunctions;
9
+ /** Registers min and max */
10
+ private registerMinMax;
11
+ /** Registers the generic `math` helper with operator as a parameter */
12
+ private registerGenericMath;
13
+ }
@@ -0,0 +1,19 @@
1
+ /**
2
+ * Converts an unknown value to a number.
3
+ *
4
+ * Conversion rules:
5
+ * - `number` → returned as-is
6
+ * - `string` → parsed via `Number()`; returns `fallback` if result is `NaN`
7
+ * - `boolean` → `true` → `1`, `false` → `0`
8
+ * - anything else → `fallback`
9
+ *
10
+ * The `fallback` parameter lets each consumer choose the right semantics:
11
+ * - **Math helpers** pass `0` so that invalid inputs silently become zero
12
+ * (e.g. `add("abc", 5)` → `5`).
13
+ * - **Logical helpers** pass `NaN` (the default) so that invalid comparisons
14
+ * evaluate to `false` (e.g. `lt("abc", 5)` → `false`).
15
+ *
16
+ * @param value - The value to convert
17
+ * @param fallback - Value returned when conversion fails (default: `NaN`)
18
+ */
19
+ export declare function toNumber(value: unknown, fallback?: number): number;
@@ -0,0 +1,2 @@
1
+ export { Typebars } from "./typebars.ts";
2
+ export { defineHelper } from "./types.ts";
package/dist/index.js ADDED
@@ -0,0 +1,4 @@
1
+ import{a as r}from"./chunk-7j6q1e3z.js";import"./chunk-kznb0bev.js";import"./chunk-1qwj7pjc.js";import"./chunk-qpzzr2rd.js";import{m as e}from"./chunk-6955jpr7.js";import"./chunk-1gm6cf0e.js";import"./chunk-ybh51hbe.js";import"./chunk-8g0d6h85.js";import"./chunk-4zv02svp.js";export{e as defineHelper,r as Typebars};
2
+
3
+ //# debugId=55D58DC910FCA0B664756E2164756E21
4
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1,9 @@
1
+ {
2
+ "version": 3,
3
+ "sources": [],
4
+ "sourcesContent": [
5
+ ],
6
+ "mappings": "",
7
+ "debugId": "55D58DC910FCA0B664756E2164756E21",
8
+ "names": []
9
+ }
@@ -0,0 +1,146 @@
1
+ /**
2
+ * Parses a template string and returns the Handlebars AST.
3
+ *
4
+ * This function does not cache results — caching is managed at the
5
+ * `Typebars` instance level via its own configurable LRU cache.
6
+ *
7
+ * @param template - The template string to parse (e.g. `"Hello {{name}}"`)
8
+ * @returns The root AST node (`hbs.AST.Program`)
9
+ * @throws {TemplateParseError} if the template syntax is invalid
10
+ */
11
+ export declare function parse(template: string): hbs.AST.Program;
12
+ /**
13
+ * Determines whether the AST represents a template consisting of a single
14
+ * expression `{{expression}}` with no text content around it.
15
+ *
16
+ * This matters for return type inference:
17
+ * - Template `{{value}}` → returns the raw type of `value` (number, object…)
18
+ * - Template `Hello {{name}}` → always returns `string` (concatenation)
19
+ *
20
+ * @param ast - The parsed AST of the template
21
+ * @returns `true` if the template is a single expression
22
+ */
23
+ export declare function isSingleExpression(ast: hbs.AST.Program): boolean;
24
+ /**
25
+ * Extracts the path segments from a Handlebars `PathExpression`.
26
+ *
27
+ * Handlebars decomposes `user.address.city` into `{ parts: ["user", "address", "city"] }`.
28
+ * This function safely extracts those segments.
29
+ *
30
+ * @param expr - The expression to extract the path from
31
+ * @returns The path segments, or an empty array if the expression is not
32
+ * a `PathExpression`
33
+ */
34
+ export declare function extractPathSegments(expr: hbs.AST.Expression): string[];
35
+ /**
36
+ * Checks whether an AST expression is a `PathExpression` pointing to `this`
37
+ * (used inside `{{#each}}` blocks).
38
+ */
39
+ export declare function isThisExpression(expr: hbs.AST.Expression): boolean;
40
+ /**
41
+ * Returns the semantically significant statements of a Program by
42
+ * filtering out `ContentStatement` nodes that contain only whitespace.
43
+ */
44
+ export declare function getEffectiveBody(program: hbs.AST.Program): hbs.AST.Statement[];
45
+ /**
46
+ * Determines whether a Program effectively consists of a single
47
+ * `BlockStatement` (ignoring surrounding whitespace).
48
+ *
49
+ * Recognized examples:
50
+ * ```
51
+ * {{#if x}}...{{/if}}
52
+ *
53
+ * {{#each items}}...{{/each}}
54
+ * ```
55
+ *
56
+ * @returns The single `BlockStatement`, or `null` if the program contains
57
+ * other significant nodes.
58
+ */
59
+ export declare function getEffectivelySingleBlock(program: hbs.AST.Program): hbs.AST.BlockStatement | null;
60
+ /**
61
+ * Determines whether a Program effectively consists of a single
62
+ * `MustacheStatement` (ignoring surrounding whitespace).
63
+ *
64
+ * Example: ` {{age}} ` → true
65
+ */
66
+ export declare function getEffectivelySingleExpression(program: hbs.AST.Program): hbs.AST.MustacheStatement | null;
67
+ /**
68
+ * Determines whether an AST can be executed via the fast-path (direct
69
+ * concatenation without going through `Handlebars.compile()`).
70
+ *
71
+ * The fast-path is possible when the template only contains:
72
+ * - `ContentStatement` nodes (static text)
73
+ * - Simple `MustacheStatement` nodes (no params, no hash)
74
+ *
75
+ * This excludes:
76
+ * - Block helpers (`{{#if}}`, `{{#each}}`, etc.)
77
+ * - Inline helpers (`{{uppercase name}}`)
78
+ * - Sub-expressions
79
+ *
80
+ * @param ast - The parsed AST of the template
81
+ * @returns `true` if the template can use the fast-path
82
+ */
83
+ export declare function canUseFastPath(ast: hbs.AST.Program): boolean;
84
+ /**
85
+ * Attempts to detect the type of a raw text literal.
86
+ *
87
+ * @param text - The trimmed text from a ContentStatement or group of ContentStatements
88
+ * @returns The detected JSON Schema type, or `null` if it's free-form text (string).
89
+ */
90
+ export declare function detectLiteralType(text: string): "number" | "boolean" | "null" | null;
91
+ /**
92
+ * Coerces a raw string from Handlebars rendering to its actual type
93
+ * if it represents a literal (number, boolean, null).
94
+ * Returns the raw (untrimmed) string otherwise.
95
+ */
96
+ export declare function coerceLiteral(raw: string): unknown;
97
+ /** Result of parsing a path segment with a potential identifier */
98
+ export interface ParsedIdentifier {
99
+ /** The variable name, without the `:N` suffix */
100
+ key: string;
101
+ /** The numeric identifier, or `null` if absent */
102
+ identifier: number | null;
103
+ }
104
+ /**
105
+ * Parses an individual path segment to extract the key and optional identifier.
106
+ *
107
+ * @param segment - A raw path segment (e.g. `"meetingId:1"` or `"meetingId"`)
108
+ * @returns An object `{ key, identifier }`
109
+ *
110
+ * @example
111
+ * ```
112
+ * parseIdentifier("meetingId:1") // → { key: "meetingId", identifier: 1 }
113
+ * parseIdentifier("meetingId") // → { key: "meetingId", identifier: null }
114
+ * parseIdentifier("meetingId:0") // → { key: "meetingId", identifier: 0 }
115
+ * ```
116
+ */
117
+ export declare function parseIdentifier(segment: string): ParsedIdentifier;
118
+ /** Result of extracting the identifier from a complete expression */
119
+ export interface ExpressionIdentifier {
120
+ /** Cleaned path segments (without the `:N` suffix on the last one) */
121
+ cleanSegments: string[];
122
+ /** The numeric identifier extracted from the last segment, or `null` */
123
+ identifier: number | null;
124
+ }
125
+ /**
126
+ * Extracts the identifier from a complete expression (array of segments).
127
+ *
128
+ * The identifier is always on the **last** segment of the path, because
129
+ * Handlebars splits on `.` before the `:`.
130
+ *
131
+ * @param segments - The raw path segments (e.g. `["user", "name:1"]`)
132
+ * @returns An object `{ cleanSegments, identifier }`
133
+ *
134
+ * @example
135
+ * ```
136
+ * extractExpressionIdentifier(["meetingId:1"])
137
+ * // → { cleanSegments: ["meetingId"], identifier: 1 }
138
+ *
139
+ * extractExpressionIdentifier(["user", "name:1"])
140
+ * // → { cleanSegments: ["user", "name"], identifier: 1 }
141
+ *
142
+ * extractExpressionIdentifier(["meetingId"])
143
+ * // → { cleanSegments: ["meetingId"], identifier: null }
144
+ * ```
145
+ */
146
+ export declare function extractExpressionIdentifier(segments: string[]): ExpressionIdentifier;
package/dist/parser.js ADDED
@@ -0,0 +1,4 @@
1
+ import{n as a,o as b,p as c,q as d,r as e,s as f,t as g,u as h,v as i,w as j,x as k,y as l}from"./chunk-1gm6cf0e.js";import"./chunk-ybh51hbe.js";export{k as parseIdentifier,a as parse,d as isThisExpression,b as isSingleExpression,g as getEffectivelySingleExpression,f as getEffectivelySingleBlock,e as getEffectiveBody,c as extractPathSegments,l as extractExpressionIdentifier,i as detectLiteralType,j as coerceLiteral,h as canUseFastPath};
2
+
3
+ //# debugId=238977E59328291964756E2164756E21
4
+ //# sourceMappingURL=parser.js.map
@@ -0,0 +1,9 @@
1
+ {
2
+ "version": 3,
3
+ "sources": [],
4
+ "sourcesContent": [
5
+ ],
6
+ "mappings": "",
7
+ "debugId": "238977E59328291964756E2164756E21",
8
+ "names": []
9
+ }
@@ -0,0 +1,50 @@
1
+ import type { JSONSchema7 } from "json-schema";
2
+ /**
3
+ * Recursively resolves `$ref` in a schema using the root schema as the
4
+ * source of definitions.
5
+ */
6
+ export declare function resolveRef(schema: JSONSchema7, root: JSONSchema7): JSONSchema7;
7
+ /**
8
+ * Resolves a full path (e.g. ["user", "address", "city"]) within a JSON
9
+ * Schema and returns the corresponding sub-schema.
10
+ *
11
+ * @param schema - The root schema describing the template context
12
+ * @param path - Array of segments (property names)
13
+ * @returns The sub-schema at the end of the path, or `undefined` if the path
14
+ * cannot be resolved.
15
+ *
16
+ * @example
17
+ * ```
18
+ * const schema = {
19
+ * type: "object",
20
+ * properties: {
21
+ * user: {
22
+ * type: "object",
23
+ * properties: {
24
+ * name: { type: "string" }
25
+ * }
26
+ * }
27
+ * }
28
+ * };
29
+ * resolveSchemaPath(schema, ["user", "name"]);
30
+ * // → { type: "string" }
31
+ * ```
32
+ */
33
+ export declare function resolveSchemaPath(schema: JSONSchema7, path: string[]): JSONSchema7 | undefined;
34
+ /**
35
+ * Resolves the item schema of an array.
36
+ * If the schema is not of type `array` or has no `items`, returns `undefined`.
37
+ *
38
+ * @param schema - The array schema
39
+ * @param root - The root schema (for resolving $refs)
40
+ */
41
+ export declare function resolveArrayItems(schema: JSONSchema7, root: JSONSchema7): JSONSchema7 | undefined;
42
+ /**
43
+ * Simplifies an output schema to avoid unnecessarily complex constructs
44
+ * (e.g. `oneOf` with a single element, duplicates, etc.).
45
+ *
46
+ * Uses `deepEqual` for deduplication — more robust and performant than
47
+ * `JSON.stringify` (independent of key order, no intermediate string
48
+ * allocations).
49
+ */
50
+ export declare function simplifySchema(schema: JSONSchema7): JSONSchema7;
@@ -0,0 +1,4 @@
1
+ import{I as a,J as b,K as c,L as d}from"./chunk-8g0d6h85.js";import"./chunk-4zv02svp.js";export{d as simplifySchema,b as resolveSchemaPath,a as resolveRef,c as resolveArrayItems};
2
+
3
+ //# debugId=0ED578ADCD4302EE64756E2164756E21
4
+ //# sourceMappingURL=schema-resolver.js.map
@@ -0,0 +1,9 @@
1
+ {
2
+ "version": 3,
3
+ "sources": [],
4
+ "sourcesContent": [
5
+ ],
6
+ "mappings": "",
7
+ "debugId": "0ED578ADCD4302EE64756E2164756E21",
8
+ "names": []
9
+ }