Finitio 0.4.x
Imports
Since 0.4 a schema can be split across several files and pull definitions from
elsewhere. An import is a line starting with @import, and imports come
first, before any type definition:
@import finitio/data
@import ./measures
{ taken: Date, values: [Measure] }
The standard library
The most common import by far, and the one nearly every 0.4 schema starts with:
@import finitio/data
It brings String, Integer, Date and the rest into scope. See the
standard library for what it contains and where the
two implementations differ.
Relative imports
A path starting with ./ or ../ is resolved relative to the file the schema
was loaded from:
@import ./measures
@import ../shared/units
Write the path without the .fio extension. The extension is added by the
resolver, so @import ./measures.fio looks for measures.fio.fio and fails.
Relative to what?
A relative import needs to know where the schema came from, and a schema parsed from a bare string does not. Load it from a file instead:
# Ruby
require 'pathname'
system = Finitio.system(Pathname.new('schemas/parent.fio'))
// JavaScript
const world = Finitio.world({ sourceUrl: `file://${path}` })
const system = Finitio.system(fs.readFileSync(path, 'utf8'), world)
Passing the source as a plain string with no context raises an error such as
Unable to resolve './measures'.
Imports are not re-exported
An imported type is usable inside the importing schema, but is not passed on to schemas that in turn import it. Given:
# child.fio
@import finitio/data
Posint = Integer( i | i >= 0 )
# parent.fio
@import ./child
Byte = Posint( i | i <= 255 ) # fine: Posint is in scope here
then a third schema importing parent sees Byte but not Posint:
@import ./parent
Byte # fine
Posint # error: No such type `Posint`
This keeps a schema's surface deliberate: what a file exports is what it
defines, not everything it happens to depend on. If Posint should be part of
the public surface of parent.fio, define an alias for it there.
Qualified imports
An import can be given a qualifier, so its definitions are reached through a prefix rather than merged into the current scope:
@import finitio/data as d
{ name: d.String }
Bundling
Imports are resolved when the schema is loaded, which means the files must be reachable at that moment. That is fine on a server and awkward in a browser, where there is no filesystem.