@fluixi/cli 0.1.0-alpha.74 → 0.1.0-alpha.76
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/dist/cli.cjs +244 -0
- package/dist/cli.js +1 -1
- package/dist/cli.mjs +243 -0
- package/dist/generate.cjs +211 -0
- package/dist/generate.js +6 -6
- package/dist/generate.mjs +186 -0
- package/dist/index.cjs +41 -0
- package/dist/index.d.ts +3 -2
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +5 -2
- package/dist/index.mjs +13 -0
- package/dist/tsconfig.lib.tsbuildinfo +1 -1
- package/package.json +13 -5
|
@@ -0,0 +1,211 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __defProp = Object.defineProperty;
|
|
3
|
+
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
4
|
+
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
5
|
+
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
6
|
+
var __export = (target, all) => {
|
|
7
|
+
for (var name in all)
|
|
8
|
+
__defProp(target, name, { get: all[name], enumerable: true });
|
|
9
|
+
};
|
|
10
|
+
var __copyProps = (to, from, except, desc) => {
|
|
11
|
+
if (from && typeof from === "object" || typeof from === "function") {
|
|
12
|
+
for (let key of __getOwnPropNames(from))
|
|
13
|
+
if (!__hasOwnProp.call(to, key) && key !== except)
|
|
14
|
+
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
|
15
|
+
}
|
|
16
|
+
return to;
|
|
17
|
+
};
|
|
18
|
+
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
19
|
+
|
|
20
|
+
// src/generate.ts
|
|
21
|
+
var generate_exports = {};
|
|
22
|
+
__export(generate_exports, {
|
|
23
|
+
generate: () => generate
|
|
24
|
+
});
|
|
25
|
+
module.exports = __toCommonJS(generate_exports);
|
|
26
|
+
var import_node_fs = require("node:fs");
|
|
27
|
+
var import_node_path = require("node:path");
|
|
28
|
+
var import_ui = require("@fluixi/start/ui");
|
|
29
|
+
var GEN_USAGE = `Usage: fluixi generate <kind> <name>
|
|
30
|
+
|
|
31
|
+
Kinds:
|
|
32
|
+
component <Name> a reusable component → src/components/<Name>.{tsx,ts}
|
|
33
|
+
route <path> a file-based route page → src/routes/<path>.{tsx,ts}
|
|
34
|
+
middleware the request middleware file → src/middleware.ts
|
|
35
|
+
auth @fluixi/auth wiring → auth.config + auth.client + middleware + /api/auth route
|
|
36
|
+
|
|
37
|
+
Component/route syntax follows the project (JSX → .tsx, html\`\` → .ts); override with --jsx / --html.
|
|
38
|
+
`;
|
|
39
|
+
function detectFormat() {
|
|
40
|
+
const args = process.argv.slice(3);
|
|
41
|
+
if (args.includes("--html")) return "html";
|
|
42
|
+
if (args.includes("--jsx")) return "jsx";
|
|
43
|
+
try {
|
|
44
|
+
const ts = JSON.parse((0, import_node_fs.readFileSync)((0, import_node_path.resolve)("tsconfig.json"), "utf8"));
|
|
45
|
+
if (ts?.compilerOptions && !ts.compilerOptions.jsx) return "html";
|
|
46
|
+
} catch {
|
|
47
|
+
}
|
|
48
|
+
return "jsx";
|
|
49
|
+
}
|
|
50
|
+
function pascal(s) {
|
|
51
|
+
return s.replace(/\[(.+?)\]/g, "$1").split(/[^a-zA-Z0-9]+/).filter(Boolean).map((w) => w[0].toUpperCase() + w.slice(1)).join("") || "Component";
|
|
52
|
+
}
|
|
53
|
+
function resolveHint(Name, ext) {
|
|
54
|
+
const configs = ["vite.config.ts", "vite.config.js", "fluixi.config.ts", "fluixi.config.js"];
|
|
55
|
+
const found = configs.map((f) => (0, import_node_path.resolve)(f)).find((f) => (0, import_node_fs.existsSync)(f));
|
|
56
|
+
if (!found) return;
|
|
57
|
+
try {
|
|
58
|
+
if (/\bresolve\s*:\s*\[/.test((0, import_node_fs.readFileSync)(found, "utf8"))) return;
|
|
59
|
+
} catch {
|
|
60
|
+
return;
|
|
61
|
+
}
|
|
62
|
+
console.log(
|
|
63
|
+
` ${import_ui.c.gray("to use")} ${import_ui.c.cyan(`<${Name} />`)} ${import_ui.c.gray("without importing it, add to")} ${import_ui.c.cyan((0, import_node_path.relative)(process.cwd(), found))}:`
|
|
64
|
+
);
|
|
65
|
+
console.log(` ${import_ui.c.gray(`resolve: [{ match: /^([A-Z]\\w+)$/, module: '/src/components/$1.${ext}' }]`)}`);
|
|
66
|
+
console.log(` ${import_ui.c.gray("one pattern covers the whole folder. Importing it works too — including with")} ${import_ui.c.cyan("load:")}`);
|
|
67
|
+
}
|
|
68
|
+
function write(file, content) {
|
|
69
|
+
const rel = (0, import_node_path.relative)(process.cwd(), file);
|
|
70
|
+
if ((0, import_node_fs.existsSync)(file)) {
|
|
71
|
+
console.error(` ${import_ui.c.red("✗")} ${rel} ${import_ui.c.gray("already exists")}`);
|
|
72
|
+
process.exit(1);
|
|
73
|
+
}
|
|
74
|
+
(0, import_node_fs.mkdirSync)((0, import_node_path.dirname)(file), { recursive: true });
|
|
75
|
+
(0, import_node_fs.writeFileSync)(file, content);
|
|
76
|
+
console.log(` ${import_ui.c.green("✓")} ${import_ui.c.gray("created")} ${import_ui.c.cyan(rel)}`);
|
|
77
|
+
}
|
|
78
|
+
var component = (Name) => `import type { Component, ComponentChild } from '@fluixi/core';
|
|
79
|
+
|
|
80
|
+
export type ${Name}Props = {
|
|
81
|
+
children?: ComponentChild;
|
|
82
|
+
};
|
|
83
|
+
|
|
84
|
+
// Typed component: \`props\` is inferred from ${Name}Props. Use FxParent/FxVoid/FxFlow
|
|
85
|
+
// from '@fluixi/core' for children-required/forbidden variants.
|
|
86
|
+
export const ${Name}: Component<${Name}Props> = (props) => {
|
|
87
|
+
return <div class="${Name.toLowerCase()}">{props.children ?? '${Name}'}</div>;
|
|
88
|
+
};
|
|
89
|
+
`;
|
|
90
|
+
var route = (Name) => `export default function ${Name}() {
|
|
91
|
+
return (
|
|
92
|
+
<section>
|
|
93
|
+
<h1>${Name}</h1>
|
|
94
|
+
</section>
|
|
95
|
+
);
|
|
96
|
+
}
|
|
97
|
+
`;
|
|
98
|
+
var componentHtml = (Name) => `import type { Component, ComponentChild } from '@fluixi/core';
|
|
99
|
+
import { html } from '@fluixi/core';
|
|
100
|
+
|
|
101
|
+
export type ${Name}Props = {
|
|
102
|
+
children?: ComponentChild;
|
|
103
|
+
};
|
|
104
|
+
|
|
105
|
+
// Typed component: \`props\` is inferred from ${Name}Props. Use FxParent/FxVoid/FxFlow
|
|
106
|
+
// from '@fluixi/core' for children-required/forbidden variants.
|
|
107
|
+
export const ${Name}: Component<${Name}Props> = (props) => {
|
|
108
|
+
return html\`<div class="${Name.toLowerCase()}">\${props.children ?? '${Name}'}</div>\`;
|
|
109
|
+
};
|
|
110
|
+
`;
|
|
111
|
+
var routeHtml = (Name) => `import { html } from '@fluixi/start';
|
|
112
|
+
|
|
113
|
+
export default function ${Name}() {
|
|
114
|
+
return html\`
|
|
115
|
+
<section>
|
|
116
|
+
<h1>${Name}</h1>
|
|
117
|
+
</section>
|
|
118
|
+
\`;
|
|
119
|
+
}
|
|
120
|
+
`;
|
|
121
|
+
var middleware = () => `import { defineMiddleware } from '@fluixi/start';
|
|
122
|
+
|
|
123
|
+
export default defineMiddleware([
|
|
124
|
+
(request, next) => {
|
|
125
|
+
// return a Response to short-circuit (auth/redirect), or next() to continue.
|
|
126
|
+
return next();
|
|
127
|
+
},
|
|
128
|
+
]);
|
|
129
|
+
`;
|
|
130
|
+
var authConfig = () => `import { betterAuth } from 'better-auth';
|
|
131
|
+
import { defineAuth } from '@fluixi/auth/server';
|
|
132
|
+
|
|
133
|
+
export type AppUser = { id: string; email: string; name?: string; role?: string };
|
|
134
|
+
|
|
135
|
+
// Better Auth owns the audited primitives; defineAuth registers it with @fluixi/auth.
|
|
136
|
+
export const auth = defineAuth<AppUser>(
|
|
137
|
+
betterAuth({
|
|
138
|
+
// database: <your adapter>,
|
|
139
|
+
emailAndPassword: { enabled: true },
|
|
140
|
+
// socialProviders: { google: { … }, github: { … } },
|
|
141
|
+
} as Parameters<typeof betterAuth>[0]),
|
|
142
|
+
);
|
|
143
|
+
`;
|
|
144
|
+
var authClient = () => `import { createAuthClient } from 'better-auth/client';
|
|
145
|
+
import { createAuthHooks } from '@fluixi/auth/client';
|
|
146
|
+
import type { AppUser } from './auth.config.js';
|
|
147
|
+
|
|
148
|
+
const client = createAuthClient({ baseURL: '/api/auth' });
|
|
149
|
+
|
|
150
|
+
// Or, to reuse an existing reactive session: createAuthHooks({ session: yourSessionStore }).
|
|
151
|
+
export const { useUser, useSession, useAuth, useSignIn, useSignOut, protectedRoute } =
|
|
152
|
+
createAuthHooks<AppUser>({ client, loginPath: '/login' });
|
|
153
|
+
`;
|
|
154
|
+
var authMiddleware = () => `import { defineMiddleware } from '@fluixi/start';
|
|
155
|
+
import { authMiddleware } from '@fluixi/auth/server';
|
|
156
|
+
import './auth.config.js';
|
|
157
|
+
|
|
158
|
+
export default defineMiddleware([authMiddleware()]);
|
|
159
|
+
`;
|
|
160
|
+
var authRoute = () => `import { mountAuthRoutes } from '@fluixi/auth/server';
|
|
161
|
+
import '../../../auth.config.js';
|
|
162
|
+
|
|
163
|
+
const handler = mountAuthRoutes();
|
|
164
|
+
export const GET = handler;
|
|
165
|
+
export const POST = handler;
|
|
166
|
+
export default handler;
|
|
167
|
+
`;
|
|
168
|
+
function generate(kind, name) {
|
|
169
|
+
switch (kind) {
|
|
170
|
+
case "component":
|
|
171
|
+
case "c": {
|
|
172
|
+
if (!name) return fail("component name required, e.g. `fluixi g component Button`");
|
|
173
|
+
const Name = pascal(name);
|
|
174
|
+
const html = detectFormat() === "html";
|
|
175
|
+
const ext = html ? "ts" : "tsx";
|
|
176
|
+
write((0, import_node_path.resolve)("src/components", `${Name}.${ext}`), (html ? componentHtml : component)(Name));
|
|
177
|
+
resolveHint(Name, ext);
|
|
178
|
+
break;
|
|
179
|
+
}
|
|
180
|
+
case "route":
|
|
181
|
+
case "r": {
|
|
182
|
+
if (!name) return fail("route path required, e.g. `fluixi g route about`");
|
|
183
|
+
const html = detectFormat() === "html";
|
|
184
|
+
const Name = pascal((0, import_node_path.basename)(name));
|
|
185
|
+
write((0, import_node_path.resolve)("src/routes", `${name}.${html ? "ts" : "tsx"}`), (html ? routeHtml : route)(Name));
|
|
186
|
+
break;
|
|
187
|
+
}
|
|
188
|
+
case "middleware":
|
|
189
|
+
case "m":
|
|
190
|
+
write((0, import_node_path.resolve)("src/middleware.ts"), middleware());
|
|
191
|
+
break;
|
|
192
|
+
case "auth":
|
|
193
|
+
write((0, import_node_path.resolve)("src/auth.config.ts"), authConfig());
|
|
194
|
+
write((0, import_node_path.resolve)("src/auth.client.ts"), authClient());
|
|
195
|
+
write((0, import_node_path.resolve)("src/middleware.ts"), authMiddleware());
|
|
196
|
+
write((0, import_node_path.resolve)("src/routes/api/auth/[...all].ts"), authRoute());
|
|
197
|
+
console.log(` ${import_ui.c.gray("next: install")} ${import_ui.c.cyan("better-auth")}${import_ui.c.gray(", set your DB adapter in auth.config.ts, and forward `request` in entry-server")}`);
|
|
198
|
+
break;
|
|
199
|
+
default:
|
|
200
|
+
console.error(GEN_USAGE);
|
|
201
|
+
process.exit(1);
|
|
202
|
+
}
|
|
203
|
+
}
|
|
204
|
+
function fail(msg) {
|
|
205
|
+
console.error(` ${import_ui.c.red("✗")} ${msg}`);
|
|
206
|
+
process.exit(1);
|
|
207
|
+
}
|
|
208
|
+
// Annotate the CommonJS export names for ESM import in node:
|
|
209
|
+
0 && (module.exports = {
|
|
210
|
+
generate
|
|
211
|
+
});
|
package/dist/generate.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* `fluixi generate <kind> <name>` (alias `g`)
|
|
2
|
+
* `fluixi generate <kind> <name>` (alias `g`), scaffold a piece into the current app.
|
|
3
3
|
* fluixi g component Button → src/components/Button.tsx
|
|
4
4
|
* fluixi g route about → src/routes/about.tsx (a file route)
|
|
5
5
|
* fluixi g route blog/[id] → src/routes/blog/[id].tsx
|
|
@@ -20,7 +20,7 @@ Component/route syntax follows the project (JSX → .tsx, html\`\` → .ts); ove
|
|
|
20
20
|
`;
|
|
21
21
|
/**
|
|
22
22
|
* Which template syntax to emit. Explicit --jsx/--html wins; otherwise infer from
|
|
23
|
-
* the project
|
|
23
|
+
* the project: an app whose tsconfig doesn't configure `jsx` is html``-authored.
|
|
24
24
|
*/
|
|
25
25
|
function detectFormat() {
|
|
26
26
|
const args = process.argv.slice(3);
|
|
@@ -34,7 +34,7 @@ function detectFormat() {
|
|
|
34
34
|
return 'html';
|
|
35
35
|
}
|
|
36
36
|
catch {
|
|
37
|
-
// no/invalid tsconfig
|
|
37
|
+
// no/invalid tsconfig: fall back to JSX
|
|
38
38
|
}
|
|
39
39
|
return 'jsx';
|
|
40
40
|
}
|
|
@@ -49,8 +49,8 @@ function pascal(s) {
|
|
|
49
49
|
/**
|
|
50
50
|
* Say how to use a generated component without importing it, when nothing would resolve it.
|
|
51
51
|
*
|
|
52
|
-
* Read-only on purpose. A vite/fluixi config is arbitrary TypeScript
|
|
53
|
-
* shared object, compute its rules, or call a resolver function
|
|
52
|
+
* Read-only on purpose. A vite/fluixi config is arbitrary TypeScript, it can spread a
|
|
53
|
+
* shared object, compute its rules, or call a resolver function, so editing it means
|
|
54
54
|
* parsing and reprinting, which loses the author's formatting and breaks on any shape we
|
|
55
55
|
* didn't anticipate. Printing the line to paste costs the user one paste and cannot
|
|
56
56
|
* corrupt anything.
|
|
@@ -106,7 +106,7 @@ const route = (Name) => `export default function ${Name}() {
|
|
|
106
106
|
);
|
|
107
107
|
}
|
|
108
108
|
`;
|
|
109
|
-
// html`` variants
|
|
109
|
+
// html`` variants: plain .ts, no JSX. Emitted when the project is html``-authored
|
|
110
110
|
// (no `jsx` in tsconfig) or with --html.
|
|
111
111
|
const componentHtml = (Name) => `import type { Component, ComponentChild } from '@fluixi/core';
|
|
112
112
|
import { html } from '@fluixi/core';
|
|
@@ -0,0 +1,186 @@
|
|
|
1
|
+
// src/generate.ts
|
|
2
|
+
import { writeFileSync, readFileSync, existsSync, mkdirSync } from "node:fs";
|
|
3
|
+
import { resolve, dirname, relative, basename } from "node:path";
|
|
4
|
+
import { c } from "@fluixi/start/ui";
|
|
5
|
+
var GEN_USAGE = `Usage: fluixi generate <kind> <name>
|
|
6
|
+
|
|
7
|
+
Kinds:
|
|
8
|
+
component <Name> a reusable component → src/components/<Name>.{tsx,ts}
|
|
9
|
+
route <path> a file-based route page → src/routes/<path>.{tsx,ts}
|
|
10
|
+
middleware the request middleware file → src/middleware.ts
|
|
11
|
+
auth @fluixi/auth wiring → auth.config + auth.client + middleware + /api/auth route
|
|
12
|
+
|
|
13
|
+
Component/route syntax follows the project (JSX → .tsx, html\`\` → .ts); override with --jsx / --html.
|
|
14
|
+
`;
|
|
15
|
+
function detectFormat() {
|
|
16
|
+
const args = process.argv.slice(3);
|
|
17
|
+
if (args.includes("--html")) return "html";
|
|
18
|
+
if (args.includes("--jsx")) return "jsx";
|
|
19
|
+
try {
|
|
20
|
+
const ts = JSON.parse(readFileSync(resolve("tsconfig.json"), "utf8"));
|
|
21
|
+
if (ts?.compilerOptions && !ts.compilerOptions.jsx) return "html";
|
|
22
|
+
} catch {
|
|
23
|
+
}
|
|
24
|
+
return "jsx";
|
|
25
|
+
}
|
|
26
|
+
function pascal(s) {
|
|
27
|
+
return s.replace(/\[(.+?)\]/g, "$1").split(/[^a-zA-Z0-9]+/).filter(Boolean).map((w) => w[0].toUpperCase() + w.slice(1)).join("") || "Component";
|
|
28
|
+
}
|
|
29
|
+
function resolveHint(Name, ext) {
|
|
30
|
+
const configs = ["vite.config.ts", "vite.config.js", "fluixi.config.ts", "fluixi.config.js"];
|
|
31
|
+
const found = configs.map((f) => resolve(f)).find((f) => existsSync(f));
|
|
32
|
+
if (!found) return;
|
|
33
|
+
try {
|
|
34
|
+
if (/\bresolve\s*:\s*\[/.test(readFileSync(found, "utf8"))) return;
|
|
35
|
+
} catch {
|
|
36
|
+
return;
|
|
37
|
+
}
|
|
38
|
+
console.log(
|
|
39
|
+
` ${c.gray("to use")} ${c.cyan(`<${Name} />`)} ${c.gray("without importing it, add to")} ${c.cyan(relative(process.cwd(), found))}:`
|
|
40
|
+
);
|
|
41
|
+
console.log(` ${c.gray(`resolve: [{ match: /^([A-Z]\\w+)$/, module: '/src/components/$1.${ext}' }]`)}`);
|
|
42
|
+
console.log(` ${c.gray("one pattern covers the whole folder. Importing it works too — including with")} ${c.cyan("load:")}`);
|
|
43
|
+
}
|
|
44
|
+
function write(file, content) {
|
|
45
|
+
const rel = relative(process.cwd(), file);
|
|
46
|
+
if (existsSync(file)) {
|
|
47
|
+
console.error(` ${c.red("✗")} ${rel} ${c.gray("already exists")}`);
|
|
48
|
+
process.exit(1);
|
|
49
|
+
}
|
|
50
|
+
mkdirSync(dirname(file), { recursive: true });
|
|
51
|
+
writeFileSync(file, content);
|
|
52
|
+
console.log(` ${c.green("✓")} ${c.gray("created")} ${c.cyan(rel)}`);
|
|
53
|
+
}
|
|
54
|
+
var component = (Name) => `import type { Component, ComponentChild } from '@fluixi/core';
|
|
55
|
+
|
|
56
|
+
export type ${Name}Props = {
|
|
57
|
+
children?: ComponentChild;
|
|
58
|
+
};
|
|
59
|
+
|
|
60
|
+
// Typed component: \`props\` is inferred from ${Name}Props. Use FxParent/FxVoid/FxFlow
|
|
61
|
+
// from '@fluixi/core' for children-required/forbidden variants.
|
|
62
|
+
export const ${Name}: Component<${Name}Props> = (props) => {
|
|
63
|
+
return <div class="${Name.toLowerCase()}">{props.children ?? '${Name}'}</div>;
|
|
64
|
+
};
|
|
65
|
+
`;
|
|
66
|
+
var route = (Name) => `export default function ${Name}() {
|
|
67
|
+
return (
|
|
68
|
+
<section>
|
|
69
|
+
<h1>${Name}</h1>
|
|
70
|
+
</section>
|
|
71
|
+
);
|
|
72
|
+
}
|
|
73
|
+
`;
|
|
74
|
+
var componentHtml = (Name) => `import type { Component, ComponentChild } from '@fluixi/core';
|
|
75
|
+
import { html } from '@fluixi/core';
|
|
76
|
+
|
|
77
|
+
export type ${Name}Props = {
|
|
78
|
+
children?: ComponentChild;
|
|
79
|
+
};
|
|
80
|
+
|
|
81
|
+
// Typed component: \`props\` is inferred from ${Name}Props. Use FxParent/FxVoid/FxFlow
|
|
82
|
+
// from '@fluixi/core' for children-required/forbidden variants.
|
|
83
|
+
export const ${Name}: Component<${Name}Props> = (props) => {
|
|
84
|
+
return html\`<div class="${Name.toLowerCase()}">\${props.children ?? '${Name}'}</div>\`;
|
|
85
|
+
};
|
|
86
|
+
`;
|
|
87
|
+
var routeHtml = (Name) => `import { html } from '@fluixi/start';
|
|
88
|
+
|
|
89
|
+
export default function ${Name}() {
|
|
90
|
+
return html\`
|
|
91
|
+
<section>
|
|
92
|
+
<h1>${Name}</h1>
|
|
93
|
+
</section>
|
|
94
|
+
\`;
|
|
95
|
+
}
|
|
96
|
+
`;
|
|
97
|
+
var middleware = () => `import { defineMiddleware } from '@fluixi/start';
|
|
98
|
+
|
|
99
|
+
export default defineMiddleware([
|
|
100
|
+
(request, next) => {
|
|
101
|
+
// return a Response to short-circuit (auth/redirect), or next() to continue.
|
|
102
|
+
return next();
|
|
103
|
+
},
|
|
104
|
+
]);
|
|
105
|
+
`;
|
|
106
|
+
var authConfig = () => `import { betterAuth } from 'better-auth';
|
|
107
|
+
import { defineAuth } from '@fluixi/auth/server';
|
|
108
|
+
|
|
109
|
+
export type AppUser = { id: string; email: string; name?: string; role?: string };
|
|
110
|
+
|
|
111
|
+
// Better Auth owns the audited primitives; defineAuth registers it with @fluixi/auth.
|
|
112
|
+
export const auth = defineAuth<AppUser>(
|
|
113
|
+
betterAuth({
|
|
114
|
+
// database: <your adapter>,
|
|
115
|
+
emailAndPassword: { enabled: true },
|
|
116
|
+
// socialProviders: { google: { … }, github: { … } },
|
|
117
|
+
} as Parameters<typeof betterAuth>[0]),
|
|
118
|
+
);
|
|
119
|
+
`;
|
|
120
|
+
var authClient = () => `import { createAuthClient } from 'better-auth/client';
|
|
121
|
+
import { createAuthHooks } from '@fluixi/auth/client';
|
|
122
|
+
import type { AppUser } from './auth.config.js';
|
|
123
|
+
|
|
124
|
+
const client = createAuthClient({ baseURL: '/api/auth' });
|
|
125
|
+
|
|
126
|
+
// Or, to reuse an existing reactive session: createAuthHooks({ session: yourSessionStore }).
|
|
127
|
+
export const { useUser, useSession, useAuth, useSignIn, useSignOut, protectedRoute } =
|
|
128
|
+
createAuthHooks<AppUser>({ client, loginPath: '/login' });
|
|
129
|
+
`;
|
|
130
|
+
var authMiddleware = () => `import { defineMiddleware } from '@fluixi/start';
|
|
131
|
+
import { authMiddleware } from '@fluixi/auth/server';
|
|
132
|
+
import './auth.config.js';
|
|
133
|
+
|
|
134
|
+
export default defineMiddleware([authMiddleware()]);
|
|
135
|
+
`;
|
|
136
|
+
var authRoute = () => `import { mountAuthRoutes } from '@fluixi/auth/server';
|
|
137
|
+
import '../../../auth.config.js';
|
|
138
|
+
|
|
139
|
+
const handler = mountAuthRoutes();
|
|
140
|
+
export const GET = handler;
|
|
141
|
+
export const POST = handler;
|
|
142
|
+
export default handler;
|
|
143
|
+
`;
|
|
144
|
+
function generate(kind, name) {
|
|
145
|
+
switch (kind) {
|
|
146
|
+
case "component":
|
|
147
|
+
case "c": {
|
|
148
|
+
if (!name) return fail("component name required, e.g. `fluixi g component Button`");
|
|
149
|
+
const Name = pascal(name);
|
|
150
|
+
const html = detectFormat() === "html";
|
|
151
|
+
const ext = html ? "ts" : "tsx";
|
|
152
|
+
write(resolve("src/components", `${Name}.${ext}`), (html ? componentHtml : component)(Name));
|
|
153
|
+
resolveHint(Name, ext);
|
|
154
|
+
break;
|
|
155
|
+
}
|
|
156
|
+
case "route":
|
|
157
|
+
case "r": {
|
|
158
|
+
if (!name) return fail("route path required, e.g. `fluixi g route about`");
|
|
159
|
+
const html = detectFormat() === "html";
|
|
160
|
+
const Name = pascal(basename(name));
|
|
161
|
+
write(resolve("src/routes", `${name}.${html ? "ts" : "tsx"}`), (html ? routeHtml : route)(Name));
|
|
162
|
+
break;
|
|
163
|
+
}
|
|
164
|
+
case "middleware":
|
|
165
|
+
case "m":
|
|
166
|
+
write(resolve("src/middleware.ts"), middleware());
|
|
167
|
+
break;
|
|
168
|
+
case "auth":
|
|
169
|
+
write(resolve("src/auth.config.ts"), authConfig());
|
|
170
|
+
write(resolve("src/auth.client.ts"), authClient());
|
|
171
|
+
write(resolve("src/middleware.ts"), authMiddleware());
|
|
172
|
+
write(resolve("src/routes/api/auth/[...all].ts"), authRoute());
|
|
173
|
+
console.log(` ${c.gray("next: install")} ${c.cyan("better-auth")}${c.gray(", set your DB adapter in auth.config.ts, and forward `request` in entry-server")}`);
|
|
174
|
+
break;
|
|
175
|
+
default:
|
|
176
|
+
console.error(GEN_USAGE);
|
|
177
|
+
process.exit(1);
|
|
178
|
+
}
|
|
179
|
+
}
|
|
180
|
+
function fail(msg) {
|
|
181
|
+
console.error(` ${c.red("✗")} ${msg}`);
|
|
182
|
+
process.exit(1);
|
|
183
|
+
}
|
|
184
|
+
export {
|
|
185
|
+
generate
|
|
186
|
+
};
|
package/dist/index.cjs
ADDED
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
/*! @fluixi/cli v0.1.0-alpha.76 | (c) 2026 Ibrahima Touré and Fluixi contributors | MIT */
|
|
2
|
+
"use strict";
|
|
3
|
+
var __defProp = Object.defineProperty;
|
|
4
|
+
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
5
|
+
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
6
|
+
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
7
|
+
var __export = (target, all) => {
|
|
8
|
+
for (var name in all)
|
|
9
|
+
__defProp(target, name, { get: all[name], enumerable: true });
|
|
10
|
+
};
|
|
11
|
+
var __copyProps = (to, from, except, desc) => {
|
|
12
|
+
if (from && typeof from === "object" || typeof from === "function") {
|
|
13
|
+
for (let key of __getOwnPropNames(from))
|
|
14
|
+
if (!__hasOwnProp.call(to, key) && key !== except)
|
|
15
|
+
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
|
16
|
+
}
|
|
17
|
+
return to;
|
|
18
|
+
};
|
|
19
|
+
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
20
|
+
|
|
21
|
+
// src/index.ts
|
|
22
|
+
var index_exports = {};
|
|
23
|
+
__export(index_exports, {
|
|
24
|
+
build: () => import_commands.build,
|
|
25
|
+
defineConfig: () => import_start.defineConfig,
|
|
26
|
+
dev: () => import_commands.dev,
|
|
27
|
+
loadConfig: () => import_config.loadConfig,
|
|
28
|
+
start: () => import_commands.start
|
|
29
|
+
});
|
|
30
|
+
module.exports = __toCommonJS(index_exports);
|
|
31
|
+
var import_start = require("@fluixi/start");
|
|
32
|
+
var import_config = require("@fluixi/start/config");
|
|
33
|
+
var import_commands = require("@fluixi/start/commands");
|
|
34
|
+
// Annotate the CommonJS export names for ESM import in node:
|
|
35
|
+
0 && (module.exports = {
|
|
36
|
+
build,
|
|
37
|
+
defineConfig,
|
|
38
|
+
dev,
|
|
39
|
+
loadConfig,
|
|
40
|
+
start
|
|
41
|
+
});
|
package/dist/index.d.ts
CHANGED
|
@@ -1,10 +1,11 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* @fluixi/cli
|
|
2
|
+
* @fluixi/cli: the `fluixi` command-line tool.
|
|
3
3
|
*
|
|
4
4
|
* The binary lives in `cli.ts` (`fluixi <dev|build|start>`). This entry re-exports
|
|
5
5
|
* the underlying runtime so the commands can also be driven programmatically.
|
|
6
6
|
*/
|
|
7
|
-
export { defineConfig
|
|
7
|
+
export { defineConfig } from '@fluixi/start';
|
|
8
|
+
export { loadConfig } from '@fluixi/start/config';
|
|
8
9
|
export { dev, build, start } from '@fluixi/start/commands';
|
|
9
10
|
export type { FluixiConfig } from '@fluixi/start';
|
|
10
11
|
//# sourceMappingURL=index.d.ts.map
|
package/dist/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AACH,OAAO,EAAE,YAAY,EAAE,UAAU,EAAE,MAAM,
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AACH,OAAO,EAAE,YAAY,EAAE,MAAM,eAAe,CAAC;AAG7C,OAAO,EAAE,UAAU,EAAE,MAAM,sBAAsB,CAAC;AAClD,OAAO,EAAE,GAAG,EAAE,KAAK,EAAE,KAAK,EAAE,MAAM,wBAAwB,CAAC;AAC3D,YAAY,EAAE,YAAY,EAAE,MAAM,eAAe,CAAC"}
|
package/dist/index.js
CHANGED
|
@@ -1,8 +1,11 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* @fluixi/cli
|
|
2
|
+
* @fluixi/cli: the `fluixi` command-line tool.
|
|
3
3
|
*
|
|
4
4
|
* The binary lives in `cli.ts` (`fluixi <dev|build|start>`). This entry re-exports
|
|
5
5
|
* the underlying runtime so the commands can also be driven programmatically.
|
|
6
6
|
*/
|
|
7
|
-
export { defineConfig
|
|
7
|
+
export { defineConfig } from '@fluixi/start';
|
|
8
|
+
// The loader reads a file, so it is behind the config subpath rather than the root
|
|
9
|
+
// entry, which stays importable from a browser bundle.
|
|
10
|
+
export { loadConfig } from '@fluixi/start/config';
|
|
8
11
|
export { dev, build, start } from '@fluixi/start/commands';
|
package/dist/index.mjs
ADDED
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
/*! @fluixi/cli v0.1.0-alpha.76 | (c) 2026 Ibrahima Touré and Fluixi contributors | MIT */
|
|
2
|
+
|
|
3
|
+
// src/index.ts
|
|
4
|
+
import { defineConfig } from "@fluixi/start";
|
|
5
|
+
import { loadConfig } from "@fluixi/start/config";
|
|
6
|
+
import { dev, build, start } from "@fluixi/start/commands";
|
|
7
|
+
export {
|
|
8
|
+
build,
|
|
9
|
+
defineConfig,
|
|
10
|
+
dev,
|
|
11
|
+
loadConfig,
|
|
12
|
+
start
|
|
13
|
+
};
|