rimecms 0.30.3 → 0.31.1
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/README.md +1 -39
- package/dist/.rime-modules.d.ts +23 -0
- package/dist/.rime-modules.json +1 -0
- package/dist/adapter-sqlite/generate-schema/write.server.js +6 -6
- package/dist/core/areas/config/builder.server.d.ts +0 -1
- package/dist/core/collections/auth/hooks/before-upsert/augment-fields-password.server.d.ts +1 -1
- package/dist/core/collections/config/builder.server.d.ts +0 -1
- package/dist/core/collections/upload/hooks/convert-base64.server.d.ts +1 -1
- package/dist/core/collections/upload/hooks/extract-path.server.d.ts +1 -1
- package/dist/core/collections/upload/hooks/handle-path-creation.server.d.ts +1 -1
- package/dist/core/collections/upload/hooks/process-file-upload.server.d.ts +1 -1
- package/dist/core/config/auth/better-auth.server.d.ts +3 -3
- package/dist/core/config/client/augment-plugins.d.ts +1 -5
- package/dist/core/config/client/augment-plugins.js +3 -3
- package/dist/core/config/client/build-config.d.ts +1 -5
- package/dist/core/config/config-context.server.d.ts +1 -1
- package/dist/core/config/server/augment-plugins.server.d.ts +2 -42
- package/dist/core/config/server/augment-plugins.server.js +11 -6
- package/dist/core/config/server/build-config.server.d.ts +9 -4007
- package/dist/core/config/types.d.ts +12 -11
- package/dist/core/dev/cache/index.server.js +1 -1
- package/dist/core/dev/cli/clear/index.server.js +2 -0
- package/dist/core/dev/cli/generate/index.server.js +4 -0
- package/dist/core/dev/cli/generate-manifest/index.server.d.ts +17 -0
- package/dist/core/dev/cli/generate-manifest/index.server.js +221 -0
- package/dist/core/dev/cli/index.js +42 -0
- package/dist/core/dev/cli/init/index.server.js +11 -4
- package/dist/core/dev/cli/init/templates.d.ts +1 -1
- package/dist/core/dev/cli/init/templates.js +5 -3
- package/dist/core/dev/cli/util/package-manager.server.js +5 -3
- package/dist/core/dev/constants.d.ts +10 -0
- package/dist/core/dev/constants.js +15 -0
- package/dist/core/dev/generate/routes/common.server.js +4 -7
- package/dist/core/dev/generate/routes/index.server.js +25 -4
- package/dist/core/dev/generate/runtime/index.server.d.ts +34 -14
- package/dist/core/dev/generate/runtime/index.server.js +56 -57
- package/dist/core/dev/generate/runtime/parse-exports.server.d.ts +7 -0
- package/dist/core/dev/generate/runtime/parse-exports.server.js +40 -0
- package/dist/core/dev/generate/sanitize/index.server.d.ts +0 -7
- package/dist/core/dev/generate/sanitize/index.server.js +57 -5
- package/dist/core/dev/generate/types/index.server.js +16 -39
- package/dist/core/dev/vite/index.server.d.ts +1 -0
- package/dist/core/dev/vite/index.server.js +203 -42
- package/dist/core/ensure.server.d.ts +4 -3
- package/dist/core/ensure.server.js +8 -8
- package/dist/core/handlers/index.js +2 -2
- package/dist/core/operations/hooks/before-upsert/data-config-map.server.d.ts +1 -1
- package/dist/core/operations/hooks/before-upsert/handle-new-version.server.d.ts +1 -1
- package/dist/core/operations/hooks/before-upsert/original-config-map.server.d.ts +1 -1
- package/dist/core/operations/hooks/before-upsert/set-default-values.server.d.ts +1 -1
- package/dist/core/operations/hooks/before-upsert/validate-fields.server.d.ts +1 -1
- package/dist/core/operations/hooks/index.server.d.ts +0 -4
- package/dist/core/operations/hooks/index.server.js +0 -4
- package/dist/core/plugins/api-init/index.d.ts +2 -0
- package/dist/core/plugins/api-init/index.js +1 -0
- package/dist/core/plugins/api-init/{index.server.d.ts → module.server.d.ts} +0 -1
- package/dist/core/plugins/api-init/{index.server.js → module.server.js} +0 -1
- package/dist/core/plugins/cache/index.d.ts +2 -5
- package/dist/core/plugins/cache/index.js +1 -21
- package/dist/core/plugins/cache/module.d.ts +4 -0
- package/dist/core/plugins/cache/module.js +22 -0
- package/dist/core/plugins/cache/{index.server.d.ts → module.server.d.ts} +1 -2
- package/dist/core/plugins/cache/{index.server.js → module.server.js} +0 -1
- package/dist/core/plugins/index.d.ts +1 -8
- package/dist/core/plugins/index.js +0 -3
- package/dist/core/plugins/mailer/index.d.ts +2 -0
- package/dist/core/plugins/mailer/index.js +1 -0
- package/dist/core/plugins/mailer/{index.server.d.ts → module.server.d.ts} +0 -1
- package/dist/core/plugins/mailer/{index.server.js → module.server.js} +0 -1
- package/dist/core/plugins/sse/index.d.ts +2 -0
- package/dist/core/plugins/sse/index.js +1 -0
- package/dist/core/plugins/sse/{index.server.d.ts → module.server.d.ts} +0 -1
- package/dist/core/plugins/sse/{index.server.js → module.server.js} +0 -1
- package/dist/core/rime.server.d.ts +16 -16
- package/dist/fields/link/index.js +59 -56
- package/dist/fields/relation/index.js +63 -70
- package/dist/index.d.ts +3 -3
- package/dist/index.js +3 -3
- package/dist/panel/context/config.svelte.d.ts +2 -2
- package/dist/panel/context/documentForm.svelte.d.ts +2 -2
- package/dist/panel/context/live.svelte.js +1 -1
- package/dist/panel/pages/auth/sign-in/SignIn.svelte +6 -1
- package/dist/server.d.ts +4 -4
- package/dist/server.js +4 -4
- package/dist/types.d.ts +1 -1
- package/package.json +4 -2
|
@@ -1,36 +1,94 @@
|
|
|
1
1
|
import dotenv from 'dotenv';
|
|
2
|
-
import { existsSync, rmSync } from 'node:fs';
|
|
2
|
+
import { existsSync, readFileSync, rmSync, writeFileSync } from 'node:fs';
|
|
3
3
|
import path from 'node:path';
|
|
4
4
|
import { RIME_DEV_CACHE_DIR } from '../../constant.server.js';
|
|
5
5
|
import { ensureHasInit } from '../../ensure.server.js';
|
|
6
6
|
import { logger } from '../../logger/index.server.js';
|
|
7
|
-
import {
|
|
8
|
-
import {
|
|
7
|
+
import { getPackageInfoByKey } from '../cli/util/package.server.js';
|
|
8
|
+
import { INPUT_DIR, isInstalledDependency, OUTPUT_DIR, schemaPath } from '../constants.js';
|
|
9
|
+
import { findInstalledPackageRoot, findModulePair, scanModulePairs } from '../generate/runtime/index.server.js';
|
|
10
|
+
import { parseExportNames } from '../generate/runtime/parse-exports.server.js';
|
|
9
11
|
import { sanitize } from '../generate/sanitize/index.server.js';
|
|
10
12
|
dotenv.config({ override: true });
|
|
11
13
|
const dev = process.env.NODE_ENV === 'development';
|
|
14
|
+
/** Picks the client or server side of a module.(server.)ts pair. When the requested side
|
|
15
|
+
* wasn't authored (e.g. a collection's $url/$hooks, real only server-side, imported anyway by
|
|
16
|
+
* the isomorphic index.ts a client build also needs for its field definitions), stubs each of
|
|
17
|
+
* the *other* side's export names to `undefined` instead of returning nothing — ESM does
|
|
18
|
+
* static named-export binding, so an empty module isn't enough, `import { x } from ...` throws
|
|
19
|
+
* a SyntaxError at link time if `x` isn't actually exported, it doesn't lazily become
|
|
20
|
+
* `undefined`. Harmless: server-only exports are already stripped from client-side types, so
|
|
21
|
+
* nothing client-side ever reads the stubbed value — it only has to exist. */
|
|
22
|
+
function exportFrom(entry, isServer) {
|
|
23
|
+
const target = isServer ? entry.server : entry.client;
|
|
24
|
+
if (target)
|
|
25
|
+
return `export * from '${target.replace(/\.ts$/, '.js')}';`;
|
|
26
|
+
const other = isServer ? entry.client : entry.server;
|
|
27
|
+
if (!other)
|
|
28
|
+
return '';
|
|
29
|
+
return parseExportNames(other)
|
|
30
|
+
.map((name) => name === 'default' ? 'export default undefined;' : `export const ${name} = undefined;`)
|
|
31
|
+
.join('\n');
|
|
32
|
+
}
|
|
33
|
+
/** Splits `<pkg>/<subpath>` or `@scope/<pkg>/<subpath>` into its package name and the rest —
|
|
34
|
+
* a scoped name is two path segments, a plain one is one. */
|
|
35
|
+
function splitPackageSpecifier(rest) {
|
|
36
|
+
const segments = rest.split('/');
|
|
37
|
+
const pkgName = rest.startsWith('@') ? segments.slice(0, 2).join('/') : segments[0];
|
|
38
|
+
const subpath = segments.slice(pkgName.split('/').length).join('/');
|
|
39
|
+
return { pkgName, subpath };
|
|
40
|
+
}
|
|
41
|
+
// Writes the local-dev $rime/modules barrel types from every module.(server.)ts pair under
|
|
42
|
+
// src/lib. Exported so the CLI `generate` command can call it too — its Vite server runs in
|
|
43
|
+
// middlewareMode, which never fires the `listening` event `rime()` normally hooks this to.
|
|
44
|
+
export function regenerateModulesDeclaration() {
|
|
45
|
+
const libDir = path.resolve(process.cwd(), 'src/lib');
|
|
46
|
+
const pairs = scanModulePairs(libDir);
|
|
47
|
+
const exports = Array.from(pairs.values())
|
|
48
|
+
.map((entry) => entry.server || entry.client)
|
|
49
|
+
.filter(Boolean)
|
|
50
|
+
.map((file) => `$lib/${path.relative(libDir, file).split(path.sep).join('/')}`.replace(/\.ts$/, '.js'))
|
|
51
|
+
.map((aliased) => ` export * from '${aliased}';`)
|
|
52
|
+
.join('\n');
|
|
53
|
+
writeFileSync(path.resolve(process.cwd(), 'src/rime.modules.generated.d.ts'), `declare module '$rime/modules' {\n${exports}\n}\n`);
|
|
54
|
+
}
|
|
12
55
|
export function rime() {
|
|
56
|
+
/** Two reserved names, always resolved to *the currently running app's* generated
|
|
57
|
+
* config/schema, independent of who's asking — a third-party plugin importing
|
|
58
|
+
* `$rime/config` gets the host app's config, never its own. Unrelated to the modules
|
|
59
|
+
* mechanism below (a package's own client/server split): different problem, same `$rime/`
|
|
60
|
+
* namespace only by convention. */
|
|
13
61
|
const VCoreId = '$rime/config';
|
|
14
62
|
const VSchemaId = '$rime/schema';
|
|
15
|
-
/**
|
|
16
|
-
*
|
|
17
|
-
*
|
|
18
|
-
*
|
|
19
|
-
*
|
|
20
|
-
*
|
|
21
|
-
*
|
|
22
|
-
*
|
|
23
|
-
*
|
|
24
|
-
|
|
63
|
+
/**
|
|
64
|
+
* `$rime/modules` lets a package split its code into client and server files.
|
|
65
|
+
*
|
|
66
|
+
* While developing, you can just write `$rime/modules` with no path and it scans this
|
|
67
|
+
* project's own `src/lib` for every split. Before the package is published, that gets
|
|
68
|
+
* rewritten into explicit imports like `$rime/modules/<pkg>/<path>` — so anyone installing
|
|
69
|
+
* the package never sees the bare form, only real paths.
|
|
70
|
+
*
|
|
71
|
+
* When resolving one of those explicit imports: if `<pkg>` is this same project, we read
|
|
72
|
+
* straight from `src/lib`. Otherwise it's a real dependency, so we find it in
|
|
73
|
+
* `node_modules` and read the file list it shipped.
|
|
74
|
+
*
|
|
75
|
+
*/
|
|
76
|
+
const VModulesId = '$rime/modules';
|
|
77
|
+
const VModulesPrefix = '$rime/modules/';
|
|
78
|
+
const ownPackageName = getPackageInfoByKey('name');
|
|
79
|
+
// Separates a resolved root from the original specifier inside one virtual module id — never
|
|
80
|
+
// appears in a real path or a JS specifier, so it's an unambiguous split point. Only the
|
|
81
|
+
// third-party qualified-form case needs it (the root has to travel with the id since load()
|
|
82
|
+
// doesn't receive importer); the barrel and self-reference cases carry no baked-in root.
|
|
83
|
+
const ROOT_SEP = '\x01';
|
|
25
84
|
const resolvedVModule = (name) => '\0' + name;
|
|
26
|
-
let runtimeRegistry = null;
|
|
27
|
-
const getRuntimeRegistry = () => (runtimeRegistry ??= buildRuntimeRegistry());
|
|
28
85
|
return {
|
|
29
86
|
name: 'virtual-rime',
|
|
30
87
|
configureServer(server) {
|
|
31
88
|
// Add a listener for when the server starts
|
|
32
89
|
server.httpServer?.once('listening', () => {
|
|
33
90
|
dev && ensureHasInit();
|
|
91
|
+
regenerateModulesDeclaration();
|
|
34
92
|
// Check if we need to rebuild
|
|
35
93
|
const shouldRebuild = process.argv.includes('--rebuild');
|
|
36
94
|
if (shouldRebuild && existsSync(RIME_DEV_CACHE_DIR)) {
|
|
@@ -38,11 +96,30 @@ export function rime() {
|
|
|
38
96
|
logger.info('--rebuild : node_modules/.rime folder deleted');
|
|
39
97
|
}
|
|
40
98
|
});
|
|
41
|
-
//
|
|
42
|
-
//
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
99
|
+
// module.ts/module.server.ts appearing, changing, or disappearing under this project's
|
|
100
|
+
// own src/lib — regenerate the $rime/modules declaration above so the IDE picks up the
|
|
101
|
+
// new/changed/removed split immediately. Listens on add/unlink too, unlike the config
|
|
102
|
+
// watcher below (change-only) — a new split is exactly as likely to be a brand new file
|
|
103
|
+
// as an edit to an existing one.
|
|
104
|
+
const isModuleFile = (p) => /[/\\]module(\.server)?\.ts$/.test(p) &&
|
|
105
|
+
p.includes(`${path.sep}src${path.sep}lib${path.sep}`);
|
|
106
|
+
server.watcher.on('add', (p) => isModuleFile(p) && regenerateModulesDeclaration());
|
|
107
|
+
server.watcher.on('unlink', (p) => isModuleFile(p) && regenerateModulesDeclaration());
|
|
108
|
+
server.watcher.on('change', (p) => isModuleFile(p) && regenerateModulesDeclaration());
|
|
109
|
+
// Add a watcher for sanitizing config changes and triggering schema/routes/types
|
|
110
|
+
// generation. Debounced + single-flight: a config change is rarely one file (e.g. a
|
|
111
|
+
// plugin swap copying several files under +rime/ at once) — without this, each file
|
|
112
|
+
// fires its own overlapping sanitize()+generate()+migrate() run against the same db/
|
|
113
|
+
// and sqlite file, racing each other.
|
|
114
|
+
let reloadTimer = null;
|
|
115
|
+
let reloadInFlight = null;
|
|
116
|
+
let reloadQueued = false;
|
|
117
|
+
async function runConfigReload() {
|
|
118
|
+
if (reloadInFlight) {
|
|
119
|
+
reloadQueued = true;
|
|
120
|
+
return;
|
|
121
|
+
}
|
|
122
|
+
reloadInFlight = (async () => {
|
|
46
123
|
// Sanitize the config client/server
|
|
47
124
|
try {
|
|
48
125
|
await sanitize();
|
|
@@ -53,7 +130,11 @@ export function rime() {
|
|
|
53
130
|
}
|
|
54
131
|
// Trigger generation
|
|
55
132
|
try {
|
|
56
|
-
|
|
133
|
+
// ssrLoadModule wants the real .ts file path, not a $lib/*.js-style import
|
|
134
|
+
// specifier — different consumer than configImportPaths() (used for generated
|
|
135
|
+
// source code), so computed directly here.
|
|
136
|
+
const serverConfigPath = `src/lib/${OUTPUT_DIR}/rime.config.server.ts`;
|
|
137
|
+
const mod = await server.ssrLoadModule(serverConfigPath);
|
|
57
138
|
// The config's default export is the createRime() promise; ssrLoadModule
|
|
58
139
|
// only awaits the module's synchronous evaluation, so we must await it
|
|
59
140
|
// directly to observe init errors (e.g. invalid config) here instead of
|
|
@@ -63,7 +144,25 @@ export function rime() {
|
|
|
63
144
|
catch (error) {
|
|
64
145
|
logger.error('Failed to reload the config', error.message);
|
|
65
146
|
}
|
|
147
|
+
})();
|
|
148
|
+
await reloadInFlight;
|
|
149
|
+
reloadInFlight = null;
|
|
150
|
+
if (reloadQueued) {
|
|
151
|
+
reloadQueued = false;
|
|
152
|
+
await runConfigReload();
|
|
66
153
|
}
|
|
154
|
+
}
|
|
155
|
+
server.watcher.on('change', (modulePath) => {
|
|
156
|
+
const isConfigChange = modulePath.includes(`src/lib/${INPUT_DIR}`) &&
|
|
157
|
+
!modulePath.includes(`src/lib/${OUTPUT_DIR}`);
|
|
158
|
+
if (!isConfigChange)
|
|
159
|
+
return;
|
|
160
|
+
if (reloadTimer)
|
|
161
|
+
clearTimeout(reloadTimer);
|
|
162
|
+
reloadTimer = setTimeout(() => {
|
|
163
|
+
reloadTimer = null;
|
|
164
|
+
runConfigReload();
|
|
165
|
+
}, 150);
|
|
67
166
|
});
|
|
68
167
|
},
|
|
69
168
|
config() {
|
|
@@ -83,9 +182,6 @@ export function rime() {
|
|
|
83
182
|
},
|
|
84
183
|
server: {
|
|
85
184
|
watch: {
|
|
86
|
-
// db/*.sqlite (+ its -wal/-shm sidecars) and logs/ are runtime data, not source —
|
|
87
|
-
// every write (e.g. saving a document) touches them, and without this Vite's default
|
|
88
|
-
// whole-project-root watch treats that churn as a source change and force-reloads.
|
|
89
185
|
ignored: ['**/db/**', '**/logs/**']
|
|
90
186
|
}
|
|
91
187
|
}
|
|
@@ -106,43 +202,108 @@ export function rime() {
|
|
|
106
202
|
if (module)
|
|
107
203
|
return [module];
|
|
108
204
|
}
|
|
205
|
+
if (/[/\\]module(\.server)?\.ts$/.test(file) &&
|
|
206
|
+
file.includes(`${path.sep}src${path.sep}lib${path.sep}`)) {
|
|
207
|
+
const module = invalidateVModule(VModulesId);
|
|
208
|
+
if (module)
|
|
209
|
+
return [module];
|
|
210
|
+
}
|
|
109
211
|
},
|
|
110
|
-
resolveId(id) {
|
|
212
|
+
resolveId(id, importer) {
|
|
111
213
|
if (id === VCoreId) {
|
|
112
214
|
return resolvedVModule(id);
|
|
113
215
|
}
|
|
114
216
|
if (id === VSchemaId) {
|
|
115
217
|
return resolvedVModule(id);
|
|
116
218
|
}
|
|
117
|
-
if (id
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
219
|
+
if (id === VModulesId) {
|
|
220
|
+
return resolvedVModule(id); // barrel, no root to bake in — load() always scans this project's own src/lib
|
|
221
|
+
}
|
|
222
|
+
if (id.startsWith(VModulesPrefix)) {
|
|
223
|
+
const { pkgName } = splitPackageSpecifier(id.slice(VModulesPrefix.length));
|
|
224
|
+
if (pkgName === ownPackageName) {
|
|
225
|
+
return resolvedVModule(id); // self-reference: load() scans this project's own src/lib too
|
|
226
|
+
}
|
|
227
|
+
if (!importer) {
|
|
228
|
+
throw new Error(`$rime/modules: '${id}' has no importer to resolve '${pkgName}' from`);
|
|
229
|
+
}
|
|
230
|
+
// Third-party dependency: find its installed root now, while `importer` is still
|
|
231
|
+
// available (load() doesn't receive it) — baked into the id via ROOT_SEP. Walks up
|
|
232
|
+
// node_modules directly (see findInstalledPackageRoot) rather than resolving through
|
|
233
|
+
// the package's own `exports` map — confirmed in practice that both `require.resolve`
|
|
234
|
+
// and `import.meta.resolve` gate on a condition set matching, and a package whose
|
|
235
|
+
// exports only declare conditions neither uses (rime's own included: `types`/`svelte`/
|
|
236
|
+
// `import`, no `require`/`default`) fails to resolve at all through either.
|
|
237
|
+
const pkgRoot = findInstalledPackageRoot(pkgName, path.dirname(importer));
|
|
238
|
+
return resolvedVModule(`${pkgRoot}${ROOT_SEP}${id}`);
|
|
124
239
|
}
|
|
125
240
|
return null;
|
|
126
241
|
},
|
|
127
|
-
load(id) {
|
|
242
|
+
async load(id) {
|
|
128
243
|
const isServer = this.environment?.config?.consumer === 'server';
|
|
129
244
|
if (id === resolvedVModule(VCoreId)) {
|
|
130
245
|
const corePath = isServer ? 'rimecms/config/server' : 'rimecms/config';
|
|
131
246
|
return `export * from '${corePath}';`;
|
|
132
247
|
}
|
|
133
248
|
if (id === resolvedVModule(VSchemaId) && isServer) {
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
249
|
+
// Mirrors write.server.ts (adapter-sqlite/generate-schema) — the adapter itself never
|
|
250
|
+
// needed to change for this, it already goes through this virtual module instead of a
|
|
251
|
+
// hardcoded path.
|
|
252
|
+
const schemaFilePath = schemaPath();
|
|
253
|
+
if (existsSync(schemaFilePath)) {
|
|
254
|
+
const modulePath = schemaFilePath.replace('.ts', '.js');
|
|
137
255
|
return `export * from '${modulePath}'; export { default } from '${modulePath}';`;
|
|
138
256
|
}
|
|
139
257
|
}
|
|
140
|
-
if (id
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
258
|
+
if (id === resolvedVModule(VModulesId)) {
|
|
259
|
+
// Dev-mode barrel — re-exports every module.(server.)ts pair found under this
|
|
260
|
+
// project's own src/lib, live. Never ships: prepack rewrites every '$rime/modules'
|
|
261
|
+
// import into a qualified one before publish, so this only ever runs during dev.
|
|
262
|
+
const pairs = scanModulePairs(path.resolve(process.cwd(), 'src/lib'));
|
|
263
|
+
return Array.from(pairs.values())
|
|
264
|
+
.map((entry) => exportFrom(entry, isServer))
|
|
265
|
+
.filter(Boolean)
|
|
266
|
+
.join('\n');
|
|
267
|
+
}
|
|
268
|
+
// Self-reference qualified form — resolveId returned this bare, no root baked in
|
|
269
|
+
// (matches VModulesId's shape above): resolve directly off this project's own src/lib.
|
|
270
|
+
if (id.startsWith(resolvedVModule(VModulesPrefix))) {
|
|
271
|
+
const subpath = splitPackageSpecifier(id.slice(resolvedVModule(VModulesPrefix).length)).subpath;
|
|
272
|
+
const pair = findModulePair(path.resolve(process.cwd(), 'src/lib'), subpath);
|
|
273
|
+
if (!pair)
|
|
274
|
+
throw new Error(`${id.slice(1)}: doesn't resolve under this project's own src/lib`);
|
|
275
|
+
return exportFrom(pair, isServer);
|
|
276
|
+
}
|
|
277
|
+
// Third-party qualified form — resolveId baked the resolved package root in via
|
|
278
|
+
// ROOT_SEP: read what it shipped at prepack, don't guess.
|
|
279
|
+
{
|
|
280
|
+
const modulesSepIndex = id.indexOf(ROOT_SEP);
|
|
281
|
+
const modulesSpecifier = modulesSepIndex === -1 ? '' : id.slice(modulesSepIndex + 1);
|
|
282
|
+
if (modulesSpecifier.startsWith(VModulesPrefix)) {
|
|
283
|
+
const pkgRoot = id.slice(1, modulesSepIndex);
|
|
284
|
+
const rest = modulesSpecifier.slice(VModulesPrefix.length);
|
|
285
|
+
const { pkgName, subpath } = splitPackageSpecifier(rest);
|
|
286
|
+
const distDir = path.join(pkgRoot, 'dist');
|
|
287
|
+
const manifestPath = path.join(distDir, '.rime-modules.json');
|
|
288
|
+
if (!existsSync(manifestPath)) {
|
|
289
|
+
throw new Error(`$rime/modules/${pkgName}: no manifest at ${manifestPath} — does ${pkgName} run 'rime generate-manifest' at prepack?`);
|
|
290
|
+
}
|
|
291
|
+
const manifest = JSON.parse(readFileSync(manifestPath, 'utf-8'));
|
|
292
|
+
const pair = manifest[subpath];
|
|
293
|
+
if (!pair) {
|
|
294
|
+
throw new Error(`$rime/modules/${pkgName}/${subpath}: not found in ${pkgName}'s manifest`);
|
|
295
|
+
}
|
|
296
|
+
// Manifest entries are stored relative to *that package's own* dist/ (written by
|
|
297
|
+
// generate-manifest on whatever machine packed it) - re-rooted onto distDir (this
|
|
298
|
+
// installed copy's real, resolved location) here, not trusted as absolute. An
|
|
299
|
+
// absolute path baked in at pack time would silently read the package author's own
|
|
300
|
+
// working-copy dist/ instead of what's actually installed here whenever both
|
|
301
|
+
// happen to exist on the same machine (exactly what authoring rime itself hit).
|
|
302
|
+
const resolvedPair = {
|
|
303
|
+
client: pair.client ? path.join(distDir, pair.client) : '',
|
|
304
|
+
server: pair.server ? path.join(distDir, pair.server) : ''
|
|
305
|
+
};
|
|
306
|
+
return exportFrom(resolvedPair, isServer);
|
|
146
307
|
}
|
|
147
308
|
}
|
|
148
309
|
return null;
|
|
@@ -1,14 +1,15 @@
|
|
|
1
1
|
import type { BuiltCollection } from '../types.js';
|
|
2
2
|
/**
|
|
3
|
-
* Ensure sanitize config exists
|
|
3
|
+
* Ensure sanitize config exists — the generated server config inside rime.generated/.
|
|
4
4
|
*/
|
|
5
5
|
export declare function ensureGeneratedConfig(): string;
|
|
6
6
|
/**
|
|
7
|
-
* Ensure user config exists
|
|
7
|
+
* Ensure user config exists — the src/lib/+rime/ folder convention.
|
|
8
8
|
*/
|
|
9
9
|
export declare function ensureUserConfigExist(): void;
|
|
10
10
|
/**
|
|
11
|
-
* Ensure schema exists
|
|
11
|
+
* Ensure schema exists (see adapter-sqlite/generate-schema/write.server.ts, which writes to
|
|
12
|
+
* the same path).
|
|
12
13
|
*/
|
|
13
14
|
export declare function ensureSchema(): void;
|
|
14
15
|
/**
|
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
import { existsSync, mkdirSync } from 'node:fs';
|
|
2
2
|
import path from 'node:path';
|
|
3
|
-
import { INPUT_DIR, OUTPUT_DIR } from './dev/constants.js';
|
|
3
|
+
import { INPUT_DIR, OUTPUT_DIR, schemaPath } from './dev/constants.js';
|
|
4
4
|
const projectRoot = process.cwd();
|
|
5
5
|
/**
|
|
6
|
-
* Ensure sanitize config exists
|
|
6
|
+
* Ensure sanitize config exists — the generated server config inside rime.generated/.
|
|
7
7
|
*/
|
|
8
8
|
export function ensureGeneratedConfig() {
|
|
9
9
|
const configGeneratedPath = path.resolve(projectRoot, 'src/lib', OUTPUT_DIR, 'rime.config.server.ts');
|
|
@@ -13,20 +13,20 @@ export function ensureGeneratedConfig() {
|
|
|
13
13
|
return path.join('$lib', OUTPUT_DIR, 'rime.config.server.js');
|
|
14
14
|
}
|
|
15
15
|
/**
|
|
16
|
-
* Ensure user config exists
|
|
16
|
+
* Ensure user config exists — the src/lib/+rime/ folder convention.
|
|
17
17
|
*/
|
|
18
18
|
export function ensureUserConfigExist() {
|
|
19
|
-
const
|
|
20
|
-
if (!existsSync(
|
|
19
|
+
const folderConfig = path.resolve(projectRoot, 'src/lib', INPUT_DIR, 'rime.config.server.ts');
|
|
20
|
+
if (!existsSync(folderConfig)) {
|
|
21
21
|
throw new Error('Unable to find config, did you run rime init');
|
|
22
22
|
}
|
|
23
23
|
}
|
|
24
24
|
/**
|
|
25
|
-
* Ensure schema exists
|
|
25
|
+
* Ensure schema exists (see adapter-sqlite/generate-schema/write.server.ts, which writes to
|
|
26
|
+
* the same path).
|
|
26
27
|
*/
|
|
27
28
|
export function ensureSchema() {
|
|
28
|
-
|
|
29
|
-
if (!existsSync(schemaPath)) {
|
|
29
|
+
if (!existsSync(schemaPath(projectRoot))) {
|
|
30
30
|
throw new Error('Unable to find schema, did you run rime init');
|
|
31
31
|
}
|
|
32
32
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
export declare const buildDataConfigMap: import("../index.server.js").Hook<"raw", "
|
|
1
|
+
export declare const buildDataConfigMap: import("../index.server.js").Hook<"raw", "create" | "update", "before">;
|
|
@@ -2,4 +2,4 @@
|
|
|
2
2
|
* Handles version-related operations for document updates
|
|
3
3
|
* Manages specific version updates and new version creation
|
|
4
4
|
*/
|
|
5
|
-
export declare const handleNewVersion: import("../index.server.js").Hook<"raw", "
|
|
5
|
+
export declare const handleNewVersion: import("../index.server.js").Hook<"raw", "create" | "update", "before">;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
export declare const buildOriginalDocConfigMap: import("../index.server.js").Hook<"raw", "
|
|
1
|
+
export declare const buildOriginalDocConfigMap: import("../index.server.js").Hook<"raw", "create" | "update", "before">;
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import type { Adapter } from '../../../../adapter-sqlite/index.server.js';
|
|
2
2
|
import type { FormFieldBuilder } from '../../../fields/builders/form-field-builder.js';
|
|
3
|
-
export declare const setDefaultValues: import("../index.server.js").Hook<"raw", "
|
|
3
|
+
export declare const setDefaultValues: import("../index.server.js").Hook<"raw", "create" | "update", "before">;
|
|
4
4
|
type GetDefaultValue = (args: {
|
|
5
5
|
key: string;
|
|
6
6
|
config: FormFieldBuilder;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
export declare const validateFields: import("../index.server.js").Hook<"raw", "
|
|
1
|
+
export declare const validateFields: import("../index.server.js").Hook<"raw", "create" | "update", "before">;
|
|
@@ -81,10 +81,6 @@ export declare const Hooks: {
|
|
|
81
81
|
* Creates a before delete hook
|
|
82
82
|
*/
|
|
83
83
|
beforeDelete: <S extends DocType = "raw">(handler: Hook<S, "delete", "before">) => Hook<S, "delete", "before">;
|
|
84
|
-
/**
|
|
85
|
-
* Creates an after read hook
|
|
86
|
-
*/
|
|
87
|
-
afterRead: <S extends DocType = "raw">(handler: Hook<S, "read", "after">) => Hook<S, "read", "after">;
|
|
88
84
|
/**
|
|
89
85
|
* Creates an after create hook
|
|
90
86
|
*/
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export { apiInit } from "$rime/modules/rimecms/core/plugins/api-init";
|
|
@@ -1,5 +1,2 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
readonly type: "client";
|
|
4
|
-
readonly configure: <const C extends import("../../config/types.js").SanitizedConfigClient>(config: C) => C;
|
|
5
|
-
};
|
|
1
|
+
/// <reference path="../../../.rime-modules.d.ts" />
|
|
2
|
+
export { cache } from "$rime/modules/rimecms/core/plugins/cache";
|
|
@@ -1,21 +1 @@
|
|
|
1
|
-
|
|
2
|
-
import HeaderButton from './HeaderButton.svelte';
|
|
3
|
-
export const cacheClient = definePluginClient(() => {
|
|
4
|
-
return {
|
|
5
|
-
name: 'cache/client',
|
|
6
|
-
type: 'client',
|
|
7
|
-
configure: (config) => {
|
|
8
|
-
config = {
|
|
9
|
-
...config,
|
|
10
|
-
panel: {
|
|
11
|
-
...(config.panel || {}),
|
|
12
|
-
components: {
|
|
13
|
-
...(config.panel?.components || { header: [], collectionHeader: [] }),
|
|
14
|
-
header: [...(config.panel?.components?.header || []), HeaderButton]
|
|
15
|
-
}
|
|
16
|
-
}
|
|
17
|
-
};
|
|
18
|
-
return config;
|
|
19
|
-
}
|
|
20
|
-
};
|
|
21
|
-
});
|
|
1
|
+
export { cache } from "$rime/modules/rimecms/core/plugins/cache";
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import { definePlugin } from '../index.js';
|
|
2
|
+
import HeaderButton from './HeaderButton.svelte';
|
|
3
|
+
// Signature has to match module.server.ts's — the same call site (whatever the consumer
|
|
4
|
+
// wrote in rime.config.ts) compiles against both, whichever one this build resolves to.
|
|
5
|
+
export const cache = definePlugin(() => {
|
|
6
|
+
return {
|
|
7
|
+
name: 'cache',
|
|
8
|
+
configure: (config) => {
|
|
9
|
+
config = {
|
|
10
|
+
...config,
|
|
11
|
+
panel: {
|
|
12
|
+
...(config.panel || {}),
|
|
13
|
+
components: {
|
|
14
|
+
...(config.panel?.components || { header: [], collectionHeader: [] }),
|
|
15
|
+
header: [...(config.panel?.components?.header || []), HeaderButton]
|
|
16
|
+
}
|
|
17
|
+
}
|
|
18
|
+
};
|
|
19
|
+
return config;
|
|
20
|
+
}
|
|
21
|
+
};
|
|
22
|
+
});
|
|
@@ -26,8 +26,7 @@ type CacheOptions = {
|
|
|
26
26
|
export declare const toHash: (str: string) => string;
|
|
27
27
|
export declare const cache: (options?: CacheOptions) => {
|
|
28
28
|
readonly name: "cache";
|
|
29
|
-
readonly
|
|
30
|
-
readonly configure: <const C extends import("../../config/types.js").Config>(config: C) => C;
|
|
29
|
+
readonly configure: <const C extends import("../../config/types.js").Config | import("../../config/types.js").SanitizedConfigClient>(config: C) => C;
|
|
31
30
|
readonly routes: {
|
|
32
31
|
readonly '/api/clear-cache': {
|
|
33
32
|
readonly POST: () => Response;
|
|
@@ -2,19 +2,12 @@ import type { Config, RouteConfig } from '../../types.js';
|
|
|
2
2
|
import type { Handle } from '@sveltejs/kit';
|
|
3
3
|
import type { SanitizedConfigClient } from '../config/types.js';
|
|
4
4
|
type MaybeAsyncFunction = (...args: any[]) => any | Promise<any>;
|
|
5
|
-
export type PluginClient = {
|
|
6
|
-
name: string;
|
|
7
|
-
type: 'client';
|
|
8
|
-
configure?: <const C extends SanitizedConfigClient>(config: C) => C;
|
|
9
|
-
};
|
|
10
5
|
export type Plugin = {
|
|
11
6
|
name: string;
|
|
12
|
-
|
|
13
|
-
configure?: <const C extends Config>(config: C) => C;
|
|
7
|
+
configure?: <const C extends Config | SanitizedConfigClient>(config: C) => C;
|
|
14
8
|
actions?: Record<string, MaybeAsyncFunction>;
|
|
15
9
|
routes?: Record<string, RouteConfig>;
|
|
16
10
|
handler?: Handle;
|
|
17
11
|
};
|
|
18
12
|
export declare function definePlugin<const F extends (options?: any) => Plugin>(factory: F): F;
|
|
19
|
-
export declare function definePluginClient<const F extends (options?: any) => PluginClient>(factory: F): F;
|
|
20
13
|
export {};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export { mailer } from "$rime/modules/rimecms/core/plugins/mailer";
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export { sse } from "$rime/modules/rimecms/core/plugins/sse";
|
|
@@ -2,7 +2,6 @@ import { type RequestHandler } from '@sveltejs/kit';
|
|
|
2
2
|
import { broadcast } from './broadcast.js';
|
|
3
3
|
export declare const sse: () => {
|
|
4
4
|
readonly name: "sse";
|
|
5
|
-
readonly type: "server";
|
|
6
5
|
readonly actions: {
|
|
7
6
|
readonly broadcast: (data: import("./types.js").ContentUpdatePayload) => void;
|
|
8
7
|
};
|