Skip to content

Commit

Permalink
Extend DetectedRoute with start and end points and generate schemas
Browse files Browse the repository at this point in the history
  • Loading branch information
stephlow committed Oct 15, 2024
1 parent db4ef3d commit be13b79
Show file tree
Hide file tree
Showing 4 changed files with 81 additions and 50 deletions.
7 changes: 5 additions & 2 deletions fpx/src/static_analysis/ast.rs
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ pub fn detect_routes(entry_path: &Path, source: &str) -> Vec<DetectedRoute> {
routes
}

// TODO: find and traverse imports to match out of scope identifiers
fn find_route_handler_nodes(
file_path: &Path,
source: &str,
Expand Down Expand Up @@ -61,7 +62,8 @@ fn find_route_handler_nodes(
route_method: method.into(),
route_handler: route_handler.into(),
source_path: file_path.to_str().unwrap().into(),
source_point: node.start_position(),
source_start_point: node.start_position().into(),
source_end_point: node.end_position().into(),
});
}
}
Expand Down Expand Up @@ -113,7 +115,8 @@ export default instrument(app);
route_method: "get".into(),
route_handler: "(c) => {\n return c.text(\"Hello Hono!\");\n}".into(),
source_path: "src/index.ts".into(),
source_point: Point { row: 5, column: 0 }
source_start_point: Point { row: 5, column: 0 }.into(),
source_end_point: Point { row: 7, column: 2 }.into()
}]
)
}
Expand Down
27 changes: 22 additions & 5 deletions fpx/src/static_analysis/detected_route.rs
Original file line number Diff line number Diff line change
@@ -1,25 +1,42 @@
use std::fmt::Display;
use tree_sitter::Point;

#[derive(Debug, PartialEq)]
use schemars::JsonSchema;

#[derive(JsonSchema, Debug, PartialEq)]
pub struct DetectedRoute {
pub route_path: String,
pub route_method: String,
pub route_handler: String,
pub source_path: String,
pub source_point: Point,
pub source_start_point: Point,
pub source_end_point: Point,
}

#[derive(JsonSchema, Debug, PartialEq)]
pub struct Point {
pub row: usize,
pub column: usize,
}

impl From<tree_sitter::Point> for Point {
fn from(point: tree_sitter::Point) -> Self {
Self {
row: point.row,
column: point.column,
}
}
}

// TODO: temp
impl Display for DetectedRoute {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
write!(
f,
"{}: {}\n{}:{}\n{}",
"{}: {}\n{}:{:?}\n{}",
self.route_method,
self.route_path,
self.source_path,
self.source_point,
self.source_start_point,
self.route_handler
)
}
Expand Down
85 changes: 48 additions & 37 deletions packages/types/src/schemas.ts
Original file line number Diff line number Diff line change
Expand Up @@ -78,43 +78,6 @@ export const ServerMessageSchema = z

export type ServerMessage = z.infer<typeof ServerMessageSchema>;

export const AppStateSchema = z.object({
workspace: z.union([z.any(), z.null()]).optional(),
});

export type AppState = z.infer<typeof AppStateSchema>;

export const OpenWorkspaceErrorSchema = z.any().superRefine((x, ctx) => {
const schemas = [
z.object({ path: z.string(), type: z.literal("ConfigFileMissing") }),
z.object({ message: z.string(), type: z.literal("InvalidConfiguration") }),
];
const errors = schemas.reduce<z.ZodError[]>(
(errors, schema) =>
((result) => (result.error ? [...errors, result.error] : errors))(
schema.safeParse(x),
),
[],
);
if (schemas.length - errors.length !== 1) {
ctx.addIssue({
path: ctx.path,
code: "invalid_union",
unionErrors: errors,
message: "Invalid input: Should pass single schema",
});
}
});

export type OpenWorkspaceError = z.infer<typeof OpenWorkspaceErrorSchema>;

export const WorkspaceSchema = z.object({
api_port: z.number().int().gte(0),
path: z.string(),
});

export type Workspace = z.infer<typeof WorkspaceSchema>;

export const FpxConfigSchema = z.object({
listen_port: z
.union([
Expand Down Expand Up @@ -162,3 +125,51 @@ export const FpxConfigErrorSchema = z.any().superRefine((x, ctx) => {
});

export type FpxConfigError = z.infer<typeof FpxConfigErrorSchema>;

export const DetectedRouteSchema = z.object({
route_handler: z.string(),
route_method: z.string(),
route_path: z.string(),
source_end_point: z.any(),
source_path: z.string(),
source_start_point: z.any(),
});

export type DetectedRoute = z.infer<typeof DetectedRouteSchema>;

export const OpenWorkspaceErrorSchema = z.any().superRefine((x, ctx) => {
const schemas = [
z.object({ path: z.string(), type: z.literal("ConfigFileMissing") }),
z.object({ message: z.string(), type: z.literal("InvalidConfiguration") }),
];
const errors = schemas.reduce<z.ZodError[]>(
(errors, schema) =>
((result) => (result.error ? [...errors, result.error] : errors))(
schema.safeParse(x),
),
[],
);
if (schemas.length - errors.length !== 1) {
ctx.addIssue({
path: ctx.path,
code: "invalid_union",
unionErrors: errors,
message: "Invalid input: Should pass single schema",
});
}
});

export type OpenWorkspaceError = z.infer<typeof OpenWorkspaceErrorSchema>;

export const WorkspaceSchema = z.object({
api_port: z.number().int().gte(0),
path: z.string(),
});

export type Workspace = z.infer<typeof WorkspaceSchema>;

export const AppStateSchema = z.object({
workspace: z.union([z.any(), z.null()]).optional(),
});

export type AppState = z.infer<typeof AppStateSchema>;
12 changes: 6 additions & 6 deletions xtask/src/commands/schemas.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
use anyhow::Result;
use fpx::api::models::{ClientMessage, ServerMessage};
use schemars::schema::RootSchema;
use schemars::schema_for;
use serde_json::Value;
Expand All @@ -18,13 +17,14 @@ pub struct Args {
pub async fn handle_command(args: Args) -> Result<()> {
// Define which types should be used to generate schemas
let schemas = Vec::from([
schema_for!(ClientMessage),
schema_for!(ServerMessage),
schema_for!(fpx_app::state::AppState),
schema_for!(fpx_app::models::workspace::OpenWorkspaceError),
schema_for!(fpx_app::models::workspace::Workspace),
schema_for!(fpx::api::models::ClientMessage),
schema_for!(fpx::api::models::ServerMessage),
schema_for!(fpx::config::FpxConfig),
schema_for!(fpx::config::FpxConfigError),
schema_for!(fpx::static_analysis::detected_route::DetectedRoute),
schema_for!(fpx_app::models::workspace::OpenWorkspaceError),
schema_for!(fpx_app::models::workspace::Workspace),
schema_for!(fpx_app::state::AppState),
]);

let zod_schema = generate_zod_schemas(&args.project_directory, &schemas)?;
Expand Down

0 comments on commit be13b79

Please sign in to comment.