rimecms 0.32.0 → 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.
- package/dist/adapter-sqlite/generate-schema/column.server.js +1 -1
- package/dist/adapter-sqlite/generate-schema/templates.server.d.ts +7 -5
- package/dist/adapter-sqlite/generate-schema/templates.server.js +20 -7
- package/dist/core/config/types.d.ts +10 -0
- package/dist/core/dev/vite.server.js +6 -1
- package/dist/core/plugins/defaults/module.server.js +2 -2
- package/dist/core/plugins/defaults/types.d.ts +5 -3
- package/dist/core/plugins/sse/index.d.ts +1 -1
- package/dist/core/plugins/sse/index.server.d.ts +5 -6
- package/dist/core/plugins/sse/index.server.js +3 -2
- package/dist/core/plugins/sse/types.d.ts +5 -0
- package/dist/types.d.ts +1 -0
- package/package.json +1 -1
|
@@ -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)
|
|
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: () => ({}),
|
|
@@ -129,15 +129,17 @@ export declare const templateRelations: (tree: Record<string, string[]>, referen
|
|
|
129
129
|
}[]) => string;
|
|
130
130
|
/** Templates Field Relations */
|
|
131
131
|
/**
|
|
132
|
-
*
|
|
133
|
-
*
|
|
132
|
+
* The junction column pointing at one target collection. The property is keyed by the slug, which
|
|
133
|
+
* is how the adapter reads it back; the SQL column and the referenced table carry the table name.
|
|
134
134
|
*
|
|
135
|
-
*
|
|
136
|
-
*
|
|
135
|
+
* ```ts
|
|
136
|
+
* // 'medias'
|
|
137
137
|
* mediasId: text('medias_id').references(() => medias.id, { onDelete: 'cascade' })
|
|
138
|
+
* // 'eventsCategories'
|
|
139
|
+
* eventsCategoriesId: text('events_categories_id').references(() => events_categories.id, { onDelete: 'cascade' })
|
|
138
140
|
* ```
|
|
139
141
|
*/
|
|
140
|
-
export declare const templateFieldRelationColumn: (
|
|
142
|
+
export declare const templateFieldRelationColumn: (slug: string) => string;
|
|
141
143
|
/**
|
|
142
144
|
* Generates a junction table for many-to-many relationships
|
|
143
145
|
* Creates a table with references to the owner table and related tables
|
|
@@ -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(${
|
|
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.
|
|
@@ -208,16 +218,19 @@ ${entries.join(',\n')}
|
|
|
208
218
|
};
|
|
209
219
|
/** Templates Field Relations */
|
|
210
220
|
/**
|
|
211
|
-
*
|
|
212
|
-
*
|
|
221
|
+
* The junction column pointing at one target collection. The property is keyed by the slug, which
|
|
222
|
+
* is how the adapter reads it back; the SQL column and the referenced table carry the table name.
|
|
213
223
|
*
|
|
214
|
-
*
|
|
215
|
-
*
|
|
224
|
+
* ```ts
|
|
225
|
+
* // 'medias'
|
|
216
226
|
* mediasId: text('medias_id').references(() => medias.id, { onDelete: 'cascade' })
|
|
227
|
+
* // 'eventsCategories'
|
|
228
|
+
* eventsCategoriesId: text('events_categories_id').references(() => events_categories.id, { onDelete: 'cascade' })
|
|
217
229
|
* ```
|
|
218
230
|
*/
|
|
219
|
-
export const templateFieldRelationColumn = (
|
|
220
|
-
|
|
231
|
+
export const templateFieldRelationColumn = (slug) => {
|
|
232
|
+
const table = baseTableName(slug);
|
|
233
|
+
return `${slug}Id: text('${table}_id').references(() => ${table}.id, { onDelete: 'cascade' })`;
|
|
221
234
|
};
|
|
222
235
|
/**
|
|
223
236
|
* Generates a junction table for many-to-many relationships
|
|
@@ -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: {
|
|
@@ -23,7 +23,12 @@ export function regenerateModulesDeclaration() {
|
|
|
23
23
|
})
|
|
24
24
|
.filter((block) => block !== null)
|
|
25
25
|
.join('\n\n');
|
|
26
|
-
|
|
26
|
+
// Nothing to declare, no file.
|
|
27
|
+
const file = path.resolve(process.cwd(), 'src/rime.modules.generated.d.ts');
|
|
28
|
+
if (blocks)
|
|
29
|
+
writeFileSync(file, `${blocks}\n`);
|
|
30
|
+
else
|
|
31
|
+
rmSync(file, { force: true });
|
|
27
32
|
}
|
|
28
33
|
export function rime() {
|
|
29
34
|
/** Two reserved names, always resolved to *the currently running app's* generated
|
|
@@ -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
|
-
//
|
|
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`
|
|
10
|
-
* `$
|
|
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
|
};
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { emit } from './bus.server.js';
|
|
2
|
-
import type {
|
|
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
|
-
*
|
|
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
|
-
*
|
|
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';
|