Add associative map constraints and range refinement
This commit is contained in:
@@ -18,6 +18,7 @@ export type DecodalHostValue =
|
||||
| { [field: string]: DecodalHostValue }
|
||||
| DecodalPrimitiveDescriptor
|
||||
| DecodalArrayDescriptor
|
||||
| DecodalMapDescriptor
|
||||
| DecodalAbstractDescriptor;
|
||||
|
||||
export type DecodalPrimitiveType = 'String' | 'Int' | 'Float' | 'Bool';
|
||||
@@ -41,6 +42,13 @@ export interface DecodalArrayDescriptor {
|
||||
default?: DecodalHostValue;
|
||||
}
|
||||
|
||||
export interface DecodalMapDescriptor {
|
||||
$decodal: 'Map';
|
||||
value: DecodalHostValue;
|
||||
constraints?: DecodalConstraint[];
|
||||
default?: DecodalHostValue;
|
||||
}
|
||||
|
||||
export interface DecodalAbstractDescriptor {
|
||||
$decodal: 'Abstract';
|
||||
constraints?: DecodalConstraint[];
|
||||
@@ -131,7 +139,7 @@ await init();
|
||||
|
||||
const files = {
|
||||
'main.dcdl': 'let schema = import "./schema.dcdl"; in schema.Server',
|
||||
'schema.dcdl': 'Server = App.Server & { port = 8080; };',
|
||||
'schema.dcdl': 'Server = { port = 8080; } as App.Server;',
|
||||
};
|
||||
|
||||
const service = new DecodalLanguageService({
|
||||
@@ -167,7 +175,7 @@ console.log(JSON.parse(completion));
|
||||
|
||||
\`globals\`, \`loadImport\`, and \`completeImport\` are host-owned. The package does not assume a filesystem or virtual project model. Import callbacks are synchronous; preload or cache remote content before evaluation.
|
||||
|
||||
Plain strings, numbers, booleans, arrays, and objects are concrete host values. Use \`{ $decodal: 'String' | 'Int' | 'Float' | 'Bool' }\` for primitive schemas and \`{ $decodal: 'Array', item: value }\` for array schemas. Descriptors also accept \`constraints\` and \`default\`.
|
||||
Plain strings, numbers, booleans, arrays, and objects are concrete host values. Use \`{ $decodal: 'String' | 'Int' | 'Float' | 'Bool' }\` for primitive schemas, \`{ $decodal: 'Array', item: value }\` for array schemas, and \`{ $decodal: 'Map', value: value }\` for associative-array schemas. Descriptors also accept \`constraints\` and \`default\`.
|
||||
|
||||
Methods return JSON strings so callers can handle diagnostics and successful results without depending on Rust data structures.
|
||||
`,
|
||||
|
||||
@@ -15,6 +15,13 @@ test('injects one JavaScript host environment into evaluation and completion', a
|
||||
globals: {
|
||||
App: {
|
||||
enabled: { $decodal: 'Bool', default: true },
|
||||
Services: {
|
||||
$decodal: 'Map',
|
||||
value: {
|
||||
port: { $decodal: 'Int' },
|
||||
active: { $decodal: 'Bool', default: true },
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
loadImport(_currentKey, specifier) {
|
||||
@@ -39,10 +46,11 @@ test('injects one JavaScript host environment into evaluation and completion', a
|
||||
const evaluated = JSON.parse(service.evaluate(
|
||||
'main.dcdl',
|
||||
'main.dcdl',
|
||||
'let s = import "./schema.dcdl"; in { server = s.Server & { port = 8080; }; enabled = App.enabled; post = import "./post.md"; }',
|
||||
'let s = import "./schema.dcdl"; in { server = { port = 8080; } as s.Server; services = { api = { port = 8081; }; } as App.Services; enabled = App.enabled; post = import "./post.md" as { frontmatter = { draft = Bool; }; body = String; }; }',
|
||||
));
|
||||
assert.equal(evaluated.ok, true, evaluated.error);
|
||||
assert.match(evaluated.output, /"port": 8080/);
|
||||
assert.match(evaluated.output, /"active": true/);
|
||||
assert.match(evaluated.output, /"body": "# Hello"/);
|
||||
|
||||
const member = JSON.parse(service.complete('main.dcdl', 'App.en', 6, false));
|
||||
|
||||
Reference in New Issue
Block a user