@lunora/cli 1.0.0-alpha.74 → 1.0.0-alpha.75

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/index.mjs CHANGED
@@ -16,4 +16,4 @@ export { createRecordingSpawner, defaultSpawner } from './packem_shared/createRe
16
16
  export { default as parseManifest } from './packem_shared/parseManifest-Dbp-Q2q3.mjs';
17
17
  export { REQUIRED_COMPATIBILITY_DATE, REQUIRED_FLAG, validateWranglerProject as validateWrangler, validateWranglerConfig } from '@lunora/config';
18
18
  export { buildRegistryIndex } from './packem_shared/buildRegistryIndex-BS5ig822.mjs';
19
- export { r as runAddCommand, a as runBuildIndexCommand, b as runRegistryViewCommand } from './packem_shared/commands-CF2YHeFa.mjs';
19
+ export { r as runAddCommand, a as runBuildIndexCommand, b as runRegistryViewCommand } from './packem_shared/commands-ClEvcz3V.mjs';
@@ -4,8 +4,8 @@ import { join, basename } from '@visulima/path';
4
4
  import { d as defineHandler } from '../packem_shared/command-lYnl4QyF.mjs';
5
5
  import { v as validateOutputFormat, i as isJsonFormat, p as printJson, l as loggerForFormat } from '../packem_shared/output-format-B4642rjE.mjs';
6
6
  import { t as tuiText, a as tuiSelect } from '../packem_shared/tui-prompts-BjEN8XgP.mjs';
7
- import { n as normalizeFeature, E as EMAIL_ITEM, s as sanitizeBucketName, d as deriveBucketName, p as promptBucketName, r as resolveTypedDestination, M as MAIL_DESTINATION_PROMPT, a as sanitizeDatabaseName, b as deriveDatabaseName, c as promptDatabaseName, D as DEFAULT_AUTH_ITEM, e as promptAuthProvider, A as AUTH_PROVIDER_OPTIONS, w as withStorageBucketName, f as withMailDestination, g as withAuthDatabaseName } from '../packem_shared/storage-HRI1N4Ao.mjs';
8
- import { r as runAddCommand } from '../packem_shared/commands-CF2YHeFa.mjs';
7
+ import { n as normalizeFeature, E as EMAIL_ITEM, s as sanitizeBucketName, d as deriveBucketName, p as promptBucketName, r as resolveTypedDestination, M as MAIL_DESTINATION_PROMPT, a as sanitizeDatabaseName, b as deriveDatabaseName, c as promptDatabaseName, D as DEFAULT_AUTH_ITEM, e as promptAuthProvider, A as AUTH_PROVIDER_OPTIONS, w as withStorageBucketName, f as withMailDestination, g as withAuthDatabaseName } from '../packem_shared/storage-DEXpJkXh.mjs';
8
+ import { r as runAddCommand } from '../packem_shared/commands-ClEvcz3V.mjs';
9
9
 
10
10
  const providerToItem = (provider) => {
11
11
  const value = provider.trim().toLowerCase();
@@ -1,5 +1,5 @@
1
1
  import { d as defineHandler } from '../packem_shared/command-lYnl4QyF.mjs';
2
- import { r as runAddCommand, b as runRegistryViewCommand, a as runBuildIndexCommand } from '../packem_shared/commands-CF2YHeFa.mjs';
2
+ import { r as runAddCommand, b as runRegistryViewCommand, a as runBuildIndexCommand } from '../packem_shared/commands-ClEvcz3V.mjs';
3
3
 
4
4
  const execute = defineHandler(({ argument, cwd, logger, options }) => {
5
5
  const subcommand = argument[0];
@@ -11,11 +11,11 @@ import { d as detectPackageManager, a as detectInstalledManagers, i as installAr
11
11
  import MagicString from 'magic-string';
12
12
  import { Project, SyntaxKind } from 'ts-morph';
13
13
  import { P as PromptCancelledError } from '../packem_shared/prompt-cancelled-APzX1Im-.mjs';
14
- import { c as resolveTagVersions, d as resolveSourceRef, e as resolvePinnedSourceRef, f as resolveDistTag, r as runAddCommand } from '../packem_shared/commands-CF2YHeFa.mjs';
14
+ import { c as resolveTagVersions, d as resolveSourceRef, e as resolvePinnedSourceRef, f as resolveDistTag, r as runAddCommand } from '../packem_shared/commands-ClEvcz3V.mjs';
15
15
  import { defaultSpawner } from '../packem_shared/createRecordingSpawner-Cw5Iu73G.mjs';
16
16
  import { d as tuiMascot, e as tuiStep, f as tuiMoonrise, t as tuiText, g as tuiHeadline, h as tuiInfo, a as tuiSelect, b as tuiConfirm, w as withTuiSpinner, i as tuiNextSteps, j as tuiTasks, k as tuiMultiSelect, l as withTuiBadgeProgress } from '../packem_shared/tui-prompts-BjEN8XgP.mjs';
17
17
  import { logStep } from '../packem_shared/createLogger-CIWSHrTL.mjs';
18
- import { E as EMAIL_ITEM, p as promptBucketName, w as withStorageBucketName, M as MAIL_DESTINATION_PROMPT, r as resolveTypedDestination, f as withMailDestination, e as promptAuthProvider, c as promptDatabaseName, g as withAuthDatabaseName } from '../packem_shared/storage-HRI1N4Ao.mjs';
18
+ import { E as EMAIL_ITEM, p as promptBucketName, w as withStorageBucketName, M as MAIL_DESTINATION_PROMPT, r as resolveTypedDestination, f as withMailDestination, e as promptAuthProvider, c as promptDatabaseName, g as withAuthDatabaseName } from '../packem_shared/storage-DEXpJkXh.mjs';
19
19
  import dns from 'node:dns/promises';
20
20
 
21
21
  const GITHUB_CONTENT = `name: Deploy
@@ -1470,7 +1470,49 @@ const ADAPTERS = {
1470
1470
  };
1471
1471
  const isOverlayFramework = (value) => Object.hasOwn(ADAPTERS, value);
1472
1472
 
1473
- const LUNORA_SCHEMA = `import { defineSchema, defineTable, v } from "lunorash/server";
1473
+ const RATELIMIT_SCHEMA = `import type { Middleware } from "lunorash/server";
1474
+ import { defineSchemaExtension, defineTable, definePlugin, v } from "lunorash/server";
1475
+ import { createDbStore, RateLimiter } from "lunorash/ratelimit";
1476
+ import type { RateLimitConfigMap } from "lunorash/ratelimit";
1477
+
1478
+ export const limits = {
1479
+ default: { kind: "token bucket", period: 60_000, rate: 10 },
1480
+ } as const satisfies RateLimitConfigMap;
1481
+
1482
+ export type LimitName = keyof typeof limits;
1483
+
1484
+ export const makeRateLimiter = (ctx: { db: unknown }): RateLimiter<LimitName> =>
1485
+ new RateLimiter<LimitName>({
1486
+ config: limits,
1487
+ store: createDbStore({ db: ctx.db as never, table: "ratelimit_buckets" }),
1488
+ });
1489
+
1490
+ const middleware: Middleware<{ api?: Record<string, unknown>; db: unknown }, { api: Record<string, unknown>; db: unknown }> = ({ ctx, next }) =>
1491
+ next({
1492
+ ctx: {
1493
+ ...ctx,
1494
+ api: { ...ctx.api, ratelimit: makeRateLimiter(ctx) },
1495
+ },
1496
+ });
1497
+
1498
+ export const ratelimit = definePlugin("ratelimit", {
1499
+ extension: defineSchemaExtension("ratelimit", {
1500
+ tables: {
1501
+ buckets: defineTable({
1502
+ key: v.string(),
1503
+ value: v.number(),
1504
+ ts: v.number(),
1505
+ prev: v.optional(v.number()),
1506
+ })
1507
+ .index("by_key", ["key"])
1508
+ .externallyManaged(),
1509
+ },
1510
+ }),
1511
+ middleware,
1512
+ });
1513
+ `;
1514
+ const LUNORA_SCHEMA = `import { ratelimit } from "./ratelimit/schema.js";
1515
+ import { defineSchema, defineTable, v } from "lunorash/server";
1474
1516
 
1475
1517
  export default defineSchema({
1476
1518
  messages: defineTable({
@@ -1479,22 +1521,17 @@ export default defineSchema({
1479
1521
  })
1480
1522
  .shardBy("channelId")
1481
1523
  .index("by_channel", ["channelId"]),
1482
- });
1524
+ }).extend(ratelimit.extension);
1483
1525
  `;
1484
- const LUNORA_MESSAGES = `import { RateLimiter, rateLimit } from "@lunora/ratelimit";
1526
+ const LUNORA_MESSAGES = `import { RateLimiter, rateLimit, createDbStore } from "lunorash/ratelimit";
1485
1527
 
1486
1528
  import { mutation, query, v } from "#lunora/_generated/server.js";
1487
1529
 
1488
- /**
1489
- * One in-memory limiter so the public \`send\` mutation isn't an open flood target
1490
- * out of the box. The default store is in-memory (per-isolate, resets on
1491
- * eviction) — fine for a starter; run \`lunora add ratelimit\` for the durable,
1492
- * \`ctx.db\`-backed store when you ship to production.
1493
- */
1494
- const limiter = new RateLimiter({
1530
+ const limiter = (ctx: { db: unknown }) => new RateLimiter({
1495
1531
  config: {
1496
1532
  send: { kind: "token bucket", period: 60_000, rate: 30 },
1497
1533
  },
1534
+ store: createDbStore({ db: ctx.db as never, table: "ratelimit_buckets" }),
1498
1535
  });
1499
1536
 
1500
1537
  export const list = query.input({ channelId: v.string().meta({ schema: { maxLength: 256 } }), limit: v.optional(v.number()) }).query(async ({ args, ctx }) => {
@@ -1620,6 +1657,7 @@ const patchBaseViteConfig = (target, logger) => {
1620
1657
  const applyLunoraOverlay = async (options) => {
1621
1658
  const { adapter, distTag, logger, name, target } = options;
1622
1659
  const written = [];
1660
+ writeFile(target, join$1("lunora", "ratelimit", "schema.ts"), RATELIMIT_SCHEMA, written);
1623
1661
  writeFile(target, join$1("lunora", "schema.ts"), LUNORA_SCHEMA, written);
1624
1662
  writeFile(target, join$1("lunora", "messages.ts"), LUNORA_MESSAGES, written);
1625
1663
  writeFile(target, join$1("src", "server.ts"), SERVER_ENTRY, written);
@@ -148,8 +148,8 @@ const resolveDepRange = (range) => {
148
148
  }
149
149
  return rest;
150
150
  };
151
- const UMBRELLA_REEXPORTED_DEPS = /* @__PURE__ */ new Set(["@lunora/client", "@lunora/do", "@lunora/runtime", "@lunora/server", "@lunora/values"]);
152
- const UMBRELLA_IMPORT_RE = /(['"])@lunora\/(client|do|runtime|server|values)(\/[^'"]*)?\1/gu;
151
+ const UMBRELLA_REEXPORTED_DEPS = /* @__PURE__ */ new Set(["@lunora/client", "@lunora/do", "@lunora/ratelimit", "@lunora/runtime", "@lunora/server", "@lunora/values"]);
152
+ const UMBRELLA_IMPORT_RE = /(['"])@lunora\/(client|do|ratelimit|runtime|server|values)(\/[^'"]*)?\1/gu;
153
153
  const projectUsesUmbrella = (projectRoot) => {
154
154
  const packageJsonPath = join(projectRoot, "package.json");
155
155
  if (!existsSync(packageJsonPath)) {
@@ -1,4 +1,4 @@
1
1
  import 'node:fs';
2
2
  import '@visulima/path';
3
- export { r as runAddCommand, a as runBuildIndexCommand, g as runListCommand, b as runRegistryViewCommand } from './commands-CF2YHeFa.mjs';
3
+ export { r as runAddCommand, a as runBuildIndexCommand, g as runListCommand, b as runRegistryViewCommand } from './commands-ClEvcz3V.mjs';
4
4
  import './buildRegistryIndex-BS5ig822.mjs';
@@ -1,4 +1,4 @@
1
- import { s as setBindingField } from './commands-CF2YHeFa.mjs';
1
+ import { s as setBindingField } from './commands-ClEvcz3V.mjs';
2
2
 
3
3
  const INVALID_SLUG_CHARS = /[^a-z0-9]+/u;
4
4
  const toKebabSlug = (input, min, max) => {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@lunora/cli",
3
- "version": "1.0.0-alpha.74",
3
+ "version": "1.0.0-alpha.75",
4
4
  "description": "The Lunora CLI: init, dev, deploy, codegen, run, reset, and migrate commands",
5
5
  "keywords": [
6
6
  "agent-skills",