Add unknown ranges and open object values

This commit is contained in:
2026-08-14 08:00:22 +09:00
parent 8c50dd202d
commit 848c7f169f
53 changed files with 9047 additions and 6572 deletions
@@ -8,22 +8,25 @@ copyFileSync(resolve(packageDir, '../../LICENSE-APACHE'), resolve(packageDir, 'L
const declarationPath = resolve(packageDir, 'decodal_wasm.d.ts');
let declarations = readFileSync(declarationPath, 'utf8');
const hostTypes = `
/** A concrete JavaScript value or Decodal schema descriptor supplied by the host. */
export type DecodalHostValue =
const valueTypes = `
/** A concrete JavaScript value or Decodal range descriptor. */
export type DecodalValue =
| string
| number
| boolean
| DecodalHostValue[]
| { [field: string]: DecodalHostValue }
| DecodalValue[]
| { [field: string]: DecodalValue }
| DecodalPrimitiveDescriptor
| DecodalUnknownDescriptor
| DecodalArrayDescriptor
| DecodalMapDescriptor
| DecodalAbstractDescriptor;
| DecodalObjectDescriptor
| DecodalRangeDescriptor;
export type DecodalPrimitiveType = 'String' | 'Int' | 'Float' | 'Bool';
export type DecodalConstraint =
| { kind: 'unknown' }
| { kind: 'type'; value: DecodalPrimitiveType }
| { kind: 'compare'; op: '>' | '>=' | '<' | '<='; value: string | number | boolean }
| { kind: 'regex'; value: string }
@@ -32,32 +35,44 @@ export type DecodalConstraint =
export interface DecodalPrimitiveDescriptor {
$decodal: DecodalPrimitiveType;
constraints?: DecodalConstraint[];
default?: DecodalHostValue;
default?: DecodalValue;
}
export interface DecodalUnknownDescriptor {
$decodal: 'Unknown';
constraints?: DecodalConstraint[];
default?: DecodalValue;
}
export interface DecodalArrayDescriptor {
$decodal: 'Array';
item: DecodalHostValue;
item: DecodalValue;
constraints?: DecodalConstraint[];
default?: DecodalHostValue;
default?: DecodalValue;
}
export interface DecodalMapDescriptor {
$decodal: 'Map';
value: DecodalHostValue;
value: DecodalValue;
constraints?: DecodalConstraint[];
default?: DecodalHostValue;
default?: DecodalValue;
}
export interface DecodalAbstractDescriptor {
$decodal: 'Abstract';
export interface DecodalObjectDescriptor {
$decodal: 'Object';
fields: Record<string, DecodalValue>;
rest: DecodalValue;
}
export interface DecodalRangeDescriptor {
$decodal: 'Range';
constraints?: DecodalConstraint[];
default?: DecodalHostValue;
default?: DecodalValue;
}
export type DecodalLoadedImport =
| { kind: 'source'; key: string; name?: string; source: string }
| { kind: 'value'; key: string; value: DecodalHostValue };
| { kind: 'value'; key: string; value: DecodalValue };
export type DecodalImportCandidate =
| string
@@ -65,7 +80,7 @@ export type DecodalImportCandidate =
/** Host-owned environment shared by evaluation and language tooling. */
export interface DecodalEnvironment {
globals?: Record<string, DecodalHostValue>;
globals?: Record<string, DecodalValue>;
/** Synchronous import callback. Preload or cache asynchronous resources first. */
loadImport?: (currentKey: string | null, specifier: string) => DecodalLoadedImport;
/** Synchronous import completion callback. */
@@ -73,7 +88,7 @@ export interface DecodalEnvironment {
}
`;
if (!declarations.includes('export interface DecodalEnvironment')) {
declarations = declarations.replace('/* eslint-disable */\n', `/* eslint-disable */\n${hostTypes}`);
declarations = declarations.replace('/* eslint-disable */\n', `/* eslint-disable */\n${valueTypes}`);
}
declarations = declarations.replace(
'constructor(options: any);',
@@ -175,7 +190,11 @@ 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, \`{ $decodal: 'Array', item: value }\` for array schemas, and \`{ $decodal: 'Map', value: value }\` for associative-array schemas. Descriptors also accept \`constraints\` and \`default\`.
Plain strings, numbers, booleans, arrays, and objects are concrete values. Use \`{ $decodal: 'String' | 'Int' | 'Float' | 'Bool' }\` for primitive ranges, \`{ $decodal: 'Unknown' }\` for the top range, \`{ $decodal: 'Array', item: value }\` for array ranges, and \`{ $decodal: 'Map', value: value }\` for associative-array ranges. Primitive, unknown, array, and map descriptors also accept \`constraints\` and \`default\`.
Use \`{ $decodal: 'Range', constraints, default }\` when constructing a general range directly.
An object with named fields and an open rest range uses \`{ $decodal: 'Object', fields, rest }\`. The \`fields\` property is a record of values and \`rest\` is the range applied to every other field.
Methods return JSON strings so callers can handle diagnostics and successful results without depending on Rust data structures.
`,