rimecms 0.32.1 → 0.33.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.
@@ -39,7 +39,7 @@ const RESOLVE_DEFAULT = {
39
39
  checkbox: (f) => f.get.defaultValue ?? false,
40
40
  toggle: (f) => ensureBoolean(f.get.defaultValue) ?? false,
41
41
  number: (f) => ensureNumber(f.get.defaultValue) ?? 0,
42
- date: (f) => ensureDate(f.get.defaultValue)?.getTime() ?? 0,
42
+ date: (f) => ensureDate(f.get.defaultValue) ?? new Date(0),
43
43
  link: (f) => ensureObject(f.get.defaultValue) ?? {},
44
44
  richText: (f) => ensureObject(f.get.defaultValue) ?? {},
45
45
  relation: () => ({}),
@@ -147,9 +147,19 @@ export const ${declaredTableProperty(table.slug)} = sqliteTable('${baseTableName
147
147
  */
148
148
  export const templateUniqueRequired = (field, defaultValue) => {
149
149
  const { unique, required } = field;
150
- const defaultStr = required && defaultValue !== undefined ? `.default(${JSON.stringify(defaultValue)})` : '';
150
+ const defaultStr = required && defaultValue !== undefined ? `.default(${templateDefault(defaultValue)})` : '';
151
151
  return `${unique ? '.unique()' : ''}${required ? `.notNull()${defaultStr}` : ''}`;
152
152
  };
153
+ /**
154
+ * A default value as drizzle wants it written. A timestamp column takes a `Date`, which
155
+ * drizzle-kit stores as the same integer a number would have been.
156
+ *
157
+ * ```ts
158
+ * templateDefault('') // ""
159
+ * templateDefault(new Date(0)) // new Date(0)
160
+ * ```
161
+ */
162
+ const templateDefault = (value) => value instanceof Date ? `new Date(${value.getTime()})` : JSON.stringify(value);
153
163
  /** Template rows Relation */
154
164
  /**
155
165
  * The whole schema's relations, in one declaration.
@@ -10,6 +10,7 @@ import type { Adapter } from '../adapter.js';
10
10
  import type { Hook, HookBeforeOperation } from '../pipeline/types.js';
11
11
  import type { Plugin } from '../plugins/index.js';
12
12
  import type { SMTPConfig } from '../plugins/mailer/index.server.js';
13
+ import type { SSEConfig } from '../plugins/sse/types.js';
13
14
  import type { Field } from '../../fields/types.js';
14
15
  import type { RegisterArea, RegisterCollection } from '../../index.js';
15
16
  import type { DashboardEntry } from '../../panel/pages/dashboard/types.js';
@@ -85,6 +86,15 @@ export interface Config {
85
86
  $cache?: CacheConfig;
86
87
  /** SMTP config */
87
88
  $smtp?: SMTPConfig;
89
+ /**
90
+ * The event stream at `/api/sse`: which keys a caller may listen to.
91
+ *
92
+ * @example
93
+ * ```typescript
94
+ * $sse: { access: (key, user) => key.startsWith('public:') || (key === `user:${user?.id}`) }
95
+ * ```
96
+ */
97
+ $sse?: SSEConfig;
88
98
  /** Custom API routes
89
99
  * @example
90
100
  * routes: {
@@ -5,8 +5,8 @@ import { mailer } from '../mailer/index.server.js';
5
5
  import { sse } from '../sse/index.server.js';
6
6
  /** The plugins rime adds to every config, server half. Two of the four are conditional. */
7
7
  export const defaultPlugins = (config) => [
8
- // Server Sent Events
9
- sse(),
8
+ // The event stream, `$sse` says which keys an app opens
9
+ sse(config.$sse),
10
10
  // Cache plugin, with default isEnabled: event => !event.locals.user
11
11
  cache(config.$cache || {}),
12
12
  // Init endpoint, dev only
@@ -1,18 +1,20 @@
1
1
  import type { RouteConfig } from '../../config/types.js';
2
2
  import type { CacheConfig } from '../cache/types.js';
3
3
  import type { SMTPConfig } from '../mailer/index.server.js';
4
+ import type { SSEConfig } from '../sse/types.js';
4
5
  import type { Plugin } from '../index.js';
5
6
  /**
6
7
  * What the plugin step reads off a config.
7
8
  *
8
9
  * Both halves of `defaultPlugins` take this rather than `Config` or `SanitizedConfigClient`: the
9
- * step runs on both sides, and naming either one there would pin it to a side. `$cache` and
10
- * `$smtp` are what the server half branches on; a client build reads neither, and still takes the
11
- * argument so the two halves are the same function.
10
+ * step runs on both sides, and naming either one there would pin it to a side. `$cache`, `$smtp`
11
+ * and `$sse` are what the server half reads; a client build reads none of them, and still takes
12
+ * the argument so the two halves are the same function.
12
13
  */
13
14
  export type PluginHost = {
14
15
  plugins?: Plugin[];
15
16
  $routes?: Record<string, RouteConfig>;
16
17
  $cache?: CacheConfig;
17
18
  $smtp?: SMTPConfig;
19
+ $sse?: SSEConfig;
18
20
  };
@@ -7,4 +7,4 @@
7
7
  * - The client's handler is called with that event.
8
8
  */
9
9
  export { openSse } from './client.js';
10
- export type { SSEAccess, SSEEvent, SSEHandler } from './types.js';
10
+ export type { SSEAccess, SSEConfig, SSEEvent, SSEHandler } from './types.js';
@@ -1,7 +1,7 @@
1
1
  import { emit } from './bus.server.js';
2
- import type { SSEAccess } from './types.js';
2
+ import type { SSEConfig } from './types.js';
3
3
  /**
4
- * The event stream, at `/api/sse`.
4
+ * The event stream, at `/api/sse`. Added to every config, configured by its `$sse` key.
5
5
  *
6
6
  * Send with `rime.sse.emit(key, event, payload)`, listen with `openSse(keys, handler)`.
7
7
  *
@@ -9,11 +9,10 @@ import type { SSEAccess } from './types.js';
9
9
  * otherwise, so an app opens its own deliberately rather than by leaving a default alone.
10
10
  *
11
11
  * @example
12
- * sse({ access: (key) => key.startsWith('public:') })
12
+ * // rime.config.server.ts
13
+ * $sse: { access: (key) => key.startsWith('public:') }
13
14
  */
14
- export declare const sse: (options?: {
15
- access?: SSEAccess;
16
- }) => {
15
+ export declare const sse: (options?: SSEConfig) => {
17
16
  readonly name: "sse";
18
17
  readonly actions: {
19
18
  readonly emit: (key: string, event: string, payload?: Record<string, any>) => void;
@@ -1,7 +1,7 @@
1
1
  import { definePlugin } from '../index.js';
2
2
  import { connect, emit } from './bus.server.js';
3
3
  /**
4
- * The event stream, at `/api/sse`.
4
+ * The event stream, at `/api/sse`. Added to every config, configured by its `$sse` key.
5
5
  *
6
6
  * Send with `rime.sse.emit(key, event, payload)`, listen with `openSse(keys, handler)`.
7
7
  *
@@ -9,7 +9,8 @@ import { connect, emit } from './bus.server.js';
9
9
  * otherwise, so an app opens its own deliberately rather than by leaving a default alone.
10
10
  *
11
11
  * @example
12
- * sse({ access: (key) => key.startsWith('public:') })
12
+ * // rime.config.server.ts
13
+ * $sse: { access: (key) => key.startsWith('public:') }
13
14
  */
14
15
  export const sse = definePlugin((options) => ({
15
16
  name: 'sse',
@@ -14,3 +14,8 @@ export type SSEHandler = (event: SSEEvent) => void | Promise<void>;
14
14
  * point of naming keys up front rather than filtering in the browser.
15
15
  */
16
16
  export type SSEAccess = (key: string, user?: User) => boolean;
17
+ /** The `$sse` key of the config. */
18
+ export type SSEConfig = {
19
+ /** Which keys, besides the panel's own, a caller may listen to. None without it. */
20
+ access?: SSEAccess;
21
+ };
package/dist/types.d.ts CHANGED
@@ -13,6 +13,7 @@ export type { Link } from './fields/link/types.js';
13
13
  export type { WithRelationPopulated } from './core/fields/types.js';
14
14
  export type { RouteHandlers } from './core/routes/handler.server.js';
15
15
  export type { Plugin } from './core/plugins/index.js';
16
+ export type { SSEAccess, SSEConfig } from './core/plugins/sse/types.js';
16
17
  export type { Rime, RimeContext } from './core/rime.server.js';
17
18
  export type { BlocksFieldBlockRenderTitle } from './fields/blocks/index.js';
18
19
  export type { RichTextFeature, RichTextFeatureMark, RichTextFeatureNode } from './fields/rich-text/core/types.js';
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "rimecms",
3
- "version": "0.32.1",
3
+ "version": "0.33.0",
4
4
  "homepage": "https://github.com/bienbiendev/rime",
5
5
  "packageManager": "bun@1.3.0",
6
6
  "scripts": {