diff --git a/experiments/data_model/ts_eemeli/data-model-examples.ts b/experiments/data_model/ts_eemeli/data-model-examples.ts index b1f93984c..0a495d327 100644 --- a/experiments/data_model/ts_eemeli/data-model-examples.ts +++ b/experiments/data_model/ts_eemeli/data-model-examples.ts @@ -1,6 +1,6 @@ // MF1: { gender, select, male{he} female{she} other{they} } const genderSelect: Select = { - select: [{ path: ['gender'] }], + select: [{ var_path: ['gender'] }], cases: [ { key: ['male'], value: ['he'] }, { key: ['female'], value: ['she'] }, @@ -10,12 +10,12 @@ const genderSelect: Select = { // MF1: { count, plural, one{a message} other{# messages} } const countPlural: Select = { - select: [{ func: 'plural', args: [{ path: ['count'] }] }], + select: [{ func: 'plural', args: [{ var_path: ['count'] }] }], cases: [ { key: ['one'], value: ['a message'] }, { key: ['other'], - value: [{ func: 'number', args: [{ path: ['count'] }] }, ' messages'] + value: [{ func: 'number', args: [{ var_path: ['count'] }] }, ' messages'] } ] } @@ -23,99 +23,111 @@ const countPlural: Select = { const gameMessages: Resource = { id: 'game-messages', locale: 'en', - messages: { - monsters: { - messages: { - dinosaur: { - messages: { - indefinite: { value: ['a Dinosaur'] }, - plural: { value: ['Dinosaurs'] } - } - }, - elephant: { - messages: { - indefinite: { value: ['an Elephant'] }, - plural: { value: ['Elephants'] } - } - }, - ogre: { - messages: { - indefinite: { value: ['an Ogre'] }, - plural: { value: ['Ogres'] } - } + entries: [ + { + id: 'monsters', + entries: [ + { + id: 'dinosaur', + entries: [ + { id: 'indefinite', value: ['a Dinosaur'] }, + { id: 'plural', value: ['Dinosaurs'] } + ] }, - other: { - messages: { - indefinite: { value: ['a Monster'] }, - plural: { value: ['Monsters'] } - } - } - } - }, - 'killed-by': { - value: [ - 'You have been killed by ', - { msg: ['monsters', { path: ['monster'] }, 'indefinite'] } - ] - }, - 'kill-count': { - select: [ - { func: 'plural', args: [{ path: ['monster-count'] }] }, - { func: 'plural', args: [{ path: ['dungeon-count'] }] } - ], - cases: [ { - key: ['one'], - value: [ - 'You have killed ', - { msg: ['monsters', { path: ['monster'] }, 'indefinite'] }, - '.' + id: 'elephant', + entries: [ + { id: 'indefinite', value: ['an Elephant'] }, + { id: 'plural', value: ['Elephants'] } ] }, { - key: ['other', 'one'], - value: [ - 'You have killed ', - { func: 'number', args: [{ path: ['monster-count'] }] }, - ' ', - { msg: ['monsters', { path: ['monster'] }, 'plural'] }, - ' in one dungeon.' + id: 'ogre', + entries: [ + { id: 'indefinite', value: ['an Ogre'] }, + { id: 'plural', value: ['Ogres'] } ] }, { - key: ['other', 'other'], - value: [ - 'You have killed ', - { func: 'number', args: [{ path: ['monster-count'] }] }, - ' ', - { msg: ['monsters', { path: ['monster'] }, 'plural'] }, - ' in ', - { func: 'number', args: [{ path: ['dungeon-count'] }] }, - ' dungeons.' + id: 'other', + entries: [ + { id: 'indefinite', value: ['a Monster'] }, + { id: 'plural', value: ['Monsters'] } ] } ] + }, + { + id: 'killed-by', + value: [ + 'You have been killed by ', + { msg_path: ['monsters', { var_path: ['monster'] }, 'indefinite'] } + ] + }, + { + id: 'kill-count', + value: { + select: [ + { func: 'plural', args: [{ var_path: ['monster-count'] }] }, + { func: 'plural', args: [{ var_path: ['dungeon-count'] }] } + ], + cases: [ + { + key: ['one'], + value: [ + 'You have killed ', + { + msg_path: ['monsters', { var_path: ['monster'] }, 'indefinite'] + }, + '.' + ] + }, + { + key: ['other', 'one'], + value: [ + 'You have killed ', + { func: 'number', args: [{ var_path: ['monster-count'] }] }, + ' ', + { msg_path: ['monsters', { var_path: ['monster'] }, 'plural'] }, + ' in one dungeon.' + ] + }, + { + key: ['other', 'other'], + value: [ + 'You have killed ', + { func: 'number', args: [{ var_path: ['monster-count'] }] }, + ' ', + { msg_path: ['monsters', { var_path: ['monster'] }, 'plural'] }, + ' in ', + { func: 'number', args: [{ var_path: ['dungeon-count'] }] }, + ' dungeons.' + ] + } + ] + } } - } + ] } const extMessages: Resource = { id: 'remote-ref', locale: 'en', - messages: { - friend: { + entries: [ + { + id: 'friend', value: [ 'Your friend has become ', { func: 'sparkle', args: [ { - id: 'game-messages', - msg: ['monsters', { path: ['monster'] }, 'indefinite'] + res_id: 'game-messages', + msg_path: ['monsters', { var_path: ['monster'] }, 'indefinite'] } ] } ] } - } + ] } diff --git a/experiments/data_model/ts_eemeli/data-model.d.ts b/experiments/data_model/ts_eemeli/data-model.d.ts index e4d1c16d5..39d8b41bc 100644 --- a/experiments/data_model/ts_eemeli/data-model.d.ts +++ b/experiments/data_model/ts_eemeli/data-model.d.ts @@ -6,12 +6,15 @@ interface Resource { id: string locale: string - messages: Record + entries: Entry[] meta?: Meta } +type Entry = Message | MessageSet + interface MessageSet { - messages: Record + id: string + entries: Entry[] meta?: Meta } @@ -24,14 +27,13 @@ interface Meta { [key: string]: unknown } -type Formattable = Message | Select - /** * The string parts of a message represent fixed values, while placeholder * values are variable. */ interface Message { - value: Value[] + id: string + value: Value[] | Select meta?: Meta } @@ -46,8 +48,7 @@ interface Message { */ interface Select { select: Value[] - cases: Array<{ key: string[]; value: Value[]; meta?: Meta }> - meta?: Meta + cases: Array<{ key: Literal[]; value: Value[]; meta?: Meta }> } /** @@ -77,7 +78,7 @@ type Literal = string | number * `{ name: 'Kat' }` as the value of the `'user'` scope variable. */ interface VariableReference { - path: Value[] + var_path: Path meta?: Meta } @@ -97,14 +98,14 @@ interface VariableReference { interface FunctionReference { func: string args: Value[] - options?: Record + options?: Array<{ key: string; value: string | number | boolean }> meta?: Meta } /** * A MessageReference is a pointer to a Message or a Select. * - * If `id` is undefined, the message is sought in the current Resource. + * If `resource` is undefined, the message is sought in the current Resource. * If it is set, it identifies the resource for the sought message. * * While `msg` has superficially the same type as a Message, all but the last @@ -115,8 +116,15 @@ interface FunctionReference { * `scope` overrides values in the current scope when resolving the message. */ interface MessageReference { - id?: string - msg: Value[] - scope?: Record + res_id?: string + msg_path: Path + scope?: Scope[] meta?: Meta } + +interface Scope { + name: string + value: Value | boolean | Scope +} + +type Path = Value[]