howone 0.1.3 → 0.1.5

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/bin/index.mjs CHANGED
@@ -1,13 +1,14 @@
1
1
  #!/usr/bin/env bun
2
2
  import { createRequire } from "node:module";
3
- import { cancel, confirm, intro, isCancel, outro, select, spinner, text } from "@clack/prompts";
4
- import { cac } from "cac";
3
+ import { say, spinner } from "@astrojs/cli-kit";
4
+ import { cancel, confirm, isCancel, select, text } from "@clack/prompts";
5
5
  import { readdir, rename, stat, writeFile } from "node:fs/promises";
6
6
  import { copy, emptyDir, ensureDir, pathExists } from "fs-extra/esm";
7
- import pc from "picocolors";
8
7
  import path from "node:path";
9
8
  import { fileURLToPath } from "node:url";
9
+ import pc from "picocolors";
10
10
  import validatePackageName from "validate-npm-package-name";
11
+ import yargsParser from "yargs-parser";
11
12
  //#region src/index.ts
12
13
  const packageJson = createRequire(import.meta.url)("../package.json");
13
14
  const DEFAULT_PROJECT_NAME = "howone-app";
@@ -25,78 +26,108 @@ var CliError = class extends Error {
25
26
  this.name = "CliError";
26
27
  }
27
28
  };
28
- const cli = cac("howone");
29
- cli.version(packageJson.version, "-v, --version");
30
- cli.help();
31
- cli.command("create [projectName] [legacyProjectName]", "Create a new project from a HowOne template.").alias("new").alias("init").option("-t, --template <template>", "Template to use: vite, nextjs").option("--vite", "Shortcut for --template vite").option("--nextjs", "Shortcut for --template nextjs").option("--next", "Alias for --nextjs").option("-f, --force", "Overwrite an existing non-empty target directory").option("-y, --yes", "Disable prompts and accept defaults where possible").option("--json", "Print machine-readable JSON output").option("--cwd <dir>", "Directory in which to create the project").example("howone vite my-app").example("howone next my-app").example("howone create my-app --template vite").example("howone create my-app --template nextjs --yes").example("howone create my-app --template vite --json --yes").example("howone create template --vite my-app").action((projectName, legacyProjectName, options) => {
32
- runCreate(projectName, legacyProjectName, options).catch((error) => handleFatalError(error, Boolean(options.json)));
33
- });
34
- try {
35
- cli.parse(normalizeCliArgv(process.argv), { run: true });
36
- } catch (error) {
29
+ main().catch((error) => {
37
30
  handleFatalError(error, process.argv.includes("--json"));
31
+ });
32
+ async function main() {
33
+ const command = parseCommand(process.argv.slice(2));
34
+ if (command.options.version) {
35
+ console.log(packageJson.version);
36
+ return;
37
+ }
38
+ if (command.options.help || command.path.length === 0) {
39
+ printHelp(command.path);
40
+ return;
41
+ }
42
+ const [scope, subcommand, ...rest] = command.path;
43
+ if (isTemplateAlias(scope)) {
44
+ await runInitApp(compact([subcommand, ...rest]), {
45
+ ...command.options,
46
+ template: resolveTemplateAlias(scope)
47
+ });
48
+ return;
49
+ }
50
+ if (scope === "init" || scope === "new") {
51
+ await runInitApp(subcommand === "app" ? rest : compact([subcommand, ...rest]), command.options);
52
+ return;
53
+ }
54
+ if (scope === "create") {
55
+ await runCreatePlaceholder(command.options);
56
+ return;
57
+ }
58
+ if (scope === "deploy") {
59
+ await runDeploy(command.options);
60
+ return;
61
+ }
62
+ if (scope === "ai" && subcommand === "run") {
63
+ await runAiRun(rest, command.options);
64
+ return;
65
+ }
66
+ throw new CliError("E_COMMAND_UNKNOWN", `Unknown command: ${command.path.join(" ")}`);
38
67
  }
39
- function normalizeCliArgv(argv) {
40
- if (argv.length < 3) return argv;
41
- const runtime = argv[0];
42
- const script = argv[1];
43
- const userArgs = argv.slice(2);
44
- const first = userArgs[0];
45
- if (!first || first === "create" || first === "new" || first === "init" || first === "--help" || first === "-h") return normalizeCreateSubcommandArgv(argv);
46
- const template = resolveTemplateAlias(first);
47
- if (template) return [
48
- runtime,
49
- script,
50
- "create",
51
- ...userArgs.slice(1),
52
- "--template",
53
- template
54
- ];
55
- if (!first.startsWith("-") && hasTemplateFlag(userArgs)) return [
56
- runtime,
57
- script,
58
- "create",
59
- ...userArgs
60
- ];
61
- return argv;
62
- }
63
- function normalizeCreateSubcommandArgv(argv) {
64
- const runtime = argv[0];
65
- const script = argv[1];
66
- const command = argv[2];
67
- const rest = argv.slice(3);
68
- if (!command || command !== "create" && command !== "new" && command !== "init") return argv;
69
- const first = rest[0];
70
- const template = resolveTemplateAlias(first);
71
- if (!template) return argv;
72
- return [
73
- runtime,
74
- script,
75
- command,
76
- ...rest.slice(1),
77
- "--template",
78
- template
79
- ];
80
- }
81
- function resolveTemplateAlias(value) {
82
- if (!value) return void 0;
83
- const normalized = TEMPLATE_ALIASES[value];
84
- return normalized && isTemplate(normalized) ? normalized : void 0;
68
+ function parseCommand(args) {
69
+ const hasHelp = args.includes("--help") || args.includes("-h");
70
+ const hasVersion = args.includes("--version") || args.includes("-v");
71
+ const parsed = yargsParser(args, {
72
+ alias: {
73
+ h: "help",
74
+ v: "version",
75
+ t: "template",
76
+ f: "force",
77
+ y: "yes"
78
+ },
79
+ boolean: [
80
+ "help",
81
+ "version",
82
+ "vite",
83
+ "nextjs",
84
+ "next",
85
+ "force",
86
+ "yes",
87
+ "json"
88
+ ],
89
+ string: ["template", "cwd"],
90
+ configuration: { "camel-case-expansion": false }
91
+ });
92
+ return {
93
+ path: parsed._.map(String),
94
+ options: {
95
+ template: typeof parsed.template === "string" ? parsed.template : void 0,
96
+ vite: Boolean(parsed.vite),
97
+ nextjs: Boolean(parsed.nextjs),
98
+ next: Boolean(parsed.next),
99
+ force: Boolean(parsed.force),
100
+ yes: Boolean(parsed.yes),
101
+ json: Boolean(parsed.json),
102
+ cwd: typeof parsed.cwd === "string" ? parsed.cwd : void 0,
103
+ help: Boolean(parsed.help) || hasHelp,
104
+ version: Boolean(parsed.version) || hasVersion
105
+ }
106
+ };
85
107
  }
86
- function hasTemplateFlag(args) {
87
- return args.some((arg) => arg === "--vite" || arg === "--next" || arg === "--nextjs" || arg === "--template");
108
+ function compact(values) {
109
+ return values.filter((value) => Boolean(value));
88
110
  }
89
- async function runCreate(projectNameArg, legacyProjectNameArg, options) {
90
- const plan = await resolveCreatePlan(projectNameArg, legacyProjectNameArg, options, path.resolve(options.cwd ?? process.cwd()), process.stdout.isTTY && !options.yes && !options.json);
91
- if (!options.json) intro(pc.bold("HowOne"));
92
- await createTemplate(plan, Boolean(options.json));
111
+ async function runInitApp(pathArgs, options) {
112
+ const plan = await resolveCreatePlan(pathArgs, options, path.resolve(options.cwd ?? process.cwd()), process.stdout.isTTY && !options.yes && !options.json);
113
+ const howoneContext = resolveHowoneCreateContext();
114
+ if (options.json) await createTemplate(plan, howoneContext, true);
115
+ else {
116
+ await say(pc.bold("HowOne"));
117
+ await createTemplate(plan, howoneContext, false);
118
+ }
93
119
  const result = {
94
120
  ok: true,
95
- command: "create",
121
+ command: "init app",
96
122
  template: plan.template,
97
123
  projectName: plan.projectName,
98
124
  targetDir: plan.targetDir,
99
125
  packageManager: "bun",
126
+ ...howoneContext ? { howone: {
127
+ projectId: howoneContext.projectId,
128
+ env: howoneContext.env,
129
+ envFile: path.join(plan.targetDir, ".env")
130
+ } } : {},
100
131
  nextSteps: [
101
132
  `cd ${formatPathForShell(path.relative(plan.cwd, plan.targetDir) || ".")}`,
102
133
  "bun install",
@@ -107,16 +138,51 @@ async function runCreate(projectNameArg, legacyProjectNameArg, options) {
107
138
  console.log(JSON.stringify(result, null, 2));
108
139
  return;
109
140
  }
110
- outro([
111
- `${pc.green("Created")} ${pc.bold(plan.template)} template in ${pc.cyan(path.relative(plan.cwd, plan.targetDir) || ".")}`,
112
- "",
113
- pc.bold("Next steps:"),
114
- ...result.nextSteps.map((step) => ` ${step}`)
115
- ].join("\n"));
141
+ printCreateSuccess(plan, result);
116
142
  }
117
- async function resolveCreatePlan(projectNameArg, legacyProjectNameArg, options, cwd, isInteractive) {
143
+ async function runCreatePlaceholder(options) {
144
+ const result = {
145
+ ok: true,
146
+ command: "create",
147
+ status: "pending",
148
+ message: "howone create is reserved for a future workflow."
149
+ };
150
+ if (options.json) {
151
+ console.log(JSON.stringify(result, null, 2));
152
+ return;
153
+ }
154
+ printPending("howone create", result.message ?? "howone create is reserved for a future workflow.");
155
+ }
156
+ async function runDeploy(options) {
157
+ const result = {
158
+ ok: true,
159
+ command: "deploy",
160
+ status: "pending",
161
+ message: "howone deploy is not implemented yet."
162
+ };
163
+ if (options.json) {
164
+ console.log(JSON.stringify(result, null, 2));
165
+ return;
166
+ }
167
+ printPending("howone deploy", "Deploy is not implemented yet.");
168
+ }
169
+ async function runAiRun(pathArgs, options) {
170
+ const aiId = pathArgs[0];
171
+ const result = {
172
+ ok: true,
173
+ command: "ai run",
174
+ status: "pending",
175
+ message: aiId ? `howone ai run ${aiId} is not implemented yet.` : "howone ai run is not implemented yet."
176
+ };
177
+ if (options.json) {
178
+ console.log(JSON.stringify(result, null, 2));
179
+ return;
180
+ }
181
+ printPending("howone ai run", result.message ?? "AI run is not implemented yet.");
182
+ }
183
+ async function resolveCreatePlan(pathArgs, options, cwd, isInteractive) {
118
184
  const template = resolveTemplateOption(options);
119
- const projectName = projectNameArg === "template" ? legacyProjectNameArg : projectNameArg;
185
+ const projectName = pathArgs[0] === "template" ? pathArgs[1] : pathArgs[0];
120
186
  const resolvedTemplate = template ?? (isInteractive ? await promptTemplate() : void 0);
121
187
  if (!resolvedTemplate) throw new CliError("E_TEMPLATE_REQUIRED", "Missing template. Use --template vite or --template nextjs.");
122
188
  const resolvedProjectName = projectName ?? (isInteractive ? await promptProjectName() : DEFAULT_PROJECT_NAME);
@@ -130,7 +196,8 @@ async function resolveCreatePlan(projectNameArg, legacyProjectNameArg, options,
130
196
  entries: entries.slice(0, 20),
131
197
  retryWithForce: [
132
198
  "howone",
133
- "create",
199
+ "init",
200
+ "app",
134
201
  resolvedProjectName,
135
202
  "--template",
136
203
  resolvedTemplate,
@@ -145,10 +212,11 @@ async function resolveCreatePlan(projectNameArg, legacyProjectNameArg, options,
145
212
  message: `Directory "${path.relative(cwd, targetDir) || "."}" is not empty. Overwrite it?`,
146
213
  initialValue: false
147
214
  });
148
- if (isCancel(shouldOverwrite) || !shouldOverwrite) {
215
+ if (isCancel(shouldOverwrite)) {
149
216
  cancel("Cancelled.");
150
217
  process.exit(0);
151
218
  }
219
+ if (!shouldOverwrite) throw new CliError("E_CANCELLED", "Cancelled.");
152
220
  }
153
221
  await assertTargetWritable(targetDir);
154
222
  return {
@@ -210,12 +278,21 @@ async function promptProjectName() {
210
278
  cancel("Cancelled.");
211
279
  process.exit(0);
212
280
  }
213
- return value;
281
+ return String(value || DEFAULT_PROJECT_NAME);
214
282
  }
215
- async function createTemplate(plan, json) {
283
+ async function createTemplate(plan, howoneContext, json) {
284
+ if (json) {
285
+ await performCreateTemplate(plan, howoneContext);
286
+ return;
287
+ }
288
+ await spinner({
289
+ start: "Creating project",
290
+ end: "Project created",
291
+ while: () => performCreateTemplate(plan, howoneContext)
292
+ });
293
+ }
294
+ async function performCreateTemplate(plan, howoneContext) {
216
295
  const templateDir = getTemplateDir(plan.template);
217
- const task = json ? null : spinner();
218
- task?.start("Creating project");
219
296
  if (plan.force && await pathExists(plan.targetDir)) await emptyDir(plan.targetDir);
220
297
  else await ensureDir(plan.targetDir);
221
298
  await copy(templateDir, plan.targetDir, {
@@ -226,9 +303,8 @@ async function createTemplate(plan, json) {
226
303
  }
227
304
  });
228
305
  await restoreGitignore(plan.targetDir);
229
- await writeHowoneEnvFile(plan);
306
+ await writeHowoneEnvFile(plan, howoneContext);
230
307
  await assertTemplateCopied(plan);
231
- task?.stop("Project created");
232
308
  }
233
309
  function normalizeHowoneEnv(value) {
234
310
  const normalized = value?.trim().toLowerCase();
@@ -238,7 +314,7 @@ function normalizeHowoneEnv(value) {
238
314
  if (normalized === "local" || normalized === "dev" || normalized === "prod") return normalized;
239
315
  return "dev";
240
316
  }
241
- function getHowoneCreateContext() {
317
+ function resolveHowoneCreateContext() {
242
318
  const projectId = process.env.HOWONE_PROJECT_ID?.trim();
243
319
  if (!projectId) return null;
244
320
  return {
@@ -250,10 +326,9 @@ function getTemplateEnvEntries(template, context) {
250
326
  if (template === "vite") return [["VITE_HOWONE_PROJECT_ID", context.projectId], ["VITE_HOWONE_ENV", context.env]];
251
327
  return [["NEXT_PUBLIC_HOWONE_PROJECT_ID", context.projectId], ["NEXT_PUBLIC_HOWONE_ENV", context.env]];
252
328
  }
253
- async function writeHowoneEnvFile(plan) {
254
- const context = getHowoneCreateContext();
255
- if (!context) return;
256
- const lines = getTemplateEnvEntries(plan.template, context).map(([key, value]) => `${key}=${value}`);
329
+ async function writeHowoneEnvFile(plan, howoneContext) {
330
+ if (!howoneContext) return;
331
+ const lines = getTemplateEnvEntries(plan.template, howoneContext).map(([key, value]) => `${key}=${value}`);
257
332
  await writeFile(path.join(plan.targetDir, ".env"), [...lines, ""].join("\n"), "utf-8");
258
333
  }
259
334
  function getTemplateDir(template) {
@@ -288,19 +363,106 @@ function validateProjectName(projectName) {
288
363
  if (result.validForNewPackages) return;
289
364
  throw new CliError("E_PROJECT_NAME_INVALID", [...result.errors ?? [], ...result.warnings ?? []][0] ?? `Invalid project name: ${projectName}`);
290
365
  }
366
+ function resolveTemplateAlias(value) {
367
+ if (!value) return void 0;
368
+ const normalized = TEMPLATE_ALIASES[value];
369
+ return normalized && isTemplate(normalized) ? normalized : void 0;
370
+ }
371
+ function isTemplateAlias(value) {
372
+ return Boolean(resolveTemplateAlias(value));
373
+ }
291
374
  function isTemplate(value) {
292
- return TEMPLATES.includes(value);
375
+ return typeof value === "string" && TEMPLATES.includes(value);
293
376
  }
294
377
  function formatPathForShell(value) {
295
378
  return value.includes(" ") ? JSON.stringify(value) : value;
296
379
  }
297
- function handleFatalError(error, json) {
298
- if (error instanceof CliError) {
299
- printError(error, json);
300
- process.exit(1);
380
+ function printHelp(pathArgs) {
381
+ const topic = pathArgs.join(" ");
382
+ if (topic === "init" || topic === "init app" || topic === "new" || topic === "new app") {
383
+ printInitHelp();
384
+ return;
385
+ }
386
+ if (topic === "create") {
387
+ printReservedHelp("howone create", "Reserved for a future create workflow.");
388
+ return;
301
389
  }
302
- printError(new CliError("E_UNEXPECTED", error instanceof Error ? error.message : String(error)), json);
303
- process.exit(1);
390
+ if (topic === "deploy") {
391
+ printReservedHelp("howone deploy", "Deploy support is reserved and not implemented yet.");
392
+ return;
393
+ }
394
+ if (topic === "ai" || topic === "ai run") {
395
+ printReservedHelp("howone ai run [aiId]", "AI run support is reserved and not implemented yet.");
396
+ return;
397
+ }
398
+ printRootHelp();
399
+ }
400
+ function printRootHelp() {
401
+ console.log(formatPanel(`${pc.bold("HowOne CLI")} ${pc.dim(`v${packageJson.version}`)}`, [
402
+ `${pc.dim("Usage")} howone <command> [options]`,
403
+ "",
404
+ pc.bold("Commands"),
405
+ formatCommand("init app [name]", "Create an app from a template"),
406
+ formatCommand("create", "Reserved placeholder"),
407
+ formatCommand("deploy", "Reserved placeholder"),
408
+ formatCommand("ai run [aiId]", "Reserved placeholder"),
409
+ "",
410
+ pc.bold("Options"),
411
+ formatCommand("-h, --help", "Show help"),
412
+ formatCommand("-v, --version", "Show version"),
413
+ "",
414
+ pc.bold("Examples"),
415
+ ` ${pc.cyan("howone init app my-app --template vite")}`,
416
+ ` ${pc.cyan("howone deploy")}`,
417
+ ` ${pc.cyan("howone ai run generateImage")}`
418
+ ]));
419
+ }
420
+ function printInitHelp() {
421
+ console.log(formatPanel(`${pc.bold("Create an app")}`, [
422
+ `${pc.dim("Usage")} howone init app [name] [options]`,
423
+ "",
424
+ pc.bold("Options"),
425
+ formatCommand("-t, --template <template>", "Template to use: vite, nextjs"),
426
+ formatCommand("--vite", "Shortcut for --template vite"),
427
+ formatCommand("--nextjs", "Shortcut for --template nextjs"),
428
+ formatCommand("--next", "Alias for --nextjs"),
429
+ formatCommand("-f, --force", "Overwrite an existing non-empty directory"),
430
+ formatCommand("-y, --yes", "Disable prompts and accept defaults"),
431
+ formatCommand("--json", "Print machine-readable JSON output"),
432
+ formatCommand("--cwd <dir>", "Directory in which to create the app"),
433
+ "",
434
+ pc.bold("Examples"),
435
+ ` ${pc.cyan("howone init app my-app --template vite")}`,
436
+ ` ${pc.cyan("howone init app my-app --template nextjs --yes")}`
437
+ ]));
438
+ }
439
+ function printReservedHelp(command, description) {
440
+ console.log(formatPanel(pc.bold(command), [
441
+ description,
442
+ "",
443
+ `${pc.yellow("Pending")} This command is available as a stable placeholder.`
444
+ ]));
445
+ }
446
+ function printPending(command, message) {
447
+ console.log(formatPanel(pc.bold(command), [`${pc.yellow("Pending")} ${message}`]));
448
+ }
449
+ function printCreateSuccess(plan, result) {
450
+ const relativeTarget = path.relative(plan.cwd, plan.targetDir) || ".";
451
+ const lines = [`${pc.green("Created")} ${pc.bold(plan.template)} app in ${pc.cyan(relativeTarget)}`];
452
+ if (result.howone) lines.push("", pc.bold("HowOne context"), formatCommand("project", result.howone.projectId), formatCommand("env", result.howone.env), formatCommand("file", path.relative(plan.cwd, result.howone.envFile) || ".env"));
453
+ lines.push("", pc.bold("Next steps"), ...(result.nextSteps ?? []).map((step) => ` ${pc.cyan(step)}`));
454
+ console.log(formatPanel(pc.bold("App ready"), lines));
455
+ }
456
+ function formatPanel(title, lines) {
457
+ return [`${pc.green("◆")} ${title}`, ...lines.map((line) => line ? ` ${line}` : "")].join("\n");
458
+ }
459
+ function formatCommand(command, description) {
460
+ return ` ${pc.cyan(command.padEnd(28))} ${description}`;
461
+ }
462
+ function handleFatalError(error, json) {
463
+ const cliError = error instanceof CliError ? error : new CliError("E_UNEXPECTED", error instanceof Error ? error.message : String(error));
464
+ printError(cliError, json);
465
+ process.exit(cliError.code === "E_CANCELLED" ? 0 : 1);
304
466
  }
305
467
  function printError(error, json) {
306
468
  const payload = {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "howone",
3
- "version": "0.1.3",
3
+ "version": "0.1.5",
4
4
  "private": false,
5
5
  "description": "HowOne command line tools for creating app templates.",
6
6
  "type": "module",
@@ -27,17 +27,19 @@
27
27
  "typecheck": "tsc -p tsconfig.json --noEmit"
28
28
  },
29
29
  "dependencies": {
30
+ "@astrojs/cli-kit": "^0.4.1",
30
31
  "@clack/prompts": "^1.3.0",
31
- "cac": "^7.0.0",
32
32
  "fs-extra": "^11.3.4",
33
33
  "picocolors": "^1.1.1",
34
- "validate-npm-package-name": "^7.0.2"
34
+ "validate-npm-package-name": "^7.0.2",
35
+ "yargs-parser": "^22.0.0"
35
36
  },
36
37
  "devDependencies": {
37
38
  "@howone/tsconfig": "workspace:*",
38
39
  "@types/fs-extra": "^11.0.4",
39
40
  "@types/node": "^25.6.0",
40
41
  "@types/validate-npm-package-name": "^4.0.2",
42
+ "@types/yargs-parser": "^21.0.3",
41
43
  "tsdown": "^0.21.10",
42
44
  "typescript": "^5.7.3"
43
45
  }
@@ -1,10 +1,8 @@
1
1
  import { createClient, defineEntities, withEntities } from '@howone/sdk'
2
2
 
3
- export const HOWONE_PROJECT_ID = process.env.NEXT_PUBLIC_HOWONE_PROJECT_ID ?? 'demo'
4
-
5
3
  const client = createClient({
6
- projectId: HOWONE_PROJECT_ID,
7
- env: (process.env.NEXT_PUBLIC_HOWONE_ENV ?? 'prod') as 'local' | 'dev' | 'prod',
4
+ projectId: process.env.NEXT_PUBLIC_HOWONE_PROJECT_ID,
5
+ env: process.env.NEXT_PUBLIC_HOWONE_ENV,
8
6
  })
9
7
 
10
8
  export const entities = defineEntities({
@@ -14,7 +14,7 @@
14
14
  "dependencies": {
15
15
  "@base-ui/react": "^1.4.1",
16
16
  "@fontsource-variable/inter": "^5.2.8",
17
- "@howone/sdk": "2.0.0-beta.6",
17
+ "@howone/sdk": "2.0.0-beta.7",
18
18
  "@tailwindcss/vite": "^4.2.1",
19
19
  "class-variance-authority": "^0.7.1",
20
20
  "clsx": "^2.1.1",
@@ -1,8 +1,8 @@
1
- import { HowOneProvider } from '@howone/sdk'
1
+ import { HowOneProvider } from '@howone/sdk/react'
2
2
 
3
3
  function App() {
4
4
  return (
5
- <HowOneProvider>
5
+ <HowOneProvider auth="optional" brand="visible">
6
6
  <div className="App">
7
7
  <h1>Hello HowOne</h1>
8
8
  </div>
@@ -1,10 +1,8 @@
1
1
  import { createClient, defineEntities, withEntities } from '@howone/sdk'
2
2
 
3
- export const HOWONE_PROJECT_ID = import.meta.env.VITE_HOWONE_PROJECT_ID
4
-
5
3
  const client = createClient({
6
- projectId: HOWONE_PROJECT_ID,
7
- env: import.meta.env.VITE_HOWONE_ENV
4
+ projectId: import.meta.env.VITE_HOWONE_PROJECT_ID,
5
+ env: import.meta.env.VITE_HOWONE_ENV,
8
6
  })
9
7
 
10
8
  export const entities = defineEntities({