@meekojs/meeko 0.0.4 → 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +21 -19
- package/dist/autoimports-ts.d.ts +4 -4
- package/dist/autoimports-ts.js +86 -30
- package/dist/autoimports-ts.js.map +1 -1
- package/dist/autoimports.d.ts +2 -2
- package/dist/autoimports.js +23 -7
- package/dist/autoimports.js.map +1 -1
- package/dist/check.js +39 -10
- package/dist/check.js.map +1 -1
- package/dist/cli.js +37 -4
- package/dist/cli.js.map +1 -1
- package/dist/compiler/events.d.ts +2 -0
- package/dist/compiler/events.js +6 -0
- package/dist/compiler/events.js.map +1 -0
- package/dist/compiler/props.d.ts +12 -0
- package/dist/compiler/props.js +32 -0
- package/dist/compiler/props.js.map +1 -0
- package/dist/compiler.js +55 -12
- package/dist/compiler.js.map +1 -1
- package/dist/component-errors.d.ts +18 -0
- package/dist/component-errors.js +65 -0
- package/dist/component-errors.js.map +1 -0
- package/dist/devtools.js +2 -4
- package/dist/devtools.js.map +1 -1
- package/dist/dom.d.ts +11 -5
- package/dist/dom.js +288 -88
- package/dist/dom.js.map +1 -1
- package/dist/error-observer.d.ts +6 -0
- package/dist/error-observer.js +41 -0
- package/dist/error-observer.js.map +1 -0
- package/dist/framework/check-app.js +160 -5
- package/dist/framework/check-app.js.map +1 -1
- package/dist/framework/check-project.d.ts +4 -0
- package/dist/framework/check-project.js +42 -0
- package/dist/framework/check-project.js.map +1 -0
- package/dist/framework/client.d.ts +3 -0
- package/dist/framework/client.js +136 -33
- package/dist/framework/client.js.map +1 -1
- package/dist/framework/clients.js +12 -4
- package/dist/framework/clients.js.map +1 -1
- package/dist/framework/contracts-generate.js +66 -3
- package/dist/framework/contracts-generate.js.map +1 -1
- package/dist/framework/init.js +21 -200
- package/dist/framework/init.js.map +1 -1
- package/dist/framework/middleware.d.ts +14 -0
- package/dist/framework/middleware.js +16 -0
- package/dist/framework/middleware.js.map +1 -0
- package/dist/framework/page-contracts-check.d.ts +8 -0
- package/dist/framework/page-contracts-check.js +110 -0
- package/dist/framework/page-contracts-check.js.map +1 -0
- package/dist/framework/page-contracts-generate.d.ts +2 -0
- package/dist/framework/page-contracts-generate.js +94 -0
- package/dist/framework/page-contracts-generate.js.map +1 -0
- package/dist/framework/page.d.ts +7 -3
- package/dist/framework/page.js +3 -1
- package/dist/framework/page.js.map +1 -1
- package/dist/framework/prerender.js +11 -5
- package/dist/framework/prerender.js.map +1 -1
- package/dist/framework/project-templates.d.ts +3 -0
- package/dist/framework/project-templates.js +119 -0
- package/dist/framework/project-templates.js.map +1 -0
- package/dist/framework/project.d.ts +9 -0
- package/dist/framework/project.js +272 -0
- package/dist/framework/project.js.map +1 -0
- package/dist/framework/router.d.ts +3 -1
- package/dist/framework/router.js +94 -8
- package/dist/framework/router.js.map +1 -1
- package/dist/framework/server.d.ts +17 -3
- package/dist/framework/server.js +71 -24
- package/dist/framework/server.js.map +1 -1
- package/dist/framework/socket-contracts-generate.js +8 -5
- package/dist/framework/socket-contracts-generate.js.map +1 -1
- package/dist/framework/socket.d.ts +2 -0
- package/dist/framework/socket.js +119 -17
- package/dist/framework/socket.js.map +1 -1
- package/dist/framework/standard-schema-types.d.ts +7 -0
- package/dist/framework/standard-schema-types.js +69 -0
- package/dist/framework/standard-schema-types.js.map +1 -0
- package/dist/framework/state.d.ts +7 -0
- package/dist/framework/state.js +78 -14
- package/dist/framework/state.js.map +1 -1
- package/dist/framework/styles.d.ts +2 -0
- package/dist/framework/styles.js +6 -0
- package/dist/framework/styles.js.map +1 -0
- package/dist/framework/type-declarations.d.ts +5 -0
- package/dist/framework/type-declarations.js +84 -0
- package/dist/framework/type-declarations.js.map +1 -0
- package/dist/framework-server/contracts.d.ts +11 -2
- package/dist/framework-server/contracts.js +62 -7
- package/dist/framework-server/contracts.js.map +1 -1
- package/dist/framework-server/discovery.d.ts +4 -1
- package/dist/framework-server/discovery.js +21 -16
- package/dist/framework-server/discovery.js.map +1 -1
- package/dist/framework-server/local.d.ts +2 -0
- package/dist/framework-server/local.js +5 -3
- package/dist/framework-server/local.js.map +1 -1
- package/dist/framework-server/middleware.d.ts +4 -0
- package/dist/framework-server/middleware.js +56 -0
- package/dist/framework-server/middleware.js.map +1 -0
- package/dist/framework-server/node-upgrade.js +27 -9
- package/dist/framework-server/node-upgrade.js.map +1 -1
- package/dist/framework-server/node-websocket.js +4 -2
- package/dist/framework-server/node-websocket.js.map +1 -1
- package/dist/framework-server/session-stores.d.ts +9 -2
- package/dist/framework-server/session-stores.js +37 -11
- package/dist/framework-server/session-stores.js.map +1 -1
- package/dist/framework-server/sessions.d.ts +6 -0
- package/dist/framework-server/sessions.js +41 -10
- package/dist/framework-server/sessions.js.map +1 -1
- package/dist/framework-server/socket.js +62 -27
- package/dist/framework-server/socket.js.map +1 -1
- package/dist/framework-server.d.ts +2 -0
- package/dist/framework-server.js +1 -0
- package/dist/framework-server.js.map +1 -1
- package/dist/framework.d.ts +3 -1
- package/dist/framework.js +1 -0
- package/dist/framework.js.map +1 -1
- package/dist/hmr.js +74 -24
- package/dist/hmr.js.map +1 -1
- package/dist/index.d.ts +2 -0
- package/dist/index.js +1 -0
- package/dist/index.js.map +1 -1
- package/dist/init.js +27 -1
- package/dist/init.js.map +1 -1
- package/dist/internal.d.ts +2 -2
- package/dist/internal.js +2 -2
- package/dist/internal.js.map +1 -1
- package/dist/node.d.ts +5 -1
- package/dist/node.js +80 -10
- package/dist/node.js.map +1 -1
- package/dist/reactivity.d.ts +12 -3
- package/dist/reactivity.js +94 -17
- package/dist/reactivity.js.map +1 -1
- package/dist/types.d.ts +2 -0
- package/dist/types.js +3 -1
- package/dist/types.js.map +1 -1
- package/dist/vite.js +29 -9
- package/dist/vite.js.map +1 -1
- package/package.json +2 -2
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"contracts-generate.js","sourceRoot":"","sources":["../../src/framework/contracts-generate.ts"],"names":[],"mappings":"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","sourcesContent":["import { mkdir, readFile, writeFile } from \"node:fs/promises\";\nimport { dirname, isAbsolute, join, relative, resolve, sep } from \"node:path\";\nimport ts from \"@typescript/typescript6\";\nimport { discoverServerManifest } from \"../framework-server/discovery.js\";\nimport type { ApiEndpoint, RpcEndpoint } from \"../framework-server/discovery.js\";\nimport { generateSocketContracts } from \"./socket-contracts-generate.js\";\n\nexport interface GeneratedServerContracts {\n readonly types: string;\n readonly manifest: string;\n readonly apiCount: number;\n readonly rpcCount: number;\n}\n\nasync function writeIfChanged(file: string, source: string): Promise<void> {\n try { if (await readFile(file, \"utf8\") === source) return; }\n catch (error) { if ((error as NodeJS.ErrnoException).code !== \"ENOENT\") throw error; }\n await writeFile(file, source, \"utf8\");\n}\n\ntype Kind = \"api\" | \"rpc\";\ntype Imports = Map<string, { file: string; exported: string }>;\n\nfunction inside(parent: string, child: string): boolean {\n const path = relative(parent, child);\n return path === \"\" || (path !== \"..\" && !path.startsWith(`..${sep}`) && !isAbsolute(path));\n}\n\nfunction optionsFor(root: string): ts.CompilerOptions {\n const config = ts.findConfigFile(root, ts.sys.fileExists, \"tsconfig.json\");\n if (!config) return { module: ts.ModuleKind.NodeNext, moduleResolution: ts.ModuleResolutionKind.NodeNext, target: ts.ScriptTarget.ES2022, skipLibCheck: true };\n const loaded = ts.readConfigFile(config, ts.sys.readFile);\n if (loaded.error) throw new Error(ts.flattenDiagnosticMessageText(loaded.error.messageText, \"\\n\"));\n return ts.parseJsonConfigFileContent(loaded.config, ts.sys, dirname(config)).options;\n}\n\nfunction resolvedImport(specifier: string, importer: string, options: ts.CompilerOptions): string | undefined {\n return ts.resolveModuleName(specifier, importer, options, ts.sys).resolvedModule?.resolvedFileName;\n}\n\nfunction importMap(file: ts.SourceFile, sharedRoot: string, options: ts.CompilerOptions): Imports {\n const imports: Imports = new Map();\n for (const statement of file.statements) {\n if (!ts.isImportDeclaration(statement) || !ts.isStringLiteral(statement.moduleSpecifier)) continue;\n const specifier = statement.moduleSpecifier.text;\n const target = resolvedImport(specifier, file.fileName, options);\n if (!target || !inside(sharedRoot, target)) continue;\n const clause = statement.importClause;\n if (!clause) continue;\n if (clause.name) imports.set(clause.name.text, { file: target, exported: \"default\" });\n if (clause.namedBindings && ts.isNamedImports(clause.namedBindings)) {\n for (const element of clause.namedBindings.elements) imports.set(element.name.text, { file: target, exported: element.propertyName?.text ?? element.name.text });\n }\n if (clause.namedBindings && ts.isNamespaceImport(clause.namedBindings)) imports.set(clause.namedBindings.name.text, { file: target, exported: \"*\" });\n }\n return imports;\n}\n\nfunction objectProperty(object: ts.ObjectLiteralExpression, name: string): ts.Expression | undefined {\n const property = object.properties.find((candidate) => {\n if (!ts.isPropertyAssignment(candidate) && !ts.isShorthandPropertyAssignment(candidate)) return false;\n return candidate.name.getText(object.getSourceFile()).replace(/^['\"]|['\"]$/g, \"\") === name;\n });\n if (!property) return undefined;\n if (ts.isPropertyAssignment(property)) return property.initializer;\n return ts.isShorthandPropertyAssignment(property) ? property.name : undefined;\n}\n\nfunction definition(file: ts.SourceFile, kind: Kind): ts.ObjectLiteralExpression {\n const assignment = file.statements.find((statement): statement is ts.ExportAssignment => ts.isExportAssignment(statement) && !statement.isExportEquals);\n const expression = assignment?.expression;\n const name = kind === \"api\" ? \"defineApiRoute\" : \"defineRpc\";\n if (!expression || !ts.isCallExpression(expression) || !ts.isIdentifier(expression.expression) || expression.expression.text !== name || !expression.arguments[0] || !ts.isObjectLiteralExpression(expression.arguments[0])) {\n throw new Error(`${file.fileName}: public ${kind.toUpperCase()} contract requires export default ${name}({...})`);\n }\n return expression.arguments[0];\n}\n\nfunction publicSchema(expression: ts.Expression | undefined, label: string, file: ts.SourceFile, imports: Imports, checker: ts.TypeChecker, root: string, sharedRoot: string, options: ts.CompilerOptions, outputDir: string): string | undefined {\n if (!expression) return undefined;\n let local: string;\n let member: string | undefined;\n if (ts.isIdentifier(expression)) local = expression.text;\n else if (ts.isPropertyAccessExpression(expression) && ts.isIdentifier(expression.expression)) { local = expression.expression.text; member = expression.name.text; }\n else throw new Error(`${file.fileName}: ${label} must reference an imported shared schema`);\n const imported = imports.get(local);\n if (!imported) throw new Error(`${file.fileName}: ${label} must come from shared/`);\n const exported = imported.exported === \"*\" ? member : imported.exported;\n if (!exported || (imported.exported !== \"*\" && member)) throw new Error(`${file.fileName}: ${label} must reference one shared export`);\n const type = checker.getTypeAtLocation(expression);\n if (type.flags & ts.TypeFlags.Any) throw new Error(`${file.fileName}: ${label} has type any; public schema cannot be inferred`);\n validateSharedGraph(imported.file, root, sharedRoot, options, new Set());\n const target = relative(outputDir, imported.file).replaceAll(\"\\\\\", \"/\").replace(/\\.(?:ts|mts|cts)$/, (suffix) => suffix === \".mts\" ? \".mjs\" : suffix === \".cts\" ? \".cjs\" : \".js\");\n const specifier = target.startsWith(\".\") ? target : `./${target}`;\n return `typeof import(${JSON.stringify(specifier)})[${JSON.stringify(exported)}]`;\n}\n\nfunction validateSharedGraph(file: string, root: string, sharedRoot: string, options: ts.CompilerOptions, seen: Set<string>): void {\n if (seen.has(file)) return;\n seen.add(file);\n if (!inside(sharedRoot, file)) throw new Error(`${file}: public schema dependency escapes shared/`);\n const source = ts.sys.readFile(file);\n if (source === undefined) throw new Error(`${file}: public schema dependency not found`);\n const ast = ts.createSourceFile(file, source, ts.ScriptTarget.Latest, true);\n const checkDependency = (specifier: string): void => {\n const target = resolvedImport(specifier, file, options);\n if (!target) throw new Error(`${file}: unresolved public schema dependency ${specifier}`);\n if (inside(root, target) && !relative(root, target).split(sep).includes(\"node_modules\")) validateSharedGraph(target, root, sharedRoot, options, seen);\n };\n for (const statement of ast.statements) {\n if (!ts.isImportDeclaration(statement) && !ts.isExportDeclaration(statement)) continue;\n const literal = statement.moduleSpecifier;\n if (!literal || !ts.isStringLiteral(literal)) continue;\n checkDependency(literal.text);\n }\n const visit = (node: ts.Node): void => {\n if (ts.isImportTypeNode(node) && ts.isLiteralTypeNode(node.argument) && ts.isStringLiteral(node.argument.literal)) checkDependency(node.argument.literal.text);\n ts.forEachChild(node, visit);\n };\n visit(ast);\n}\n\nfunction shapeFor(endpoint: ApiEndpoint | RpcEndpoint, checker: ts.TypeChecker, program: ts.Program, root: string, options: ts.CompilerOptions, outputDir: string): { type: string; contentType?: \"response\" } {\n const file = program.getSourceFile(endpoint.file);\n if (!file) throw new Error(`Handler not found: ${endpoint.file}`);\n const sharedRoot = join(root, \"shared\");\n const imports = importMap(file, sharedRoot, options);\n const kind: Kind = endpoint.kind;\n const contract = definition(file, kind);\n const schema = (name: string): string | undefined => publicSchema(objectProperty(contract, name), name, file, imports, checker, root, sharedRoot, options, outputDir);\n if (kind === \"rpc\") {\n const input = schema(\"input\");\n const output = schema(\"output\");\n if (!input || !output) throw new Error(`${file.fileName}: RPC requires public input and output schemas`);\n return { type: `import(\"@meekojs/meeko/framework\").RpcOperation<__Input<${input}>, __Output<${output}>>` };\n }\n const params = schema(\"params\");\n const query = schema(\"query\");\n const body = schema(\"body\");\n const response = schema(\"response\");\n const content = objectProperty(contract, \"contentType\");\n if (content && (!ts.isStringLiteral(content) || (content.text !== \"json\" && content.text !== \"response\"))) throw new Error(`${file.fileName}: contentType must be a static json or response literal`);\n const responseType = content && ts.isStringLiteral(content) && content.text === \"response\";\n if (!responseType && !response) throw new Error(`${file.fileName}: API requires a public response schema`);\n if (endpoint.pathname.includes(\"[\") && !params) throw new Error(`${file.fileName}: dynamic API path requires a public params schema`);\n return {\n type: `import(\"@meekojs/meeko/framework\").ApiOperation<${params ? `__Input<${params}>` : \"undefined\"}, ${query ? `__Input<${query}>` : \"undefined\"}, ${body ? `__Input<${body}>` : \"undefined\"}, ${responseType ? \"Response\" : `__Output<${response}>`}>`,\n ...(responseType ? { contentType: \"response\" as const } : {}),\n };\n}\n\n/** Generate public API/RPC declarations without importing handler modules. */\nexport async function generateServerContracts(projectRoot: string): Promise<GeneratedServerContracts> {\n const root = resolve(projectRoot);\n await generateSocketContracts(root);\n const discovered = await discoverServerManifest(root);\n const outputDir = join(root, \".meeko\", \"types\");\n const types = join(outputDir, \"server-contracts.d.ts\");\n const manifest = join(root, \".meeko\", \"manifests\", \"server.json\");\n const generatedDir = join(root, \".meeko\", \"generated\");\n const options = optionsFor(root);\n const files = [...discovered.api, ...discovered.rpc].map((entry) => entry.file);\n const program = ts.createProgram(files, { ...options, noEmit: true });\n const checker = program.getTypeChecker();\n const api = discovered.api.map((endpoint) => ({ endpoint, shape: shapeFor(endpoint, checker, program, root, options, outputDir) }));\n const rpc = discovered.rpc.map((endpoint) => ({ endpoint, shape: shapeFor(endpoint, checker, program, root, options, outputDir) }));\n const apiMethods = new Map<string, string[]>();\n for (const { endpoint, shape } of api) {\n const methods = apiMethods.get(endpoint.clientKey) ?? [];\n methods.push(`${endpoint.method.toLowerCase()}: ${shape.type}`);\n apiMethods.set(endpoint.clientKey, methods);\n }\n const lines = [\n \"// Generated by Meeko. Public schemas must live in shared/.\",\n 'type __Input<S> = S extends { readonly \"~standard\": { readonly types?: infer T } } ? NonNullable<T> extends { readonly input: infer I } ? I : never : never;',\n 'type __Output<S> = S extends { readonly \"~standard\": { readonly types?: infer T } } ? NonNullable<T> extends { readonly output: infer O } ? O : never : never;',\n \"export type ApiContract = {\",\n ...[...apiMethods].map(([key, methods]) => ` ${JSON.stringify(key)}: { ${methods.join(\"; \")} };`),\n \"};\",\n \"export type RpcContract = {\",\n ...rpc.map(({ endpoint, shape }) => ` ${JSON.stringify(endpoint.id)}: ${shape.type};`),\n \"};\",\n \"\",\n ];\n await mkdir(outputDir, { recursive: true });\n await mkdir(dirname(manifest), { recursive: true });\n await writeIfChanged(types, lines.join(\"\\n\"));\n const publicManifest = { version: 1, api: api.map(({ endpoint, shape }) => ({ clientKey: endpoint.clientKey, pathname: endpoint.pathname, method: endpoint.method, ...(shape.contentType ? { contentType: shape.contentType } : {}) })), rpc: rpc.map(({ endpoint }) => ({ id: endpoint.id, pathname: endpoint.pathname })) };\n await writeIfChanged(manifest, `${JSON.stringify(publicManifest, null, 2)}\\n`);\n await mkdir(generatedDir, { recursive: true });\n const clientSource = (server: boolean): string => [\n \"// Generated by Meeko. Contains only public route descriptors and shared contract types.\",\n `import { createApiClient, createRpcClient${server ? \"\" : \", createBrowserClientOptions\"} } from \"@meekojs/meeko/framework\";`,\n 'import { createSocketRegistry, useSocketChannel, type SocketRegistryOptions } from \"@meekojs/meeko/framework\";',\n ...(server ? ['import { createServerClientOptions } from \"@meekojs/meeko/server\";'] : []),\n 'import type { ApiContract, RpcContract } from \"../types/server-contracts.js\";',\n 'import { socketContracts } from \"./socket-contracts.js\";',\n `const manifest = ${JSON.stringify(publicManifest, null, 2)} as const;`,\n `const options = ${server ? \"createServerClientOptions()\" : \"createBrowserClientOptions()\"};`,\n \"export const api = createApiClient<ApiContract>(manifest, options);\",\n \"export const rpc = createRpcClient<RpcContract>(manifest, options);\",\n \"export const socket = createSocketRegistry(socketContracts);\",\n \"export const useSocket = <K extends keyof typeof socketContracts & string>(name: K, options?: SocketRegistryOptions) => useSocketChannel(socketContracts, name, options);\",\n \"\",\n ].join(\"\\n\");\n await writeIfChanged(join(generatedDir, \"clients.client.ts\"), clientSource(false));\n await writeIfChanged(join(generatedDir, \"clients.server.ts\"), clientSource(true));\n return { types, manifest, apiCount: api.length, rpcCount: rpc.length };\n}\n"]}
|
|
1
|
+
{"version":3,"file":"contracts-generate.js","sourceRoot":"","sources":["../../src/framework/contracts-generate.ts"],"names":[],"mappings":"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","sourcesContent":["import { mkdir, readFile, writeFile } from \"node:fs/promises\";\nimport { dirname, isAbsolute, join, relative, resolve, sep } from \"node:path\";\nimport ts from \"@typescript/typescript6\";\nimport { discoverServerManifest } from \"../framework-server/discovery.js\";\nimport type { ApiEndpoint, RpcEndpoint } from \"../framework-server/discovery.js\";\nimport { generateSocketContracts } from \"./socket-contracts-generate.js\";\nimport { standardSchemaTypes } from \"./standard-schema-types.js\";\n\nexport interface GeneratedServerContracts {\n readonly types: string;\n readonly manifest: string;\n readonly apiCount: number;\n readonly rpcCount: number;\n}\n\nasync function writeIfChanged(file: string, source: string): Promise<void> {\n try { if (await readFile(file, \"utf8\") === source) return; }\n catch (error) { if ((error as NodeJS.ErrnoException).code !== \"ENOENT\") throw error; }\n await writeFile(file, source, \"utf8\");\n}\n\ntype Kind = \"api\" | \"rpc\";\ntype Imports = Map<string, { file: string; exported: string }>;\n\nfunction inside(parent: string, child: string): boolean {\n const path = relative(parent, child);\n return path === \"\" || (path !== \"..\" && !path.startsWith(`..${sep}`) && !isAbsolute(path));\n}\n\nfunction optionsFor(root: string): ts.CompilerOptions {\n const config = ts.findConfigFile(root, ts.sys.fileExists, \"tsconfig.json\");\n if (!config) return { module: ts.ModuleKind.NodeNext, moduleResolution: ts.ModuleResolutionKind.NodeNext, target: ts.ScriptTarget.ES2022, skipLibCheck: true };\n const loaded = ts.readConfigFile(config, ts.sys.readFile);\n if (loaded.error) throw new Error(ts.flattenDiagnosticMessageText(loaded.error.messageText, \"\\n\"));\n return ts.parseJsonConfigFileContent(loaded.config, ts.sys, dirname(config)).options;\n}\n\nfunction resolvedImport(specifier: string, importer: string, options: ts.CompilerOptions): string | undefined {\n return ts.resolveModuleName(specifier, importer, options, ts.sys).resolvedModule?.resolvedFileName;\n}\n\nfunction importMap(file: ts.SourceFile, sharedRoot: string, options: ts.CompilerOptions): Imports {\n const imports: Imports = new Map();\n for (const statement of file.statements) {\n if (!ts.isImportDeclaration(statement) || !ts.isStringLiteral(statement.moduleSpecifier)) continue;\n const specifier = statement.moduleSpecifier.text;\n const target = resolvedImport(specifier, file.fileName, options);\n if (!target || !inside(sharedRoot, target)) continue;\n const clause = statement.importClause;\n if (!clause) continue;\n if (clause.name) imports.set(clause.name.text, { file: target, exported: \"default\" });\n if (clause.namedBindings && ts.isNamedImports(clause.namedBindings)) {\n for (const element of clause.namedBindings.elements) imports.set(element.name.text, { file: target, exported: element.propertyName?.text ?? element.name.text });\n }\n if (clause.namedBindings && ts.isNamespaceImport(clause.namedBindings)) imports.set(clause.namedBindings.name.text, { file: target, exported: \"*\" });\n }\n return imports;\n}\n\nfunction objectProperty(object: ts.ObjectLiteralExpression, name: string): ts.Expression | undefined {\n const property = object.properties.find((candidate) => {\n if (!ts.isPropertyAssignment(candidate) && !ts.isShorthandPropertyAssignment(candidate)) return false;\n return candidate.name.getText(object.getSourceFile()).replace(/^['\"]|['\"]$/g, \"\") === name;\n });\n if (!property) return undefined;\n if (ts.isPropertyAssignment(property)) return property.initializer;\n return ts.isShorthandPropertyAssignment(property) ? property.name : undefined;\n}\n\nfunction definition(file: ts.SourceFile, kind: Kind): ts.ObjectLiteralExpression {\n const assignment = file.statements.find((statement): statement is ts.ExportAssignment => ts.isExportAssignment(statement) && !statement.isExportEquals);\n const expression = assignment?.expression;\n const name = kind === \"api\" ? \"defineApiRoute\" : \"defineRpc\";\n if (!expression || !ts.isCallExpression(expression) || !ts.isIdentifier(expression.expression) || expression.expression.text !== name || !expression.arguments[0] || !ts.isObjectLiteralExpression(expression.arguments[0])) {\n throw new Error(`${file.fileName}: public ${kind.toUpperCase()} contract requires export default ${name}({...})`);\n }\n return expression.arguments[0];\n}\n\nfunction publicSchema(expression: ts.Expression | undefined, label: string, file: ts.SourceFile, imports: Imports, checker: ts.TypeChecker, root: string, sharedRoot: string, options: ts.CompilerOptions, outputDir: string): string | undefined {\n if (!expression) return undefined;\n let local: string;\n let member: string | undefined;\n if (ts.isIdentifier(expression)) local = expression.text;\n else if (ts.isPropertyAccessExpression(expression) && ts.isIdentifier(expression.expression)) { local = expression.expression.text; member = expression.name.text; }\n else throw new Error(`${file.fileName}: ${label} must reference an imported shared schema`);\n const imported = imports.get(local);\n if (!imported) throw new Error(`${file.fileName}: ${label} must come from shared/`);\n const exported = imported.exported === \"*\" ? member : imported.exported;\n if (!exported || (imported.exported !== \"*\" && member)) throw new Error(`${file.fileName}: ${label} must reference one shared export`);\n standardSchemaTypes(expression, checker, () => new Error(`${file.fileName}: ${label} must expose concrete Standard Schema input and output types`));\n validateSharedGraph(imported.file, root, sharedRoot, options, new Set());\n const target = relative(outputDir, imported.file).replaceAll(\"\\\\\", \"/\").replace(/\\.(?:ts|mts|cts)$/, (suffix) => suffix === \".mts\" ? \".mjs\" : suffix === \".cts\" ? \".cjs\" : \".js\");\n const specifier = target.startsWith(\".\") ? target : `./${target}`;\n return `typeof import(${JSON.stringify(specifier)})[${JSON.stringify(exported)}]`;\n}\n\nfunction schemaInputType(expression: ts.Expression, checker: ts.TypeChecker, invalid: () => Error): ts.Type {\n return standardSchemaTypes(expression, checker, invalid).input;\n}\n\nfunction validatePathParams(expression: ts.Expression, pathname: string, checker: ts.TypeChecker, file: ts.SourceFile): void {\n const expected = [...pathname.matchAll(/\\[(?:\\.\\.\\.)?([A-Za-z_$][\\w$]*)\\]/g)].map((match) => match[1]!);\n const invalid = () => new Error(`${file.fileName}: params must contain exactly the route parameters as required URL strings`);\n const inputType = schemaInputType(expression, checker, invalid);\n const stringType = checker.getStringType();\n for (const variant of inputType.isUnion() ? inputType.types : [inputType]) {\n if (variant.flags & (ts.TypeFlags.Any | ts.TypeFlags.Unknown | ts.TypeFlags.Never)\n || checker.getIndexTypeOfType(variant, ts.IndexKind.String)) throw invalid();\n const fields = checker.getPropertiesOfType(variant);\n if (fields.length !== expected.length || fields.some((field) => !expected.includes(field.getName()))) throw invalid();\n for (const name of expected) {\n const field = checker.getPropertyOfType(variant, name);\n if (!field || field.flags & ts.SymbolFlags.Optional) throw invalid();\n const value = checker.getTypeOfSymbolAtLocation(field, expression);\n if (value.flags & (ts.TypeFlags.Any | ts.TypeFlags.Unknown | ts.TypeFlags.Never)\n || !checker.isTypeAssignableTo(value, stringType)) throw invalid();\n }\n }\n}\n\nfunction validateQuery(expression: ts.Expression, checker: ts.TypeChecker, file: ts.SourceFile): void {\n const invalid = () => new Error(`${file.fileName}: query values must be URL strings or arrays of URL strings`);\n const inputType = schemaInputType(expression, checker, invalid);\n const stringType = checker.getStringType();\n const validValue = (value: ts.Type, arrayAllowed: boolean): boolean => {\n if (value.flags & (ts.TypeFlags.Any | ts.TypeFlags.Unknown | ts.TypeFlags.Never)) return false;\n if (value.isUnion()) return value.types.every((part) => validValue(part, arrayAllowed));\n if (value.flags & ts.TypeFlags.Undefined) return true;\n if (checker.isTypeAssignableTo(value, stringType)) return true;\n if (arrayAllowed && (checker.isArrayType(value) || checker.isTupleType(value))) {\n const item = checker.getIndexTypeOfType(value, ts.IndexKind.Number);\n return !!item && validValue(item, false);\n }\n return false;\n };\n for (const variant of inputType.isUnion() ? inputType.types : [inputType]) {\n if (!(variant.flags & (ts.TypeFlags.Object | ts.TypeFlags.Intersection))\n || checker.isArrayType(variant) || checker.isTupleType(variant)) throw invalid();\n for (const field of checker.getPropertiesOfType(variant)) {\n if (!validValue(checker.getTypeOfSymbolAtLocation(field, expression), true)) throw invalid();\n }\n const indexValue = checker.getIndexTypeOfType(variant, ts.IndexKind.String);\n if (indexValue && !validValue(indexValue, true)) throw invalid();\n }\n}\n\nfunction validateSharedGraph(file: string, root: string, sharedRoot: string, options: ts.CompilerOptions, seen: Set<string>): void {\n if (seen.has(file)) return;\n seen.add(file);\n if (!inside(sharedRoot, file)) throw new Error(`${file}: public schema dependency escapes shared/`);\n const source = ts.sys.readFile(file);\n if (source === undefined) throw new Error(`${file}: public schema dependency not found`);\n const ast = ts.createSourceFile(file, source, ts.ScriptTarget.Latest, true);\n const checkDependency = (specifier: string): void => {\n const target = resolvedImport(specifier, file, options);\n if (!target) throw new Error(`${file}: unresolved public schema dependency ${specifier}`);\n if (inside(root, target) && !relative(root, target).split(sep).includes(\"node_modules\")) validateSharedGraph(target, root, sharedRoot, options, seen);\n };\n for (const statement of ast.statements) {\n if (!ts.isImportDeclaration(statement) && !ts.isExportDeclaration(statement)) continue;\n const literal = statement.moduleSpecifier;\n if (!literal || !ts.isStringLiteral(literal)) continue;\n checkDependency(literal.text);\n }\n const visit = (node: ts.Node): void => {\n if (ts.isImportTypeNode(node) && ts.isLiteralTypeNode(node.argument) && ts.isStringLiteral(node.argument.literal)) checkDependency(node.argument.literal.text);\n ts.forEachChild(node, visit);\n };\n visit(ast);\n}\n\nfunction shapeFor(endpoint: ApiEndpoint | RpcEndpoint, checker: ts.TypeChecker, program: ts.Program, root: string, options: ts.CompilerOptions, outputDir: string): { type: string; contentType?: \"response\" } {\n const file = program.getSourceFile(endpoint.file);\n if (!file) throw new Error(`Handler not found: ${endpoint.file}`);\n const sharedRoot = join(root, \"shared\");\n const imports = importMap(file, sharedRoot, options);\n const kind: Kind = endpoint.kind;\n const contract = definition(file, kind);\n const schema = (name: string): string | undefined => publicSchema(objectProperty(contract, name), name, file, imports, checker, root, sharedRoot, options, outputDir);\n if (kind === \"rpc\") {\n const input = schema(\"input\");\n const output = schema(\"output\");\n if (!input || !output) throw new Error(`${file.fileName}: RPC requires public input and output schemas`);\n return { type: `import(\"@meekojs/meeko/framework\").RpcOperation<__Input<${input}>, __Output<${output}>>` };\n }\n const params = schema(\"params\");\n if (params && !endpoint.pathname.includes(\"[\")) throw new Error(`${file.fileName}: static API path cannot declare params`);\n if (params) validatePathParams(objectProperty(contract, \"params\")!, endpoint.pathname, checker, file);\n const query = schema(\"query\");\n if (query) validateQuery(objectProperty(contract, \"query\")!, checker, file);\n const body = schema(\"body\");\n const response = schema(\"response\");\n const content = objectProperty(contract, \"contentType\");\n if (content && (!ts.isStringLiteral(content) || (content.text !== \"json\" && content.text !== \"response\"))) throw new Error(`${file.fileName}: contentType must be a static json or response literal`);\n const responseType = content && ts.isStringLiteral(content) && content.text === \"response\";\n if (!responseType && !response) throw new Error(`${file.fileName}: API requires a public response schema`);\n if (endpoint.pathname.includes(\"[\") && !params) throw new Error(`${file.fileName}: dynamic API path requires a public params schema`);\n return {\n type: `import(\"@meekojs/meeko/framework\").ApiOperation<${params ? `__Input<${params}>` : \"undefined\"}, ${query ? `__Input<${query}>` : \"undefined\"}, ${body ? `__Input<${body}>` : \"undefined\"}, ${responseType ? \"Response\" : `__Output<${response}>`}>`,\n ...(responseType ? { contentType: \"response\" as const } : {}),\n };\n}\n\n/** Generate public API/RPC declarations without importing handler modules. */\nexport async function generateServerContracts(projectRoot: string): Promise<GeneratedServerContracts> {\n const root = resolve(projectRoot);\n await generateSocketContracts(root);\n const discovered = await discoverServerManifest(root);\n const outputDir = join(root, \".meeko\", \"types\");\n const types = join(outputDir, \"server-contracts.d.ts\");\n const manifest = join(root, \".meeko\", \"manifests\", \"server.json\");\n const generatedDir = join(root, \".meeko\", \"generated\");\n const options = optionsFor(root);\n const files = [...discovered.api, ...discovered.rpc].map((entry) => entry.file);\n const program = ts.createProgram(files, { ...options, noEmit: true });\n const checker = program.getTypeChecker();\n const api = discovered.api.map((endpoint) => ({ endpoint, shape: shapeFor(endpoint, checker, program, root, options, outputDir) }));\n const rpc = discovered.rpc.map((endpoint) => ({ endpoint, shape: shapeFor(endpoint, checker, program, root, options, outputDir) }));\n const apiMethods = new Map<string, string[]>();\n for (const { endpoint, shape } of api) {\n const methods = apiMethods.get(endpoint.clientKey) ?? [];\n methods.push(`${endpoint.method.toLowerCase()}: ${shape.type}`);\n apiMethods.set(endpoint.clientKey, methods);\n }\n const lines = [\n \"// Generated by Meeko. Public schemas must live in shared/.\",\n 'type __Input<S> = S extends { readonly \"~standard\": { readonly types?: infer T } } ? NonNullable<T> extends { readonly input: infer I } ? I : never : never;',\n 'type __Output<S> = S extends { readonly \"~standard\": { readonly types?: infer T } } ? NonNullable<T> extends { readonly output: infer O } ? O : never : never;',\n \"export type ApiContract = {\",\n ...[...apiMethods].map(([key, methods]) => ` ${JSON.stringify(key)}: { ${methods.join(\"; \")} };`),\n \"};\",\n \"export type RpcContract = {\",\n ...rpc.map(({ endpoint, shape }) => ` ${JSON.stringify(endpoint.id)}: ${shape.type};`),\n \"};\",\n \"\",\n ];\n await mkdir(outputDir, { recursive: true });\n await mkdir(dirname(manifest), { recursive: true });\n await writeIfChanged(types, lines.join(\"\\n\"));\n const publicManifest = { version: 1, api: api.map(({ endpoint, shape }) => ({ clientKey: endpoint.clientKey, pathname: endpoint.pathname, method: endpoint.method, ...(shape.contentType ? { contentType: shape.contentType } : {}) })), rpc: rpc.map(({ endpoint }) => ({ id: endpoint.id, pathname: endpoint.pathname })) };\n await writeIfChanged(manifest, `${JSON.stringify(publicManifest, null, 2)}\\n`);\n await mkdir(generatedDir, { recursive: true });\n const clientSource = (server: boolean): string => [\n \"// Generated by Meeko. Contains only public route descriptors and shared contract types.\",\n `import { createApiClient, createRpcClient${server ? \"\" : \", createBrowserClientOptions\"} } from \"@meekojs/meeko/framework\";`,\n 'import { createSocketRegistry, useSocketChannel, type SocketRegistryOptions } from \"@meekojs/meeko/framework\";',\n ...(server ? ['import { createServerClientOptions } from \"@meekojs/meeko/server\";'] : []),\n 'import type { ApiContract, RpcContract } from \"../types/server-contracts.js\";',\n 'import { socketContracts } from \"./socket-contracts.js\";',\n `const manifest = ${JSON.stringify(publicManifest, null, 2)} as const;`,\n `const options = ${server ? \"createServerClientOptions()\" : \"createBrowserClientOptions()\"};`,\n \"export const api = createApiClient<ApiContract>(manifest, options);\",\n \"export const rpc = createRpcClient<RpcContract>(manifest, options);\",\n \"export const socket = createSocketRegistry(socketContracts);\",\n \"export const useSocket = <K extends keyof typeof socketContracts & string>(name: K, options?: SocketRegistryOptions) => useSocketChannel(socketContracts, name, options);\",\n \"\",\n ].join(\"\\n\");\n await writeIfChanged(join(generatedDir, \"clients.client.ts\"), clientSource(false));\n await writeIfChanged(join(generatedDir, \"clients.server.ts\"), clientSource(true));\n return { types, manifest, apiCount: api.length, rpcCount: rpc.length };\n}\n"]}
|
package/dist/framework/init.js
CHANGED
|
@@ -4,6 +4,10 @@ const allowedEntries = new Set(["package.json", "package-lock.json", "pnpm-lock.
|
|
|
4
4
|
const files = {
|
|
5
5
|
".gitignore": "node_modules/\n.meeko/\n",
|
|
6
6
|
"public/.gitkeep": "",
|
|
7
|
+
"app/styles/main.css": `:root { color-scheme: light dark; font-family: system-ui, sans-serif; }
|
|
8
|
+
* { box-sizing: border-box; }
|
|
9
|
+
body { margin: 0; }
|
|
10
|
+
`,
|
|
7
11
|
"meeko.config.ts": `import { defineMeekoConfig } from "@meekojs/meeko/framework";
|
|
8
12
|
|
|
9
13
|
export default defineMeekoConfig({
|
|
@@ -11,30 +15,6 @@ export default defineMeekoConfig({
|
|
|
11
15
|
modules: [],
|
|
12
16
|
imports: { serverDirs: [] },
|
|
13
17
|
});
|
|
14
|
-
`,
|
|
15
|
-
"vite.config.ts": `import { defineConfig } from "vite";
|
|
16
|
-
import { meeko } from "@meekojs/meeko/vite";
|
|
17
|
-
|
|
18
|
-
export default defineConfig({
|
|
19
|
-
plugins: [meeko()],
|
|
20
|
-
build: {
|
|
21
|
-
outDir: ".meeko/output/client",
|
|
22
|
-
manifest: true,
|
|
23
|
-
rollupOptions: { input: "app/entry-client.ts" },
|
|
24
|
-
},
|
|
25
|
-
});
|
|
26
|
-
`,
|
|
27
|
-
"vite.server.config.ts": `import { defineConfig } from "vite";
|
|
28
|
-
import { meeko } from "@meekojs/meeko/vite";
|
|
29
|
-
|
|
30
|
-
export default defineConfig({
|
|
31
|
-
plugins: [meeko()],
|
|
32
|
-
build: {
|
|
33
|
-
ssr: "server/entry.ts",
|
|
34
|
-
outDir: ".meeko/output/server",
|
|
35
|
-
rollupOptions: { output: { entryFileNames: "entry.js" } },
|
|
36
|
-
},
|
|
37
|
-
});
|
|
38
18
|
`,
|
|
39
19
|
"tsconfig.json": `{
|
|
40
20
|
"compilerOptions": {
|
|
@@ -48,24 +28,12 @@ export default defineConfig({
|
|
|
48
28
|
"allowArbitraryExtensions": true,
|
|
49
29
|
"skipLibCheck": true
|
|
50
30
|
},
|
|
51
|
-
"
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
"tsconfig.
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
"include": ["app/**/*.ts", "layers/**/app/**/*.ts", "modules/**/app/**/*.ts", ".meeko/types/**/*.d.meeko.ts", ".meeko/types/routes.d.ts", ".meeko/types/virtual-pages.d.ts", ".meeko/types/server-contracts.d.ts", ".meeko/types/autoimports/client.d.ts"],
|
|
58
|
-
"exclude": ["app/pages/**/*.route.ts", "layers/**/app/pages/**/*.route.ts", "modules/**/app/pages/**/*.route.ts"]
|
|
59
|
-
}
|
|
60
|
-
`,
|
|
61
|
-
"tsconfig.server.json": `{
|
|
62
|
-
"extends": "./tsconfig.json",
|
|
63
|
-
"include": ["server/**/*.ts", "app/pages/**/*.route.ts", "layers/**/app/pages/**/*.route.ts", "modules/**/app/pages/**/*.route.ts", "layers/**/server/**/*.ts", "modules/**/server/**/*.ts", ".meeko/types/virtual-pages.d.ts", ".meeko/types/autoimports/server.d.ts"]
|
|
64
|
-
}
|
|
65
|
-
`,
|
|
66
|
-
"tsconfig.shared.json": `{
|
|
67
|
-
"extends": "./tsconfig.json",
|
|
68
|
-
"include": ["shared/**/*.ts", "layers/**/shared/**/*.ts", "modules/**/shared/**/*.ts", ".meeko/types/autoimports/shared.d.ts"]
|
|
31
|
+
"files": [],
|
|
32
|
+
"references": [
|
|
33
|
+
{ "path": "./.meeko/tsconfig.app.json" },
|
|
34
|
+
{ "path": "./.meeko/tsconfig.server.json" },
|
|
35
|
+
{ "path": "./.meeko/tsconfig.shared.json" }
|
|
36
|
+
]
|
|
69
37
|
}
|
|
70
38
|
`,
|
|
71
39
|
"app/pages/index.meeko": `<script lang="ts">
|
|
@@ -73,7 +41,7 @@ import { signal } from "@meekojs/meeko";
|
|
|
73
41
|
|
|
74
42
|
export interface Props {
|
|
75
43
|
params: Record<string, string>;
|
|
76
|
-
search: Record<string, string>;
|
|
44
|
+
search: Record<string, string | string[]>;
|
|
77
45
|
data?: unknown;
|
|
78
46
|
}
|
|
79
47
|
|
|
@@ -93,10 +61,10 @@ const count = signal(0);
|
|
|
93
61
|
export const route = definePage({ render: "prerender" });
|
|
94
62
|
`,
|
|
95
63
|
"app/app.meeko": `<script lang="ts">
|
|
96
|
-
import type {
|
|
64
|
+
import type { Component } from "@meekojs/meeko";
|
|
97
65
|
|
|
98
66
|
export interface Props {
|
|
99
|
-
outlet:
|
|
67
|
+
outlet: Component<Record<string, unknown>>;
|
|
100
68
|
}
|
|
101
69
|
|
|
102
70
|
const props = defineProps<Props>();
|
|
@@ -106,11 +74,11 @@ const props = defineProps<Props>();
|
|
|
106
74
|
<div class="site-root"><component is="props.outlet"></component></div>
|
|
107
75
|
</template>
|
|
108
76
|
`,
|
|
109
|
-
"app/
|
|
110
|
-
import type {
|
|
77
|
+
"app/layouts/default.meeko": `<script lang="ts">
|
|
78
|
+
import type { Component } from "@meekojs/meeko";
|
|
111
79
|
|
|
112
80
|
export interface Props {
|
|
113
|
-
outlet:
|
|
81
|
+
outlet: Component<Record<string, unknown>>;
|
|
114
82
|
}
|
|
115
83
|
|
|
116
84
|
const props = defineProps<Props>();
|
|
@@ -127,73 +95,6 @@ const props = defineProps<Props>();
|
|
|
127
95
|
.app-shell { max-width: 64rem; margin: 0 auto; padding: 2rem; font-family: system-ui, sans-serif; }
|
|
128
96
|
header { margin-bottom: 2rem; }
|
|
129
97
|
</style>
|
|
130
|
-
`,
|
|
131
|
-
"app/entry-client.ts": `import { mountClientApp, type ClientComponent, type RouteRecord } from "@meekojs/meeko/framework";
|
|
132
|
-
import { modules as pages } from "virtual:meeko-client-pages";
|
|
133
|
-
|
|
134
|
-
const root = document.getElementById("app");
|
|
135
|
-
const payload = document.getElementById("meeko-payload")?.textContent;
|
|
136
|
-
const routesText = document.getElementById("meeko-routes")?.textContent;
|
|
137
|
-
if (!root || !payload || !routesText) throw new Error("Missing Meeko SSR data");
|
|
138
|
-
const routes = JSON.parse(routesText) as RouteRecord[];
|
|
139
|
-
|
|
140
|
-
await mountClientApp({
|
|
141
|
-
root, payload, routes, serverData: true,
|
|
142
|
-
async loadPage(file) {
|
|
143
|
-
const load = pages[file];
|
|
144
|
-
if (!load) throw new Error("Page module missing: " + file);
|
|
145
|
-
return await load() as ClientComponent;
|
|
146
|
-
},
|
|
147
|
-
});
|
|
148
|
-
`,
|
|
149
|
-
"server/entry.ts": `import { createFrameworkHandler, createLocalServerFetch, createRequestContext, createServerDispatcher, createSocketHub, discoverServerManifest, loadSocketChannels, type FrameworkHandlerOptions } from "@meekojs/meeko/server";
|
|
150
|
-
import type { RouteRecord } from "@meekojs/meeko/framework";
|
|
151
|
-
import { modules as pages } from "virtual:meeko-server-pages";
|
|
152
|
-
import { modules as routeModules } from "virtual:meeko-server-routes";
|
|
153
|
-
import { createSessionManager } from "./session.js";
|
|
154
|
-
|
|
155
|
-
const handlers = import.meta.glob(["/server/api/**/*.ts", "/server/rpc/**/*.ts", "/server/socket/**/*.ts"], { eager: true });
|
|
156
|
-
|
|
157
|
-
function keyFor(root: string, file: string): string {
|
|
158
|
-
return "/" + file.slice(root.length).replaceAll("\\\\", "/").replace(/^\\//, "");
|
|
159
|
-
}
|
|
160
|
-
|
|
161
|
-
export const loadPage = async (root: string, file: string): Promise<Awaited<ReturnType<FrameworkHandlerOptions["loadPage"]>>> => {
|
|
162
|
-
const key = keyFor(root, file);
|
|
163
|
-
const module = pages[key];
|
|
164
|
-
if (!module) throw new Error("Page module missing: " + key);
|
|
165
|
-
return module as Awaited<ReturnType<FrameworkHandlerOptions["loadPage"]>>;
|
|
166
|
-
};
|
|
167
|
-
|
|
168
|
-
export const loadRoute = async (root: string, file: string): Promise<Awaited<ReturnType<NonNullable<FrameworkHandlerOptions["loadRoute"]>>>> => {
|
|
169
|
-
const key = keyFor(root, file);
|
|
170
|
-
const module = routeModules[key] as Record<string, unknown> | undefined;
|
|
171
|
-
if (!module) throw new Error("Route module missing: " + key);
|
|
172
|
-
return (module.route ?? module.default ?? module) as Awaited<ReturnType<NonNullable<FrameworkHandlerOptions["loadRoute"]>>>;
|
|
173
|
-
};
|
|
174
|
-
|
|
175
|
-
export async function createAppRuntime(root: string, routes: readonly RouteRecord[], clientEntry: string, production: boolean) {
|
|
176
|
-
const sessions = createSessionManager(production);
|
|
177
|
-
const manifest = await discoverServerManifest(root);
|
|
178
|
-
const load = async (file: string) => {
|
|
179
|
-
const module = handlers[keyFor(root, file)];
|
|
180
|
-
if (!module) throw new Error("Server handler missing: " + file);
|
|
181
|
-
return module;
|
|
182
|
-
};
|
|
183
|
-
const services = {};
|
|
184
|
-
const pageHandler = createFrameworkHandler({
|
|
185
|
-
routes,
|
|
186
|
-
loadPage: (file) => loadPage(root, file),
|
|
187
|
-
loadRoute: (file) => loadRoute(root, file),
|
|
188
|
-
clientEntry,
|
|
189
|
-
createContext: async (request) => createRequestContext(request, services, await sessions.load(request)),
|
|
190
|
-
serverFetch: createLocalServerFetch({ manifest, sessions, load }),
|
|
191
|
-
});
|
|
192
|
-
const endpointHandler = createServerDispatcher({ manifest, sessions, services, load });
|
|
193
|
-
const channels = await loadSocketChannels(manifest, load);
|
|
194
|
-
const socketHub = createSocketHub({ channels, sessions, services });
|
|
195
|
-
return { pageHandler, endpointHandler, socketHub, sessions, manifest };
|
|
196
|
-
}
|
|
197
98
|
`,
|
|
198
99
|
"server/session.ts": `import { MemorySessionStore, SessionManager } from "@meekojs/meeko/server";
|
|
199
100
|
|
|
@@ -201,86 +102,6 @@ export function createSessionManager(production: boolean) {
|
|
|
201
102
|
if (production) throw new Error("Configure a persistent SessionStore in server/session.ts before production startup");
|
|
202
103
|
return new SessionManager({ store: new MemorySessionStore(), production: false });
|
|
203
104
|
}
|
|
204
|
-
`,
|
|
205
|
-
"server.mjs": `import { createServer } from "node:http";
|
|
206
|
-
import { readFile, realpath } from "node:fs/promises";
|
|
207
|
-
import { dirname, extname, relative, resolve, sep } from "node:path";
|
|
208
|
-
import { fileURLToPath, pathToFileURL } from "node:url";
|
|
209
|
-
import { createServer as createViteServer } from "vite";
|
|
210
|
-
import { attachNodeWebSocketServer, discoverConfiguredRoutes, toNodeListener } from "@meekojs/meeko/server";
|
|
211
|
-
import { serializeJson } from "@meekojs/meeko";
|
|
212
|
-
|
|
213
|
-
const root = dirname(fileURLToPath(import.meta.url));
|
|
214
|
-
const production = process.argv.includes("--production");
|
|
215
|
-
const vite = production ? undefined : await createViteServer({
|
|
216
|
-
root, configFile: resolve(root, "vite.config.ts"),
|
|
217
|
-
server: { middlewareMode: true }, appType: "custom",
|
|
218
|
-
});
|
|
219
|
-
const clientRoot = resolve(root, ".meeko/output/client");
|
|
220
|
-
const publicRoot = resolve(root, "public");
|
|
221
|
-
const routes = await discoverConfiguredRoutes(root);
|
|
222
|
-
let clientEntry = "/app/entry-client.ts";
|
|
223
|
-
if (production) {
|
|
224
|
-
const manifest = JSON.parse(await readFile(resolve(clientRoot, ".vite/manifest.json"), "utf8"));
|
|
225
|
-
const entry = manifest["app/entry-client.ts"];
|
|
226
|
-
if (!entry?.file) throw new Error("Missing client entry in Vite manifest");
|
|
227
|
-
clientEntry = "/" + entry.file;
|
|
228
|
-
}
|
|
229
|
-
const serverEntry = production
|
|
230
|
-
? await import(pathToFileURL(resolve(root, ".meeko/output/server/entry.js")).href)
|
|
231
|
-
: await vite.ssrLoadModule("/server/entry.ts");
|
|
232
|
-
const portable = routes.map((route) => ({
|
|
233
|
-
id: route.id,
|
|
234
|
-
file: "/" + relative(root, route.file).replaceAll("\\\\", "/"),
|
|
235
|
-
layouts: route.layouts.map((file) => "/" + relative(root, file).replaceAll("\\\\", "/")),
|
|
236
|
-
...(route.error ? { error: "/" + relative(root, route.error).replaceAll("\\\\", "/") } : {}),
|
|
237
|
-
}));
|
|
238
|
-
const runtime = await serverEntry.createAppRuntime(root, routes, clientEntry, production);
|
|
239
|
-
const handler = runtime.pageHandler;
|
|
240
|
-
const decorated = async (request) => {
|
|
241
|
-
const path = new URL(request.url).pathname;
|
|
242
|
-
if (path.startsWith("/api/") || path.startsWith("/_meeko/rpc/")) return runtime.endpointHandler(request);
|
|
243
|
-
const result = await handler(request);
|
|
244
|
-
if (result.status !== 200 || !(result.headers.get("content-type") || "").includes("text/html")) return result;
|
|
245
|
-
let html = (await result.text()).replace("</body>", '<script id="meeko-routes" type="application/json">' + serializeJson(portable) + "</script></body>");
|
|
246
|
-
if (vite) html = await vite.transformIndexHtml(new URL(request.url).pathname, html);
|
|
247
|
-
return new Response(request.method === "HEAD" ? null : html, { status: result.status, headers: result.headers });
|
|
248
|
-
};
|
|
249
|
-
const pageListener = toNodeListener(decorated);
|
|
250
|
-
const types = { ".js": "text/javascript", ".css": "text/css", ".svg": "image/svg+xml", ".png": "image/png" };
|
|
251
|
-
async function readAsset(assetRoot, path) {
|
|
252
|
-
const file = resolve(assetRoot, "." + path);
|
|
253
|
-
if (!file.startsWith(assetRoot + sep)) return { status: 403 };
|
|
254
|
-
let actual;
|
|
255
|
-
try { actual = await realpath(file); }
|
|
256
|
-
catch (error) { if (error?.code === "ENOENT") return null; throw error; }
|
|
257
|
-
const actualRoot = await realpath(assetRoot);
|
|
258
|
-
if (!actual.startsWith(actualRoot + sep)) return { status: 403 };
|
|
259
|
-
return { status: 200, body: await readFile(actual) };
|
|
260
|
-
}
|
|
261
|
-
const server = createServer((request, response) => {
|
|
262
|
-
const path = new URL(request.url || "/", "http://localhost").pathname;
|
|
263
|
-
if (production && /\\.[a-z0-9]+$/i.test(path)) {
|
|
264
|
-
void (async () => {
|
|
265
|
-
const asset = await readAsset(clientRoot, path) ?? await readAsset(publicRoot, path);
|
|
266
|
-
if (!asset || asset.status !== 200) { response.writeHead(asset?.status ?? 404); response.end(); return; }
|
|
267
|
-
response.writeHead(200, { "content-type": types[extname(path)] || "application/octet-stream" });
|
|
268
|
-
response.end(asset.body);
|
|
269
|
-
})().catch(() => { response.writeHead(404); response.end(); });
|
|
270
|
-
return;
|
|
271
|
-
}
|
|
272
|
-
if (vite) {
|
|
273
|
-
vite.middlewares(request, response, () => pageListener(request, response));
|
|
274
|
-
return;
|
|
275
|
-
}
|
|
276
|
-
pageListener(request, response);
|
|
277
|
-
});
|
|
278
|
-
const port = Number(process.env.PORT || 4173);
|
|
279
|
-
const socketServer = runtime.manifest.socket?.length ? attachNodeWebSocketServer({
|
|
280
|
-
server, hub: runtime.socketHub, publicOrigin: process.env.PUBLIC_ORIGIN || "http://127.0.0.1:" + port,
|
|
281
|
-
}) : undefined;
|
|
282
|
-
server.listen(port, "127.0.0.1", () => console.log("http://127.0.0.1:" + port));
|
|
283
|
-
process.on("SIGINT", () => { void socketServer?.close(); server.close(); void runtime.sessions.close(); void vite?.close(); });
|
|
284
105
|
`,
|
|
285
106
|
"README.md": `# Meeko framework starter
|
|
286
107
|
|
|
@@ -291,7 +112,7 @@ npm install
|
|
|
291
112
|
npm run dev
|
|
292
113
|
\`\`\`
|
|
293
114
|
|
|
294
|
-
Routes live in \`app/pages\`.
|
|
115
|
+
Routes live in \`app/pages\`. \`app/layouts/default.meeko\` keeps the shared shell during client navigation. Put shared route guards in \`app/middleware\` with \`defineRouteMiddleware\`, and Node request middleware in \`server/middleware\` with \`defineServerMiddleware\`; see the framework guide for their execution and security boundaries. Global styles in \`app/styles/main.css\` load automatically; component styles stay in \`<style>\` blocks. Run \`npm run check\` for types, then \`npm run build\` and \`npm start\` for production SSR. Generated files live under \`.meeko/\`.
|
|
295
116
|
`,
|
|
296
117
|
};
|
|
297
118
|
function record(value) {
|
|
@@ -325,10 +146,10 @@ export async function initFrameworkProject(directory) {
|
|
|
325
146
|
throw new Error(`Invalid package.json in ${target}`);
|
|
326
147
|
}
|
|
327
148
|
const scripts = {
|
|
328
|
-
dev: "
|
|
329
|
-
check: "meeko
|
|
330
|
-
build: "
|
|
331
|
-
start: "
|
|
149
|
+
dev: "meeko dev .",
|
|
150
|
+
check: "meeko check .",
|
|
151
|
+
build: "meeko build .",
|
|
152
|
+
start: "meeko start .",
|
|
332
153
|
};
|
|
333
154
|
const oldScripts = existing.scripts;
|
|
334
155
|
for (const command of Object.keys(scripts))
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"init.js","sourceRoot":"","sources":["../../src/framework/init.ts"],"names":[],"mappings":"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","sourcesContent":["import { mkdir, readFile, readdir, stat, writeFile } from \"node:fs/promises\";\nimport { basename, dirname, join, resolve } from \"node:path\";\n\nconst allowedEntries = new Set([\"package.json\", \"package-lock.json\", \"pnpm-lock.yaml\", \"pnpm-workspace.yaml\", \"yarn.lock\", \"node_modules\", \".npmrc\", \".git\"]);\n\nconst files: Readonly<Record<string, string>> = {\n \".gitignore\": \"node_modules/\\n.meeko/\\n\",\n \"public/.gitkeep\": \"\",\n \"meeko.config.ts\": `import { defineMeekoConfig } from \"@meekojs/meeko/framework\";\n\nexport default defineMeekoConfig({\n extends: [],\n modules: [],\n imports: { serverDirs: [] },\n});\n`,\n \"vite.config.ts\": `import { defineConfig } from \"vite\";\nimport { meeko } from \"@meekojs/meeko/vite\";\n\nexport default defineConfig({\n plugins: [meeko()],\n build: {\n outDir: \".meeko/output/client\",\n manifest: true,\n rollupOptions: { input: \"app/entry-client.ts\" },\n },\n});\n`,\n \"vite.server.config.ts\": `import { defineConfig } from \"vite\";\nimport { meeko } from \"@meekojs/meeko/vite\";\n\nexport default defineConfig({\n plugins: [meeko()],\n build: {\n ssr: \"server/entry.ts\",\n outDir: \".meeko/output/server\",\n rollupOptions: { output: { entryFileNames: \"entry.js\" } },\n },\n});\n`,\n \"tsconfig.json\": `{\n \"compilerOptions\": {\n \"target\": \"ES2022\",\n \"module\": \"NodeNext\",\n \"moduleResolution\": \"NodeNext\",\n \"lib\": [\"ES2022\", \"DOM\"],\n \"types\": [\"node\", \"vite/client\"],\n \"strict\": true,\n \"noEmit\": true,\n \"allowArbitraryExtensions\": true,\n \"skipLibCheck\": true\n },\n \"include\": [\"vite.config.ts\", \"vite.server.config.ts\"]\n}\n`,\n \"tsconfig.app.json\": `{\n \"extends\": \"./tsconfig.json\",\n \"compilerOptions\": { \"rootDirs\": [\".\", \".meeko/types\"] },\n \"include\": [\"app/**/*.ts\", \"layers/**/app/**/*.ts\", \"modules/**/app/**/*.ts\", \".meeko/types/**/*.d.meeko.ts\", \".meeko/types/routes.d.ts\", \".meeko/types/virtual-pages.d.ts\", \".meeko/types/server-contracts.d.ts\", \".meeko/types/autoimports/client.d.ts\"],\n \"exclude\": [\"app/pages/**/*.route.ts\", \"layers/**/app/pages/**/*.route.ts\", \"modules/**/app/pages/**/*.route.ts\"]\n}\n`,\n \"tsconfig.server.json\": `{\n \"extends\": \"./tsconfig.json\",\n \"include\": [\"server/**/*.ts\", \"app/pages/**/*.route.ts\", \"layers/**/app/pages/**/*.route.ts\", \"modules/**/app/pages/**/*.route.ts\", \"layers/**/server/**/*.ts\", \"modules/**/server/**/*.ts\", \".meeko/types/virtual-pages.d.ts\", \".meeko/types/autoimports/server.d.ts\"]\n}\n`,\n \"tsconfig.shared.json\": `{\n \"extends\": \"./tsconfig.json\",\n \"include\": [\"shared/**/*.ts\", \"layers/**/shared/**/*.ts\", \"modules/**/shared/**/*.ts\", \".meeko/types/autoimports/shared.d.ts\"]\n}\n`,\n \"app/pages/index.meeko\": `<script lang=\"ts\">\nimport { signal } from \"@meekojs/meeko\";\n\nexport interface Props {\n params: Record<string, string>;\n search: Record<string, string>;\n data?: unknown;\n}\n\nconst count = signal(0);\n</script>\n\n<template>\n <section>\n <h1>Welcome to Meeko</h1>\n <p>File routes, server rendering, and hydration are ready.</p>\n <button type=\"button\" on:click=\"() => count.value++\">Count: {count.value}</button>\n </section>\n</template>\n`,\n \"app/pages/index.route.ts\": `import { definePage } from \"@meekojs/meeko/framework\";\n\nexport const route = definePage({ render: \"prerender\" });\n`,\n \"app/app.meeko\": `<script lang=\"ts\">\nimport type { ComponentModule } from \"@meekojs/meeko\";\n\nexport interface Props {\n outlet: ComponentModule<Record<string, unknown>>;\n}\n\nconst props = defineProps<Props>();\n</script>\n\n<template>\n <div class=\"site-root\"><component is=\"props.outlet\"></component></div>\n</template>\n`,\n \"app/pages/+layout.meeko\": `<script lang=\"ts\">\nimport type { ComponentModule } from \"@meekojs/meeko\";\n\nexport interface Props {\n outlet: ComponentModule<Record<string, unknown>>;\n}\n\nconst props = defineProps<Props>();\n</script>\n\n<template>\n <div class=\"app-shell\">\n <header><a href=\"/\">Meeko</a></header>\n <main><component is=\"props.outlet\"></component></main>\n </div>\n</template>\n\n<style scoped>\n.app-shell { max-width: 64rem; margin: 0 auto; padding: 2rem; font-family: system-ui, sans-serif; }\nheader { margin-bottom: 2rem; }\n</style>\n`,\n \"app/entry-client.ts\": `import { mountClientApp, type ClientComponent, type RouteRecord } from \"@meekojs/meeko/framework\";\nimport { modules as pages } from \"virtual:meeko-client-pages\";\n\nconst root = document.getElementById(\"app\");\nconst payload = document.getElementById(\"meeko-payload\")?.textContent;\nconst routesText = document.getElementById(\"meeko-routes\")?.textContent;\nif (!root || !payload || !routesText) throw new Error(\"Missing Meeko SSR data\");\nconst routes = JSON.parse(routesText) as RouteRecord[];\n\nawait mountClientApp({\n root, payload, routes, serverData: true,\n async loadPage(file) {\n const load = pages[file];\n if (!load) throw new Error(\"Page module missing: \" + file);\n return await load() as ClientComponent;\n },\n});\n`,\n \"server/entry.ts\": `import { createFrameworkHandler, createLocalServerFetch, createRequestContext, createServerDispatcher, createSocketHub, discoverServerManifest, loadSocketChannels, type FrameworkHandlerOptions } from \"@meekojs/meeko/server\";\nimport type { RouteRecord } from \"@meekojs/meeko/framework\";\nimport { modules as pages } from \"virtual:meeko-server-pages\";\nimport { modules as routeModules } from \"virtual:meeko-server-routes\";\nimport { createSessionManager } from \"./session.js\";\n\nconst handlers = import.meta.glob([\"/server/api/**/*.ts\", \"/server/rpc/**/*.ts\", \"/server/socket/**/*.ts\"], { eager: true });\n\nfunction keyFor(root: string, file: string): string {\n return \"/\" + file.slice(root.length).replaceAll(\"\\\\\\\\\", \"/\").replace(/^\\\\//, \"\");\n}\n\nexport const loadPage = async (root: string, file: string): Promise<Awaited<ReturnType<FrameworkHandlerOptions[\"loadPage\"]>>> => {\n const key = keyFor(root, file);\n const module = pages[key];\n if (!module) throw new Error(\"Page module missing: \" + key);\n return module as Awaited<ReturnType<FrameworkHandlerOptions[\"loadPage\"]>>;\n};\n\nexport const loadRoute = async (root: string, file: string): Promise<Awaited<ReturnType<NonNullable<FrameworkHandlerOptions[\"loadRoute\"]>>>> => {\n const key = keyFor(root, file);\n const module = routeModules[key] as Record<string, unknown> | undefined;\n if (!module) throw new Error(\"Route module missing: \" + key);\n return (module.route ?? module.default ?? module) as Awaited<ReturnType<NonNullable<FrameworkHandlerOptions[\"loadRoute\"]>>>;\n};\n\nexport async function createAppRuntime(root: string, routes: readonly RouteRecord[], clientEntry: string, production: boolean) {\n const sessions = createSessionManager(production);\n const manifest = await discoverServerManifest(root);\n const load = async (file: string) => {\n const module = handlers[keyFor(root, file)];\n if (!module) throw new Error(\"Server handler missing: \" + file);\n return module;\n };\n const services = {};\n const pageHandler = createFrameworkHandler({\n routes,\n loadPage: (file) => loadPage(root, file),\n loadRoute: (file) => loadRoute(root, file),\n clientEntry,\n createContext: async (request) => createRequestContext(request, services, await sessions.load(request)),\n serverFetch: createLocalServerFetch({ manifest, sessions, load }),\n });\n const endpointHandler = createServerDispatcher({ manifest, sessions, services, load });\n const channels = await loadSocketChannels(manifest, load);\n const socketHub = createSocketHub({ channels, sessions, services });\n return { pageHandler, endpointHandler, socketHub, sessions, manifest };\n}\n`,\n \"server/session.ts\": `import { MemorySessionStore, SessionManager } from \"@meekojs/meeko/server\";\n\nexport function createSessionManager(production: boolean) {\n if (production) throw new Error(\"Configure a persistent SessionStore in server/session.ts before production startup\");\n return new SessionManager({ store: new MemorySessionStore(), production: false });\n}\n`,\n \"server.mjs\": `import { createServer } from \"node:http\";\nimport { readFile, realpath } from \"node:fs/promises\";\nimport { dirname, extname, relative, resolve, sep } from \"node:path\";\nimport { fileURLToPath, pathToFileURL } from \"node:url\";\nimport { createServer as createViteServer } from \"vite\";\nimport { attachNodeWebSocketServer, discoverConfiguredRoutes, toNodeListener } from \"@meekojs/meeko/server\";\nimport { serializeJson } from \"@meekojs/meeko\";\n\nconst root = dirname(fileURLToPath(import.meta.url));\nconst production = process.argv.includes(\"--production\");\nconst vite = production ? undefined : await createViteServer({\n root, configFile: resolve(root, \"vite.config.ts\"),\n server: { middlewareMode: true }, appType: \"custom\",\n});\nconst clientRoot = resolve(root, \".meeko/output/client\");\nconst publicRoot = resolve(root, \"public\");\nconst routes = await discoverConfiguredRoutes(root);\nlet clientEntry = \"/app/entry-client.ts\";\nif (production) {\n const manifest = JSON.parse(await readFile(resolve(clientRoot, \".vite/manifest.json\"), \"utf8\"));\n const entry = manifest[\"app/entry-client.ts\"];\n if (!entry?.file) throw new Error(\"Missing client entry in Vite manifest\");\n clientEntry = \"/\" + entry.file;\n}\nconst serverEntry = production\n ? await import(pathToFileURL(resolve(root, \".meeko/output/server/entry.js\")).href)\n : await vite.ssrLoadModule(\"/server/entry.ts\");\nconst portable = routes.map((route) => ({\n id: route.id,\n file: \"/\" + relative(root, route.file).replaceAll(\"\\\\\\\\\", \"/\"),\n layouts: route.layouts.map((file) => \"/\" + relative(root, file).replaceAll(\"\\\\\\\\\", \"/\")),\n ...(route.error ? { error: \"/\" + relative(root, route.error).replaceAll(\"\\\\\\\\\", \"/\") } : {}),\n}));\nconst runtime = await serverEntry.createAppRuntime(root, routes, clientEntry, production);\nconst handler = runtime.pageHandler;\nconst decorated = async (request) => {\n const path = new URL(request.url).pathname;\n if (path.startsWith(\"/api/\") || path.startsWith(\"/_meeko/rpc/\")) return runtime.endpointHandler(request);\n const result = await handler(request);\n if (result.status !== 200 || !(result.headers.get(\"content-type\") || \"\").includes(\"text/html\")) return result;\n let html = (await result.text()).replace(\"</body>\", '<script id=\"meeko-routes\" type=\"application/json\">' + serializeJson(portable) + \"</script></body>\");\n if (vite) html = await vite.transformIndexHtml(new URL(request.url).pathname, html);\n return new Response(request.method === \"HEAD\" ? null : html, { status: result.status, headers: result.headers });\n};\nconst pageListener = toNodeListener(decorated);\nconst types = { \".js\": \"text/javascript\", \".css\": \"text/css\", \".svg\": \"image/svg+xml\", \".png\": \"image/png\" };\nasync function readAsset(assetRoot, path) {\n const file = resolve(assetRoot, \".\" + path);\n if (!file.startsWith(assetRoot + sep)) return { status: 403 };\n let actual;\n try { actual = await realpath(file); }\n catch (error) { if (error?.code === \"ENOENT\") return null; throw error; }\n const actualRoot = await realpath(assetRoot);\n if (!actual.startsWith(actualRoot + sep)) return { status: 403 };\n return { status: 200, body: await readFile(actual) };\n}\nconst server = createServer((request, response) => {\n const path = new URL(request.url || \"/\", \"http://localhost\").pathname;\n if (production && /\\\\.[a-z0-9]+$/i.test(path)) {\n void (async () => {\n const asset = await readAsset(clientRoot, path) ?? await readAsset(publicRoot, path);\n if (!asset || asset.status !== 200) { response.writeHead(asset?.status ?? 404); response.end(); return; }\n response.writeHead(200, { \"content-type\": types[extname(path)] || \"application/octet-stream\" });\n response.end(asset.body);\n })().catch(() => { response.writeHead(404); response.end(); });\n return;\n }\n if (vite) {\n vite.middlewares(request, response, () => pageListener(request, response));\n return;\n }\n pageListener(request, response);\n});\nconst port = Number(process.env.PORT || 4173);\nconst socketServer = runtime.manifest.socket?.length ? attachNodeWebSocketServer({\n server, hub: runtime.socketHub, publicOrigin: process.env.PUBLIC_ORIGIN || \"http://127.0.0.1:\" + port,\n}) : undefined;\nserver.listen(port, \"127.0.0.1\", () => console.log(\"http://127.0.0.1:\" + port));\nprocess.on(\"SIGINT\", () => { void socketServer?.close(); server.close(); void runtime.sessions.close(); void vite?.close(); });\n`,\n \"README.md\": `# Meeko framework starter\n\nRequires Node 24.\n\n\\`\\`\\`sh\nnpm install\nnpm run dev\n\\`\\`\\`\n\nRoutes live in \\`app/pages\\`. \\`+layout.meeko\\` keeps the shared shell during client navigation. Run \\`npm run build\\` and \\`npm start\\` for production SSR. Generated files live under \\`.meeko/\\`.\n`,\n};\n\nfunction record(value: unknown): value is Record<string, unknown> {\n return typeof value === \"object\" && value !== null && !Array.isArray(value);\n}\n\n/** Creates a framework project without overwriting unrelated user files. */\nexport async function initFrameworkProject(directory: string): Promise<string> {\n const target = resolve(directory);\n const name = basename(target).toLowerCase().replace(/[^a-z0-9._-]+/g, \"-\").replace(/^[._-]+|[._-]+$/g, \"\") || \"meeko-app\";\n const metadata: unknown = JSON.parse(await readFile(new URL(\"../../package.json\", import.meta.url), \"utf8\"));\n if (!record(metadata) || typeof metadata.version !== \"string\") throw new Error(\"Meeko package version is unavailable\");\n let entries: string[] = [];\n try {\n if (!(await stat(target)).isDirectory()) throw new Error(`Destination is not a directory: ${target}`);\n entries = await readdir(target);\n } catch (error) {\n if (!(error instanceof Error && \"code\" in error && error.code === \"ENOENT\")) throw error;\n }\n const unexpected = entries.filter((entry) => !allowedEntries.has(entry));\n if (unexpected.length || (entries.length && !entries.includes(\"package.json\"))) {\n throw new Error(`Destination is not empty: ${target}`);\n }\n const existing: unknown = entries.includes(\"package.json\") ? JSON.parse(await readFile(join(target, \"package.json\"), \"utf8\")) : {};\n if (!record(existing) || (existing.scripts !== undefined && !record(existing.scripts))\n || (existing.dependencies !== undefined && !record(existing.dependencies))\n || (existing.devDependencies !== undefined && !record(existing.devDependencies))) {\n throw new Error(`Invalid package.json in ${target}`);\n }\n const scripts = {\n dev: \"node server.mjs\",\n check: \"meeko routes . && meeko check-app . && tsc -p tsconfig.json --noEmit && tsc -p tsconfig.shared.json --noEmit && tsc -p tsconfig.app.json --noEmit && tsc -p tsconfig.server.json --noEmit\",\n build: \"npm run check && vite build --config vite.config.ts && vite build --config vite.server.config.ts && meeko prerender .\",\n start: \"node server.mjs --production\",\n };\n const oldScripts = existing.scripts as Record<string, unknown> | undefined;\n for (const command of Object.keys(scripts)) if (oldScripts && command in oldScripts) {\n throw new Error(`Destination already defines the ${command} script: ${target}`);\n }\n const manifest = {\n ...existing,\n name: typeof existing.name === \"string\" ? existing.name : name,\n private: true,\n type: \"module\",\n engines: { ...(record(existing.engines) ? existing.engines : {}), node: \">=24\" },\n scripts: { ...oldScripts, ...scripts },\n dependencies: { ...(existing.dependencies as Record<string, unknown> | undefined), \"@meekojs/meeko\": metadata.version },\n devDependencies: {\n ...(existing.devDependencies as Record<string, unknown> | undefined),\n \"@types/node\": \"^24.0.0\", typescript: \"^7.0.2\", vite: \"^8.3.5\",\n },\n };\n await mkdir(target, { recursive: true });\n for (const [filename, content] of Object.entries(files)) {\n const output = join(target, filename);\n await mkdir(dirname(output), { recursive: true });\n await writeFile(output, content, { encoding: \"utf8\", flag: \"wx\" });\n }\n await writeFile(join(target, \"package.json\"), JSON.stringify(manifest, null, 2) + \"\\n\", {\n encoding: \"utf8\", flag: entries.includes(\"package.json\") ? \"w\" : \"wx\",\n });\n return target;\n}\n"]}
|
|
1
|
+
{"version":3,"file":"init.js","sourceRoot":"","sources":["../../src/framework/init.ts"],"names":[],"mappings":"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","sourcesContent":["import { mkdir, readFile, readdir, stat, writeFile } from \"node:fs/promises\";\nimport { basename, dirname, join, resolve } from \"node:path\";\n\nconst allowedEntries = new Set([\"package.json\", \"package-lock.json\", \"pnpm-lock.yaml\", \"pnpm-workspace.yaml\", \"yarn.lock\", \"node_modules\", \".npmrc\", \".git\"]);\n\nconst files: Readonly<Record<string, string>> = {\n \".gitignore\": \"node_modules/\\n.meeko/\\n\",\n \"public/.gitkeep\": \"\",\n \"app/styles/main.css\": `:root { color-scheme: light dark; font-family: system-ui, sans-serif; }\n* { box-sizing: border-box; }\nbody { margin: 0; }\n`,\n \"meeko.config.ts\": `import { defineMeekoConfig } from \"@meekojs/meeko/framework\";\n\nexport default defineMeekoConfig({\n extends: [],\n modules: [],\n imports: { serverDirs: [] },\n});\n`,\n \"tsconfig.json\": `{\n \"compilerOptions\": {\n \"target\": \"ES2022\",\n \"module\": \"NodeNext\",\n \"moduleResolution\": \"NodeNext\",\n \"lib\": [\"ES2022\", \"DOM\"],\n \"types\": [\"node\", \"vite/client\"],\n \"strict\": true,\n \"noEmit\": true,\n \"allowArbitraryExtensions\": true,\n \"skipLibCheck\": true\n },\n \"files\": [],\n \"references\": [\n { \"path\": \"./.meeko/tsconfig.app.json\" },\n { \"path\": \"./.meeko/tsconfig.server.json\" },\n { \"path\": \"./.meeko/tsconfig.shared.json\" }\n ]\n}\n`,\n \"app/pages/index.meeko\": `<script lang=\"ts\">\nimport { signal } from \"@meekojs/meeko\";\n\nexport interface Props {\n params: Record<string, string>;\n search: Record<string, string | string[]>;\n data?: unknown;\n}\n\nconst count = signal(0);\n</script>\n\n<template>\n <section>\n <h1>Welcome to Meeko</h1>\n <p>File routes, server rendering, and hydration are ready.</p>\n <button type=\"button\" on:click=\"() => count.value++\">Count: {count.value}</button>\n </section>\n</template>\n`,\n \"app/pages/index.route.ts\": `import { definePage } from \"@meekojs/meeko/framework\";\n\nexport const route = definePage({ render: \"prerender\" });\n`,\n \"app/app.meeko\": `<script lang=\"ts\">\nimport type { Component } from \"@meekojs/meeko\";\n\nexport interface Props {\n outlet: Component<Record<string, unknown>>;\n}\n\nconst props = defineProps<Props>();\n</script>\n\n<template>\n <div class=\"site-root\"><component is=\"props.outlet\"></component></div>\n</template>\n`,\n \"app/layouts/default.meeko\": `<script lang=\"ts\">\nimport type { Component } from \"@meekojs/meeko\";\n\nexport interface Props {\n outlet: Component<Record<string, unknown>>;\n}\n\nconst props = defineProps<Props>();\n</script>\n\n<template>\n <div class=\"app-shell\">\n <header><a href=\"/\">Meeko</a></header>\n <main><component is=\"props.outlet\"></component></main>\n </div>\n</template>\n\n<style scoped>\n.app-shell { max-width: 64rem; margin: 0 auto; padding: 2rem; font-family: system-ui, sans-serif; }\nheader { margin-bottom: 2rem; }\n</style>\n`,\n \"server/session.ts\": `import { MemorySessionStore, SessionManager } from \"@meekojs/meeko/server\";\n\nexport function createSessionManager(production: boolean) {\n if (production) throw new Error(\"Configure a persistent SessionStore in server/session.ts before production startup\");\n return new SessionManager({ store: new MemorySessionStore(), production: false });\n}\n`,\n \"README.md\": `# Meeko framework starter\n\nRequires Node 24.\n\n\\`\\`\\`sh\nnpm install\nnpm run dev\n\\`\\`\\`\n\nRoutes live in \\`app/pages\\`. \\`app/layouts/default.meeko\\` keeps the shared shell during client navigation. Put shared route guards in \\`app/middleware\\` with \\`defineRouteMiddleware\\`, and Node request middleware in \\`server/middleware\\` with \\`defineServerMiddleware\\`; see the framework guide for their execution and security boundaries. Global styles in \\`app/styles/main.css\\` load automatically; component styles stay in \\`<style>\\` blocks. Run \\`npm run check\\` for types, then \\`npm run build\\` and \\`npm start\\` for production SSR. Generated files live under \\`.meeko/\\`.\n`,\n};\n\nfunction record(value: unknown): value is Record<string, unknown> {\n return typeof value === \"object\" && value !== null && !Array.isArray(value);\n}\n\n/** Creates a framework project without overwriting unrelated user files. */\nexport async function initFrameworkProject(directory: string): Promise<string> {\n const target = resolve(directory);\n const name = basename(target).toLowerCase().replace(/[^a-z0-9._-]+/g, \"-\").replace(/^[._-]+|[._-]+$/g, \"\") || \"meeko-app\";\n const metadata: unknown = JSON.parse(await readFile(new URL(\"../../package.json\", import.meta.url), \"utf8\"));\n if (!record(metadata) || typeof metadata.version !== \"string\") throw new Error(\"Meeko package version is unavailable\");\n let entries: string[] = [];\n try {\n if (!(await stat(target)).isDirectory()) throw new Error(`Destination is not a directory: ${target}`);\n entries = await readdir(target);\n } catch (error) {\n if (!(error instanceof Error && \"code\" in error && error.code === \"ENOENT\")) throw error;\n }\n const unexpected = entries.filter((entry) => !allowedEntries.has(entry));\n if (unexpected.length || (entries.length && !entries.includes(\"package.json\"))) {\n throw new Error(`Destination is not empty: ${target}`);\n }\n const existing: unknown = entries.includes(\"package.json\") ? JSON.parse(await readFile(join(target, \"package.json\"), \"utf8\")) : {};\n if (!record(existing) || (existing.scripts !== undefined && !record(existing.scripts))\n || (existing.dependencies !== undefined && !record(existing.dependencies))\n || (existing.devDependencies !== undefined && !record(existing.devDependencies))) {\n throw new Error(`Invalid package.json in ${target}`);\n }\n const scripts = {\n dev: \"meeko dev .\",\n check: \"meeko check .\",\n build: \"meeko build .\",\n start: \"meeko start .\",\n };\n const oldScripts = existing.scripts as Record<string, unknown> | undefined;\n for (const command of Object.keys(scripts)) if (oldScripts && command in oldScripts) {\n throw new Error(`Destination already defines the ${command} script: ${target}`);\n }\n const manifest = {\n ...existing,\n name: typeof existing.name === \"string\" ? existing.name : name,\n private: true,\n type: \"module\",\n engines: { ...(record(existing.engines) ? existing.engines : {}), node: \">=24\" },\n scripts: { ...oldScripts, ...scripts },\n dependencies: { ...(existing.dependencies as Record<string, unknown> | undefined), \"@meekojs/meeko\": metadata.version },\n devDependencies: {\n ...(existing.devDependencies as Record<string, unknown> | undefined),\n \"@types/node\": \"^24.0.0\", typescript: \"^7.0.2\", vite: \"^8.3.5\",\n },\n };\n await mkdir(target, { recursive: true });\n for (const [filename, content] of Object.entries(files)) {\n const output = join(target, filename);\n await mkdir(dirname(output), { recursive: true });\n await writeFile(output, content, { encoding: \"utf8\", flag: \"wx\" });\n }\n await writeFile(join(target, \"package.json\"), JSON.stringify(manifest, null, 2) + \"\\n\", {\n encoding: \"utf8\", flag: entries.includes(\"package.json\") ? \"w\" : \"wx\",\n });\n return target;\n}\n"]}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import type { RouteMatch } from "./router.js";
|
|
2
|
+
/** Runs for matched page requests and browser navigations before the loader. */
|
|
3
|
+
export interface RouteMiddlewareContext {
|
|
4
|
+
readonly url: URL;
|
|
5
|
+
readonly match: RouteMatch;
|
|
6
|
+
readonly signal: AbortSignal;
|
|
7
|
+
readonly phase: "server" | "client";
|
|
8
|
+
/** Only present during SSR. Never serialize this request to the browser. */
|
|
9
|
+
readonly request?: Request;
|
|
10
|
+
}
|
|
11
|
+
export type RouteMiddleware = (context: RouteMiddlewareContext) => void | Response | Promise<void | Response>;
|
|
12
|
+
export declare function defineRouteMiddleware(middleware: RouteMiddleware): RouteMiddleware;
|
|
13
|
+
/** Stops at the first response; middleware files are supplied in filename order. */
|
|
14
|
+
export declare function runRouteMiddleware(middlewares: readonly RouteMiddleware[], context: RouteMiddlewareContext): Promise<Response | undefined>;
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
export function defineRouteMiddleware(middleware) {
|
|
2
|
+
return middleware;
|
|
3
|
+
}
|
|
4
|
+
/** Stops at the first response; middleware files are supplied in filename order. */
|
|
5
|
+
export async function runRouteMiddleware(middlewares, context) {
|
|
6
|
+
for (const middleware of middlewares) {
|
|
7
|
+
const result = await middleware(context);
|
|
8
|
+
if (result === undefined)
|
|
9
|
+
continue;
|
|
10
|
+
if (!(result instanceof Response))
|
|
11
|
+
throw new TypeError("Route middleware must return a Response or nothing");
|
|
12
|
+
return result;
|
|
13
|
+
}
|
|
14
|
+
return undefined;
|
|
15
|
+
}
|
|
16
|
+
//# sourceMappingURL=middleware.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"middleware.js","sourceRoot":"","sources":["../../src/framework/middleware.ts"],"names":[],"mappings":"AAcA,MAAM,UAAU,qBAAqB,CAAC,UAA2B;IAC/D,OAAO,UAAU,CAAC;AACpB,CAAC;AAED,oFAAoF;AACpF,MAAM,CAAC,KAAK,UAAU,kBAAkB,CACtC,WAAuC,EACvC,OAA+B;IAE/B,KAAK,MAAM,UAAU,IAAI,WAAW,EAAE,CAAC;QACrC,MAAM,MAAM,GAAG,MAAM,UAAU,CAAC,OAAO,CAAC,CAAC;QACzC,IAAI,MAAM,KAAK,SAAS;YAAE,SAAS;QACnC,IAAI,CAAC,CAAC,MAAM,YAAY,QAAQ,CAAC;YAAE,MAAM,IAAI,SAAS,CAAC,oDAAoD,CAAC,CAAC;QAC7G,OAAO,MAAM,CAAC;IAChB,CAAC;IACD,OAAO,SAAS,CAAC;AACnB,CAAC","sourcesContent":["import type { RouteMatch } from \"./router.js\";\n\n/** Runs for matched page requests and browser navigations before the loader. */\nexport interface RouteMiddlewareContext {\n readonly url: URL;\n readonly match: RouteMatch;\n readonly signal: AbortSignal;\n readonly phase: \"server\" | \"client\";\n /** Only present during SSR. Never serialize this request to the browser. */\n readonly request?: Request;\n}\n\nexport type RouteMiddleware = (context: RouteMiddlewareContext) => void | Response | Promise<void | Response>;\n\nexport function defineRouteMiddleware(middleware: RouteMiddleware): RouteMiddleware {\n return middleware;\n}\n\n/** Stops at the first response; middleware files are supplied in filename order. */\nexport async function runRouteMiddleware(\n middlewares: readonly RouteMiddleware[],\n context: RouteMiddlewareContext,\n): Promise<Response | undefined> {\n for (const middleware of middlewares) {\n const result = await middleware(context);\n if (result === undefined) continue;\n if (!(result instanceof Response)) throw new TypeError(\"Route middleware must return a Response or nothing\");\n return result;\n }\n return undefined;\n}\n"]}
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
export interface PageContractDiagnostic {
|
|
2
|
+
readonly filename: string;
|
|
3
|
+
readonly offset: number;
|
|
4
|
+
readonly code: "MEEK_PAGE_PROPS" | "MEEK_LAYOUT_PROPS" | "MEEK_ERROR_PROPS";
|
|
5
|
+
readonly message: string;
|
|
6
|
+
}
|
|
7
|
+
/** Checks generated route/component contracts after a saved project change. */
|
|
8
|
+
export declare function checkFrameworkPageContracts(projectRoot: string): Promise<PageContractDiagnostic[]>;
|