Skip to content

Commit

Permalink
Change it so function and call explicitly expect arg: namespace.
Browse files Browse the repository at this point in the history
The `var` references to arguments will need to include `arg` so it's better to be consistent.

Part of #20.
  • Loading branch information
jkomoros committed Jul 29, 2023
1 parent afb501f commit f3a2fe8
Show file tree
Hide file tree
Showing 5 changed files with 21 additions and 20 deletions.
4 changes: 2 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -660,7 +660,7 @@ Defines a procedure that other seeds can call with `call`.
Note that semantically it's basically equivalent to a `let-multi` with named arguments, but using `function` communicates more clearly the intent that this is a callable-sub-procedure, which allows tooling to understand it better.
Required parameters:
- `arguments` - The list of names of arguments that are expected to be passed. These variable names should not include a namespace. Internally they will be prefixed with the `arg:` namespace.
- `arguments` - The list of names of arguments that are expected to be passed. These variable names must all be prefixed with an `arg:`
- `block` - The sub-seed that will be evaluated where the environment will have `name=value`.
#### call
Expand All @@ -670,7 +670,7 @@ Calls a procedure that was defined by `function`.
Semantically this is just a let-multi to set parameters and then execute the function seed-reference, but it communicates intent better.
Required parameters:
- `arguments` - The object of name -> value pairs to set. These variable names should not include a namespace. Internally they will be prefixed with the `arg:` namespace.
- `arguments` - The object of name -> value pairs to set. These variable names should all include a `arg:`
- `function` - The sub-seed refererence to the `function` to execute.
#### store
Expand Down
4 changes: 2 additions & 2 deletions seed-schema.json
Original file line number Diff line number Diff line change
Expand Up @@ -2910,7 +2910,7 @@
"type": "array",
"items": {
"type": "string",
"pattern": "^[a-zA-Z0-9-_.]*$"
"pattern": "^arg:[a-zA-Z0-9-_.]*$"
},
"description": "The map of name -> variables to set"
}
Expand Down Expand Up @@ -2988,7 +2988,7 @@
]
},
"propertyNames": {
"pattern": "^[a-zA-Z0-9-_.]*$"
"pattern": "^arg:[a-zA-Z0-9-_.]*$"
},
"description": "The map of name -> variables to set"
}
Expand Down
4 changes: 2 additions & 2 deletions src/environment.ts
Original file line number Diff line number Diff line change
Expand Up @@ -35,11 +35,11 @@ import {

const CHANGE_ME_SENTINEL = 'CHANGE_ME';

export const isNamespaced = (input : MemoryID | StoreID | VarName) : boolean => {
const isNamespaced = (input : MemoryID | StoreID | VarName) : boolean => {
return input.includes(NAMESPACE_DELIMITER);
};

export const getNamespacedID = <I extends MemoryID | StoreID | VarName>(input : I, namespace : Namespace) : I => {
const getNamespacedID = <I extends MemoryID | StoreID | VarName>(input : I, namespace : Namespace) : I => {
if (isNamespaced(input)) return input;
if (!namespaceSchema.safeParse(namespace).success) throw new Error(`${namespace} was not a valid namespace`);
return (namespace + NAMESPACE_DELIMITER + input) as I;
Expand Down
17 changes: 7 additions & 10 deletions src/grow.ts
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,8 @@ import {
fetchFormat,
SeedDataFilter,
SeedDataFunction,
SeedDataCall
SeedDataCall,
argVarName
} from './types.js';

import {
Expand All @@ -81,7 +82,7 @@ import {
} from './template.js';

import {
Environment, getNamespacedID, isNamespaced
Environment
} from './environment.js';

import {
Expand Down Expand Up @@ -688,18 +689,15 @@ const growLetMulti = async (seed : Seed<SeedDataLetMulti>, env : Environment) :
return await getProperty(seed, newEnv, data.block);
};

const FUNCTION_ARG_NAMESPACE = 'arg';

const growFunction = async (seed : Seed<SeedDataFunction>, env : Environment) : Promise<Value> => {
const data = seed.data;

const values = await getProperty(seed, env, data.arguments);
if (!Array.isArray(values)) throw new Error('Values must be an array');
for (const name of values) {
if (typeof name != 'string') throw new Error('argument name must be string');
if (isNamespaced(name)) throw new Error('arguments should not be namespaced');
const processedKey = getNamespacedID(name, FUNCTION_ARG_NAMESPACE);
const val = env.get(processedKey);
if (!argVarName.safeParse(name).success) throw new Error('Arg must start with `arg:`');
const val = env.get(name);
if (val === null) throw new Error(`${val} was not set as expected`);
}
return await getProperty(seed, env, data.block);
Expand All @@ -714,9 +712,8 @@ const growCall = async (seed : Seed<SeedDataCall>, env : Environment) : Promise<
if (!values) throw new Error('Values must be an object');
const vars : EnvironmentData = {};
for (const [key, val] of Object.entries(values)) {
if (isNamespaced(key)) throw new Error('arguments should not be namespaced');
const processedKey = getNamespacedID(key, FUNCTION_ARG_NAMESPACE);
vars[processedKey] = val;
if (!argVarName.safeParse(key).success) throw new Error(`${key} did not start with 'arg:'`);
vars[key] = val;
}
const newEnv = env.clone(vars);
//TODO: throw if data.function is not a seed-reference to a seed of type function.
Expand Down
12 changes: 8 additions & 4 deletions src/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,12 @@ const namedspacedID = z.string().regex(absoluteRegExp(namespacedIDRegExp));

export type NamespacedID = z.infer<typeof namedspacedID>;

const FUNCTION_ARG_NAMESPACE = 'arg';

const argVarRegExp = new RegExp(FUNCTION_ARG_NAMESPACE + NAMESPACE_DELIMITER + genericIDExtraRegExp.source);

export const argVarName = z.string().regex(absoluteRegExp(argVarRegExp));

export const leafValue = z.union([
z.null(),
z.number(),
Expand Down Expand Up @@ -944,8 +950,7 @@ export type SeedDataLetMulti = z.infer<typeof seedDataLetMulti>;
const seedDataConfigFunction = {
type: z.literal('function'),
properties: {
//We don't use varName because we want a non-namespaced ID
arguments: z.array(genericExtraID).describe('The map of name -> variables to set'),
arguments: z.array(argVarName).describe('The map of name -> variables to set'),
block: inputNonObjectValue.describe('The sub-expression where name=value will be set in environment')
}
};
Expand All @@ -958,8 +963,7 @@ export type SeedDataFunction = z.infer<typeof seedDataFunction>;
const seedDataConfigCall = {
type: z.literal('call'),
properties: {
//We don't use varName because we want a non-namespaced ID
arguments: z.record(genericExtraID, z.union([
arguments: z.record(argVarName, z.union([
lazySeedData,
seedReference,
inputValue
Expand Down

0 comments on commit f3a2fe8

Please sign in to comment.