Skip to content

Commit

Permalink
Add a seed_type of object.
Browse files Browse the repository at this point in the history
This is an object type that allows computed properties.

Note that as of right now non-computed nested definitions will not work (that should be fixed in next
commit)

Part of #18.
  • Loading branch information
jkomoros committed Jun 27, 2023
1 parent b9f8e88 commit 4728184
Show file tree
Hide file tree
Showing 7 changed files with 108 additions and 5 deletions.
11 changes: 9 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -172,16 +172,23 @@ Asks for input from the user.

Required parameters:
- `template` - The template string
- `vars` - The map of name -> value to use in the template. If any vars that are used in the template are missing there will be an error.
- `vars` - The map of name -> value to use in the template. If any vars that are used in the template are missing there will be an error. If some sub-seeds need to be computed, nest a sub-seed of type `object`.

#### property

Selects a named property from an object

Required parameters:
- `object` - The object to select a property from.
- `object` - The object to select a property from. If some of the sub-keys need to be computed, nest a sub-seed of type `object`.
- `property` - The property to select from the object.

#### object

Returns an object where some values may be sub-seeds that need to be computed.

Required parameters:
- `properties` - An object with keys for each key to return. The values may be LeafValue or a SeedReference / SubSeed.

#### ==

Returns true if a and b are `==`, false otherwise.
Expand Down
36 changes: 36 additions & 0 deletions seed-schema.json
Original file line number Diff line number Diff line change
Expand Up @@ -791,6 +791,42 @@
"property"
],
"additionalProperties": false
},
{
"type": "object",
"properties": {
"id": {
"$ref": "#/properties/seeds/additionalProperties/anyOf/0/properties/id"
},
"description": {
"$ref": "#/properties/seeds/additionalProperties/anyOf/0/properties/description"
},
"type": {
"type": "string",
"const": "object"
},
"properties": {
"type": "object",
"additionalProperties": {
"anyOf": [
{
"$ref": "#/properties/seeds/additionalProperties"
},
{
"$ref": "#/properties/seeds/additionalProperties/anyOf/0/properties/prompt/anyOf/1"
},
{
"$ref": "#/properties/seeds/additionalProperties/anyOf/11/properties/default/anyOf/2/anyOf/1"
}
]
}
}
},
"required": [
"type",
"properties"
],
"additionalProperties": false
}
]
},
Expand Down
18 changes: 17 additions & 1 deletion src/grow.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,10 @@ import {
SeedDataTemplate,
SeedDataInput,
leafValue,
SeedDataProperty
SeedDataProperty,
SeedDataObject,
ValueObject,
LeafValue
} from './types.js';

import {
Expand Down Expand Up @@ -191,6 +194,16 @@ const growProperty = async (seed : Seed<SeedDataProperty>) : Promise<Value> => {
return obj[property];
};

const growObject = async (seed : Seed<SeedDataObject>) : Promise<Value> => {
const data = seed.data;
const result : ValueObject = {};
for (const [key, value] of Object.entries(data.properties)) {
//Cheat and pretned the return value is a LeafValue event hough it might not be
result[key] = await getProperty(seed, value) as LeafValue;
}
return result;
};

export const grow = async (seed : Seed) : Promise<Value> => {
const env = seed.garden.environment;
const verbose = env.getKnownBooleanKey('verbose');
Expand Down Expand Up @@ -242,6 +255,9 @@ export const grow = async (seed : Seed) : Promise<Value> => {
case 'property':
result = await growProperty(seed as Seed<SeedDataProperty>);
break;
case 'object':
result = await growObject(seed as Seed<SeedDataObject>);
break;
default:
return assertUnreachable(typ);
}
Expand Down
2 changes: 2 additions & 0 deletions src/seed.ts
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,8 @@ const expandSeedData = (idFromParent : SeedID, data : SeedData, result : Expande
const id = data.id !== undefined ? data.id : idFromParent;

const resultData = {...data} as ExpandedSeedData;
//TODO: if it's a SeedDataObject, iterate through and set the properties.()
//object instead of the top-level object.
for (const [key, value] of Object.entries(data)) {
//if it's a reserved key, a normal value, or a SeedReference, then the copied over value is fine.

Expand Down
28 changes: 26 additions & 2 deletions src/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,8 @@ export type LeafValue = z.infer<typeof leafValue>;

const valueObject = z.record(z.string(), leafValue);

export type ValueObject = z.infer<typeof valueObject>;

const value = z.union([
leafValue,
valueObject
Expand Down Expand Up @@ -379,6 +381,26 @@ const seedDataProperty = makeSeedData(seedDataConfigProperty);

export type SeedDataProperty = z.infer<typeof seedDataProperty>;


//Object is special in that even sub-keys of a property might need to be
//computed, so handle its definition manually.
const seedDataObject = seedDataBase.extend({
type: z.literal('object'),
properties: z.record(z.string(), makeSeedReferenceProperty(value))
});

const nestedSeedDataObject = seedDataBase.extend({
type: z.literal('object'),
properties: z.record(z.string(), z.union([
z.lazy(() => seedData),
seedReference,
value
]))
}) as never;
//^ This 'as never' is the only thing I found to make this build.

export type SeedDataObject = z.infer<typeof seedDataObject>;

/*
*
* End Seed Types
Expand All @@ -398,7 +420,8 @@ export const expandedSeedData = z.discriminatedUnion('type', [
seedDataNot,
seedDataTemplate,
seedDataInput,
seedDataProperty
seedDataProperty,
seedDataObject
]);

export type ExpandedSeedData = z.infer<typeof expandedSeedData>;
Expand All @@ -416,7 +439,8 @@ export const seedData = z.discriminatedUnion('type', [
nestedSeedDataNot,
nestedSeedDataTemplate,
nestedSeedDataInput,
nestedSeedDataProperty
nestedSeedDataProperty,
nestedSeedDataObject
]);

//Note that the typescript inferred type for this technically is missing the
Expand Down
7 changes: 7 additions & 0 deletions test/base/a_test.json
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,13 @@
"name": "Bob",
"age": "5"
}
},
"non-computed-object": {
"type": "object",
"properties": {
"a": 5,
"b": true
}
}
}
}
11 changes: 11 additions & 0 deletions test/base/test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -296,6 +296,17 @@ describe('Garden smoke test', () => {
assert.deepStrictEqual(result, golden);
});

it ('testing non-computed object seed', async () => {
const garden = loadTestGarden();
const seed = await garden.seed('non-computed-object');
const result = await seed.grow();
const golden = {
a: 5,
b: true
};
assert.deepStrictEqual(result, golden);
});


});

Expand Down

0 comments on commit 4728184

Please sign in to comment.