@junojs/core 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/LICENSE +21 -0
- package/README.md +75 -0
- package/dist/cli/cli.d.ts +12 -0
- package/dist/cli/cli.d.ts.map +1 -0
- package/dist/cli.cjs +88 -0
- package/dist/cli.cjs.map +1 -0
- package/dist/cli.js +238 -0
- package/dist/cli.js.map +1 -0
- package/dist/common/forms/form-model.d.ts +29 -0
- package/dist/common/forms/form-model.d.ts.map +1 -0
- package/dist/common/forms/index.d.ts +4 -0
- package/dist/common/forms/index.d.ts.map +1 -0
- package/dist/common/forms/schema.d.ts +33 -0
- package/dist/common/forms/schema.d.ts.map +1 -0
- package/dist/common/forms/validators.d.ts +18 -0
- package/dist/common/forms/validators.d.ts.map +1 -0
- package/dist/common/http/http.service.d.ts +25 -0
- package/dist/common/http/http.service.d.ts.map +1 -0
- package/dist/common/http/index.d.ts +3 -0
- package/dist/common/http/index.d.ts.map +1 -0
- package/dist/common/i18n/i18n.service.d.ts +36 -0
- package/dist/common/i18n/i18n.service.d.ts.map +1 -0
- package/dist/common/i18n/index.d.ts +2 -0
- package/dist/common/i18n/index.d.ts.map +1 -0
- package/dist/common/router/index.d.ts +2 -0
- package/dist/common/router/index.d.ts.map +1 -0
- package/dist/common/router/router.service.d.ts +46 -0
- package/dist/common/router/router.service.d.ts.map +1 -0
- package/dist/core/bootstrap.d.ts +3 -0
- package/dist/core/bootstrap.d.ts.map +1 -0
- package/dist/core/decorators.d.ts +56 -0
- package/dist/core/decorators.d.ts.map +1 -0
- package/dist/core/dom.d.ts +6 -0
- package/dist/core/dom.d.ts.map +1 -0
- package/dist/core/engine.d.ts +7 -0
- package/dist/core/engine.d.ts.map +1 -0
- package/dist/core/error-handler.d.ts +34 -0
- package/dist/core/error-handler.d.ts.map +1 -0
- package/dist/core/index.d.ts +9 -0
- package/dist/core/index.d.ts.map +1 -0
- package/dist/core/persist.d.ts +15 -0
- package/dist/core/persist.d.ts.map +1 -0
- package/dist/core/reactivity.d.ts +3 -0
- package/dist/core/reactivity.d.ts.map +1 -0
- package/dist/index.cjs +2 -0
- package/dist/index.cjs.map +1 -0
- package/dist/index.d.ts +8 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +896 -0
- package/dist/index.js.map +1 -0
- package/package.json +67 -0
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 JunoJS contributors
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
package/README.md
ADDED
|
@@ -0,0 +1,75 @@
|
|
|
1
|
+
# JunoJS
|
|
2
|
+
|
|
3
|
+
**JunoJS** is an AI-Native Reactive Engine for building modern web applications using **Native Web Components** and **Proxy-based Reactivity**.
|
|
4
|
+
|
|
5
|
+
## Features
|
|
6
|
+
|
|
7
|
+
- ⚛️ **Native Web Components**: Standard-based, no proprietary runtime required.
|
|
8
|
+
- ⚡ **Proxy-based Reactivity**: Effortless state management with zero boilerplate.
|
|
9
|
+
- 🎨 **HTML-First Templates**: Clean, declarative templates that just work.
|
|
10
|
+
- 🛠️ **Decorator-driven TypeScript**: Use `@Component`, `@State`, and dependency injection with ease.
|
|
11
|
+
- 🛡️ **Built-in Validation**: Robust validation decorators like `@Required` and `@Email`.
|
|
12
|
+
- 🧩 **Zero Virtual DOM**: High-performance rendering with direct DOM interaction.
|
|
13
|
+
|
|
14
|
+
## Installation
|
|
15
|
+
|
|
16
|
+
```bash
|
|
17
|
+
npm install @junojs/core
|
|
18
|
+
```
|
|
19
|
+
|
|
20
|
+
## Quick Start
|
|
21
|
+
|
|
22
|
+
```typescript
|
|
23
|
+
import { Component, State, bootstrap } from '@junojs/core';
|
|
24
|
+
|
|
25
|
+
@Component({
|
|
26
|
+
tag: 'juno-counter',
|
|
27
|
+
template: `
|
|
28
|
+
<div class="counter">
|
|
29
|
+
<h1>Count: {count}</h1>
|
|
30
|
+
<button onclick="{increment}">Increment</button>
|
|
31
|
+
</div>
|
|
32
|
+
`
|
|
33
|
+
})
|
|
34
|
+
export class CounterComponent {
|
|
35
|
+
@State() count = 0;
|
|
36
|
+
|
|
37
|
+
increment() {
|
|
38
|
+
this.count++;
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
bootstrap();
|
|
43
|
+
```
|
|
44
|
+
|
|
45
|
+
## Core Directives
|
|
46
|
+
|
|
47
|
+
- `@Component({ tag, templateUrl, shadow })`: Defines a new custom element.
|
|
48
|
+
- `@State()`: Automatically re-renders the component when the value changes.
|
|
49
|
+
- `@Use(ServiceClass)`: Injects a singleton service.
|
|
50
|
+
- `@Validate(predicate, msg)`: Custom validation for form fields.
|
|
51
|
+
- `@HostElement()`: Injects the native `HTMLElement` of the component.
|
|
52
|
+
|
|
53
|
+
## Lifecycle Hooks
|
|
54
|
+
|
|
55
|
+
- `onInit()`: Runs before the first render.
|
|
56
|
+
- `onRender()`: Runs after every render.
|
|
57
|
+
- `onDestroy()`: Runs when the component is removed from the DOM.
|
|
58
|
+
|
|
59
|
+
## Template Logic
|
|
60
|
+
|
|
61
|
+
Use custom elements for logic:
|
|
62
|
+
|
|
63
|
+
```html
|
|
64
|
+
<if condition="{isVisible}">
|
|
65
|
+
<p>Now you see me!</p>
|
|
66
|
+
</if>
|
|
67
|
+
|
|
68
|
+
<for each="{items}" as="item">
|
|
69
|
+
<li>{item.name}</li>
|
|
70
|
+
</for>
|
|
71
|
+
```
|
|
72
|
+
|
|
73
|
+
## License
|
|
74
|
+
|
|
75
|
+
MIT © [JunoJS contributors](LICENSE)
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
/**
|
|
3
|
+
* JunoJS CLI — Scaffolding & Manifest
|
|
4
|
+
*
|
|
5
|
+
* Commands:
|
|
6
|
+
* juno new <project> — Create a new JunoJS project
|
|
7
|
+
* juno generate component <name> — Generate a component (.ts + .html)
|
|
8
|
+
* juno generate service <name> — Generate a service class
|
|
9
|
+
* juno manifest — Generate junojs.manifest.json
|
|
10
|
+
*/
|
|
11
|
+
export {};
|
|
12
|
+
//# sourceMappingURL=cli.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"cli.d.ts","sourceRoot":"","sources":["../../src/cli/cli.ts"],"names":[],"mappings":";AACA;;;;;;;;GAQG"}
|
package/dist/cli.cjs
ADDED
|
@@ -0,0 +1,88 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
"use strict";const j=require("fs"),S=require("path");function d(e){const t=Object.create(null,{[Symbol.toStringTag]:{value:"Module"}});if(e){for(const o in e)if(o!=="default"){const s=Object.getOwnPropertyDescriptor(e,o);Object.defineProperty(t,o,s.get?s:{enumerable:!0,get:()=>e[o]})}}return t.default=e,Object.freeze(t)}const r=d(j),n=d(S),i=process.argv.slice(2),$=i[0];switch($){case"new":h(i[1]);break;case"generate":case"g":y(i[1],i[2]);break;case"manifest":k();break;default:O()}function h(e){e||(console.error("Usage: juno new <project-name>"),process.exit(1));const t=n.resolve(process.cwd(),e);r.existsSync(t)&&(console.error(`Directory "${e}" already exists.`),process.exit(1)),console.log(`
|
|
3
|
+
⚡ Creating JunoJS project: ${e}
|
|
4
|
+
`);const o=["","src","src/core","src/common","src/components","src/services"];for(const s of o)r.mkdirSync(n.join(t,s),{recursive:!0});c(t,"package.json",JSON.stringify({name:e,version:"0.1.0",private:!0,type:"module",scripts:{dev:"vite",build:"tsc && vite build",preview:"vite preview",types:"ts-node scripts/meta-compiler.ts"},dependencies:{"@junojs/core":"^0.1.0","reflect-metadata":"^0.2.1"},devDependencies:{typescript:"^5.2.2",vite:"^5.4.0","ts-node":"^10.9.0"}},null,2)),c(t,"tsconfig.json",JSON.stringify({compilerOptions:{target:"ESNext",module:"ESNext",experimentalDecorators:!0,emitDecoratorMetadata:!0,moduleResolution:"bundler",strict:!0,outDir:"dist",lib:["ESNext","DOM","DOM.Iterable"],skipLibCheck:!0,esModuleInterop:!0},include:["src","main.ts"]},null,2)),c(t,"index.html",`<!DOCTYPE html>
|
|
5
|
+
<html lang="en">
|
|
6
|
+
<head>
|
|
7
|
+
<meta charset="UTF-8" />
|
|
8
|
+
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
|
9
|
+
<title>${e}</title>
|
|
10
|
+
</head>
|
|
11
|
+
<body>
|
|
12
|
+
<app-root></app-root>
|
|
13
|
+
<script type="module" src="/main.ts"><\/script>
|
|
14
|
+
</body>
|
|
15
|
+
</html>`),c(t,"main.ts",`import 'reflect-metadata';
|
|
16
|
+
import { Component, State, bootstrap } from './src/core';
|
|
17
|
+
|
|
18
|
+
@Component({ tag: 'app-root' })
|
|
19
|
+
class AppRoot {
|
|
20
|
+
@State() message: string = 'Welcome to ${e}!';
|
|
21
|
+
|
|
22
|
+
template = \`
|
|
23
|
+
<h1>{message}</h1>
|
|
24
|
+
\`;
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
bootstrap(AppRoot);
|
|
28
|
+
`),c(t,"junojs.manifest.json",JSON.stringify({name:e,version:"0.1.0",framework:"@junojs/core",generatedAt:new Date().toISOString(),structure:{components:"src/components/",services:"src/services/",core:"src/core/",common:"src/common/"},entry:"main.ts",discovered:{components:[],services:[]}},null,2)),console.log(" ✅ Project scaffolded successfully!"),console.log(`
|
|
29
|
+
Next steps:`),console.log(` cd ${e}`),console.log(" npm install"),console.log(` npm run dev
|
|
30
|
+
`)}function y(e,t){switch((!e||!t)&&(console.error("Usage: juno generate <component|service> <name>"),process.exit(1)),e){case"component":case"c":w(t);break;case"service":case"s":b(t);break;default:console.error(`Unknown generator: "${e}". Use "component" or "service".`),process.exit(1)}}function w(e){const t=g(e),o=v(e),s=n.resolve(process.cwd(),"src","components",t);r.mkdirSync(s,{recursive:!0}),c(s,`${t}.ts`,`import { Component, State } from '../../core/decorators';
|
|
31
|
+
|
|
32
|
+
@Component({
|
|
33
|
+
tag: '${t}',
|
|
34
|
+
templateUrl: './src/components/${t}/${t}.html',
|
|
35
|
+
})
|
|
36
|
+
export class ${o} {
|
|
37
|
+
@State() title: string = '${o} works!';
|
|
38
|
+
|
|
39
|
+
onInit() {
|
|
40
|
+
// Async data fetching
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
onRender(el: HTMLElement) {
|
|
44
|
+
// Post-render DOM access
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
onDestroy() {
|
|
48
|
+
// Cleanup
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
`),c(s,`${t}.html`,`<div class="${t}">
|
|
52
|
+
<h2>{title}</h2>
|
|
53
|
+
</div>
|
|
54
|
+
`),console.log(`
|
|
55
|
+
⚡ Generated component: <${t}>`),console.log(` → ${s}/${t}.ts`),console.log(` → ${s}/${t}.html
|
|
56
|
+
`)}function b(e){const t=g(e),o=v(e),s=n.resolve(process.cwd(),"src","services");r.mkdirSync(s,{recursive:!0}),c(s,`${t}.service.ts`,`/**
|
|
57
|
+
* ${o}Service — Singleton
|
|
58
|
+
*/
|
|
59
|
+
export class ${o}Service {
|
|
60
|
+
private static _instance: ${o}Service;
|
|
61
|
+
|
|
62
|
+
static get instance(): ${o}Service {
|
|
63
|
+
if (!${o}Service._instance) {
|
|
64
|
+
${o}Service._instance = new ${o}Service();
|
|
65
|
+
}
|
|
66
|
+
return ${o}Service._instance;
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
// Add your service methods here
|
|
70
|
+
}
|
|
71
|
+
`),console.log(`
|
|
72
|
+
⚡ Generated service: ${o}Service`),console.log(` → ${s}/${t}.service.ts
|
|
73
|
+
`)}function k(){const e=process.cwd(),t=n.join(e,"package.json");let o="junojs-app",s="0.1.0";if(r.existsSync(t)){const m=JSON.parse(r.readFileSync(t,"utf-8"));o=m.name||o,s=m.version||s}const l=a(n.join(e,"src","components"),".ts"),p=a(n.join(e,"src","services"),".service.ts"),f={name:o,version:s,framework:"@junojs/core",generatedAt:new Date().toISOString(),structure:{components:"src/components/",services:"src/services/",core:"src/core/",common:"src/common/"},entry:"main.ts",discovered:{components:l,services:p}},u=n.join(e,"junojs.manifest.json");r.writeFileSync(u,JSON.stringify(f,null,2),"utf-8"),console.log(`
|
|
74
|
+
⚡ Generated manifest: ${u}`),console.log(` → ${l.length} component(s), ${p.length} service(s)
|
|
75
|
+
`)}function g(e){return e.replace(/([a-z])([A-Z])/g,"$1-$2").replace(/[\s_]+/g,"-").toLowerCase()}function v(e){return e.replace(/[-_\s]+(.)/g,(t,o)=>o.toUpperCase()).replace(/^(.)/,(t,o)=>o.toUpperCase())}function c(e,t,o){const s=n.join(e,t);r.writeFileSync(s,o,"utf-8")}function a(e,t){if(!r.existsSync(e))return[];const o=[];for(const s of r.readdirSync(e,{withFileTypes:!0}))s.isDirectory()?o.push(...a(n.join(e,s.name),t)):s.name.endsWith(t)&&o.push(n.relative(process.cwd(),n.join(e,s.name)));return o}function O(){console.log(`
|
|
76
|
+
⚡ JunoJS CLI v1.0
|
|
77
|
+
|
|
78
|
+
Usage:
|
|
79
|
+
juno new <project> Create a new JunoJS project
|
|
80
|
+
juno generate component <name> Generate a component (.ts + .html)
|
|
81
|
+
juno generate service <name> Generate a service class
|
|
82
|
+
juno manifest Generate junojs.manifest.json
|
|
83
|
+
|
|
84
|
+
Shortcuts:
|
|
85
|
+
juno g c <name> → generate component
|
|
86
|
+
juno g s <name> → generate service
|
|
87
|
+
`)}
|
|
88
|
+
//# sourceMappingURL=cli.cjs.map
|
package/dist/cli.cjs.map
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"cli.cjs","sources":["../src/cli/cli.ts"],"sourcesContent":["#!/usr/bin/env node\n/**\n * JunoJS CLI — Scaffolding & Manifest\n *\n * Commands:\n * juno new <project> — Create a new JunoJS project\n * juno generate component <name> — Generate a component (.ts + .html)\n * juno generate service <name> — Generate a service class\n * juno manifest — Generate junojs.manifest.json\n */\n\nimport * as fs from 'fs';\nimport * as path from 'path';\n\nconst args = process.argv.slice(2);\nconst command = args[0];\n\n// ─── Main Router ────────────────────────────────────────────\n\nswitch (command) {\n case 'new':\n createProject(args[1]);\n break;\n case 'generate':\n case 'g':\n generate(args[1], args[2]);\n break;\n case 'manifest':\n generateManifest();\n break;\n default:\n printHelp();\n}\n\n// ─── Commands ───────────────────────────────────────────────\n\nfunction createProject(name?: string) {\n if (!name) {\n console.error('Usage: juno new <project-name>');\n process.exit(1);\n }\n\n const dir = path.resolve(process.cwd(), name);\n if (fs.existsSync(dir)) {\n console.error(`Directory \"${name}\" already exists.`);\n process.exit(1);\n }\n\n console.log(`\\n⚡ Creating JunoJS project: ${name}\\n`);\n\n // Create directory structure\n const dirs = [\n '',\n 'src',\n 'src/core',\n 'src/common',\n 'src/components',\n 'src/services',\n ];\n for (const d of dirs) {\n fs.mkdirSync(path.join(dir, d), { recursive: true });\n }\n\n // package.json\n writeFile(dir, 'package.json', JSON.stringify({\n name,\n version: '0.1.0',\n private: true,\n type: 'module',\n scripts: {\n dev: 'vite',\n build: 'tsc && vite build',\n preview: 'vite preview',\n types: 'ts-node scripts/meta-compiler.ts',\n },\n dependencies: {\n '@junojs/core': '^0.1.0',\n 'reflect-metadata': '^0.2.1',\n },\n devDependencies: {\n typescript: '^5.2.2',\n vite: '^5.4.0',\n 'ts-node': '^10.9.0',\n },\n }, null, 2));\n\n // tsconfig.json\n writeFile(dir, 'tsconfig.json', JSON.stringify({\n compilerOptions: {\n target: 'ESNext',\n module: 'ESNext',\n experimentalDecorators: true,\n emitDecoratorMetadata: true,\n moduleResolution: 'bundler',\n strict: true,\n outDir: 'dist',\n lib: ['ESNext', 'DOM', 'DOM.Iterable'],\n skipLibCheck: true,\n esModuleInterop: true,\n },\n include: ['src', 'main.ts'],\n }, null, 2));\n\n // index.html\n writeFile(dir, 'index.html', `<!DOCTYPE html>\n<html lang=\"en\">\n<head>\n <meta charset=\"UTF-8\" />\n <meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0\" />\n <title>${name}</title>\n</head>\n<body>\n <app-root></app-root>\n <script type=\"module\" src=\"/main.ts\"></script>\n</body>\n</html>`);\n\n // main.ts\n writeFile(dir, 'main.ts', `import 'reflect-metadata';\nimport { Component, State, bootstrap } from './src/core';\n\n@Component({ tag: 'app-root' })\nclass AppRoot {\n @State() message: string = 'Welcome to ${name}!';\n\n template = \\`\n <h1>{message}</h1>\n \\`;\n}\n\nbootstrap(AppRoot);\n`);\n\n // junojs.manifest.json\n writeFile(dir, 'junojs.manifest.json', JSON.stringify({\n name,\n version: '0.1.0',\n framework: '@junojs/core',\n generatedAt: new Date().toISOString(),\n structure: {\n components: 'src/components/',\n services: 'src/services/',\n core: 'src/core/',\n common: 'src/common/',\n },\n entry: 'main.ts',\n discovered: {\n components: [],\n services: [],\n },\n }, null, 2));\n\n console.log(' ✅ Project scaffolded successfully!');\n console.log(`\\n Next steps:`);\n console.log(` cd ${name}`);\n console.log(` npm install`);\n console.log(` npm run dev\\n`);\n}\n\nfunction generate(type?: string, name?: string) {\n if (!type || !name) {\n console.error('Usage: juno generate <component|service> <name>');\n process.exit(1);\n }\n\n switch (type) {\n case 'component':\n case 'c':\n generateComponent(name);\n break;\n case 'service':\n case 's':\n generateService(name);\n break;\n default:\n console.error(`Unknown generator: \"${type}\". Use \"component\" or \"service\".`);\n process.exit(1);\n }\n}\n\nfunction generateComponent(name: string) {\n const kebab = toKebab(name);\n const pascal = toPascal(name);\n const dir = path.resolve(process.cwd(), 'src', 'components', kebab);\n\n fs.mkdirSync(dir, { recursive: true });\n\n // TypeScript file\n writeFile(dir, `${kebab}.ts`, `import { Component, State } from '../../core/decorators';\n\n@Component({\n tag: '${kebab}',\n templateUrl: './src/components/${kebab}/${kebab}.html',\n})\nexport class ${pascal} {\n @State() title: string = '${pascal} works!';\n\n onInit() {\n // Async data fetching\n }\n\n onRender(el: HTMLElement) {\n // Post-render DOM access\n }\n\n onDestroy() {\n // Cleanup\n }\n}\n`);\n\n // HTML template\n writeFile(dir, `${kebab}.html`, `<div class=\"${kebab}\">\n <h2>{title}</h2>\n</div>\n`);\n\n console.log(`\\n⚡ Generated component: <${kebab}>`);\n console.log(` → ${dir}/${kebab}.ts`);\n console.log(` → ${dir}/${kebab}.html\\n`);\n}\n\nfunction generateService(name: string) {\n const kebab = toKebab(name);\n const pascal = toPascal(name);\n const dir = path.resolve(process.cwd(), 'src', 'services');\n\n fs.mkdirSync(dir, { recursive: true });\n\n writeFile(dir, `${kebab}.service.ts`, `/**\n * ${pascal}Service — Singleton\n */\nexport class ${pascal}Service {\n private static _instance: ${pascal}Service;\n\n static get instance(): ${pascal}Service {\n if (!${pascal}Service._instance) {\n ${pascal}Service._instance = new ${pascal}Service();\n }\n return ${pascal}Service._instance;\n }\n\n // Add your service methods here\n}\n`);\n\n console.log(`\\n⚡ Generated service: ${pascal}Service`);\n console.log(` → ${dir}/${kebab}.service.ts\\n`);\n}\n\nfunction generateManifest() {\n const cwd = process.cwd();\n const pkgPath = path.join(cwd, 'package.json');\n\n let name = 'junojs-app';\n let version = '0.1.0';\n\n if (fs.existsSync(pkgPath)) {\n const pkg = JSON.parse(fs.readFileSync(pkgPath, 'utf-8'));\n name = pkg.name || name;\n version = pkg.version || version;\n }\n\n // Discover components and services\n const components = discoverFiles(path.join(cwd, 'src', 'components'), '.ts');\n const services = discoverFiles(path.join(cwd, 'src', 'services'), '.service.ts');\n\n const manifest = {\n name,\n version,\n framework: '@junojs/core',\n generatedAt: new Date().toISOString(),\n structure: {\n components: 'src/components/',\n services: 'src/services/',\n core: 'src/core/',\n common: 'src/common/',\n },\n entry: 'main.ts',\n discovered: {\n components,\n services,\n },\n };\n\n const outPath = path.join(cwd, 'junojs.manifest.json');\n fs.writeFileSync(outPath, JSON.stringify(manifest, null, 2), 'utf-8');\n console.log(`\\n⚡ Generated manifest: ${outPath}`);\n console.log(` → ${components.length} component(s), ${services.length} service(s)\\n`);\n}\n\n// ─── Utilities ──────────────────────────────────────────────\n\nfunction toKebab(name: string): string {\n return name\n .replace(/([a-z])([A-Z])/g, '$1-$2')\n .replace(/[\\s_]+/g, '-')\n .toLowerCase();\n}\n\nfunction toPascal(name: string): string {\n return name\n .replace(/[-_\\s]+(.)/g, (_, c) => c.toUpperCase())\n .replace(/^(.)/, (_, c) => c.toUpperCase());\n}\n\nfunction writeFile(dir: string, filename: string, content: string): void {\n const filePath = path.join(dir, filename);\n fs.writeFileSync(filePath, content, 'utf-8');\n}\n\nfunction discoverFiles(dir: string, ext: string): string[] {\n if (!fs.existsSync(dir)) return [];\n const files: string[] = [];\n for (const entry of fs.readdirSync(dir, { withFileTypes: true })) {\n if (entry.isDirectory()) {\n files.push(...discoverFiles(path.join(dir, entry.name), ext));\n } else if (entry.name.endsWith(ext)) {\n files.push(path.relative(process.cwd(), path.join(dir, entry.name)));\n }\n }\n return files;\n}\n\nfunction printHelp() {\n console.log(`\n ⚡ JunoJS CLI v1.0\n\n Usage:\n juno new <project> Create a new JunoJS project\n juno generate component <name> Generate a component (.ts + .html)\n juno generate service <name> Generate a service class\n juno manifest Generate junojs.manifest.json\n\n Shortcuts:\n juno g c <name> → generate component\n juno g s <name> → generate service\n`);\n}\n"],"names":["args","command","createProject","generate","generateManifest","printHelp","name","dir","path","fs","dirs","d","writeFile","type","generateComponent","generateService","kebab","toKebab","pascal","toPascal","cwd","pkgPath","version","pkg","components","discoverFiles","services","manifest","outPath","_","c","filename","content","filePath","ext","files","entry"],"mappings":"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"}
|
package/dist/cli.js
ADDED
|
@@ -0,0 +1,238 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
import * as r from "fs";
|
|
3
|
+
import * as n from "path";
|
|
4
|
+
const i = process.argv.slice(2), f = i[0];
|
|
5
|
+
switch (f) {
|
|
6
|
+
case "new":
|
|
7
|
+
j(i[1]);
|
|
8
|
+
break;
|
|
9
|
+
case "generate":
|
|
10
|
+
case "g":
|
|
11
|
+
S(i[1], i[2]);
|
|
12
|
+
break;
|
|
13
|
+
case "manifest":
|
|
14
|
+
w();
|
|
15
|
+
break;
|
|
16
|
+
default:
|
|
17
|
+
y();
|
|
18
|
+
}
|
|
19
|
+
function j(e) {
|
|
20
|
+
e || (console.error("Usage: juno new <project-name>"), process.exit(1));
|
|
21
|
+
const t = n.resolve(process.cwd(), e);
|
|
22
|
+
r.existsSync(t) && (console.error(`Directory "${e}" already exists.`), process.exit(1)), console.log(`
|
|
23
|
+
⚡ Creating JunoJS project: ${e}
|
|
24
|
+
`);
|
|
25
|
+
const o = [
|
|
26
|
+
"",
|
|
27
|
+
"src",
|
|
28
|
+
"src/core",
|
|
29
|
+
"src/common",
|
|
30
|
+
"src/components",
|
|
31
|
+
"src/services"
|
|
32
|
+
];
|
|
33
|
+
for (const s of o)
|
|
34
|
+
r.mkdirSync(n.join(t, s), { recursive: !0 });
|
|
35
|
+
c(t, "package.json", JSON.stringify({
|
|
36
|
+
name: e,
|
|
37
|
+
version: "0.1.0",
|
|
38
|
+
private: !0,
|
|
39
|
+
type: "module",
|
|
40
|
+
scripts: {
|
|
41
|
+
dev: "vite",
|
|
42
|
+
build: "tsc && vite build",
|
|
43
|
+
preview: "vite preview",
|
|
44
|
+
types: "ts-node scripts/meta-compiler.ts"
|
|
45
|
+
},
|
|
46
|
+
dependencies: {
|
|
47
|
+
"@junojs/core": "^0.1.0",
|
|
48
|
+
"reflect-metadata": "^0.2.1"
|
|
49
|
+
},
|
|
50
|
+
devDependencies: {
|
|
51
|
+
typescript: "^5.2.2",
|
|
52
|
+
vite: "^5.4.0",
|
|
53
|
+
"ts-node": "^10.9.0"
|
|
54
|
+
}
|
|
55
|
+
}, null, 2)), c(t, "tsconfig.json", JSON.stringify({
|
|
56
|
+
compilerOptions: {
|
|
57
|
+
target: "ESNext",
|
|
58
|
+
module: "ESNext",
|
|
59
|
+
experimentalDecorators: !0,
|
|
60
|
+
emitDecoratorMetadata: !0,
|
|
61
|
+
moduleResolution: "bundler",
|
|
62
|
+
strict: !0,
|
|
63
|
+
outDir: "dist",
|
|
64
|
+
lib: ["ESNext", "DOM", "DOM.Iterable"],
|
|
65
|
+
skipLibCheck: !0,
|
|
66
|
+
esModuleInterop: !0
|
|
67
|
+
},
|
|
68
|
+
include: ["src", "main.ts"]
|
|
69
|
+
}, null, 2)), c(t, "index.html", `<!DOCTYPE html>
|
|
70
|
+
<html lang="en">
|
|
71
|
+
<head>
|
|
72
|
+
<meta charset="UTF-8" />
|
|
73
|
+
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
|
74
|
+
<title>${e}</title>
|
|
75
|
+
</head>
|
|
76
|
+
<body>
|
|
77
|
+
<app-root></app-root>
|
|
78
|
+
<script type="module" src="/main.ts"><\/script>
|
|
79
|
+
</body>
|
|
80
|
+
</html>`), c(t, "main.ts", `import 'reflect-metadata';
|
|
81
|
+
import { Component, State, bootstrap } from './src/core';
|
|
82
|
+
|
|
83
|
+
@Component({ tag: 'app-root' })
|
|
84
|
+
class AppRoot {
|
|
85
|
+
@State() message: string = 'Welcome to ${e}!';
|
|
86
|
+
|
|
87
|
+
template = \`
|
|
88
|
+
<h1>{message}</h1>
|
|
89
|
+
\`;
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
bootstrap(AppRoot);
|
|
93
|
+
`), c(t, "junojs.manifest.json", JSON.stringify({
|
|
94
|
+
name: e,
|
|
95
|
+
version: "0.1.0",
|
|
96
|
+
framework: "@junojs/core",
|
|
97
|
+
generatedAt: (/* @__PURE__ */ new Date()).toISOString(),
|
|
98
|
+
structure: {
|
|
99
|
+
components: "src/components/",
|
|
100
|
+
services: "src/services/",
|
|
101
|
+
core: "src/core/",
|
|
102
|
+
common: "src/common/"
|
|
103
|
+
},
|
|
104
|
+
entry: "main.ts",
|
|
105
|
+
discovered: {
|
|
106
|
+
components: [],
|
|
107
|
+
services: []
|
|
108
|
+
}
|
|
109
|
+
}, null, 2)), console.log(" ✅ Project scaffolded successfully!"), console.log(`
|
|
110
|
+
Next steps:`), console.log(` cd ${e}`), console.log(" npm install"), console.log(` npm run dev
|
|
111
|
+
`);
|
|
112
|
+
}
|
|
113
|
+
function S(e, t) {
|
|
114
|
+
switch ((!e || !t) && (console.error("Usage: juno generate <component|service> <name>"), process.exit(1)), e) {
|
|
115
|
+
case "component":
|
|
116
|
+
case "c":
|
|
117
|
+
$(t);
|
|
118
|
+
break;
|
|
119
|
+
case "service":
|
|
120
|
+
case "s":
|
|
121
|
+
h(t);
|
|
122
|
+
break;
|
|
123
|
+
default:
|
|
124
|
+
console.error(`Unknown generator: "${e}". Use "component" or "service".`), process.exit(1);
|
|
125
|
+
}
|
|
126
|
+
}
|
|
127
|
+
function $(e) {
|
|
128
|
+
const t = d(e), o = g(e), s = n.resolve(process.cwd(), "src", "components", t);
|
|
129
|
+
r.mkdirSync(s, { recursive: !0 }), c(s, `${t}.ts`, `import { Component, State } from '../../core/decorators';
|
|
130
|
+
|
|
131
|
+
@Component({
|
|
132
|
+
tag: '${t}',
|
|
133
|
+
templateUrl: './src/components/${t}/${t}.html',
|
|
134
|
+
})
|
|
135
|
+
export class ${o} {
|
|
136
|
+
@State() title: string = '${o} works!';
|
|
137
|
+
|
|
138
|
+
onInit() {
|
|
139
|
+
// Async data fetching
|
|
140
|
+
}
|
|
141
|
+
|
|
142
|
+
onRender(el: HTMLElement) {
|
|
143
|
+
// Post-render DOM access
|
|
144
|
+
}
|
|
145
|
+
|
|
146
|
+
onDestroy() {
|
|
147
|
+
// Cleanup
|
|
148
|
+
}
|
|
149
|
+
}
|
|
150
|
+
`), c(s, `${t}.html`, `<div class="${t}">
|
|
151
|
+
<h2>{title}</h2>
|
|
152
|
+
</div>
|
|
153
|
+
`), console.log(`
|
|
154
|
+
⚡ Generated component: <${t}>`), console.log(` → ${s}/${t}.ts`), console.log(` → ${s}/${t}.html
|
|
155
|
+
`);
|
|
156
|
+
}
|
|
157
|
+
function h(e) {
|
|
158
|
+
const t = d(e), o = g(e), s = n.resolve(process.cwd(), "src", "services");
|
|
159
|
+
r.mkdirSync(s, { recursive: !0 }), c(s, `${t}.service.ts`, `/**
|
|
160
|
+
* ${o}Service — Singleton
|
|
161
|
+
*/
|
|
162
|
+
export class ${o}Service {
|
|
163
|
+
private static _instance: ${o}Service;
|
|
164
|
+
|
|
165
|
+
static get instance(): ${o}Service {
|
|
166
|
+
if (!${o}Service._instance) {
|
|
167
|
+
${o}Service._instance = new ${o}Service();
|
|
168
|
+
}
|
|
169
|
+
return ${o}Service._instance;
|
|
170
|
+
}
|
|
171
|
+
|
|
172
|
+
// Add your service methods here
|
|
173
|
+
}
|
|
174
|
+
`), console.log(`
|
|
175
|
+
⚡ Generated service: ${o}Service`), console.log(` → ${s}/${t}.service.ts
|
|
176
|
+
`);
|
|
177
|
+
}
|
|
178
|
+
function w() {
|
|
179
|
+
const e = process.cwd(), t = n.join(e, "package.json");
|
|
180
|
+
let o = "junojs-app", s = "0.1.0";
|
|
181
|
+
if (r.existsSync(t)) {
|
|
182
|
+
const u = JSON.parse(r.readFileSync(t, "utf-8"));
|
|
183
|
+
o = u.name || o, s = u.version || s;
|
|
184
|
+
}
|
|
185
|
+
const l = a(n.join(e, "src", "components"), ".ts"), p = a(n.join(e, "src", "services"), ".service.ts"), v = {
|
|
186
|
+
name: o,
|
|
187
|
+
version: s,
|
|
188
|
+
framework: "@junojs/core",
|
|
189
|
+
generatedAt: (/* @__PURE__ */ new Date()).toISOString(),
|
|
190
|
+
structure: {
|
|
191
|
+
components: "src/components/",
|
|
192
|
+
services: "src/services/",
|
|
193
|
+
core: "src/core/",
|
|
194
|
+
common: "src/common/"
|
|
195
|
+
},
|
|
196
|
+
entry: "main.ts",
|
|
197
|
+
discovered: {
|
|
198
|
+
components: l,
|
|
199
|
+
services: p
|
|
200
|
+
}
|
|
201
|
+
}, m = n.join(e, "junojs.manifest.json");
|
|
202
|
+
r.writeFileSync(m, JSON.stringify(v, null, 2), "utf-8"), console.log(`
|
|
203
|
+
⚡ Generated manifest: ${m}`), console.log(` → ${l.length} component(s), ${p.length} service(s)
|
|
204
|
+
`);
|
|
205
|
+
}
|
|
206
|
+
function d(e) {
|
|
207
|
+
return e.replace(/([a-z])([A-Z])/g, "$1-$2").replace(/[\s_]+/g, "-").toLowerCase();
|
|
208
|
+
}
|
|
209
|
+
function g(e) {
|
|
210
|
+
return e.replace(/[-_\s]+(.)/g, (t, o) => o.toUpperCase()).replace(/^(.)/, (t, o) => o.toUpperCase());
|
|
211
|
+
}
|
|
212
|
+
function c(e, t, o) {
|
|
213
|
+
const s = n.join(e, t);
|
|
214
|
+
r.writeFileSync(s, o, "utf-8");
|
|
215
|
+
}
|
|
216
|
+
function a(e, t) {
|
|
217
|
+
if (!r.existsSync(e)) return [];
|
|
218
|
+
const o = [];
|
|
219
|
+
for (const s of r.readdirSync(e, { withFileTypes: !0 }))
|
|
220
|
+
s.isDirectory() ? o.push(...a(n.join(e, s.name), t)) : s.name.endsWith(t) && o.push(n.relative(process.cwd(), n.join(e, s.name)));
|
|
221
|
+
return o;
|
|
222
|
+
}
|
|
223
|
+
function y() {
|
|
224
|
+
console.log(`
|
|
225
|
+
⚡ JunoJS CLI v1.0
|
|
226
|
+
|
|
227
|
+
Usage:
|
|
228
|
+
juno new <project> Create a new JunoJS project
|
|
229
|
+
juno generate component <name> Generate a component (.ts + .html)
|
|
230
|
+
juno generate service <name> Generate a service class
|
|
231
|
+
juno manifest Generate junojs.manifest.json
|
|
232
|
+
|
|
233
|
+
Shortcuts:
|
|
234
|
+
juno g c <name> → generate component
|
|
235
|
+
juno g s <name> → generate service
|
|
236
|
+
`);
|
|
237
|
+
}
|
|
238
|
+
//# sourceMappingURL=cli.js.map
|
package/dist/cli.js.map
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"cli.js","sources":["../src/cli/cli.ts"],"sourcesContent":["#!/usr/bin/env node\n/**\n * JunoJS CLI — Scaffolding & Manifest\n *\n * Commands:\n * juno new <project> — Create a new JunoJS project\n * juno generate component <name> — Generate a component (.ts + .html)\n * juno generate service <name> — Generate a service class\n * juno manifest — Generate junojs.manifest.json\n */\n\nimport * as fs from 'fs';\nimport * as path from 'path';\n\nconst args = process.argv.slice(2);\nconst command = args[0];\n\n// ─── Main Router ────────────────────────────────────────────\n\nswitch (command) {\n case 'new':\n createProject(args[1]);\n break;\n case 'generate':\n case 'g':\n generate(args[1], args[2]);\n break;\n case 'manifest':\n generateManifest();\n break;\n default:\n printHelp();\n}\n\n// ─── Commands ───────────────────────────────────────────────\n\nfunction createProject(name?: string) {\n if (!name) {\n console.error('Usage: juno new <project-name>');\n process.exit(1);\n }\n\n const dir = path.resolve(process.cwd(), name);\n if (fs.existsSync(dir)) {\n console.error(`Directory \"${name}\" already exists.`);\n process.exit(1);\n }\n\n console.log(`\\n⚡ Creating JunoJS project: ${name}\\n`);\n\n // Create directory structure\n const dirs = [\n '',\n 'src',\n 'src/core',\n 'src/common',\n 'src/components',\n 'src/services',\n ];\n for (const d of dirs) {\n fs.mkdirSync(path.join(dir, d), { recursive: true });\n }\n\n // package.json\n writeFile(dir, 'package.json', JSON.stringify({\n name,\n version: '0.1.0',\n private: true,\n type: 'module',\n scripts: {\n dev: 'vite',\n build: 'tsc && vite build',\n preview: 'vite preview',\n types: 'ts-node scripts/meta-compiler.ts',\n },\n dependencies: {\n '@junojs/core': '^0.1.0',\n 'reflect-metadata': '^0.2.1',\n },\n devDependencies: {\n typescript: '^5.2.2',\n vite: '^5.4.0',\n 'ts-node': '^10.9.0',\n },\n }, null, 2));\n\n // tsconfig.json\n writeFile(dir, 'tsconfig.json', JSON.stringify({\n compilerOptions: {\n target: 'ESNext',\n module: 'ESNext',\n experimentalDecorators: true,\n emitDecoratorMetadata: true,\n moduleResolution: 'bundler',\n strict: true,\n outDir: 'dist',\n lib: ['ESNext', 'DOM', 'DOM.Iterable'],\n skipLibCheck: true,\n esModuleInterop: true,\n },\n include: ['src', 'main.ts'],\n }, null, 2));\n\n // index.html\n writeFile(dir, 'index.html', `<!DOCTYPE html>\n<html lang=\"en\">\n<head>\n <meta charset=\"UTF-8\" />\n <meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0\" />\n <title>${name}</title>\n</head>\n<body>\n <app-root></app-root>\n <script type=\"module\" src=\"/main.ts\"></script>\n</body>\n</html>`);\n\n // main.ts\n writeFile(dir, 'main.ts', `import 'reflect-metadata';\nimport { Component, State, bootstrap } from './src/core';\n\n@Component({ tag: 'app-root' })\nclass AppRoot {\n @State() message: string = 'Welcome to ${name}!';\n\n template = \\`\n <h1>{message}</h1>\n \\`;\n}\n\nbootstrap(AppRoot);\n`);\n\n // junojs.manifest.json\n writeFile(dir, 'junojs.manifest.json', JSON.stringify({\n name,\n version: '0.1.0',\n framework: '@junojs/core',\n generatedAt: new Date().toISOString(),\n structure: {\n components: 'src/components/',\n services: 'src/services/',\n core: 'src/core/',\n common: 'src/common/',\n },\n entry: 'main.ts',\n discovered: {\n components: [],\n services: [],\n },\n }, null, 2));\n\n console.log(' ✅ Project scaffolded successfully!');\n console.log(`\\n Next steps:`);\n console.log(` cd ${name}`);\n console.log(` npm install`);\n console.log(` npm run dev\\n`);\n}\n\nfunction generate(type?: string, name?: string) {\n if (!type || !name) {\n console.error('Usage: juno generate <component|service> <name>');\n process.exit(1);\n }\n\n switch (type) {\n case 'component':\n case 'c':\n generateComponent(name);\n break;\n case 'service':\n case 's':\n generateService(name);\n break;\n default:\n console.error(`Unknown generator: \"${type}\". Use \"component\" or \"service\".`);\n process.exit(1);\n }\n}\n\nfunction generateComponent(name: string) {\n const kebab = toKebab(name);\n const pascal = toPascal(name);\n const dir = path.resolve(process.cwd(), 'src', 'components', kebab);\n\n fs.mkdirSync(dir, { recursive: true });\n\n // TypeScript file\n writeFile(dir, `${kebab}.ts`, `import { Component, State } from '../../core/decorators';\n\n@Component({\n tag: '${kebab}',\n templateUrl: './src/components/${kebab}/${kebab}.html',\n})\nexport class ${pascal} {\n @State() title: string = '${pascal} works!';\n\n onInit() {\n // Async data fetching\n }\n\n onRender(el: HTMLElement) {\n // Post-render DOM access\n }\n\n onDestroy() {\n // Cleanup\n }\n}\n`);\n\n // HTML template\n writeFile(dir, `${kebab}.html`, `<div class=\"${kebab}\">\n <h2>{title}</h2>\n</div>\n`);\n\n console.log(`\\n⚡ Generated component: <${kebab}>`);\n console.log(` → ${dir}/${kebab}.ts`);\n console.log(` → ${dir}/${kebab}.html\\n`);\n}\n\nfunction generateService(name: string) {\n const kebab = toKebab(name);\n const pascal = toPascal(name);\n const dir = path.resolve(process.cwd(), 'src', 'services');\n\n fs.mkdirSync(dir, { recursive: true });\n\n writeFile(dir, `${kebab}.service.ts`, `/**\n * ${pascal}Service — Singleton\n */\nexport class ${pascal}Service {\n private static _instance: ${pascal}Service;\n\n static get instance(): ${pascal}Service {\n if (!${pascal}Service._instance) {\n ${pascal}Service._instance = new ${pascal}Service();\n }\n return ${pascal}Service._instance;\n }\n\n // Add your service methods here\n}\n`);\n\n console.log(`\\n⚡ Generated service: ${pascal}Service`);\n console.log(` → ${dir}/${kebab}.service.ts\\n`);\n}\n\nfunction generateManifest() {\n const cwd = process.cwd();\n const pkgPath = path.join(cwd, 'package.json');\n\n let name = 'junojs-app';\n let version = '0.1.0';\n\n if (fs.existsSync(pkgPath)) {\n const pkg = JSON.parse(fs.readFileSync(pkgPath, 'utf-8'));\n name = pkg.name || name;\n version = pkg.version || version;\n }\n\n // Discover components and services\n const components = discoverFiles(path.join(cwd, 'src', 'components'), '.ts');\n const services = discoverFiles(path.join(cwd, 'src', 'services'), '.service.ts');\n\n const manifest = {\n name,\n version,\n framework: '@junojs/core',\n generatedAt: new Date().toISOString(),\n structure: {\n components: 'src/components/',\n services: 'src/services/',\n core: 'src/core/',\n common: 'src/common/',\n },\n entry: 'main.ts',\n discovered: {\n components,\n services,\n },\n };\n\n const outPath = path.join(cwd, 'junojs.manifest.json');\n fs.writeFileSync(outPath, JSON.stringify(manifest, null, 2), 'utf-8');\n console.log(`\\n⚡ Generated manifest: ${outPath}`);\n console.log(` → ${components.length} component(s), ${services.length} service(s)\\n`);\n}\n\n// ─── Utilities ──────────────────────────────────────────────\n\nfunction toKebab(name: string): string {\n return name\n .replace(/([a-z])([A-Z])/g, '$1-$2')\n .replace(/[\\s_]+/g, '-')\n .toLowerCase();\n}\n\nfunction toPascal(name: string): string {\n return name\n .replace(/[-_\\s]+(.)/g, (_, c) => c.toUpperCase())\n .replace(/^(.)/, (_, c) => c.toUpperCase());\n}\n\nfunction writeFile(dir: string, filename: string, content: string): void {\n const filePath = path.join(dir, filename);\n fs.writeFileSync(filePath, content, 'utf-8');\n}\n\nfunction discoverFiles(dir: string, ext: string): string[] {\n if (!fs.existsSync(dir)) return [];\n const files: string[] = [];\n for (const entry of fs.readdirSync(dir, { withFileTypes: true })) {\n if (entry.isDirectory()) {\n files.push(...discoverFiles(path.join(dir, entry.name), ext));\n } else if (entry.name.endsWith(ext)) {\n files.push(path.relative(process.cwd(), path.join(dir, entry.name)));\n }\n }\n return files;\n}\n\nfunction printHelp() {\n console.log(`\n ⚡ JunoJS CLI v1.0\n\n Usage:\n juno new <project> Create a new JunoJS project\n juno generate component <name> Generate a component (.ts + .html)\n juno generate service <name> Generate a service class\n juno manifest Generate junojs.manifest.json\n\n Shortcuts:\n juno g c <name> → generate component\n juno g s <name> → generate service\n`);\n}\n"],"names":["args","command","createProject","generate","generateManifest","printHelp","name","dir","path","fs","dirs","d","writeFile","type","generateComponent","generateService","kebab","toKebab","pascal","toPascal","cwd","pkgPath","version","pkg","components","discoverFiles","services","manifest","outPath","_","c","filename","content","filePath","ext","files","entry"],"mappings":"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"}
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
import "reflect-metadata";
|
|
2
|
+
/**
|
|
3
|
+
* Base class for reactive form models.
|
|
4
|
+
*
|
|
5
|
+
* Usage:
|
|
6
|
+
* class LoginForm extends FormModel {
|
|
7
|
+
* @Required() @Email() email = '';
|
|
8
|
+
* @Required() password = '';
|
|
9
|
+
* }
|
|
10
|
+
*/
|
|
11
|
+
export declare class FormModel {
|
|
12
|
+
private _initialValues;
|
|
13
|
+
private _touched;
|
|
14
|
+
constructor();
|
|
15
|
+
/** Returns true if every validated field passes all its rules. */
|
|
16
|
+
isValid(): boolean;
|
|
17
|
+
/** Returns a map of field → error messages (only fields with errors). */
|
|
18
|
+
getErrors(): Record<string, string[]>;
|
|
19
|
+
/** Resets all fields to their initial values and clears touched state. */
|
|
20
|
+
reset(): void;
|
|
21
|
+
/** True if any field differs from its initial value. */
|
|
22
|
+
get dirty(): boolean;
|
|
23
|
+
/** Per-field touched tracking. */
|
|
24
|
+
get touched(): Record<string, boolean>;
|
|
25
|
+
/** Mark a field as touched (e.g. on blur). */
|
|
26
|
+
markTouched(field: string): void;
|
|
27
|
+
private _captureInitialValues;
|
|
28
|
+
}
|
|
29
|
+
//# sourceMappingURL=form-model.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"form-model.d.ts","sourceRoot":"","sources":["../../../src/common/forms/form-model.ts"],"names":[],"mappings":"AAAA,OAAO,kBAAkB,CAAC;AAQ1B;;;;;;;;GAQG;AACH,qBAAa,SAAS;IACpB,OAAO,CAAC,cAAc,CAA2B;IACjD,OAAO,CAAC,QAAQ,CAA+B;;IAU/C,kEAAkE;IAClE,OAAO,IAAI,OAAO;IAKlB,yEAAyE;IACzE,SAAS,IAAI,MAAM,CAAC,MAAM,EAAE,MAAM,EAAE,CAAC;IAuBrC,0EAA0E;IAC1E,KAAK,IAAI,IAAI;IAOb,wDAAwD;IACxD,IAAI,KAAK,IAAI,OAAO,CAKnB;IAED,kCAAkC;IAClC,IAAI,OAAO,IAAI,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAErC;IAED,8CAA8C;IAC9C,WAAW,CAAC,KAAK,EAAE,MAAM,GAAG,IAAI;IAMhC,OAAO,CAAC,qBAAqB;CAS9B"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/common/forms/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,KAAK,EAAE,KAAK,EAAE,OAAO,EAAE,MAAM,cAAc,CAAC;AAC/D,OAAO,EAAE,SAAS,EAAE,MAAM,cAAc,CAAC;AACzC,cAAc,UAAU,CAAC"}
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
export type ValidationResult = {
|
|
2
|
+
success: boolean;
|
|
3
|
+
errors?: Record<string, string>;
|
|
4
|
+
};
|
|
5
|
+
export declare class SchemaField {
|
|
6
|
+
private rules;
|
|
7
|
+
private IS_REQUIRED;
|
|
8
|
+
required(msg?: string): this;
|
|
9
|
+
email(msg?: string): this;
|
|
10
|
+
min(length: number, msg?: string): this;
|
|
11
|
+
max(length: number, msg?: string): this;
|
|
12
|
+
validate(value: any, data: any): string | undefined;
|
|
13
|
+
}
|
|
14
|
+
export declare class Schema {
|
|
15
|
+
private fields;
|
|
16
|
+
private refines;
|
|
17
|
+
string(): SchemaField;
|
|
18
|
+
number(): SchemaField;
|
|
19
|
+
boolean(): SchemaField;
|
|
20
|
+
shape(fields: Record<string, SchemaField>): this;
|
|
21
|
+
refine(validate: (data: any) => boolean | Promise<boolean>, params: {
|
|
22
|
+
message: string;
|
|
23
|
+
path: string;
|
|
24
|
+
}): this;
|
|
25
|
+
parse(data: any): Promise<ValidationResult>;
|
|
26
|
+
}
|
|
27
|
+
export declare const s: {
|
|
28
|
+
string: () => SchemaField;
|
|
29
|
+
number: () => SchemaField;
|
|
30
|
+
boolean: () => SchemaField;
|
|
31
|
+
object: (fields: Record<string, SchemaField>) => Schema;
|
|
32
|
+
};
|
|
33
|
+
//# sourceMappingURL=schema.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"schema.d.ts","sourceRoot":"","sources":["../../../src/common/forms/schema.ts"],"names":[],"mappings":"AAAA,MAAM,MAAM,gBAAgB,GAAG;IAAE,OAAO,EAAE,OAAO,CAAC;IAAC,MAAM,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAA;CAAE,CAAC;AAErF,qBAAa,WAAW;IACtB,OAAO,CAAC,KAAK,CAAyD;IACtE,OAAO,CAAC,WAAW,CAAS;IAE5B,QAAQ,CAAC,GAAG,SAAa;IAMzB,KAAK,CAAC,GAAG,SAAkB;IAQ3B,GAAG,CAAC,MAAM,EAAE,MAAM,EAAE,GAAG,CAAC,EAAE,MAAM;IAQhC,GAAG,CAAC,MAAM,EAAE,MAAM,EAAE,GAAG,CAAC,EAAE,MAAM;IAQhC,QAAQ,CAAC,KAAK,EAAE,GAAG,EAAE,IAAI,EAAE,GAAG,GAAG,MAAM,GAAG,SAAS;CAOpD;AAED,qBAAa,MAAM;IACjB,OAAO,CAAC,MAAM,CAAmC;IACjD,OAAO,CAAC,OAAO,CAAgG;IAE/G,MAAM;IACN,MAAM;IACN,OAAO;IAEP,KAAK,CAAC,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,WAAW,CAAC;IAKzC,MAAM,CAAC,QAAQ,EAAE,CAAC,IAAI,EAAE,GAAG,KAAK,OAAO,GAAG,OAAO,CAAC,OAAO,CAAC,EAAE,MAAM,EAAE;QAAE,OAAO,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,MAAM,CAAA;KAAE;IAK/F,KAAK,CAAC,IAAI,EAAE,GAAG,GAAG,OAAO,CAAC,gBAAgB,CAAC;CAyBlD;AAED,eAAO,MAAM,CAAC;;;;qBAIK,MAAM,CAAC,MAAM,EAAE,WAAW,CAAC;CAC7C,CAAC"}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import "reflect-metadata";
|
|
2
|
+
/**
|
|
3
|
+
* Field must be non-empty (non-null, non-undefined, non-empty-string).
|
|
4
|
+
*/
|
|
5
|
+
export declare function Required(message?: string): (target: any, key: string) => void;
|
|
6
|
+
/**
|
|
7
|
+
* Field must be a valid email address.
|
|
8
|
+
*/
|
|
9
|
+
export declare function Email(message?: string): (target: any, key: string) => void;
|
|
10
|
+
/**
|
|
11
|
+
* Field must equal the value of another property.
|
|
12
|
+
*/
|
|
13
|
+
export declare function Match(otherProp: string, message?: string): (target: any, key: string) => void;
|
|
14
|
+
/**
|
|
15
|
+
* Field must match a regular expression.
|
|
16
|
+
*/
|
|
17
|
+
export declare function Pattern(regex: RegExp, message?: string): (target: any, key: string) => void;
|
|
18
|
+
//# sourceMappingURL=validators.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"validators.d.ts","sourceRoot":"","sources":["../../../src/common/forms/validators.ts"],"names":[],"mappings":"AAAA,OAAO,kBAAkB,CAAC;AAqB1B;;GAEG;AACH,wBAAgB,QAAQ,CAAC,OAAO,SAA2B,IACjD,QAAQ,GAAG,EAAE,KAAK,MAAM,UAQjC;AAED;;GAEG;AACH,wBAAgB,KAAK,CAAC,OAAO,SAA0B,IAC7C,QAAQ,GAAG,EAAE,KAAK,MAAM,UAUjC;AAED;;GAEG;AACH,wBAAgB,KAAK,CAAC,SAAS,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,MAAM,IAC/C,QAAQ,GAAG,EAAE,KAAK,MAAM,UAOjC;AAED;;GAEG;AACH,wBAAgB,OAAO,CAAC,KAAK,EAAE,MAAM,EAAE,OAAO,SAAmB,IACvD,QAAQ,GAAG,EAAE,KAAK,MAAM,UAUjC"}
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
import { ErrorHandler } from '../../core/error-handler';
|
|
2
|
+
export interface RequestConfig {
|
|
3
|
+
headers?: Record<string, string>;
|
|
4
|
+
timeout?: number;
|
|
5
|
+
signal?: AbortSignal;
|
|
6
|
+
params?: Record<string, string>;
|
|
7
|
+
}
|
|
8
|
+
export type RequestInterceptor = (url: string, init: RequestInit) => [string, RequestInit] | void;
|
|
9
|
+
export type ResponseInterceptor = (response: Response) => Response | void;
|
|
10
|
+
export declare class HttpClient {
|
|
11
|
+
private requestInterceptors;
|
|
12
|
+
private responseInterceptors;
|
|
13
|
+
private errorHandler;
|
|
14
|
+
/** Plug in the global ErrorHandler for automatic error routing. */
|
|
15
|
+
setErrorHandler(handler: ErrorHandler): void;
|
|
16
|
+
addRequestInterceptor(fn: RequestInterceptor): void;
|
|
17
|
+
addResponseInterceptor(fn: ResponseInterceptor): void;
|
|
18
|
+
get<T>(url: string, config?: RequestConfig): Promise<T>;
|
|
19
|
+
post<T>(url: string, body?: any, config?: RequestConfig): Promise<T>;
|
|
20
|
+
put<T>(url: string, body?: any, config?: RequestConfig): Promise<T>;
|
|
21
|
+
delete<T>(url: string, config?: RequestConfig): Promise<T>;
|
|
22
|
+
patch<T>(url: string, body?: any, config?: RequestConfig): Promise<T>;
|
|
23
|
+
private request;
|
|
24
|
+
}
|
|
25
|
+
//# sourceMappingURL=http.service.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"http.service.d.ts","sourceRoot":"","sources":["../../../src/common/http/http.service.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,MAAM,0BAA0B,CAAC;AAIxD,MAAM,WAAW,aAAa;IAC5B,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IACjC,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,MAAM,CAAC,EAAE,WAAW,CAAC;IACrB,MAAM,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;CACjC;AAED,MAAM,MAAM,kBAAkB,GAAG,CAC/B,GAAG,EAAE,MAAM,EACX,IAAI,EAAE,WAAW,KACd,CAAC,MAAM,EAAE,WAAW,CAAC,GAAG,IAAI,CAAC;AAElC,MAAM,MAAM,mBAAmB,GAAG,CAAC,QAAQ,EAAE,QAAQ,KAAK,QAAQ,GAAG,IAAI,CAAC;AAI1E,qBAAa,UAAU;IACrB,OAAO,CAAC,mBAAmB,CAA4B;IACvD,OAAO,CAAC,oBAAoB,CAA6B;IACzD,OAAO,CAAC,YAAY,CAA6B;IAEjD,mEAAmE;IACnE,eAAe,CAAC,OAAO,EAAE,YAAY,GAAG,IAAI;IAM5C,qBAAqB,CAAC,EAAE,EAAE,kBAAkB,GAAG,IAAI;IAInD,sBAAsB,CAAC,EAAE,EAAE,mBAAmB,GAAG,IAAI;IAM/C,GAAG,CAAC,CAAC,EAAE,GAAG,EAAE,MAAM,EAAE,MAAM,CAAC,EAAE,aAAa,GAAG,OAAO,CAAC,CAAC,CAAC;IAIvD,IAAI,CAAC,CAAC,EAAE,GAAG,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE,GAAG,EAAE,MAAM,CAAC,EAAE,aAAa,GAAG,OAAO,CAAC,CAAC,CAAC;IAIpE,GAAG,CAAC,CAAC,EAAE,GAAG,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE,GAAG,EAAE,MAAM,CAAC,EAAE,aAAa,GAAG,OAAO,CAAC,CAAC,CAAC;IAInE,MAAM,CAAC,CAAC,EAAE,GAAG,EAAE,MAAM,EAAE,MAAM,CAAC,EAAE,aAAa,GAAG,OAAO,CAAC,CAAC,CAAC;IAI1D,KAAK,CAAC,CAAC,EAAE,GAAG,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE,GAAG,EAAE,MAAM,CAAC,EAAE,aAAa,GAAG,OAAO,CAAC,CAAC,CAAC;YAM7D,OAAO;CA+EtB"}
|