API support for added template functions (eg. cookies)

This commit is contained in:
Gregory Schier
2025-05-25 20:25:13 -07:00
parent 9d54e40aa8
commit 0a932798a0
14 changed files with 285 additions and 46 deletions

View File

@@ -1,6 +1,6 @@
{
"name": "@yaakapp/api",
"version": "0.5.3",
"version": "0.6.0",
"main": "lib/index.js",
"typings": "./lib/index.d.ts",
"files": [

View File

@@ -104,7 +104,11 @@ hideLabel?: boolean,
/**
* The default value
*/
defaultValue?: string, disabled?: boolean, };
defaultValue?: string, disabled?: boolean,
/**
* Longer description of the input, likely shown in a tooltip
*/
description?: string, };
export type FormInputCheckbox = {
/**
@@ -131,7 +135,11 @@ hideLabel?: boolean,
/**
* The default value
*/
defaultValue?: string, disabled?: boolean, };
defaultValue?: string, disabled?: boolean,
/**
* Longer description of the input, likely shown in a tooltip
*/
description?: string, };
export type FormInputEditor = {
/**
@@ -170,7 +178,11 @@ hideLabel?: boolean,
/**
* The default value
*/
defaultValue?: string, disabled?: boolean, };
defaultValue?: string, disabled?: boolean,
/**
* Longer description of the input, likely shown in a tooltip
*/
description?: string, };
export type FormInputFile = {
/**
@@ -205,7 +217,11 @@ hideLabel?: boolean,
/**
* The default value
*/
defaultValue?: string, disabled?: boolean, };
defaultValue?: string, disabled?: boolean,
/**
* Longer description of the input, likely shown in a tooltip
*/
description?: string, };
export type FormInputHttpRequest = {
/**
@@ -232,7 +248,11 @@ hideLabel?: boolean,
/**
* The default value
*/
defaultValue?: string, disabled?: boolean, };
defaultValue?: string, disabled?: boolean,
/**
* Longer description of the input, likely shown in a tooltip
*/
description?: string, };
export type FormInputMarkdown = { content: string, hidden?: boolean, };
@@ -265,7 +285,11 @@ hideLabel?: boolean,
/**
* The default value
*/
defaultValue?: string, disabled?: boolean, };
defaultValue?: string, disabled?: boolean,
/**
* Longer description of the input, likely shown in a tooltip
*/
description?: string, };
export type FormInputSelectOption = { label: string, value: string, };
@@ -306,7 +330,11 @@ hideLabel?: boolean,
/**
* The default value
*/
defaultValue?: string, disabled?: boolean, };
defaultValue?: string, disabled?: boolean,
/**
* Longer description of the input, likely shown in a tooltip
*/
description?: string, };
export type GenericCompletionOption = { label: string, detail?: string, info?: string, type?: CompletionOptionType, boost?: number, };

View File

@@ -36,9 +36,6 @@ var plugin = {
}
],
async onRender(ctx, args) {
console.log("COOKIE", args.values.cookie_name);
const cookies = await ctx.cookies.listNames({});
console.log("COOKIES", cookies);
return ctx.cookies.getValue({ name: String(args.values.cookie_name) });
}
}

View File

@@ -0,0 +1,49 @@
"use strict";
var __defProp = Object.defineProperty;
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
var __getOwnPropNames = Object.getOwnPropertyNames;
var __hasOwnProp = Object.prototype.hasOwnProperty;
var __export = (target, all) => {
for (var name in all)
__defProp(target, name, { get: all[name], enumerable: true });
};
var __copyProps = (to, from, except, desc) => {
if (from && typeof from === "object" || typeof from === "function") {
for (let key of __getOwnPropNames(from))
if (!__hasOwnProp.call(to, key) && key !== except)
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
}
return to;
};
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
// src/index.ts
var src_exports = {};
__export(src_exports, {
plugin: () => plugin
});
module.exports = __toCommonJS(src_exports);
var plugin = {
templateFunctions: [
{
name: "base64.encode",
description: "Encode a value to base64",
args: [{ label: "Plain Text", type: "text", name: "value", multiLine: true }],
async onRender(_ctx, args) {
return Buffer.from(args.values.value ?? "").toString("base64");
}
},
{
name: "base64.decode",
description: "Decode a value from base64",
args: [{ label: "Encoded Value", type: "text", name: "value", multiLine: true }],
async onRender(_ctx, args) {
return Buffer.from(args.values.value ?? "", "base64").toString("utf-8");
}
}
]
};
// Annotate the CommonJS export names for ESM import in node:
0 && (module.exports = {
plugin
});

View File

@@ -0,0 +1,9 @@
{
"name": "@yaakapp/template-function-encode",
"private": true,
"version": "0.0.1",
"scripts": {
"build": "yaakcli build ./src/index.ts",
"dev": "yaakcli dev ./src/index.js"
}
}

View File

@@ -25,24 +25,76 @@ __export(src_exports, {
module.exports = __toCommonJS(src_exports);
var import_node_crypto = require("node:crypto");
var algorithms = ["md5", "sha1", "sha256", "sha512"];
var plugin = {
templateFunctions: algorithms.map((algorithm) => ({
name: `hash.${algorithm}`,
description: "Hash a value to its hexidecimal representation",
args: [
{
name: "input",
label: "Input",
placeholder: "input text",
type: "text"
}
],
async onRender(_ctx, args) {
if (!args.values.input) return "";
return (0, import_node_crypto.createHash)(algorithm).update(args.values.input, "utf-8").digest("hex");
var encodings = ["base64", "hex"];
var hashFunctions = algorithms.map((algorithm) => ({
name: `hash.${algorithm}`,
description: "Hash a value to its hexidecimal representation",
args: [
{
type: "text",
name: "input",
label: "Input",
placeholder: "input text",
multiLine: true
},
{
type: "select",
name: "encoding",
label: "Encoding",
defaultValue: "base64",
options: encodings.map((encoding) => ({
label: capitalize(encoding),
value: encoding
}))
}
}))
],
async onRender(_ctx, args) {
const input = String(args.values.input);
const encoding = String(args.values.encoding);
return (0, import_node_crypto.createHash)(algorithm).update(input, "utf-8").digest(encoding);
}
}));
var hmacFunctions = algorithms.map((algorithm) => ({
name: `hmac.${algorithm}`,
description: "Compute the HMAC of a value",
args: [
{
type: "text",
name: "input",
label: "Input",
placeholder: "input text",
multiLine: true
},
{
type: "text",
name: "key",
label: "Key",
password: true
},
{
type: "select",
name: "encoding",
label: "Encoding",
defaultValue: "base64",
options: encodings.map((encoding) => ({
value: encoding,
label: capitalize(encoding)
}))
}
],
async onRender(_ctx, args) {
const input = String(args.values.input);
const key = String(args.values.key);
const encoding = String(args.values.encoding);
return (0, import_node_crypto.createHmac)(algorithm, key, {}).update(input).digest(encoding);
}
}));
var plugin = {
templateFunctions: [...hashFunctions, ...hmacFunctions]
};
function capitalize(str) {
return str.charAt(0).toUpperCase() + str.slice(1);
}
// Annotate the CommonJS export names for ESM import in node:
0 && (module.exports = {
plugin

View File

@@ -0,0 +1,52 @@
"use strict";
var __defProp = Object.defineProperty;
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
var __getOwnPropNames = Object.getOwnPropertyNames;
var __hasOwnProp = Object.prototype.hasOwnProperty;
var __export = (target, all) => {
for (var name in all)
__defProp(target, name, { get: all[name], enumerable: true });
};
var __copyProps = (to, from, except, desc) => {
if (from && typeof from === "object" || typeof from === "function") {
for (let key of __getOwnPropNames(from))
if (!__hasOwnProp.call(to, key) && key !== except)
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
}
return to;
};
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
// src/index.ts
var src_exports = {};
__export(src_exports, {
plugin: () => plugin
});
module.exports = __toCommonJS(src_exports);
var plugin = {
templateFunctions: [{
name: "regex.match",
description: "Extract",
args: [
{
type: "text",
name: "regex",
label: "Regular Expression",
placeholder: "^w+=(?<value>w*)$",
defaultValue: "^(.*)$",
description: "A JavaScript regular expression, evaluated using the Node.js RegExp engine. Capture groups or named groups can be used to extract values."
},
{ type: "text", name: "input", label: "Input Text", multiLine: true }
],
async onRender(_ctx, args) {
if (!args.values.regex) return "";
const regex = new RegExp(String(args.values.regex));
const match = args.values.input?.match(regex);
return match?.groups ? Object.values(match.groups)[0] ?? "" : match?.[1] ?? match?.[0] ?? "";
}
}]
};
// Annotate the CommonJS export names for ESM import in node:
0 && (module.exports = {
plugin
});

View File

@@ -0,0 +1,9 @@
{
"name": "@yaakapp/template-function-regex",
"private": true,
"version": "0.0.1",
"scripts": {
"build": "yaakcli build ./src/index.ts",
"dev": "yaakcli dev ./src/index.js"
}
}

View File

@@ -401,7 +401,7 @@ impl UpsertModelInfo for WorkspaceMeta {
#[derive(Debug, Clone, Serialize, Deserialize, TS)]
#[ts(export, export_to = "gen_models.ts")]
enum CookieDomain {
pub enum CookieDomain {
HostOnly(String),
Suffix(String),
NotPresent,
@@ -410,7 +410,7 @@ enum CookieDomain {
#[derive(Debug, Clone, Serialize, Deserialize, TS)]
#[ts(export, export_to = "gen_models.ts")]
enum CookieExpires {
pub enum CookieExpires {
AtUtc(String),
SessionEnd,
}

View File

@@ -104,7 +104,11 @@ hideLabel?: boolean,
/**
* The default value
*/
defaultValue?: string, disabled?: boolean, };
defaultValue?: string, disabled?: boolean,
/**
* Longer description of the input, likely shown in a tooltip
*/
description?: string, };
export type FormInputCheckbox = {
/**
@@ -131,7 +135,11 @@ hideLabel?: boolean,
/**
* The default value
*/
defaultValue?: string, disabled?: boolean, };
defaultValue?: string, disabled?: boolean,
/**
* Longer description of the input, likely shown in a tooltip
*/
description?: string, };
export type FormInputEditor = {
/**
@@ -170,7 +178,11 @@ hideLabel?: boolean,
/**
* The default value
*/
defaultValue?: string, disabled?: boolean, };
defaultValue?: string, disabled?: boolean,
/**
* Longer description of the input, likely shown in a tooltip
*/
description?: string, };
export type FormInputFile = {
/**
@@ -205,7 +217,11 @@ hideLabel?: boolean,
/**
* The default value
*/
defaultValue?: string, disabled?: boolean, };
defaultValue?: string, disabled?: boolean,
/**
* Longer description of the input, likely shown in a tooltip
*/
description?: string, };
export type FormInputHttpRequest = {
/**
@@ -232,7 +248,11 @@ hideLabel?: boolean,
/**
* The default value
*/
defaultValue?: string, disabled?: boolean, };
defaultValue?: string, disabled?: boolean,
/**
* Longer description of the input, likely shown in a tooltip
*/
description?: string, };
export type FormInputMarkdown = { content: string, hidden?: boolean, };
@@ -265,7 +285,11 @@ hideLabel?: boolean,
/**
* The default value
*/
defaultValue?: string, disabled?: boolean, };
defaultValue?: string, disabled?: boolean,
/**
* Longer description of the input, likely shown in a tooltip
*/
description?: string, };
export type FormInputSelectOption = { label: string, value: string, };
@@ -306,7 +330,11 @@ hideLabel?: boolean,
/**
* The default value
*/
defaultValue?: string, disabled?: boolean, };
defaultValue?: string, disabled?: boolean,
/**
* Longer description of the input, likely shown in a tooltip
*/
description?: string, };
export type GenericCompletionOption = { label: string, detail?: string, info?: string, type?: CompletionOptionType, boost?: number, };

View File

@@ -594,6 +594,10 @@ pub struct FormInputBase {
#[ts(optional)]
pub disabled: Option<bool>,
/// Longer description of the input, likely shown in a tooltip
#[ts(optional)]
pub description: Option<String>,
}
#[derive(Debug, Clone, Default, Serialize, Deserialize, TS)]

View File

@@ -237,6 +237,7 @@ function TextArg({
defaultValue={value === DYNAMIC_FORM_NULL_ARG ? arg.defaultValue : value}
required={!arg.optional}
disabled={arg.disabled}
help={arg.description}
type={arg.password ? 'password' : 'text'}
label={arg.label ?? arg.name}
size={INPUT_SIZE}
@@ -278,6 +279,7 @@ function EditorArg({
htmlFor={id}
required={!arg.optional}
visuallyHidden={arg.hideLabel}
help={arg.description}
tags={arg.language ? [capitalize(arg.language)] : undefined}
>
{arg.label}
@@ -319,6 +321,7 @@ function SelectArg({
<Select
label={arg.label ?? arg.name}
name={arg.name}
help={arg.description}
onChange={onChange}
hideLabel={arg.hideLabel}
value={value}
@@ -341,6 +344,7 @@ function FileArg({
return (
<SelectFile
disabled={arg.disabled}
help={arg.description}
onChange={({ filePath }) => onChange(filePath)}
filePath={filePath === '__NULL__' ? null : filePath}
directory={!!arg.directory}
@@ -365,6 +369,7 @@ function HttpRequestArg({
label={arg.label ?? arg.name}
name={arg.name}
onChange={onChange}
help={arg.description}
value={value}
disabled={arg.disabled}
options={[
@@ -412,6 +417,7 @@ function CheckboxArg({
<Checkbox
onChange={onChange}
checked={value}
help={arg.description}
disabled={arg.disabled}
title={arg.label ?? arg.name}
hideLabel={arg.label == null}

View File

@@ -58,6 +58,7 @@ export type InputProps = Pick<
fullHeight?: boolean;
hideLabel?: boolean;
inputWrapperClassName?: string;
help?: ReactNode;
label: ReactNode;
labelClassName?: string;
labelPosition?: 'top' | 'left';
@@ -94,33 +95,34 @@ const BaseInput = forwardRef<EditorView, InputProps>(function InputBase(
{
className,
containerClassName,
inputWrapperClassName,
defaultValue,
disableObscureToggle,
disabled,
forceUpdateKey,
fullHeight,
help,
hideLabel,
inputWrapperClassName,
label,
labelClassName,
labelPosition = 'top',
leftSlot,
multiLine,
onBlur,
onChange,
onFocus,
onPaste,
onPasteOverwrite,
placeholder,
readOnly,
required,
rightSlot,
wrapLines,
size = 'md',
type = 'text',
disableObscureToggle,
tint,
validate,
readOnly,
stateKey,
multiLine,
disabled,
tint,
type = 'text',
validate,
wrapLines,
...props
}: InputProps,
ref,
@@ -216,6 +218,7 @@ const BaseInput = forwardRef<EditorView, InputProps>(function InputBase(
>
<Label
htmlFor={id.current}
help={help}
required={required}
visuallyHidden={hideLabel}
className={classNames(labelClassName)}

View File

@@ -16,6 +16,7 @@ export interface SelectProps<T extends string> {
labelClassName?: string;
hideLabel?: boolean;
value: T;
help?: ReactNode;
leftSlot?: ReactNode;
options: RadioDropdownItem<T>[];
onChange: (value: T) => void;
@@ -28,6 +29,7 @@ export interface SelectProps<T extends string> {
export function Select<T extends string>({
labelPosition = 'top',
name,
help,
labelClassName,
disabled,
hideLabel,
@@ -59,7 +61,7 @@ export function Select<T extends string>({
labelPosition === 'top' && 'flex-row gap-0.5',
)}
>
<Label htmlFor={id} visuallyHidden={hideLabel} className={labelClassName}>
<Label htmlFor={id} visuallyHidden={hideLabel} className={labelClassName} help={help}>
{label}
</Label>
{type() === 'macos' ? (