First upload version 0.0.1

This commit is contained in:
Neyra
2026-02-05 15:27:49 +08:00
commit 8e9b7201ed
4182 changed files with 593136 additions and 0 deletions

21
node_modules/@huggingface/jinja/LICENSE generated vendored Normal file
View File

@@ -0,0 +1,21 @@
MIT License
Copyright (c) 2023 Hugging Face
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.

78
node_modules/@huggingface/jinja/README.md generated vendored Normal file
View File

@@ -0,0 +1,78 @@
# Jinja
A minimalistic JavaScript implementation of the Jinja templating engine, specifically designed for parsing and rendering ML chat templates.
## Usage
### Load template from a model on the Hugging Face Hub
First, install the jinja and hub packages:
```sh
npm i @huggingface/jinja
npm i @huggingface/hub
```
You can then load a tokenizer from the Hugging Face Hub and render a list of chat messages, as follows:
```js
import { Template } from "@huggingface/jinja";
import { downloadFile } from "@huggingface/hub";
const config = await (
await downloadFile({
repo: "mistralai/Mistral-7B-Instruct-v0.1",
path: "tokenizer_config.json",
})
).json();
const chat = [
{ role: "user", content: "Hello, how are you?" },
{ role: "assistant", content: "I'm doing great. How can I help you today?" },
{ role: "user", content: "I'd like to show off how chat templating works!" },
];
const template = new Template(config.chat_template);
const result = template.render({
messages: chat,
bos_token: config.bos_token,
eos_token: config.eos_token,
});
// "<s>[INST] Hello, how are you? [/INST]I'm doing great. How can I help you today?</s> [INST] I'd like to show off how chat templating works! [/INST]"
```
### Transformers.js
First, install `@huggingface/transformers`:
```sh
npm i @huggingface/transformers
```
You can then render a list of chat messages using a tokenizer's `apply_chat_template` method.
```js
import { AutoTokenizer } from "@huggingface/transformers";
// Load tokenizer from the Hugging Face Hub
const tokenizer = await AutoTokenizer.from_pretrained("mistralai/Mistral-7B-Instruct-v0.1");
// Define chat messages
const chat = [
{ role: "user", content: "Hello, how are you?" },
{ role: "assistant", content: "I'm doing great. How can I help you today?" },
{ role: "user", content: "I'd like to show off how chat templating works!" },
];
const text = tokenizer.apply_chat_template(chat, { tokenize: false });
// "<s>[INST] Hello, how are you? [/INST]I'm doing great. How can I help you today?</s> [INST] I'd like to show off how chat templating works! [/INST]"
```
Notice how the entire chat is condensed into a single string. If you would instead like to return the tokenized version (i.e., a list of token IDs), you can use the following:
```js
const input_ids = tokenizer.apply_chat_template(chat, { tokenize: true, return_tensor: false });
// [1, 733, 16289, 28793, 22557, 28725, 910, 460, 368, 28804, 733, 28748, 16289, 28793, 28737, 28742, 28719, 2548, 1598, 28723, 1602, 541, 315, 1316, 368, 3154, 28804, 2, 28705, 733, 16289, 28793, 315, 28742, 28715, 737, 298, 1347, 805, 910, 10706, 5752, 1077, 3791, 28808, 733, 28748, 16289, 28793]
```
For more information about chat templates, check out the transformers [documentation](https://huggingface.co/docs/transformers/main/en/chat_templating).

221
node_modules/@huggingface/jinja/dist/ast.d.ts generated vendored Normal file
View File

@@ -0,0 +1,221 @@
import type { Token } from "./lexer";
/**
* Statements do not result in a value at runtime. They contain one or more expressions internally.
*/
export declare class Statement {
type: string;
}
/**
* Defines a block which contains many statements. Each chat template corresponds to one Program.
*/
export declare class Program extends Statement {
body: Statement[];
type: string;
constructor(body: Statement[]);
}
export declare class If extends Statement {
test: Expression;
body: Statement[];
alternate: Statement[];
type: string;
constructor(test: Expression, body: Statement[], alternate: Statement[]);
}
/**
* Loop over each item in a sequence
* https://jinja.palletsprojects.com/en/3.0.x/templates/#for
*/
export declare class For extends Statement {
loopvar: Identifier | TupleLiteral;
iterable: Expression;
body: Statement[];
defaultBlock: Statement[];
type: string;
constructor(loopvar: Identifier | TupleLiteral, iterable: Expression, body: Statement[], defaultBlock: Statement[]);
}
export declare class Break extends Statement {
type: string;
}
export declare class Continue extends Statement {
type: string;
}
export declare class SetStatement extends Statement {
assignee: Expression;
value: Expression | null;
body: Statement[];
type: string;
constructor(assignee: Expression, value: Expression | null, body: Statement[]);
}
export declare class Macro extends Statement {
name: Identifier;
args: Expression[];
body: Statement[];
type: string;
constructor(name: Identifier, args: Expression[], body: Statement[]);
}
export declare class Comment extends Statement {
value: string;
type: string;
constructor(value: string);
}
/**
* Expressions will result in a value at runtime (unlike statements).
*/
export declare class Expression extends Statement {
type: string;
}
export declare class MemberExpression extends Expression {
object: Expression;
property: Expression;
computed: boolean;
type: string;
constructor(object: Expression, property: Expression, computed: boolean);
}
export declare class CallExpression extends Expression {
callee: Expression;
args: Expression[];
type: string;
constructor(callee: Expression, args: Expression[]);
}
/**
* Represents a user-defined variable or symbol in the template.
*/
export declare class Identifier extends Expression {
value: string;
type: string;
/**
* @param {string} value The name of the identifier
*/
constructor(value: string);
}
/**
* Abstract base class for all Literal expressions.
* Should not be instantiated directly.
*/
declare abstract class Literal<T> extends Expression {
value: T;
type: string;
constructor(value: T);
}
export declare class IntegerLiteral extends Literal<number> {
type: string;
}
export declare class FloatLiteral extends Literal<number> {
type: string;
}
/**
* Represents a text constant in the template.
*/
export declare class StringLiteral extends Literal<string> {
type: string;
}
/**
* Represents an array literal in the template.
*/
export declare class ArrayLiteral extends Literal<Expression[]> {
type: string;
}
/**
* Represents a tuple literal in the template.
*/
export declare class TupleLiteral extends Literal<Expression[]> {
type: string;
}
/**
* Represents an object literal in the template.
*/
export declare class ObjectLiteral extends Literal<Map<Expression, Expression>> {
type: string;
}
/**
* An operation with two sides, separated by an operator.
* Note: Either side can be a Complex Expression, with order
* of operations being determined by the operator.
*/
export declare class BinaryExpression extends Expression {
operator: Token;
left: Expression;
right: Expression;
type: string;
constructor(operator: Token, left: Expression, right: Expression);
}
/**
* An operation with two sides, separated by the | operator.
* Operator precedence: https://github.com/pallets/jinja/issues/379#issuecomment-168076202
*/
export declare class FilterExpression extends Expression {
operand: Expression;
filter: Identifier | CallExpression;
type: string;
constructor(operand: Expression, filter: Identifier | CallExpression);
}
export declare class FilterStatement extends Statement {
filter: Identifier | CallExpression;
body: Statement[];
type: string;
constructor(filter: Identifier | CallExpression, body: Statement[]);
}
/**
* An operation which filters a sequence of objects by applying a test to each object,
* and only selecting the objects with the test succeeding.
*
* It may also be used as a shortcut for a ternary operator.
*/
export declare class SelectExpression extends Expression {
lhs: Expression;
test: Expression;
type: string;
constructor(lhs: Expression, test: Expression);
}
/**
* An operation with two sides, separated by the "is" operator.
*/
export declare class TestExpression extends Expression {
operand: Expression;
negate: boolean;
test: Identifier;
type: string;
constructor(operand: Expression, negate: boolean, test: Identifier);
}
/**
* An operation with one side (operator on the left).
*/
export declare class UnaryExpression extends Expression {
operator: Token;
argument: Expression;
type: string;
constructor(operator: Token, argument: Expression);
}
export declare class SliceExpression extends Expression {
start: Expression | undefined;
stop: Expression | undefined;
step: Expression | undefined;
type: string;
constructor(start?: Expression | undefined, stop?: Expression | undefined, step?: Expression | undefined);
}
export declare class KeywordArgumentExpression extends Expression {
key: Identifier;
value: Expression;
type: string;
constructor(key: Identifier, value: Expression);
}
export declare class SpreadExpression extends Expression {
argument: Expression;
type: string;
constructor(argument: Expression);
}
export declare class CallStatement extends Statement {
call: CallExpression;
callerArgs: Expression[] | null;
body: Statement[];
type: string;
constructor(call: CallExpression, callerArgs: Expression[] | null, body: Statement[]);
}
export declare class Ternary extends Expression {
condition: Expression;
trueExpr: Expression;
falseExpr: Expression;
type: string;
constructor(condition: Expression, trueExpr: Expression, falseExpr: Expression);
}
export {};
//# sourceMappingURL=ast.d.ts.map

1
node_modules/@huggingface/jinja/dist/ast.d.ts.map generated vendored Normal file
View File

@@ -0,0 +1 @@
{"version":3,"file":"ast.d.ts","sourceRoot":"","sources":["../src/ast.ts"],"names":[],"mappings":"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"}

3
node_modules/@huggingface/jinja/dist/format.d.ts generated vendored Normal file
View File

@@ -0,0 +1,3 @@
import type { Program } from "./ast";
export declare function format(program: Program, indent?: string | number): string;
//# sourceMappingURL=format.d.ts.map

1
node_modules/@huggingface/jinja/dist/format.d.ts.map generated vendored Normal file
View File

@@ -0,0 +1 @@
{"version":3,"file":"format.d.ts","sourceRoot":"","sources":["../src/format.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACX,OAAO,EA4BP,MAAM,OAAO,CAAC;AAsBf,wBAAgB,MAAM,CAAC,OAAO,EAAE,OAAO,EAAE,MAAM,GAAE,MAAM,GAAG,MAAa,GAAG,MAAM,CAI/E"}

2857
node_modules/@huggingface/jinja/dist/index.cjs generated vendored Normal file

File diff suppressed because it is too large Load Diff

29
node_modules/@huggingface/jinja/dist/index.d.ts generated vendored Normal file
View File

@@ -0,0 +1,29 @@
/**
* @file Jinja templating engine
*
* A minimalistic JavaScript reimplementation of the [Jinja](https://github.com/pallets/jinja) templating engine,
* to support the chat templates. Special thanks to [Tyler Laceby](https://github.com/tlaceby) for his amazing
* ["Guide to Interpreters"](https://github.com/tlaceby/guide-to-interpreters-series) tutorial series,
* which provided the basis for this implementation.
*
* See the [Transformers documentation](https://huggingface.co/docs/transformers/main/en/chat_templating) for more information.
*
* @module index
*/
import { tokenize } from "./lexer";
import { parse } from "./parser";
import { Environment, Interpreter } from "./runtime";
import type { Program } from "./ast";
export declare class Template {
parsed: Program;
/**
* @param {string} template The template string
*/
constructor(template: string);
render(items?: Record<string, unknown>): string;
format(options?: {
indent: string | number;
}): string;
}
export { Environment, Interpreter, tokenize, parse };
//# sourceMappingURL=index.d.ts.map

1
node_modules/@huggingface/jinja/dist/index.d.ts.map generated vendored Normal file
View File

@@ -0,0 +1 @@
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AACH,OAAO,EAAE,QAAQ,EAAE,MAAM,SAAS,CAAC;AACnC,OAAO,EAAE,KAAK,EAAE,MAAM,UAAU,CAAC;AACjC,OAAO,EAAE,WAAW,EAAE,WAAW,EAAgB,MAAM,WAAW,CAAC;AACnE,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,OAAO,CAAC;AAIrC,qBAAa,QAAQ;IACpB,MAAM,EAAE,OAAO,CAAC;IAEhB;;OAEG;gBACS,QAAQ,EAAE,MAAM;IAQ5B,MAAM,CAAC,KAAK,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,MAAM;IAkB/C,MAAM,CAAC,OAAO,CAAC,EAAE;QAAE,MAAM,EAAE,MAAM,GAAG,MAAM,CAAA;KAAE,GAAG,MAAM;CAGrD;AAED,OAAO,EAAE,WAAW,EAAE,WAAW,EAAE,QAAQ,EAAE,KAAK,EAAE,CAAC"}

2826
node_modules/@huggingface/jinja/dist/index.js generated vendored Normal file

File diff suppressed because it is too large Load Diff

53
node_modules/@huggingface/jinja/dist/lexer.d.ts generated vendored Normal file
View File

@@ -0,0 +1,53 @@
/**
* Represents tokens that our language understands in parsing.
*/
export declare const TOKEN_TYPES: Readonly<{
Text: "Text";
NumericLiteral: "NumericLiteral";
StringLiteral: "StringLiteral";
Identifier: "Identifier";
Equals: "Equals";
OpenParen: "OpenParen";
CloseParen: "CloseParen";
OpenStatement: "OpenStatement";
CloseStatement: "CloseStatement";
OpenExpression: "OpenExpression";
CloseExpression: "CloseExpression";
OpenSquareBracket: "OpenSquareBracket";
CloseSquareBracket: "CloseSquareBracket";
OpenCurlyBracket: "OpenCurlyBracket";
CloseCurlyBracket: "CloseCurlyBracket";
Comma: "Comma";
Dot: "Dot";
Colon: "Colon";
Pipe: "Pipe";
CallOperator: "CallOperator";
AdditiveBinaryOperator: "AdditiveBinaryOperator";
MultiplicativeBinaryOperator: "MultiplicativeBinaryOperator";
ComparisonBinaryOperator: "ComparisonBinaryOperator";
UnaryOperator: "UnaryOperator";
Comment: "Comment";
}>;
export type TokenType = keyof typeof TOKEN_TYPES;
/**
* Represents a single token in the template.
*/
export declare class Token {
value: string;
type: TokenType;
/**
* Constructs a new Token.
* @param {string} value The raw value as seen inside the source code.
* @param {TokenType} type The type of token.
*/
constructor(value: string, type: TokenType);
}
export interface PreprocessOptions {
trim_blocks?: boolean;
lstrip_blocks?: boolean;
}
/**
* Generate a list of tokens from a source string.
*/
export declare function tokenize(source: string, options?: PreprocessOptions): Token[];
//# sourceMappingURL=lexer.d.ts.map

1
node_modules/@huggingface/jinja/dist/lexer.d.ts.map generated vendored Normal file
View File

@@ -0,0 +1 @@
{"version":3,"file":"lexer.d.ts","sourceRoot":"","sources":["../src/lexer.ts"],"names":[],"mappings":"AAAA;;GAEG;AACH,eAAO,MAAM,WAAW;;;;;;;;;;;;;;;;;;;;;;;;;;EA4BtB,CAAC;AAEH,MAAM,MAAM,SAAS,GAAG,MAAM,OAAO,WAAW,CAAC;AAEjD;;GAEG;AACH,qBAAa,KAAK;IAOT,KAAK,EAAE,MAAM;IACb,IAAI,EAAE,SAAS;IAPvB;;;;OAIG;gBAEK,KAAK,EAAE,MAAM,EACb,IAAI,EAAE,SAAS;CAEvB;AAgED,MAAM,WAAW,iBAAiB;IACjC,WAAW,CAAC,EAAE,OAAO,CAAC;IACtB,aAAa,CAAC,EAAE,OAAO,CAAC;CACxB;AA8BD;;GAEG;AACH,wBAAgB,QAAQ,CAAC,MAAM,EAAE,MAAM,EAAE,OAAO,GAAE,iBAAsB,GAAG,KAAK,EAAE,CAqPjF"}

8
node_modules/@huggingface/jinja/dist/parser.d.ts generated vendored Normal file
View File

@@ -0,0 +1,8 @@
import { Token } from "./lexer";
import { Program } from "./ast";
/**
* Generate the Abstract Syntax Tree (AST) from a list of tokens.
* Operator precedence can be found here: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Operator_precedence#table
*/
export declare function parse(tokens: Token[]): Program;
//# sourceMappingURL=parser.d.ts.map

1
node_modules/@huggingface/jinja/dist/parser.d.ts.map generated vendored Normal file
View File

@@ -0,0 +1 @@
{"version":3,"file":"parser.d.ts","sourceRoot":"","sources":["../src/parser.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,EAAe,MAAM,SAAS,CAAC;AAG7C,OAAO,EACN,OAAO,EA4BP,MAAM,OAAO,CAAC;AAEf;;;GAGG;AACH,wBAAgB,KAAK,CAAC,MAAM,EAAE,KAAK,EAAE,GAAG,OAAO,CAunB9C"}

201
node_modules/@huggingface/jinja/dist/runtime.d.ts generated vendored Normal file
View File

@@ -0,0 +1,201 @@
import type { Statement, Program } from "./ast";
export type AnyRuntimeValue = IntegerValue | FloatValue | StringValue | BooleanValue | ObjectValue | ArrayValue | FunctionValue | NullValue | UndefinedValue;
/**
* Abstract base class for all Runtime values.
* Should not be instantiated directly.
*/
declare abstract class RuntimeValue<T> {
type: string;
value: T;
/**
* A collection of built-in functions for this type.
*/
builtins: Map<string, AnyRuntimeValue>;
/**
* Creates a new RuntimeValue.
*/
constructor(value?: T);
/**
* Determines truthiness or falsiness of the runtime value.
* This function should be overridden by subclasses if it has custom truthiness criteria.
* @returns {BooleanValue} BooleanValue(true) if the value is truthy, BooleanValue(false) otherwise.
*/
__bool__(): BooleanValue;
toString(): string;
}
/**
* Represents an integer value at runtime.
*/
export declare class IntegerValue extends RuntimeValue<number> {
type: string;
}
/**
* Represents a float value at runtime.
*/
export declare class FloatValue extends RuntimeValue<number> {
type: string;
toString(): string;
}
/**
* Represents a string value at runtime.
*/
export declare class StringValue extends RuntimeValue<string> {
type: string;
builtins: Map<string, AnyRuntimeValue>;
}
/**
* Represents a boolean value at runtime.
*/
export declare class BooleanValue extends RuntimeValue<boolean> {
type: string;
}
/**
* Represents an Object value at runtime.
*/
export declare class ObjectValue extends RuntimeValue<Map<string, AnyRuntimeValue>> {
type: string;
/**
* NOTE: necessary to override since all JavaScript arrays are considered truthy,
* while only non-empty Python arrays are consider truthy.
*
* e.g.,
* - JavaScript: {} && 5 -> 5
* - Python: {} and 5 -> {}
*/
__bool__(): BooleanValue;
builtins: Map<string, AnyRuntimeValue>;
items(): ArrayValue;
keys(): ArrayValue;
values(): ArrayValue;
toString(): string;
}
/**
* Represents a KeywordArguments value at runtime.
*/
export declare class KeywordArgumentsValue extends ObjectValue {
type: string;
}
/**
* Represents an Array value at runtime.
*/
export declare class ArrayValue extends RuntimeValue<AnyRuntimeValue[]> {
type: string;
builtins: Map<string, AnyRuntimeValue>;
/**
* NOTE: necessary to override since all JavaScript arrays are considered truthy,
* while only non-empty Python arrays are consider truthy.
*
* e.g.,
* - JavaScript: [] && 5 -> 5
* - Python: [] and 5 -> []
*/
__bool__(): BooleanValue;
toString(): string;
}
/**
* Represents a Tuple value at runtime.
* NOTE: We extend ArrayValue since JavaScript does not have a built-in Tuple type.
*/
export declare class TupleValue extends ArrayValue {
type: string;
}
/**
* Represents a Function value at runtime.
*/
export declare class FunctionValue extends RuntimeValue<(args: AnyRuntimeValue[], scope: Environment) => AnyRuntimeValue> {
type: string;
}
/**
* Represents a Null value at runtime.
*/
export declare class NullValue extends RuntimeValue<null> {
type: string;
}
/**
* Represents an Undefined value at runtime.
*/
export declare class UndefinedValue extends RuntimeValue<undefined> {
type: string;
}
/**
* Represents the current environment (scope) at runtime.
*/
export declare class Environment {
parent?: Environment | undefined;
/**
* The variables declared in this environment.
*/
variables: Map<string, AnyRuntimeValue>;
/**
* The tests available in this environment.
*/
tests: Map<string, (...value: AnyRuntimeValue[]) => boolean>;
constructor(parent?: Environment | undefined);
/**
* Set the value of a variable in the current environment.
*/
set(name: string, value: unknown): AnyRuntimeValue;
private declareVariable;
/**
* Set variable in the current scope.
* See https://jinja.palletsprojects.com/en/3.0.x/templates/#assignments for more information.
*/
setVariable(name: string, value: AnyRuntimeValue): AnyRuntimeValue;
/**
* Resolve the environment in which the variable is declared.
* @param {string} name The name of the variable.
* @returns {Environment} The environment in which the variable is declared.
*/
private resolve;
lookupVariable(name: string): AnyRuntimeValue;
}
export declare function setupGlobals(env: Environment): void;
export declare class Interpreter {
global: Environment;
constructor(env?: Environment);
/**
* Run the program.
*/
run(program: Program): AnyRuntimeValue;
/**
* Evaluates expressions following the binary operation type.
*/
private evaluateBinaryExpression;
private evaluateArguments;
private applyFilter;
/**
* Evaluates expressions following the filter operation type.
*/
private evaluateFilterExpression;
/**
* Evaluates expressions following the test operation type.
*/
private evaluateTestExpression;
/**
* Evaluates expressions following the select operation type.
*/
private evaluateSelectExpression;
/**
* Evaluates expressions following the unary operation type.
*/
private evaluateUnaryExpression;
private evaluateTernaryExpression;
private evalProgram;
private evaluateBlock;
private evaluateIdentifier;
private evaluateCallExpression;
private evaluateSliceExpression;
private evaluateMemberExpression;
private evaluateSet;
private evaluateIf;
private evaluateFor;
/**
* See https://jinja.palletsprojects.com/en/3.1.x/templates/#macros for more information.
*/
private evaluateMacro;
private evaluateCallStatement;
private evaluateFilterStatement;
evaluate(statement: Statement | undefined, environment: Environment): AnyRuntimeValue;
}
export {};
//# sourceMappingURL=runtime.d.ts.map

View File

@@ -0,0 +1 @@
{"version":3,"file":"runtime.d.ts","sourceRoot":"","sources":["../src/runtime.ts"],"names":[],"mappings":"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"}

33
node_modules/@huggingface/jinja/dist/utils.d.ts generated vendored Normal file
View File

@@ -0,0 +1,33 @@
/**
* Function that mimics Python's range() function.
* @param start The start value of the range.
* @param stop The stop value of the range. If not provided, start will be 0 and stop will be the provided start value.
* @param step The step value of the range. Defaults to 1.
* @returns The range of numbers.
*/
export declare function range(start: number, stop?: number, step?: number): number[];
/**
* Function that mimics Python's array slicing.
* @param array The array to slice.
* @param start The start index of the slice. Defaults to 0.
* @param stop The last index of the slice. Defaults to `array.length`.
* @param step The step value of the slice. Defaults to 1.
* @returns The sliced array.
*/
export declare function slice<T>(array: T[], start?: number, stop?: number, step?: number): T[];
/**
* Function that mimics Python's string.title() function.
* @param value The string to title case.
* @returns The title cased string.
*/
export declare function titleCase(value: string): string;
export declare function strftime_now(format: string): string;
/**
* A minimalistic implementation of Python's strftime function.
*/
export declare function strftime(date: Date, format: string): string;
/**
* Function that mimics Python's string.replace() function.
*/
export declare function replace(str: string, oldvalue: string, newvalue: string, count?: number | null): string;
//# sourceMappingURL=utils.d.ts.map

1
node_modules/@huggingface/jinja/dist/utils.d.ts.map generated vendored Normal file
View File

@@ -0,0 +1 @@
{"version":3,"file":"utils.d.ts","sourceRoot":"","sources":["../src/utils.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AACH,wBAAgB,KAAK,CAAC,KAAK,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE,MAAM,EAAE,IAAI,SAAI,GAAG,MAAM,EAAE,CAqBtE;AAED;;;;;;;GAOG;AACH,wBAAgB,KAAK,CAAC,CAAC,EAAE,KAAK,EAAE,CAAC,EAAE,EAAE,KAAK,CAAC,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE,MAAM,EAAE,IAAI,SAAI,GAAG,CAAC,EAAE,CAgBjF;AAED;;;;GAIG;AACH,wBAAgB,SAAS,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,CAE/C;AAED,wBAAgB,YAAY,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,CAEnD;AAED;;GAEG;AACH,wBAAgB,QAAQ,CAAC,IAAI,EAAE,IAAI,EAAE,MAAM,EAAE,MAAM,GAAG,MAAM,CA6B3D;AAMD;;GAEG;AACH,wBAAgB,OAAO,CAAC,GAAG,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,EAAE,KAAK,CAAC,EAAE,MAAM,GAAG,IAAI,GAAG,MAAM,CAYtG"}

54
node_modules/@huggingface/jinja/package.json generated vendored Normal file
View File

@@ -0,0 +1,54 @@
{
"name": "@huggingface/jinja",
"version": "0.5.5",
"description": "A minimalistic JavaScript implementation of the Jinja templating engine, specifically designed for parsing and rendering ML chat templates.",
"keywords": [
"face",
"hugging",
"huggingface",
"jinja",
"templates"
],
"license": "MIT",
"author": "Hugging Face",
"repository": "https://github.com/huggingface/huggingface.js.git",
"source": "src/index.ts",
"files": [
"dist",
"README.md",
"src",
"tsconfig.json"
],
"type": "module",
"main": "./dist/index.cjs",
"module": "./dist/index.js",
"types": "./dist/index.d.ts",
"exports": {
".": {
"types": "./dist/index.d.ts",
"require": "./dist/index.cjs",
"import": "./dist/index.js"
}
},
"publishConfig": {
"access": "public"
},
"devDependencies": {
"@huggingface/transformers": "^3.0.0",
"typescript": "^5.3.2",
"@huggingface/hub": "^2.8.0"
},
"engines": {
"node": ">=18"
},
"scripts": {
"lint": "eslint --quiet --fix --ext .cjs,.ts .",
"lint:check": "eslint --ext .cjs,.ts .",
"format": "oxfmt .",
"format:check": "oxfmt --check .",
"build": "tsup src/index.ts --format cjs,esm --clean && tsc --emitDeclarationOnly --declaration",
"test": "vitest run",
"test:browser": "vitest run --browser.name=chrome --browser.headless",
"check": "tsc"
}
}

320
node_modules/@huggingface/jinja/src/ast.ts generated vendored Normal file
View File

@@ -0,0 +1,320 @@
import type { Token } from "./lexer";
/**
* Statements do not result in a value at runtime. They contain one or more expressions internally.
*/
export class Statement {
type = "Statement";
}
/**
* Defines a block which contains many statements. Each chat template corresponds to one Program.
*/
export class Program extends Statement {
override type = "Program";
constructor(public body: Statement[]) {
super();
}
}
export class If extends Statement {
override type = "If";
constructor(
public test: Expression,
public body: Statement[],
public alternate: Statement[],
) {
super();
}
}
/**
* Loop over each item in a sequence
* https://jinja.palletsprojects.com/en/3.0.x/templates/#for
*/
export class For extends Statement {
override type = "For";
constructor(
public loopvar: Identifier | TupleLiteral,
public iterable: Expression,
public body: Statement[],
public defaultBlock: Statement[], // if no iteration took place
) {
super();
}
}
export class Break extends Statement {
override type = "Break";
}
export class Continue extends Statement {
override type = "Continue";
}
export class SetStatement extends Statement {
override type = "Set";
constructor(
public assignee: Expression,
public value: Expression | null,
public body: Statement[],
) {
super();
}
}
export class Macro extends Statement {
override type = "Macro";
constructor(
public name: Identifier,
public args: Expression[],
public body: Statement[],
) {
super();
}
}
export class Comment extends Statement {
override type = "Comment";
constructor(public value: string) {
super();
}
}
/**
* Expressions will result in a value at runtime (unlike statements).
*/
export class Expression extends Statement {
override type = "Expression";
}
export class MemberExpression extends Expression {
override type = "MemberExpression";
constructor(
public object: Expression,
public property: Expression,
public computed: boolean,
) {
super();
}
}
export class CallExpression extends Expression {
override type = "CallExpression";
constructor(
public callee: Expression,
public args: Expression[],
) {
super();
}
}
/**
* Represents a user-defined variable or symbol in the template.
*/
export class Identifier extends Expression {
override type = "Identifier";
/**
* @param {string} value The name of the identifier
*/
constructor(public value: string) {
super();
}
}
/**
* Abstract base class for all Literal expressions.
* Should not be instantiated directly.
*/
abstract class Literal<T> extends Expression {
override type = "Literal";
constructor(public value: T) {
super();
}
}
export class IntegerLiteral extends Literal<number> {
override type = "IntegerLiteral";
}
export class FloatLiteral extends Literal<number> {
override type = "FloatLiteral";
}
/**
* Represents a text constant in the template.
*/
export class StringLiteral extends Literal<string> {
override type = "StringLiteral";
}
/**
* Represents an array literal in the template.
*/
export class ArrayLiteral extends Literal<Expression[]> {
override type = "ArrayLiteral";
}
/**
* Represents a tuple literal in the template.
*/
export class TupleLiteral extends Literal<Expression[]> {
override type = "TupleLiteral";
}
/**
* Represents an object literal in the template.
*/
export class ObjectLiteral extends Literal<Map<Expression, Expression>> {
override type = "ObjectLiteral";
}
/**
* An operation with two sides, separated by an operator.
* Note: Either side can be a Complex Expression, with order
* of operations being determined by the operator.
*/
export class BinaryExpression extends Expression {
override type = "BinaryExpression";
constructor(
public operator: Token,
public left: Expression,
public right: Expression,
) {
super();
}
}
/**
* An operation with two sides, separated by the | operator.
* Operator precedence: https://github.com/pallets/jinja/issues/379#issuecomment-168076202
*/
export class FilterExpression extends Expression {
override type = "FilterExpression";
constructor(
public operand: Expression,
public filter: Identifier | CallExpression,
) {
super();
}
}
export class FilterStatement extends Statement {
override type = "FilterStatement";
constructor(
public filter: Identifier | CallExpression,
public body: Statement[],
) {
super();
}
}
/**
* An operation which filters a sequence of objects by applying a test to each object,
* and only selecting the objects with the test succeeding.
*
* It may also be used as a shortcut for a ternary operator.
*/
export class SelectExpression extends Expression {
override type = "SelectExpression";
constructor(
public lhs: Expression,
public test: Expression,
) {
super();
}
}
/**
* An operation with two sides, separated by the "is" operator.
*/
export class TestExpression extends Expression {
override type = "TestExpression";
constructor(
public operand: Expression,
public negate: boolean,
public test: Identifier, // TODO: Add support for non-identifier tests
) {
super();
}
}
/**
* An operation with one side (operator on the left).
*/
export class UnaryExpression extends Expression {
override type = "UnaryExpression";
constructor(
public operator: Token,
public argument: Expression,
) {
super();
}
}
export class SliceExpression extends Expression {
override type = "SliceExpression";
constructor(
public start: Expression | undefined = undefined,
public stop: Expression | undefined = undefined,
public step: Expression | undefined = undefined,
) {
super();
}
}
export class KeywordArgumentExpression extends Expression {
override type = "KeywordArgumentExpression";
constructor(
public key: Identifier,
public value: Expression,
) {
super();
}
}
export class SpreadExpression extends Expression {
override type = "SpreadExpression";
constructor(public argument: Expression) {
super();
}
}
export class CallStatement extends Statement {
override type = "CallStatement";
constructor(
public call: CallExpression,
public callerArgs: Expression[] | null,
public body: Statement[],
) {
super();
}
}
export class Ternary extends Expression {
override type = "Ternary";
constructor(
public condition: Expression,
public trueExpr: Expression,
public falseExpr: Expression,
) {
super();
}
}

318
node_modules/@huggingface/jinja/src/format.ts generated vendored Normal file
View File

@@ -0,0 +1,318 @@
import type {
Program,
Statement,
Comment,
If,
For,
SetStatement,
Macro,
Expression,
MemberExpression,
CallExpression,
Identifier,
FloatLiteral,
IntegerLiteral,
StringLiteral,
ArrayLiteral,
TupleLiteral,
ObjectLiteral,
BinaryExpression,
FilterExpression,
SelectExpression,
TestExpression,
UnaryExpression,
SliceExpression,
KeywordArgumentExpression,
CallStatement,
FilterStatement,
SpreadExpression,
Ternary,
} from "./ast";
const NEWLINE = "\n";
const OPEN_STATEMENT = "{%- ";
const CLOSE_STATEMENT = " -%}";
function getBinaryOperatorPrecedence(expr: BinaryExpression): number {
switch (expr.operator.type) {
case "MultiplicativeBinaryOperator":
return 4;
case "AdditiveBinaryOperator":
return 3;
case "ComparisonBinaryOperator":
return 2;
case "Identifier":
if (expr.operator.value === "and") return 1;
if (expr.operator.value === "in" || expr.operator.value === "not in") return 2;
return 0;
}
return 0;
}
export function format(program: Program, indent: string | number = "\t"): string {
const indentStr = typeof indent === "number" ? " ".repeat(indent) : indent;
const body = formatStatements(program.body, 0, indentStr);
return body.replace(/\n$/, "");
}
function createStatement(...text: string[]): string {
return OPEN_STATEMENT + text.join(" ") + CLOSE_STATEMENT;
}
function formatStatements(stmts: Statement[], depth: number, indentStr: string): string {
return stmts.map((stmt) => formatStatement(stmt, depth, indentStr)).join(NEWLINE);
}
function formatStatement(node: Statement, depth: number, indentStr: string): string {
const pad = indentStr.repeat(depth);
switch (node.type) {
case "Program":
return formatStatements((node as Program).body, depth, indentStr);
case "If":
return formatIf(node as If, depth, indentStr);
case "For":
return formatFor(node as For, depth, indentStr);
case "Set":
return formatSet(node as SetStatement, depth, indentStr);
case "Macro":
return formatMacro(node as Macro, depth, indentStr);
case "Break":
return pad + createStatement("break");
case "Continue":
return pad + createStatement("continue");
case "CallStatement":
return formatCallStatement(node as CallStatement, depth, indentStr);
case "FilterStatement":
return formatFilterStatement(node as FilterStatement, depth, indentStr);
case "Comment":
return pad + "{# " + (node as Comment).value + " #}";
default:
return pad + "{{- " + formatExpression(node as Expression) + " -}}";
}
}
function formatIf(node: If, depth: number, indentStr: string): string {
const pad = indentStr.repeat(depth);
const clauses: { test: Expression; body: Statement[] }[] = [];
let current: If | undefined = node;
while (current) {
clauses.push({ test: current.test, body: current.body });
if (current.alternate.length === 1 && current.alternate[0].type === "If") {
current = current.alternate[0] as If;
} else {
break;
}
}
// IF
let out =
pad +
createStatement("if", formatExpression(clauses[0].test)) +
NEWLINE +
formatStatements(clauses[0].body, depth + 1, indentStr);
// ELIF(s)
for (let i = 1; i < clauses.length; ++i) {
out +=
NEWLINE +
pad +
createStatement("elif", formatExpression(clauses[i].test)) +
NEWLINE +
formatStatements(clauses[i].body, depth + 1, indentStr);
}
// ELSE
if (current && current.alternate.length > 0) {
out +=
NEWLINE + pad + createStatement("else") + NEWLINE + formatStatements(current.alternate, depth + 1, indentStr);
}
// ENDIF
out += NEWLINE + pad + createStatement("endif");
return out;
}
function formatFor(node: For, depth: number, indentStr: string): string {
const pad = indentStr.repeat(depth);
let formattedIterable = "";
if (node.iterable.type === "SelectExpression") {
// Handle special case: e.g., `for x in [1, 2, 3] if x > 2`
const n = node.iterable as SelectExpression;
formattedIterable = `${formatExpression(n.lhs)} if ${formatExpression(n.test)}`;
} else {
formattedIterable = formatExpression(node.iterable);
}
let out =
pad +
createStatement("for", formatExpression(node.loopvar), "in", formattedIterable) +
NEWLINE +
formatStatements(node.body, depth + 1, indentStr);
if (node.defaultBlock.length > 0) {
out +=
NEWLINE + pad + createStatement("else") + NEWLINE + formatStatements(node.defaultBlock, depth + 1, indentStr);
}
out += NEWLINE + pad + createStatement("endfor");
return out;
}
function formatSet(node: SetStatement, depth: number, indentStr: string): string {
const pad = indentStr.repeat(depth);
const left = formatExpression(node.assignee);
const right = node.value ? formatExpression(node.value) : "";
const value = pad + createStatement("set", `${left}${node.value ? " = " + right : ""}`);
if (node.body.length === 0) {
return value;
}
return (
value + NEWLINE + formatStatements(node.body, depth + 1, indentStr) + NEWLINE + pad + createStatement("endset")
);
}
function formatMacro(node: Macro, depth: number, indentStr: string): string {
const pad = indentStr.repeat(depth);
const args = node.args.map(formatExpression).join(", ");
return (
pad +
createStatement("macro", `${node.name.value}(${args})`) +
NEWLINE +
formatStatements(node.body, depth + 1, indentStr) +
NEWLINE +
pad +
createStatement("endmacro")
);
}
function formatCallStatement(node: CallStatement, depth: number, indentStr: string): string {
const pad = indentStr.repeat(depth);
const params =
node.callerArgs && node.callerArgs.length > 0 ? `(${node.callerArgs.map(formatExpression).join(", ")})` : "";
const callExpr = formatExpression(node.call);
let out = pad + createStatement(`call${params}`, callExpr) + NEWLINE;
out += formatStatements(node.body, depth + 1, indentStr) + NEWLINE;
out += pad + createStatement("endcall");
return out;
}
function formatFilterStatement(node: FilterStatement, depth: number, indentStr: string): string {
const pad = indentStr.repeat(depth);
const spec =
node.filter.type === "Identifier"
? (node.filter as Identifier).value
: formatExpression(node.filter as CallExpression);
let out = pad + createStatement("filter", spec) + NEWLINE;
out += formatStatements(node.body, depth + 1, indentStr) + NEWLINE;
out += pad + createStatement("endfilter");
return out;
}
function formatExpression(node: Expression, parentPrec: number = -1): string {
switch (node.type) {
case "SpreadExpression": {
const n = node as SpreadExpression;
return `*${formatExpression(n.argument)}`;
}
case "Identifier":
return (node as Identifier).value;
case "IntegerLiteral":
return `${(node as IntegerLiteral).value}`;
case "FloatLiteral":
return `${(node as FloatLiteral).value}`;
case "StringLiteral":
return JSON.stringify((node as StringLiteral).value);
case "BinaryExpression": {
const n = node as BinaryExpression;
const thisPrecedence = getBinaryOperatorPrecedence(n);
const left = formatExpression(n.left, thisPrecedence);
const right = formatExpression(n.right, thisPrecedence + 1);
const expr = `${left} ${n.operator.value} ${right}`;
return thisPrecedence < parentPrec ? `(${expr})` : expr;
}
case "UnaryExpression": {
const n = node as UnaryExpression;
const val = n.operator.value + (n.operator.value === "not" ? " " : "") + formatExpression(n.argument, Infinity);
return val;
}
case "CallExpression": {
const n = node as CallExpression;
const args = n.args.map(formatExpression).join(", ");
return `${formatExpression(n.callee)}(${args})`;
}
case "MemberExpression": {
const n = node as MemberExpression;
let obj = formatExpression(n.object);
// only wrap if it's not a simple or chained access/call
if (
![
"Identifier",
"MemberExpression",
"CallExpression",
"StringLiteral",
"IntegerLiteral",
"FloatLiteral",
"ArrayLiteral",
"TupleLiteral",
"ObjectLiteral",
].includes(n.object.type)
) {
obj = `(${obj})`;
}
let prop = formatExpression(n.property);
if (!n.computed && n.property.type !== "Identifier") {
prop = `(${prop})`;
}
return n.computed ? `${obj}[${prop}]` : `${obj}.${prop}`;
}
case "FilterExpression": {
const n = node as FilterExpression;
const operand = formatExpression(n.operand, Infinity);
if (n.filter.type === "CallExpression") {
return `${operand} | ${formatExpression(n.filter)}`;
}
return `${operand} | ${(n.filter as Identifier).value}`;
}
case "SelectExpression": {
const n = node as SelectExpression;
return `${formatExpression(n.lhs)} if ${formatExpression(n.test)}`;
}
case "TestExpression": {
const n = node as TestExpression;
return `${formatExpression(n.operand)} is${n.negate ? " not" : ""} ${n.test.value}`;
}
case "ArrayLiteral":
case "TupleLiteral": {
const elems = ((node as ArrayLiteral | TupleLiteral).value as Expression[]).map(formatExpression);
const brackets = node.type === "ArrayLiteral" ? "[]" : "()";
return `${brackets[0]}${elems.join(", ")}${brackets[1]}`;
}
case "ObjectLiteral": {
const entries = Array.from((node as ObjectLiteral).value.entries()).map(
([k, v]) => `${formatExpression(k)}: ${formatExpression(v)}`,
);
return `{${entries.join(", ")}}`;
}
case "SliceExpression": {
const n = node as SliceExpression;
const s = n.start ? formatExpression(n.start) : "";
const t = n.stop ? formatExpression(n.stop) : "";
const st = n.step ? `:${formatExpression(n.step)}` : "";
return `${s}:${t}${st}`;
}
case "KeywordArgumentExpression": {
const n = node as KeywordArgumentExpression;
return `${n.key.value}=${formatExpression(n.value)}`;
}
case "Ternary": {
const n = node as Ternary;
const expr = `${formatExpression(n.trueExpr)} if ${formatExpression(n.condition, 0)} else ${formatExpression(
n.falseExpr,
)}`;
return parentPrec > -1 ? `(${expr})` : expr;
}
default:
throw new Error(`Unknown expression type: ${node.type}`);
}
}

57
node_modules/@huggingface/jinja/src/index.ts generated vendored Normal file
View File

@@ -0,0 +1,57 @@
/**
* @file Jinja templating engine
*
* A minimalistic JavaScript reimplementation of the [Jinja](https://github.com/pallets/jinja) templating engine,
* to support the chat templates. Special thanks to [Tyler Laceby](https://github.com/tlaceby) for his amazing
* ["Guide to Interpreters"](https://github.com/tlaceby/guide-to-interpreters-series) tutorial series,
* which provided the basis for this implementation.
*
* See the [Transformers documentation](https://huggingface.co/docs/transformers/main/en/chat_templating) for more information.
*
* @module index
*/
import { tokenize } from "./lexer";
import { parse } from "./parser";
import { Environment, Interpreter, setupGlobals } from "./runtime";
import type { Program } from "./ast";
import type { StringValue } from "./runtime";
import { format } from "./format";
export class Template {
parsed: Program;
/**
* @param {string} template The template string
*/
constructor(template: string) {
const tokens = tokenize(template, {
lstrip_blocks: true,
trim_blocks: true,
});
this.parsed = parse(tokens);
}
render(items?: Record<string, unknown>): string {
// Create a new environment for this template
const env = new Environment();
setupGlobals(env);
// Add user-defined variables
if (items) {
for (const [key, value] of Object.entries(items)) {
env.set(key, value);
}
}
const interpreter = new Interpreter(env);
const result = interpreter.run(this.parsed) as StringValue;
return result.value;
}
format(options?: { indent: string | number }): string {
return format(this.parsed, options?.indent || "\t");
}
}
export { Environment, Interpreter, tokenize, parse };

394
node_modules/@huggingface/jinja/src/lexer.ts generated vendored Normal file
View File

@@ -0,0 +1,394 @@
/**
* Represents tokens that our language understands in parsing.
*/
export const TOKEN_TYPES = Object.freeze({
Text: "Text", // The text between Jinja statements or expressions
NumericLiteral: "NumericLiteral", // e.g., 123, 1.0
StringLiteral: "StringLiteral", // 'string'
Identifier: "Identifier", // Variables, functions, statements, booleans, etc.
Equals: "Equals", // =
OpenParen: "OpenParen", // (
CloseParen: "CloseParen", // )
OpenStatement: "OpenStatement", // {%
CloseStatement: "CloseStatement", // %}
OpenExpression: "OpenExpression", // {{
CloseExpression: "CloseExpression", // }}
OpenSquareBracket: "OpenSquareBracket", // [
CloseSquareBracket: "CloseSquareBracket", // ]
OpenCurlyBracket: "OpenCurlyBracket", // {
CloseCurlyBracket: "CloseCurlyBracket", // }
Comma: "Comma", // ,
Dot: "Dot", // .
Colon: "Colon", // :
Pipe: "Pipe", // |
CallOperator: "CallOperator", // ()
AdditiveBinaryOperator: "AdditiveBinaryOperator", // + - ~
MultiplicativeBinaryOperator: "MultiplicativeBinaryOperator", // * / %
ComparisonBinaryOperator: "ComparisonBinaryOperator", // < > <= >= == !=
UnaryOperator: "UnaryOperator", // ! - +
Comment: "Comment", // {# ... #}
});
export type TokenType = keyof typeof TOKEN_TYPES;
/**
* Represents a single token in the template.
*/
export class Token {
/**
* Constructs a new Token.
* @param {string} value The raw value as seen inside the source code.
* @param {TokenType} type The type of token.
*/
constructor(
public value: string,
public type: TokenType,
) {}
}
function isWord(char: string): boolean {
return /\w/.test(char);
}
function isInteger(char: string): boolean {
return /[0-9]/.test(char);
}
function isWhitespace(char: string): boolean {
return /\s/.test(char);
}
/**
* A data structure which contains a list of rules to test
*/
const ORDERED_MAPPING_TABLE: [string, TokenType][] = [
// Control sequences
["{%", TOKEN_TYPES.OpenStatement],
["%}", TOKEN_TYPES.CloseStatement],
["{{", TOKEN_TYPES.OpenExpression],
["}}", TOKEN_TYPES.CloseExpression],
// Single character tokens
["(", TOKEN_TYPES.OpenParen],
[")", TOKEN_TYPES.CloseParen],
["{", TOKEN_TYPES.OpenCurlyBracket],
["}", TOKEN_TYPES.CloseCurlyBracket],
["[", TOKEN_TYPES.OpenSquareBracket],
["]", TOKEN_TYPES.CloseSquareBracket],
[",", TOKEN_TYPES.Comma],
[".", TOKEN_TYPES.Dot],
[":", TOKEN_TYPES.Colon],
["|", TOKEN_TYPES.Pipe],
// Comparison operators
["<=", TOKEN_TYPES.ComparisonBinaryOperator],
[">=", TOKEN_TYPES.ComparisonBinaryOperator],
["==", TOKEN_TYPES.ComparisonBinaryOperator],
["!=", TOKEN_TYPES.ComparisonBinaryOperator],
["<", TOKEN_TYPES.ComparisonBinaryOperator],
[">", TOKEN_TYPES.ComparisonBinaryOperator],
// Arithmetic operators
["+", TOKEN_TYPES.AdditiveBinaryOperator],
["-", TOKEN_TYPES.AdditiveBinaryOperator],
["~", TOKEN_TYPES.AdditiveBinaryOperator],
["*", TOKEN_TYPES.MultiplicativeBinaryOperator],
["/", TOKEN_TYPES.MultiplicativeBinaryOperator],
["%", TOKEN_TYPES.MultiplicativeBinaryOperator],
// Assignment operator
["=", TOKEN_TYPES.Equals],
];
const ESCAPE_CHARACTERS = new Map([
["n", "\n"], // New line
["t", "\t"], // Horizontal tab
["r", "\r"], // Carriage return
["b", "\b"], // Backspace
["f", "\f"], // Form feed
["v", "\v"], // Vertical tab
["'", "'"], // Single quote
['"', '"'], // Double quote
["\\", "\\"], // Backslash
]);
export interface PreprocessOptions {
trim_blocks?: boolean;
lstrip_blocks?: boolean;
}
function preprocess(template: string, options: PreprocessOptions = {}): string {
// According to https://jinja.palletsprojects.com/en/3.0.x/templates/#whitespace-control
// In the default configuration:
// - a single trailing newline is stripped if present
// - other whitespace (spaces, tabs, newlines etc.) is returned unchanged
if (template.endsWith("\n")) {
template = template.slice(0, -1);
}
if (options.lstrip_blocks) {
// The lstrip_blocks option can also be set to strip tabs and spaces from the
// beginning of a line to the start of a block. (Nothing will be stripped if
// there are other characters before the start of the block.)
template = template.replace(/^[ \t]*({[#%-])/gm, "$1");
}
if (options.trim_blocks) {
// If an application configures Jinja to trim_blocks, the first newline after
// a template tag is removed automatically (like in PHP).
template = template.replace(/([#%-]})\n/g, "$1");
}
// Handle the custom transformers-specific `generation` tag.
// See https://github.com/huggingface/transformers/pull/30650 for more information.
return template.replace(/{%\s*(end)?generation\s*%}/gs, "");
}
/**
* Generate a list of tokens from a source string.
*/
export function tokenize(source: string, options: PreprocessOptions = {}): Token[] {
const tokens: Token[] = [];
const src: string = preprocess(source, options);
let cursorPosition = 0;
let curlyBracketDepth = 0;
const consumeWhile = (predicate: (char: string) => boolean): string => {
let str = "";
while (predicate(src[cursorPosition])) {
// Check for escaped characters
if (src[cursorPosition] === "\\") {
// Consume the backslash
++cursorPosition;
// Check for end of input
if (cursorPosition >= src.length) throw new SyntaxError("Unexpected end of input");
// Add the escaped character
const escaped = src[cursorPosition++];
const unescaped = ESCAPE_CHARACTERS.get(escaped);
if (unescaped === undefined) {
throw new SyntaxError(`Unexpected escaped character: ${escaped}`);
}
str += unescaped;
continue;
}
str += src[cursorPosition++];
if (cursorPosition >= src.length) throw new SyntaxError("Unexpected end of input");
}
return str;
};
const stripTrailingWhitespace = () => {
const lastToken = tokens.at(-1);
if (lastToken && lastToken.type === TOKEN_TYPES.Text) {
lastToken.value = lastToken.value.trimEnd();
if (lastToken.value === "") {
tokens.pop(); // Remove empty text token
}
}
};
const skipLeadingWhitespace = () => {
while (cursorPosition < src.length && isWhitespace(src[cursorPosition])) {
++cursorPosition;
}
};
// Build each token until end of input
main: while (cursorPosition < src.length) {
// First, consume all text that is outside of a Jinja statement or expression
const lastTokenType = tokens.at(-1)?.type;
if (
lastTokenType === undefined ||
lastTokenType === TOKEN_TYPES.CloseStatement ||
lastTokenType === TOKEN_TYPES.CloseExpression ||
lastTokenType === TOKEN_TYPES.Comment
) {
let text = "";
while (
cursorPosition < src.length &&
// Keep going until we hit the next Jinja statement or expression
!(
src[cursorPosition] === "{" &&
(src[cursorPosition + 1] === "%" || src[cursorPosition + 1] === "{" || src[cursorPosition + 1] === "#")
)
) {
// Consume text
text += src[cursorPosition++];
}
// There is some text to add
if (text.length > 0) {
tokens.push(new Token(text, TOKEN_TYPES.Text));
continue;
}
}
// Possibly consume a comment
if (src[cursorPosition] === "{" && src[cursorPosition + 1] === "#") {
cursorPosition += 2; // Skip the opening {#
// Check for leading hyphen for whitespace control {#-
const stripBefore = src[cursorPosition] === "-";
if (stripBefore) {
++cursorPosition; // Skip the hyphen
}
let comment = "";
while (src[cursorPosition] !== "#" || src[cursorPosition + 1] !== "}") {
// Check for end of input
if (cursorPosition + 2 >= src.length) {
throw new SyntaxError("Missing end of comment tag");
}
comment += src[cursorPosition++];
}
// Check for trailing hyphen for whitespace control -#}
const stripAfter = comment.endsWith("-");
if (stripAfter) {
comment = comment.slice(0, -1); // Remove the trailing hyphen
}
// Apply whitespace stripping for leading hyphen
if (stripBefore) {
stripTrailingWhitespace();
}
tokens.push(new Token(comment, TOKEN_TYPES.Comment));
cursorPosition += 2; // Skip the closing #}
// Apply whitespace stripping for trailing hyphen
if (stripAfter) {
skipLeadingWhitespace();
}
continue;
}
// Check for opening statement with whitespace control {%-
if (src.slice(cursorPosition, cursorPosition + 3) === "{%-") {
stripTrailingWhitespace();
tokens.push(new Token("{%", TOKEN_TYPES.OpenStatement));
cursorPosition += 3; // Skip {%-
continue;
}
// Check for opening expression with whitespace control {{-
if (src.slice(cursorPosition, cursorPosition + 3) === "{{-") {
stripTrailingWhitespace();
tokens.push(new Token("{{", TOKEN_TYPES.OpenExpression));
curlyBracketDepth = 0;
cursorPosition += 3; // Skip {{-
continue;
}
// Consume (and ignore) all whitespace inside Jinja statements or expressions
consumeWhile(isWhitespace);
// Check for closing statement with whitespace control -%}
if (src.slice(cursorPosition, cursorPosition + 3) === "-%}") {
tokens.push(new Token("%}", TOKEN_TYPES.CloseStatement));
cursorPosition += 3; // Skip -%}
skipLeadingWhitespace();
continue;
}
// Check for closing expression with whitespace control -}}
if (src.slice(cursorPosition, cursorPosition + 3) === "-}}") {
tokens.push(new Token("}}", TOKEN_TYPES.CloseExpression));
cursorPosition += 3; // Skip -}}
skipLeadingWhitespace();
continue;
}
// Handle multi-character tokens
const char = src[cursorPosition];
// Check for unary operators
if (char === "-" || char === "+") {
const lastTokenType = tokens.at(-1)?.type;
if (lastTokenType === TOKEN_TYPES.Text || lastTokenType === undefined) {
throw new SyntaxError(`Unexpected character: ${char}`);
}
switch (lastTokenType) {
case TOKEN_TYPES.Identifier:
case TOKEN_TYPES.NumericLiteral:
case TOKEN_TYPES.StringLiteral:
case TOKEN_TYPES.CloseParen:
case TOKEN_TYPES.CloseSquareBracket:
// Part of a binary operator
// a - 1, 1 - 1, true - 1, "apple" - 1, (1) - 1, a[1] - 1
// Continue parsing normally
break;
default: {
// Is part of a unary operator
// (-1), [-1], (1 + -1), not -1, -apple
++cursorPosition; // consume the unary operator
// Check for numbers following the unary operator
const num = consumeWhile(isInteger);
tokens.push(
new Token(`${char}${num}`, num.length > 0 ? TOKEN_TYPES.NumericLiteral : TOKEN_TYPES.UnaryOperator),
);
continue;
}
}
}
// Try to match one of the tokens in the mapping table
for (const [seq, type] of ORDERED_MAPPING_TABLE) {
// inside an object literal, don't treat "}}" as expression-end
if (seq === "}}" && curlyBracketDepth > 0) {
continue;
}
const slice = src.slice(cursorPosition, cursorPosition + seq.length);
if (slice === seq) {
tokens.push(new Token(seq, type));
// possibly adjust the curly bracket depth
if (type === TOKEN_TYPES.OpenExpression) {
curlyBracketDepth = 0;
} else if (type === TOKEN_TYPES.OpenCurlyBracket) {
++curlyBracketDepth;
} else if (type === TOKEN_TYPES.CloseCurlyBracket) {
--curlyBracketDepth;
}
cursorPosition += seq.length;
continue main;
}
}
if (char === "'" || char === '"') {
++cursorPosition; // Skip the opening quote
const str = consumeWhile((c) => c !== char);
tokens.push(new Token(str, TOKEN_TYPES.StringLiteral));
++cursorPosition; // Skip the closing quote
continue;
}
if (isInteger(char)) {
// Consume integer part
let num = consumeWhile(isInteger);
// Possibly, consume fractional part
if (src[cursorPosition] === "." && isInteger(src[cursorPosition + 1])) {
++cursorPosition; // consume '.'
const frac = consumeWhile(isInteger);
num = `${num}.${frac}`;
}
tokens.push(new Token(num, TOKEN_TYPES.NumericLiteral));
continue;
}
if (isWord(char)) {
// consume any word characters and always classify as Identifier
const word = consumeWhile(isWord);
tokens.push(new Token(word, TOKEN_TYPES.Identifier));
continue;
}
throw new SyntaxError(`Unexpected character: ${char}`);
}
return tokens;
}

670
node_modules/@huggingface/jinja/src/parser.ts generated vendored Normal file
View File

@@ -0,0 +1,670 @@
import { Token, TOKEN_TYPES } from "./lexer";
import type { TokenType } from "./lexer";
import type { Statement } from "./ast";
import {
Program,
If,
For,
Break,
Continue,
SetStatement,
MemberExpression,
CallExpression,
Identifier,
StringLiteral,
ArrayLiteral,
ObjectLiteral,
BinaryExpression,
FilterExpression,
TestExpression,
UnaryExpression,
SliceExpression,
KeywordArgumentExpression,
TupleLiteral,
Macro,
SelectExpression,
CallStatement,
FilterStatement,
SpreadExpression,
IntegerLiteral,
FloatLiteral,
Ternary,
Comment,
} from "./ast";
/**
* Generate the Abstract Syntax Tree (AST) from a list of tokens.
* Operator precedence can be found here: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Operator_precedence#table
*/
export function parse(tokens: Token[]): Program {
const program = new Program([]);
let current = 0;
/**
* Consume the next token if it matches the expected type, otherwise throw an error.
* @param type The expected token type
* @param error The error message to throw if the token does not match the expected type
* @returns The consumed token
*/
function expect(type: string, error: string): Token {
const prev = tokens[current++];
if (!prev || prev.type !== type) {
throw new Error(`Parser Error: ${error}. ${prev.type} !== ${type}.`);
}
return prev;
}
function expectIdentifier(name: string): void {
if (!isIdentifier(name)) {
throw new SyntaxError(`Expected ${name}`);
}
++current;
}
function parseAny(): Statement {
switch (tokens[current].type) {
case TOKEN_TYPES.Comment:
return new Comment(tokens[current++].value);
case TOKEN_TYPES.Text:
return parseText();
case TOKEN_TYPES.OpenStatement:
return parseJinjaStatement();
case TOKEN_TYPES.OpenExpression:
return parseJinjaExpression();
default:
throw new SyntaxError(`Unexpected token type: ${tokens[current].type}`);
}
}
function is(...types: TokenType[]): boolean {
return current + types.length <= tokens.length && types.every((type, i) => type === tokens[current + i].type);
}
function isStatement(...names: string[]): boolean {
return (
tokens[current]?.type === TOKEN_TYPES.OpenStatement &&
tokens[current + 1]?.type === TOKEN_TYPES.Identifier &&
names.includes(tokens[current + 1]?.value)
);
}
function isIdentifier(...names: string[]): boolean {
return (
current + names.length <= tokens.length &&
names.every((name, i) => tokens[current + i].type === "Identifier" && name === tokens[current + i].value)
);
}
function parseText(): StringLiteral {
return new StringLiteral(expect(TOKEN_TYPES.Text, "Expected text token").value);
}
function parseJinjaStatement(): Statement {
// Consume {% token
expect(TOKEN_TYPES.OpenStatement, "Expected opening statement token");
// next token must be Identifier whose .value tells us which statement
if (tokens[current].type !== TOKEN_TYPES.Identifier) {
throw new SyntaxError(`Unknown statement, got ${tokens[current].type}`);
}
const name = tokens[current].value;
let result: Statement;
switch (name) {
case "set":
++current;
result = parseSetStatement();
break;
case "if":
++current;
result = parseIfStatement();
// expect {% endif %}
expect(TOKEN_TYPES.OpenStatement, "Expected {% token");
expectIdentifier("endif");
expect(TOKEN_TYPES.CloseStatement, "Expected %} token");
break;
case "macro":
++current;
result = parseMacroStatement();
// expect {% endmacro %}
expect(TOKEN_TYPES.OpenStatement, "Expected {% token");
expectIdentifier("endmacro");
expect(TOKEN_TYPES.CloseStatement, "Expected %} token");
break;
case "for":
++current;
result = parseForStatement();
// expect {% endfor %}
expect(TOKEN_TYPES.OpenStatement, "Expected {% token");
expectIdentifier("endfor");
expect(TOKEN_TYPES.CloseStatement, "Expected %} token");
break;
case "call": {
++current; // consume 'call'
let callerArgs: Statement[] | null = null;
if (is(TOKEN_TYPES.OpenParen)) {
// Optional caller arguments, e.g. {% call(user) dump_users(...) %}
callerArgs = parseArgs();
}
const callee = parsePrimaryExpression();
if (callee.type !== "Identifier") {
throw new SyntaxError(`Expected identifier following call statement`);
}
const callArgs = parseArgs();
expect(TOKEN_TYPES.CloseStatement, "Expected closing statement token");
const body: Statement[] = [];
while (!isStatement("endcall")) {
body.push(parseAny());
}
expect(TOKEN_TYPES.OpenStatement, "Expected '{%'");
expectIdentifier("endcall");
expect(TOKEN_TYPES.CloseStatement, "Expected closing statement token");
const callExpr = new CallExpression(callee, callArgs);
result = new CallStatement(callExpr, callerArgs, body);
break;
}
case "break":
++current;
expect(TOKEN_TYPES.CloseStatement, "Expected closing statement token");
result = new Break();
break;
case "continue":
++current;
expect(TOKEN_TYPES.CloseStatement, "Expected closing statement token");
result = new Continue();
break;
case "filter": {
++current; // consume 'filter'
let filterNode = parsePrimaryExpression();
if (filterNode instanceof Identifier && is(TOKEN_TYPES.OpenParen)) {
filterNode = parseCallExpression(filterNode);
}
expect(TOKEN_TYPES.CloseStatement, "Expected closing statement token");
const filterBody: Statement[] = [];
while (!isStatement("endfilter")) {
filterBody.push(parseAny());
}
expect(TOKEN_TYPES.OpenStatement, "Expected '{%'");
expectIdentifier("endfilter");
expect(TOKEN_TYPES.CloseStatement, "Expected '%}'");
result = new FilterStatement(filterNode as Identifier | CallExpression, filterBody);
break;
}
default:
throw new SyntaxError(`Unknown statement type: ${name}`);
}
return result;
}
function parseJinjaExpression(): Statement {
// Consume {{ }} tokens
expect(TOKEN_TYPES.OpenExpression, "Expected opening expression token");
const result = parseExpression();
expect(TOKEN_TYPES.CloseExpression, "Expected closing expression token");
return result;
}
// NOTE: `set` acts as both declaration statement and assignment expression
function parseSetStatement(): Statement {
const left = parseExpressionSequence();
let value: Statement | null = null;
const body: Statement[] = [];
if (is(TOKEN_TYPES.Equals)) {
++current;
value = parseExpressionSequence();
} else {
// parsing multiline set here
expect(TOKEN_TYPES.CloseStatement, "Expected %} token");
while (!isStatement("endset")) {
body.push(parseAny());
}
expect(TOKEN_TYPES.OpenStatement, "Expected {% token");
expectIdentifier("endset");
}
expect(TOKEN_TYPES.CloseStatement, "Expected closing statement token");
return new SetStatement(left, value, body);
}
function parseIfStatement(): If {
const test = parseExpression();
expect(TOKEN_TYPES.CloseStatement, "Expected closing statement token");
const body: Statement[] = [];
const alternate: Statement[] = [];
// Keep parsing 'if' body until we reach the first {% elif %} or {% else %} or {% endif %}
while (!isStatement("elif", "else", "endif")) {
body.push(parseAny());
}
// handle {% elif %}
if (isStatement("elif")) {
++current; // consume {%
++current; // consume 'elif'
const result = parseIfStatement(); // nested If
alternate.push(result);
}
// handle {% else %}
else if (isStatement("else")) {
++current; // consume {%
++current; // consume 'else'
expect(TOKEN_TYPES.CloseStatement, "Expected closing statement token");
// keep going until we hit {% endif %}
while (!isStatement("endif")) {
alternate.push(parseAny());
}
}
return new If(test, body, alternate);
}
function parseMacroStatement(): Macro {
const name = parsePrimaryExpression();
if (name.type !== "Identifier") {
throw new SyntaxError(`Expected identifier following macro statement`);
}
const args = parseArgs();
expect(TOKEN_TYPES.CloseStatement, "Expected closing statement token");
// Body of macro
const body: Statement[] = [];
// Keep going until we hit {% endmacro
while (!isStatement("endmacro")) {
body.push(parseAny());
}
return new Macro(name as Identifier, args, body);
}
function parseExpressionSequence(primary = false): Statement {
const fn = primary ? parsePrimaryExpression : parseExpression;
const expressions = [fn()];
const isTuple = is(TOKEN_TYPES.Comma);
while (isTuple) {
++current; // consume comma
expressions.push(fn());
if (!is(TOKEN_TYPES.Comma)) {
break;
}
}
return isTuple ? new TupleLiteral(expressions) : expressions[0];
}
function parseForStatement(): For {
// e.g., `message` in `for message in messages`
const loopVariable = parseExpressionSequence(true); // should be an identifier/tuple
if (!(loopVariable instanceof Identifier || loopVariable instanceof TupleLiteral)) {
throw new SyntaxError(`Expected identifier/tuple for the loop variable, got ${loopVariable.type} instead`);
}
if (!isIdentifier("in")) {
throw new SyntaxError("Expected `in` keyword following loop variable");
}
++current;
// `messages` in `for message in messages`
const iterable = parseExpression();
expect(TOKEN_TYPES.CloseStatement, "Expected closing statement token");
// Body of for loop
const body: Statement[] = [];
// Keep going until we hit {% endfor or {% else
while (!isStatement("endfor", "else")) {
body.push(parseAny());
}
// (Optional) else block
const alternative: Statement[] = [];
if (isStatement("else")) {
++current; // consume {%
++current; // consume 'else'
expect(TOKEN_TYPES.CloseStatement, "Expected closing statement token");
while (!isStatement("endfor")) {
alternative.push(parseAny());
}
}
return new For(loopVariable, iterable, body, alternative);
}
function parseExpression(): Statement {
// Choose parse function with lowest precedence
return parseIfExpression();
}
function parseIfExpression(): Statement {
const a = parseLogicalOrExpression();
if (isIdentifier("if")) {
// Ternary expression
++current; // consume 'if'
const test = parseLogicalOrExpression();
if (isIdentifier("else")) {
// Ternary expression with else
++current; // consume 'else'
const falseExpr = parseIfExpression(); // recurse to support chained ternaries
return new Ternary(test, a, falseExpr);
} else {
// Select expression on iterable
return new SelectExpression(a, test);
}
}
return a;
}
function parseLogicalOrExpression(): Statement {
let left = parseLogicalAndExpression();
while (isIdentifier("or")) {
const operator = tokens[current];
++current;
const right = parseLogicalAndExpression();
left = new BinaryExpression(operator, left, right);
}
return left;
}
function parseLogicalAndExpression(): Statement {
let left = parseLogicalNegationExpression();
while (isIdentifier("and")) {
const operator = tokens[current];
++current;
const right = parseLogicalNegationExpression();
left = new BinaryExpression(operator, left, right);
}
return left;
}
function parseLogicalNegationExpression(): Statement {
let right: UnaryExpression | undefined;
// Try parse unary operators
while (isIdentifier("not")) {
// not not ...
const operator = tokens[current];
++current;
const arg = parseLogicalNegationExpression(); // not test.x === not (test.x)
right = new UnaryExpression(operator, arg);
}
return right ?? parseComparisonExpression();
}
function parseComparisonExpression(): Statement {
// NOTE: membership has same precedence as comparison
// e.g., ('a' in 'apple' == 'b' in 'banana') evaluates as ('a' in ('apple' == ('b' in 'banana')))
let left = parseAdditiveExpression();
while (true) {
let operator: Token;
if (isIdentifier("not", "in")) {
operator = new Token("not in", TOKEN_TYPES.Identifier);
current += 2;
} else if (isIdentifier("in")) {
operator = tokens[current++];
} else if (is(TOKEN_TYPES.ComparisonBinaryOperator)) {
operator = tokens[current++];
} else {
break;
}
const right = parseAdditiveExpression();
left = new BinaryExpression(operator, left, right);
}
return left;
}
function parseAdditiveExpression(): Statement {
let left = parseMultiplicativeExpression();
while (is(TOKEN_TYPES.AdditiveBinaryOperator)) {
const operator = tokens[current];
++current;
const right = parseMultiplicativeExpression();
left = new BinaryExpression(operator, left, right);
}
return left;
}
function parseCallMemberExpression(): Statement {
// Handle member expressions recursively
const member = parseMemberExpression(parsePrimaryExpression()); // foo.x
if (is(TOKEN_TYPES.OpenParen)) {
// foo.x()
return parseCallExpression(member);
}
return member;
}
function parseCallExpression(callee: Statement): Statement {
let expression: Statement = new CallExpression(callee, parseArgs());
expression = parseMemberExpression(expression); // foo.x().y
if (is(TOKEN_TYPES.OpenParen)) {
// foo.x()()
expression = parseCallExpression(expression);
}
return expression;
}
function parseArgs(): Statement[] {
// add (x + 5, foo())
expect(TOKEN_TYPES.OpenParen, "Expected opening parenthesis for arguments list");
const args = parseArgumentsList();
expect(TOKEN_TYPES.CloseParen, "Expected closing parenthesis for arguments list");
return args;
}
function parseArgumentsList(): Statement[] {
// comma-separated arguments list
const args = [];
while (!is(TOKEN_TYPES.CloseParen)) {
let argument: Statement;
// unpacking: *expr
if (tokens[current].type === TOKEN_TYPES.MultiplicativeBinaryOperator && tokens[current].value === "*") {
++current;
const expr = parseExpression();
argument = new SpreadExpression(expr);
} else {
argument = parseExpression();
if (is(TOKEN_TYPES.Equals)) {
// keyword argument
// e.g., func(x = 5, y = a or b)
++current; // consume equals
if (!(argument instanceof Identifier)) {
throw new SyntaxError(`Expected identifier for keyword argument`);
}
const value = parseExpression();
argument = new KeywordArgumentExpression(argument as Identifier, value);
}
}
args.push(argument);
if (is(TOKEN_TYPES.Comma)) {
++current; // consume comma
}
}
return args;
}
function parseMemberExpressionArgumentsList(): Statement {
// NOTE: This also handles slice expressions colon-separated arguments list
// e.g., ['test'], [0], [:2], [1:], [1:2], [1:2:3]
const slices: (Statement | undefined)[] = [];
let isSlice = false;
while (!is(TOKEN_TYPES.CloseSquareBracket)) {
if (is(TOKEN_TYPES.Colon)) {
// A case where a default is used
// e.g., [:2] will be parsed as [undefined, 2]
slices.push(undefined);
++current; // consume colon
isSlice = true;
} else {
slices.push(parseExpression());
if (is(TOKEN_TYPES.Colon)) {
++current; // consume colon after expression, if it exists
isSlice = true;
}
}
}
if (slices.length === 0) {
// []
throw new SyntaxError(`Expected at least one argument for member/slice expression`);
}
if (isSlice) {
if (slices.length > 3) {
throw new SyntaxError(`Expected 0-3 arguments for slice expression`);
}
return new SliceExpression(...slices);
}
return slices[0] as Statement; // normal member expression
}
function parseMemberExpression(object: Statement): Statement {
while (is(TOKEN_TYPES.Dot) || is(TOKEN_TYPES.OpenSquareBracket)) {
const operator = tokens[current]; // . or [
++current;
let property: Statement;
const computed = operator.type === TOKEN_TYPES.OpenSquareBracket;
if (computed) {
// computed (i.e., bracket notation: obj[expr])
property = parseMemberExpressionArgumentsList();
expect(TOKEN_TYPES.CloseSquareBracket, "Expected closing square bracket");
} else {
// non-computed (i.e., dot notation: obj.expr)
property = parsePrimaryExpression(); // should be an identifier
if (property.type !== "Identifier") {
throw new SyntaxError(`Expected identifier following dot operator`);
}
}
object = new MemberExpression(object, property, computed);
}
return object;
}
function parseMultiplicativeExpression(): Statement {
let left = parseTestExpression();
// Multiplicative operators have higher precedence than test expressions
// e.g., (4 * 4 is divisibleby(2)) evaluates as (4 * (4 is divisibleby(2)))
while (is(TOKEN_TYPES.MultiplicativeBinaryOperator)) {
const operator = tokens[current++];
const right = parseTestExpression();
left = new BinaryExpression(operator, left, right);
}
return left;
}
function parseTestExpression(): Statement {
let operand = parseFilterExpression();
while (isIdentifier("is")) {
// Support chaining tests
++current; // consume is
const negate = isIdentifier("not");
if (negate) {
++current; // consume not
}
const filter = parsePrimaryExpression();
if (!(filter instanceof Identifier)) {
throw new SyntaxError(`Expected identifier for the test`);
}
// TODO: Add support for non-identifier tests
operand = new TestExpression(operand, negate, filter);
}
return operand;
}
function parseFilterExpression(): Statement {
let operand = parseCallMemberExpression();
while (is(TOKEN_TYPES.Pipe)) {
// Support chaining filters
++current; // consume pipe
let filter = parsePrimaryExpression(); // should be an identifier
if (!(filter instanceof Identifier)) {
throw new SyntaxError(`Expected identifier for the filter`);
}
if (is(TOKEN_TYPES.OpenParen)) {
filter = parseCallExpression(filter);
}
operand = new FilterExpression(operand, filter as Identifier | CallExpression);
}
return operand;
}
function parsePrimaryExpression(): Statement {
// Primary expression: number, string, identifier, function call, parenthesized expression
const token = tokens[current++];
switch (token.type) {
case TOKEN_TYPES.NumericLiteral: {
const num = token.value;
return num.includes(".") ? new FloatLiteral(Number(num)) : new IntegerLiteral(Number(num));
}
case TOKEN_TYPES.StringLiteral: {
let value = token.value;
while (is(TOKEN_TYPES.StringLiteral)) {
value += tokens[current++].value;
}
return new StringLiteral(value);
}
case TOKEN_TYPES.Identifier:
return new Identifier(token.value);
case TOKEN_TYPES.OpenParen: {
const expression = parseExpressionSequence();
expect(TOKEN_TYPES.CloseParen, "Expected closing parenthesis, got ${tokens[current].type} instead.");
return expression;
}
case TOKEN_TYPES.OpenSquareBracket: {
const values = [];
while (!is(TOKEN_TYPES.CloseSquareBracket)) {
values.push(parseExpression());
if (is(TOKEN_TYPES.Comma)) {
++current; // consume comma
}
}
++current; // consume closing square bracket
return new ArrayLiteral(values);
}
case TOKEN_TYPES.OpenCurlyBracket: {
const values = new Map();
while (!is(TOKEN_TYPES.CloseCurlyBracket)) {
const key = parseExpression();
expect(TOKEN_TYPES.Colon, "Expected colon between key and value in object literal");
const value = parseExpression();
values.set(key, value);
if (is(TOKEN_TYPES.Comma)) {
++current; // consume comma
}
}
++current; // consume closing curly bracket
return new ObjectLiteral(values);
}
default:
throw new SyntaxError(`Unexpected token: ${token.type}`);
}
}
while (current < tokens.length) {
program.body.push(parseAny());
}
return program;
}

1880
node_modules/@huggingface/jinja/src/runtime.ts generated vendored Normal file

File diff suppressed because it is too large Load Diff

123
node_modules/@huggingface/jinja/src/utils.ts generated vendored Normal file
View File

@@ -0,0 +1,123 @@
/**
* Function that mimics Python's range() function.
* @param start The start value of the range.
* @param stop The stop value of the range. If not provided, start will be 0 and stop will be the provided start value.
* @param step The step value of the range. Defaults to 1.
* @returns The range of numbers.
*/
export function range(start: number, stop?: number, step = 1): number[] {
if (stop === undefined) {
stop = start;
start = 0;
}
if (step === 0) {
throw new Error("range() step must not be zero");
}
const result: number[] = [];
if (step > 0) {
for (let i = start; i < stop; i += step) {
result.push(i);
}
} else {
for (let i = start; i > stop; i += step) {
result.push(i);
}
}
return result;
}
/**
* Function that mimics Python's array slicing.
* @param array The array to slice.
* @param start The start index of the slice. Defaults to 0.
* @param stop The last index of the slice. Defaults to `array.length`.
* @param step The step value of the slice. Defaults to 1.
* @returns The sliced array.
*/
export function slice<T>(array: T[], start?: number, stop?: number, step = 1): T[] {
const direction = Math.sign(step);
if (direction >= 0) {
start = (start ??= 0) < 0 ? Math.max(array.length + start, 0) : Math.min(start, array.length);
stop = (stop ??= array.length) < 0 ? Math.max(array.length + stop, 0) : Math.min(stop, array.length);
} else {
start = (start ??= array.length - 1) < 0 ? Math.max(array.length + start, -1) : Math.min(start, array.length - 1);
stop = (stop ??= -1) < -1 ? Math.max(array.length + stop, -1) : Math.min(stop, array.length - 1);
}
const result: T[] = [];
for (let i = start; direction * i < direction * stop; i += step) {
result.push(array[i]);
}
return result;
}
/**
* Function that mimics Python's string.title() function.
* @param value The string to title case.
* @returns The title cased string.
*/
export function titleCase(value: string): string {
return value.replace(/\b\w/g, (c) => c.toUpperCase());
}
export function strftime_now(format: string): string {
return strftime(new Date(), format);
}
/**
* A minimalistic implementation of Python's strftime function.
*/
export function strftime(date: Date, format: string): string {
// Set locale to undefined to use the default locale
const monthFormatterLong = new Intl.DateTimeFormat(undefined, { month: "long" });
const monthFormatterShort = new Intl.DateTimeFormat(undefined, { month: "short" });
const pad2 = (n: number): string => (n < 10 ? "0" + n : n.toString());
return format.replace(/%[YmdbBHM%]/g, (token) => {
switch (token) {
case "%Y":
return date.getFullYear().toString();
case "%m":
return pad2(date.getMonth() + 1);
case "%d":
return pad2(date.getDate());
case "%b":
return monthFormatterShort.format(date);
case "%B":
return monthFormatterLong.format(date);
case "%H":
return pad2(date.getHours());
case "%M":
return pad2(date.getMinutes());
case "%%":
return "%";
default:
return token;
}
});
}
function escapeRegExp(s: string): string {
return s.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
}
/**
* Function that mimics Python's string.replace() function.
*/
export function replace(str: string, oldvalue: string, newvalue: string, count?: number | null): string {
if (count === 0) return str;
let remaining = count == null || count < 0 ? Infinity : count;
// NB: Use a Unicode-aware global regex so unpaired surrogates won't match
const pattern = oldvalue.length === 0 ? new RegExp("(?=)", "gu") : new RegExp(escapeRegExp(oldvalue), "gu");
return str.replaceAll(pattern, (match) => {
if (remaining > 0) {
--remaining;
return newvalue;
}
return match;
});
}

20
node_modules/@huggingface/jinja/tsconfig.json generated vendored Normal file
View File

@@ -0,0 +1,20 @@
{
"compilerOptions": {
"allowSyntheticDefaultImports": true,
"lib": ["ES2022", "DOM"],
"module": "ESNext",
"moduleResolution": "node",
"target": "ESNext",
"forceConsistentCasingInFileNames": true,
"strict": true,
"noImplicitAny": true,
"strictNullChecks": true,
"skipLibCheck": true,
"noImplicitOverride": true,
"outDir": "./dist",
"declaration": true,
"declarationMap": true
},
"include": ["src", "index.ts"],
"exclude": ["dist"]
}