packages/structure/README.md
IMPORTANT: This is an internal and development-time only package :exclamation:
/model/*: The main API and classes (such as RWProject, RWPage, RWService, etc)/language_server/*: A Language Server Protocol implementation that wraps the model classes. More info hereThe most common use-case is getting the diagnostics of a complete Redwood project:
import { getProject } from '@redwoodjs/structure'
async function test() {
const project = getProject('/path/to/app') // or "file:///path/to/app"
for (const d of await project.collectDiagnostics()) {
console.log(d.diagnostic.severity + ': ' + d.diagnostic.message)
}
}
// ...
// error: Router must have only one "notfound" page
// error: Duplicate path in router: '/about-us'
// error: Parameter "id" in route '/product/{id}' does not exist on ProductPage
// error: PostsCell is missing the "Success" exported const
// error: Property "email" does not exist on "User" model
// warning: Unused page AboutUs.js
Note: Gathering all diagnostics is expensive. It will trigger the creation of the complete project graph.
You can also traverse the graph to get more detailed information on multiple aspects of your app.
For example, iterating over the routes of a Redwood project:
import { getProject } from '@redwoodjs/structure'
async function test() {
const project = getProject('/path/to/app')
for (const route of project.router.routes) {
console.log(route.path + (route.isPrivate ? ' (private)' : ''))
}
}
// /
// /about
// /product/{id}
// /admin (private)
id property.child.id.startsWith(parent.id) === true)import { getProject } from '@redwoodjs/structure'
async function test() {
const project = getProject('/path/to/app')
const router = await project.findNode('file:///path/to/app/web/src/Routes.js')
console.log(router.routes.length)
}
Here are some examples of ids:
"file:///project/root"
"file:///project/root/web/src/Routes.js""file:///project/root/web/src/Routes.js /home" (notice that this id has two elements - it is an "internal" node)An id is "usually" a file or folder.
Anatomy of an id:
To allow use cases like dealing with unsaved files in IDEs, some filesystem methods can be overridden via the Host interface.
import { Host, getProject } from '@redwoodjs/structure'
const myHost: Host {
readFileSync(path:string){
// ...
}
// ...
}
const project = getProject('/path/to/project', myHost)
When possible, the project graph is constructed synchronously. There are only a few exceptions. This simplifies the domain logic and validations, which is the main driver behind the project model itself.
import { getProject, DiagnosticSeverity } from '@redwoodjs/structure'
async function test() {
try {
const project = getProject('/path/to/app')
const diagnostics = await project.collectDiagnostics()
const hasErrors = diagnostics.some(
(d) => d.diagnostic.severity === DiagnosticSeverity.Error,
)
} catch (e) {
// we caught a runtime error
// in some cases this is the desired behavior
// but in MOST cases we SHOULD turn this into a diagnostic error
// please file an issue if you believe this should be the case
throw e
}
}
NOTE: It is possible (and very likely at this point) that this package will sometimes fail with a runtime error (for example, it will try to read a file that doesn't exist).