Skip to content
This repository was archived by the owner on Sep 24, 2025. It is now read-only.
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions bun.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion eslint.config.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@ export default [
sourceType: 'script',

parserOptions: {
project: ['./tsconfig.json'],
project: ['./tsconfig.eslint.json'],
tsconfigRootDir: __dirname,
},
},
Expand Down
44 changes: 39 additions & 5 deletions hono.d.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,41 @@
import type { ProjectFiles, ToddleProject } from '@nordcraft/ssr/dist/ssr.types'
import type {
Component,
PageComponent,
} from '@nordcraft/core/dist/component/component.types'
import type {
ProjectFiles,
Route,
ToddleProject,
} from '@nordcraft/ssr/dist/ssr.types'
import type { Routes } from './src/middleware/routesLoader'

export interface HonoEnv {
Variables: {
project: { files: ProjectFiles; project: ToddleProject }
}
export interface HonoEnv<T = never> {
Variables: T
}

export interface HonoProject {
// Holds project info such as sitemap, robots and icon
project: ToddleProject
config: ProjectFiles['config']
}

export interface HonoRoutes {
// Holds routes for the project
routes: Routes
}

export interface HonoRoute {
route?: Route
}

export interface HonoComponent {
// Holds all relevant files for a given component
files: ProjectFiles & { customCode: boolean }
component: Component
}

export interface HonoPage {
// Holds all relevant files for a given component
files: ProjectFiles & { customCode: boolean }
page: PageComponent
}
7 changes: 4 additions & 3 deletions package.json
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
{
"name": "nordcraft-cloudflare-worker",
"scripts": {
"predev": "bun scripts/syncStaticAssets.js && bunx esbuild --bundle --outdir=dist --platform=node --format=esm src/index.ts",
"dev": "wrangler dev --no-bundle",
"build": "bun scripts/syncStaticAssets.js && bunx esbuild --bundle --outdir=dist --platform=node --format=esm src/index.ts",
"predev": "bun scripts/syncStaticAssets.ts && bunx esbuild --bundle --outdir=dist --platform=node --format=esm src/index.ts",
"dev": "wrangler dev --no-bundle --port 8989",
"build": "bun scripts/syncStaticAssets.ts && bunx esbuild --bundle --outdir=dist --platform=node --format=esm src/index.ts",
"deploy": "wrangler deploy --no-bundle",
"typecheck": "tsc --noEmit",
"watch": "tsc --noEmit -w",
Expand All @@ -22,6 +22,7 @@
"@nordcraft/runtime": "1.0.1",
"@typescript-eslint/eslint-plugin": "8.31.0",
"@typescript-eslint/parser": "8.31.0",
"@types/node": "22.14.1",
"eslint-plugin-inclusive-language": "2.2.1",
"eslint": "9.25.1",
"prettier-plugin-organize-imports": "4.1.0",
Expand Down
117 changes: 117 additions & 0 deletions scripts/routes.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,117 @@
import type {
Component,
RouteDeclaration,
} from '@toddledev/core/dist/component/component.types'
import { isPageComponent } from '@toddledev/core/dist/component/isPageComponent'
import { createStylesheet } from '@toddledev/core/dist/styling/style.css'
import { theme as defaultTheme } from '@toddledev/core/dist/styling/theme.const'
import { takeIncludedComponents } from '@toddledev/ssr/dist/components/utils'
import type {
ProjectFiles,
Route,
ToddleProject,
} from '@toddledev/ssr/dist/ssr.types'
import {
generateCustomCodeFile,
hasCustomCode,
takeReferencedFormulasAndActions,
} from '@toddledev/ssr/src/custom-code/codeRefs'
import { removeTestData } from '@toddledev/ssr/src/rendering/testData'

interface Routes {
pages: Record<string, { name: string; route: RouteDeclaration }>
routes: Record<string, Route>
}

type Files = Record<
string,
{ component: Component; files: ProjectFiles & { customCode: boolean } }
>

export const splitRoutes = (json: {
files: ProjectFiles
project: ToddleProject
}): {
project: { project: ToddleProject; config: ProjectFiles['config'] }
routes: Routes
files: Files
styles: Record<string, string>
code: Record<string, string>
components: Partial<Record<string, Component>>
} => {
const filesMap: Files = {}
const stylesMap: Record<string, string> = {}
const codeMap: Record<string, string> = {}
const { files } = json

const routes: Routes = {
routes: { ...(files.routes ?? {}) },
pages: {},
}
Object.entries(files.components).forEach(([name, component]) => {
if (component) {
if (isPageComponent(component)) {
routes.pages[name] = {
name,
route: {
path: component.route.path,
query: component.route.query,
},
}
const components = takeIncludedComponents({
root: component,
projectComponents: files.components,
packages: files.packages,
includeRoot: true,
})
const theme =
(files.themes
? Object.values(files.themes)[0]
: files.config?.theme) ?? defaultTheme
const styles = createStylesheet(component, components, theme, {
// The reset stylesheet is loaded separately
includeResetStyle: false,
// Font faces are created from a stylesheet referenced in the head
createFontFaces: false,
})
stylesMap[name] = styles
let customCode = false
if (hasCustomCode(component, files)) {
customCode = true
const code = takeReferencedFormulasAndActions({
component,
files,
})
const output = generateCustomCodeFile({
code,
componentName: component.name,
projectId: 'toddle',
})
codeMap[name] = output
}
filesMap[name] = {
component: removeTestData(component),
files: {
customCode,
config: files.config,
themes: files.themes,
components: Object.fromEntries(
components.map((c) => [c.name, removeTestData(c)]),
),
// Routes are not necessary in output files for components
routes: undefined,
},
}
}
}
})

return {
routes,
components: files.components,
files: filesMap,
styles: stylesMap,
code: codeMap,
project: { project: json.project, config: files.config },
}
}
25 changes: 0 additions & 25 deletions scripts/syncStaticAssets.js

This file was deleted.

62 changes: 62 additions & 0 deletions scripts/syncStaticAssets.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
// Copy files from the static-assets directory to the dist directory using fs
// This script is executed by the build process
import { RESET_STYLES } from '@nordcraft/core/dist/styling/theme.const'
import * as fs from 'fs'
import { splitRoutes } from './routes'

// assets/_static/ folder
fs.rmdirSync(`${__dirname}/../assets/_static`, { recursive: true })
fs.mkdirSync(`${__dirname}/../assets/_static`, { recursive: true })
;[
'page.main.esm.js',
'page.main.esm.js.map',
'custom-element.main.esm.js',
].forEach((f) =>
fs.copyFileSync(
`${__dirname}/../node_modules/@nordcraft/runtime/dist/${f}`,
`${__dirname}/../assets/_static/${f}`,
),
)
fs.writeFileSync(`${__dirname}/../assets/_static/reset.css`, RESET_STYLES)

// dist/ folder
fs.rmdirSync(`${__dirname}/../dist`, { recursive: true })
fs.mkdirSync(`${__dirname}/../dist`, { recursive: true })
const projectFile = fs.readFileSync(`${__dirname}/../__project__/project.json`)
const json = JSON.parse(projectFile.toString())
// eslint-disable-next-line @typescript-eslint/no-unused-vars
const { project, routes, components, files, styles, code } = splitRoutes(json)
// Create a stylesheet for each component
Object.entries(styles).forEach(([name, style]) => {
fs.writeFileSync(
`${__dirname}/../assets/_static/${name.toLowerCase()}.css`,
style,
)
})
// Create a js file with custom code for each component
Object.entries(code).forEach(([name, c]) => {
fs.writeFileSync(
`${__dirname}/../assets/_static/cc_${name.toLowerCase()}.js`,
c,
)
})
const jsiFy = (obj: any) => `export default ${JSON.stringify(obj)}`
fs.writeFileSync(`${__dirname}/../dist/project.js`, jsiFy(project))
fs.writeFileSync(`${__dirname}/../dist/routes.js`, jsiFy(routes))
// fs.writeFileSync(
// `${__dirname}/../dist/components.js`,
// JSON.stringify(Object.entries(components).map(([name]) => name)),
// )
fs.mkdirSync(`${__dirname}/../dist/components`, { recursive: true })
Object.entries(files).forEach(([name, file]) => {
fs.writeFileSync(
`${__dirname}/../dist/components/${name.toLowerCase()}.js`,
jsiFy(file.files),
)
})
// Object.entries(components).forEach(([name, file]) => {
// fs.writeFileSync(
// `${__dirname}/../dist/components/${name.toLowerCase()}.js`,
// JSON.stringify(file),
// )
// })
Loading
Loading