rsf-zero 0.2.0 → 0.3.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.
Files changed (42) hide show
  1. package/dist/cli/build/buildClientFiles.d.ts.map +1 -1
  2. package/dist/cli/build/buildClientFiles.js +2 -1
  3. package/dist/cli/build/buildServerFiles.d.ts.map +1 -1
  4. package/dist/cli/build/buildServerFiles.js +19 -76
  5. package/dist/cli/dev/startVite.js +1 -1
  6. package/dist/cli/dev.d.ts +2 -1
  7. package/dist/cli/dev.d.ts.map +1 -1
  8. package/dist/cli/dev.js +5 -2
  9. package/dist/cli/start/createActionRoute.d.ts.map +1 -1
  10. package/dist/cli/start/createActionRoute.js +2 -1
  11. package/dist/cli/start.d.ts +2 -2
  12. package/dist/cli/start.d.ts.map +1 -1
  13. package/dist/cli/start.js +5 -2
  14. package/dist/cli.js +2 -2
  15. package/dist/transform/asRelativeImport.d.ts +1 -3
  16. package/dist/transform/asRelativeImport.d.ts.map +1 -1
  17. package/dist/transform/asRelativeImport.js +1 -3
  18. package/dist/transform/client/transformTopLevelRsf.js +1 -1
  19. package/dist/transform/server/generateActionRegistry.d.ts +3 -7
  20. package/dist/transform/server/generateActionRegistry.d.ts.map +1 -1
  21. package/dist/transform/server/generateActionRegistry.js +5 -29
  22. package/dist/utils/customRoutes.d.ts +4 -0
  23. package/dist/utils/customRoutes.d.ts.map +1 -0
  24. package/dist/utils/customRoutes.js +36 -0
  25. package/dist/utils/debug.d.ts.map +1 -0
  26. package/dist/utils/export-types.d.ts +7 -0
  27. package/dist/utils/export-types.d.ts.map +1 -0
  28. package/dist/utils/options.d.ts +7 -0
  29. package/dist/utils/options.d.ts.map +1 -0
  30. package/package.json +4 -4
  31. package/dist/debug.d.ts.map +0 -1
  32. package/dist/export-types.d.ts +0 -5
  33. package/dist/export-types.d.ts.map +0 -1
  34. package/dist/options.d.ts +0 -7
  35. package/dist/options.d.ts.map +0 -1
  36. package/dist/transform/replaceFileExt.d.ts +0 -2
  37. package/dist/transform/replaceFileExt.d.ts.map +0 -1
  38. package/dist/transform/replaceFileExt.js +0 -5
  39. /package/dist/{debug.d.ts → utils/debug.d.ts} +0 -0
  40. /package/dist/{debug.js → utils/debug.js} +0 -0
  41. /package/dist/{export-types.js → utils/export-types.js} +0 -0
  42. /package/dist/{options.js → utils/options.js} +0 -0
@@ -1 +1 @@
1
- {"version":3,"file":"buildClientFiles.d.ts","sourceRoot":"","sources":["../../../src/cli/build/buildClientFiles.ts"],"names":[],"mappings":"AAIA,OAAO,EAAC,MAAM,EAAC,MAAM,gBAAgB,CAAC;AAItC,eAAO,MAAM,gBAAgB,GAAU,SAAS,MAAM,EAAE,eAAe,CAAC,MAAM,EAAE,MAAM,KAAK,EAAE,kBAwB5F,CAAA"}
1
+ {"version":3,"file":"buildClientFiles.d.ts","sourceRoot":"","sources":["../../../src/cli/build/buildClientFiles.ts"],"names":[],"mappings":"AAIA,OAAO,EAAC,MAAM,EAAC,MAAM,gBAAgB,CAAC;AAItC,eAAO,MAAM,gBAAgB,GAAU,SAAS,MAAM,EAAE,eAAe,CAAC,MAAM,EAAE,MAAM,KAAK,EAAE,kBA0B5F,CAAA"}
@@ -2,8 +2,9 @@ import path from "path";
2
2
  import { build as viteBuild } from "vite";
3
3
  import viteReact from "@vitejs/plugin-react";
4
4
  import { transformRsfForClientPlugin } from "../../transform/client/transformRsfForClientPlugin.js";
5
- import { debug } from "../../debug.js";
5
+ import { debug } from "../../utils/debug.js";
6
6
  export const buildClientFiles = async (rootDir, onActionFound) => {
7
+ debug(`Building client files.`);
7
8
  let actionCounter = 0; // for logging
8
9
  const _onActionFound = (action) => {
9
10
  actionCounter++;
@@ -1 +1 @@
1
- {"version":3,"file":"buildServerFiles.d.ts","sourceRoot":"","sources":["../../../src/cli/build/buildServerFiles.ts"],"names":[],"mappings":"AAQA,OAAO,EAAC,MAAM,EAAC,MAAM,gBAAgB,CAAC;AAWtC,eAAO,MAAM,gBAAgB,GAAI,SAAS,MAAM,EAAE,EAAE,SAAS,MAAM,SAuBlE,CAAA"}
1
+ {"version":3,"file":"buildServerFiles.d.ts","sourceRoot":"","sources":["../../../src/cli/build/buildServerFiles.ts"],"names":[],"mappings":"AAEA,OAAO,EAAC,MAAM,EAAC,MAAM,gBAAgB,CAAC;AAKtC,eAAO,MAAM,gBAAgB,GAAI,SAAS,MAAM,EAAE,EAAE,SAAS,MAAM,SAiBlE,CAAA"}
@@ -1,89 +1,32 @@
1
1
  import path from "path";
2
2
  import fs from "fs";
3
- import { createProgram, flattenDiagnosticMessageText, ModuleKind, } from "typescript";
4
- import md5 from "md5";
5
- import * as os from "node:os";
6
- import { generateActionRegistryJs, generateActionRegistryTs, generateEmptyActionRegistryJs } from "../../transform/server/generateActionRegistry.js";
7
- import { debug } from "../../debug.js";
3
+ import { generateActionRegistryTs, generateEmptyActionRegistryTs } from "../../transform/server/generateActionRegistry.js";
4
+ import { debug } from "../../utils/debug.js";
8
5
  export const buildServerFiles = (actions, rootDir) => {
6
+ debug('Building server files.');
9
7
  const serverOutDir = path.join(rootDir, 'dist/server');
10
- const srcDir = path.join(rootDir, 'src');
11
8
  // Clear /dist/server before starting
12
9
  if (fs.existsSync(serverOutDir)) {
13
10
  fs.rmSync(serverOutDir, { recursive: true });
14
- fs.mkdirSync(serverOutDir, { recursive: true });
15
11
  }
16
- const actionRegistryJsPath = path.join(serverOutDir, 'actionRegistry.js');
12
+ fs.mkdirSync(serverOutDir, { recursive: true });
13
+ const actionRegistryPath = path.join(serverOutDir, 'actionRegistry.ts');
14
+ // Create the registry
15
+ writeRegistryFile(actions, serverOutDir, actionRegistryPath);
16
+ debug(`Built server with ${actions.length} actions to ${actionRegistryPath}.`);
17
+ };
18
+ const writeRegistryFile = (actions, serverOutDir, actionRegistryPath) => {
19
+ // This file is what the server loads. It imports all the user's actions.
20
+ // It also exports a map of the action id to the action function.
21
+ // We write this file into the user's /src directory, because we don't build, we run ts files directly.
17
22
  if (actions.length > 0) {
18
- // Compile and output all standard files, e.g. those which are imported by the user's actions
19
- buildStandardFiles(actions, serverOutDir, srcDir);
20
- // Then generate a registry file which the server will load
21
- buildRegistryFile(actions, srcDir, actionRegistryJsPath);
23
+ const registryContent = generateActionRegistryTs(actions, serverOutDir);
24
+ fs.writeFileSync(actionRegistryPath, registryContent);
25
+ debug('wrote action registry to: ' + actionRegistryPath);
22
26
  }
23
27
  else {
24
- // Create an empty registry file
25
- buildEmptyRegistryFile(actionRegistryJsPath);
26
- }
27
- debug(`Built server with ${actions.length} actions to ${serverOutDir}.`);
28
- };
29
- const buildStandardFiles = (actions, serverOutDir, srcDir) => {
30
- // Create tmp directory
31
- const tmpDir = os.tmpdir();
32
- const projectHash = md5(process.cwd());
33
- const generatedRegistryFilePath = path.join(tmpDir, `rsf-zero-registry-${projectHash}.ts`);
34
- const compilerOptions = {
35
- strict: true,
36
- module: ModuleKind.ESNext,
37
- allowSyntheticDefaultImports: true,
38
- skipLibCheck: true,
39
- rewriteRelativeImportExtensions: true,
40
- outDir: serverOutDir,
41
- rootDir: srcDir,
42
- };
43
- // Generate registry ts file
44
- const registryContent = generateActionRegistryTs(actions, tmpDir);
45
- fs.writeFileSync(generatedRegistryFilePath, registryContent);
46
- debug('wrote action registry ts file to: ' + generatedRegistryFilePath);
47
- // Create TypeScript program with the temporary file as entry point
48
- const program = createProgram([generatedRegistryFilePath], compilerOptions);
49
- // Emit the compiled files
50
- const emitResult = program.emit();
51
- debug('Built server files to: ' + serverOutDir);
52
- // Check for compilation errors
53
- const allDiagnostics = program.getSemanticDiagnostics()
54
- .concat(program.getSyntacticDiagnostics())
55
- .concat(emitResult.diagnostics);
56
- if (allDiagnostics.length > 0) {
57
- allDiagnostics.forEach(diagnostic => {
58
- if (diagnostic.file) {
59
- const { line, character } = diagnostic.file.getLineAndCharacterOfPosition(diagnostic.start);
60
- const message = flattenDiagnosticMessageText(diagnostic.messageText, '\n');
61
- console.error(`${diagnostic.file.fileName} (${line + 1},${character + 1}): ${message}`);
62
- }
63
- else {
64
- console.error(flattenDiagnosticMessageText(diagnostic.messageText, '\n'));
65
- }
66
- });
67
- if (emitResult.emitSkipped) {
68
- throw new Error('TypeScript compilation failed');
69
- }
28
+ // We still need an empty file for the server
29
+ fs.writeFileSync(actionRegistryPath, generateEmptyActionRegistryTs());
30
+ debug('wrote empty action registry to: ' + actionRegistryPath);
70
31
  }
71
32
  };
72
- const buildRegistryFile = (actions, srcDir, actionRegistryJsPath) => {
73
- // This file is what the server loads. It imports all the user's actions.
74
- // It also exports a map of the action id to the action function.
75
- //
76
- // There are two ways to build this file, one is to place it in the user's src/ directory
77
- // and use tsc to compile it and output it into dist. The other is to directly write it to
78
- // dist as a javascript file.
79
- //
80
- // The first way means we pollute the user's src/ directory, which I don't like, so instead
81
- // we do the direct option. A bit less ideal in this codebase, but a nicer DevEx for the user.
82
- fs.writeFileSync(actionRegistryJsPath, generateActionRegistryJs(actions, srcDir));
83
- debug('wrote action registry js file to: ' + actionRegistryJsPath);
84
- };
85
- const buildEmptyRegistryFile = (actionRegistryJsPath) => {
86
- // We still need an empty file for the server
87
- fs.writeFileSync(actionRegistryJsPath, generateEmptyActionRegistryJs());
88
- debug('wrote empty action registry js file to: ' + actionRegistryJsPath);
89
- };
@@ -2,7 +2,7 @@ import { createServer as createViteServer } from "vite";
2
2
  import fs from "fs";
3
3
  import viteReact from "@vitejs/plugin-react";
4
4
  import { transformRsfForClientPlugin } from "../../transform/client/transformRsfForClientPlugin.js";
5
- import { debug } from "../../debug.js";
5
+ import { debug } from "../../utils/debug.js";
6
6
  export const startVite = async ({ app, onActionFound }) => {
7
7
  debug('starting dev vite');
8
8
  const vite = await createViteServer({
package/dist/cli/dev.d.ts CHANGED
@@ -1,3 +1,4 @@
1
1
  import "dotenv/config";
2
- export declare const dev: () => Promise<void>;
2
+ import { RsfZeroConfig } from "../utils/export-types.js";
3
+ export declare const dev: (options: RsfZeroConfig) => Promise<void>;
3
4
  //# sourceMappingURL=dev.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"dev.d.ts","sourceRoot":"","sources":["../../src/cli/dev.ts"],"names":[],"mappings":"AAEA,OAAO,eAAe,CAAC;AAOvB,eAAO,MAAM,GAAG,qBA4Bf,CAAA"}
1
+ {"version":3,"file":"dev.d.ts","sourceRoot":"","sources":["../../src/cli/dev.ts"],"names":[],"mappings":"AAEA,OAAO,eAAe,CAAC;AAOvB,OAAO,EAAC,aAAa,EAAC,MAAM,0BAA0B,CAAC;AAEvD,eAAO,MAAM,GAAG,GAAU,SAAS,aAAa,kBA+B/C,CAAA"}
package/dist/cli/dev.js CHANGED
@@ -3,8 +3,9 @@ import morgan from "morgan";
3
3
  import "dotenv/config";
4
4
  import { startVite } from "./dev/startVite.js";
5
5
  import { createActionRoute } from "./start/createActionRoute.js";
6
- import { debug } from "../debug.js";
7
- export const dev = async () => {
6
+ import { debug } from "../utils/debug.js";
7
+ import { customRoutes } from "../utils/customRoutes.js";
8
+ export const dev = async (options) => {
8
9
  const app = express();
9
10
  const port = 3000;
10
11
  app.use(morgan("dev"));
@@ -20,6 +21,8 @@ export const dev = async () => {
20
21
  addToActionRegistry(action.id, actionFn);
21
22
  debug("Loaded action handler: " + action.name);
22
23
  };
24
+ // - register custom routes
25
+ await customRoutes(options, app);
23
26
  // Serve the frontend
24
27
  // - transform any actions found for the frontend
25
28
  // - and inform the onActionFound callback above
@@ -1 +1 @@
1
- {"version":3,"file":"createActionRoute.d.ts","sourceRoot":"","sources":["../../../src/cli/start/createActionRoute.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,SAAS,CAAC;AAEvC,OAAO,EAAC,MAAM,EAAE,cAAc,EAAC,MAAM,gBAAgB,CAAC;AAGtD,KAAK,UAAU,GAAG;IAChB,GAAG,EAAE,CAAC,QAAQ,EAAE,MAAM,CAAC,IAAI,CAAC,EAAE,QAAQ,EAAE,gBAAgB,KAAK,IAAI,CAAC;IAClE,GAAG,EAAE,CAAC,cAAc,EAAE,cAAc,KAAK,IAAI,CAAC;CAC/C,CAAA;AAED,eAAO,MAAM,iBAAiB,GAAI,KAAK,OAAO,KAAG,UAwChD,CAAC"}
1
+ {"version":3,"file":"createActionRoute.d.ts","sourceRoot":"","sources":["../../../src/cli/start/createActionRoute.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAC,OAAO,EAAC,MAAM,SAAS,CAAC;AAErC,OAAO,EAAC,MAAM,EAAE,cAAc,EAAC,MAAM,gBAAgB,CAAC;AAGtD,KAAK,UAAU,GAAG;IAChB,GAAG,EAAE,CAAC,QAAQ,EAAE,MAAM,CAAC,IAAI,CAAC,EAAE,QAAQ,EAAE,gBAAgB,KAAK,IAAI,CAAC;IAClE,GAAG,EAAE,CAAC,cAAc,EAAE,cAAc,KAAK,IAAI,CAAC;CAC/C,CAAA;AAED,eAAO,MAAM,iBAAiB,GAAI,KAAK,OAAO,KAAG,UAyChD,CAAC"}
@@ -1,5 +1,5 @@
1
1
  import { parse, stringify } from "superjson";
2
- import { debug } from "../../debug.js";
2
+ import { debug } from "../../utils/debug.js";
3
3
  export const createActionRoute = (app) => {
4
4
  let actionRegistry = {};
5
5
  const add = (actionId, actionFn) => {
@@ -7,6 +7,7 @@ export const createActionRoute = (app) => {
7
7
  actionRegistry[actionId] = actionFn;
8
8
  };
9
9
  const set = (newActionRegistry) => {
10
+ debug('Setting action registry: ', newActionRegistry);
10
11
  actionRegistry = newActionRegistry;
11
12
  };
12
13
  app.post("/actions/:actionId", async (req, res) => {
@@ -1,4 +1,4 @@
1
1
  import "dotenv/config";
2
- import { RsfZeroOptions } from "../export-types.ts";
3
- export declare const start: (options: RsfZeroOptions) => Promise<void>;
2
+ import { RsfZeroConfig } from "../utils/export-types.ts";
3
+ export declare const start: (options: RsfZeroConfig) => Promise<void>;
4
4
  //# sourceMappingURL=start.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"start.d.ts","sourceRoot":"","sources":["../../src/cli/start.ts"],"names":[],"mappings":"AAGA,OAAO,eAAe,CAAC;AAIvB,OAAO,EAAC,cAAc,EAAC,MAAM,oBAAoB,CAAC;AAIlD,eAAO,MAAM,KAAK,GAAU,SAAS,cAAc,kBAyBlD,CAAA"}
1
+ {"version":3,"file":"start.d.ts","sourceRoot":"","sources":["../../src/cli/start.ts"],"names":[],"mappings":"AAIA,OAAO,eAAe,CAAC;AAGvB,OAAO,EAAC,aAAa,EAAC,MAAM,0BAA0B,CAAC;AAKvD,eAAO,MAAM,KAAK,GAAU,SAAS,aAAa,kBA2BjD,CAAA"}
package/dist/cli/start.js CHANGED
@@ -11,7 +11,8 @@ import express from "express";
11
11
  import morgan from "morgan";
12
12
  import "dotenv/config";
13
13
  import { createActionRoute } from "./start/createActionRoute.js";
14
- import { debug } from "../debug.js";
14
+ import { debug } from "../utils/debug.js";
15
+ import { customRoutes } from "../utils/customRoutes.js";
15
16
  export const start = async (options) => {
16
17
  const app = express();
17
18
  const port = 3000;
@@ -25,10 +26,12 @@ export const start = async (options) => {
25
26
  // - create action route
26
27
  const { set: setActionRegistry } = createActionRoute(app);
27
28
  // - load actionRegistry dynamically
28
- const module = await import(__rewriteRelativeImportExtension(path.join(process.cwd(), 'dist/server/actionRegistry.js')));
29
+ const module = await import(__rewriteRelativeImportExtension(path.join(process.cwd(), 'dist/server/actionRegistry.ts')));
29
30
  const { actionRegistry } = module;
30
31
  // - register action handlers
31
32
  setActionRegistry(actionRegistry);
33
+ // - register custom routes
34
+ await customRoutes(options, app);
32
35
  app.listen(port, () => {
33
36
  console.log(`Server is running at http://localhost:${port}`);
34
37
  });
package/dist/cli.js CHANGED
@@ -2,14 +2,14 @@
2
2
  import { dev } from "./cli/dev.js";
3
3
  import { build } from "./cli/build.js";
4
4
  import { start } from "./cli/start.js";
5
- import { loadOptions } from "./options.js";
5
+ import { loadOptions } from "./utils/options.js";
6
6
  import { banner } from "./cli/utils.js";
7
7
  const args = process.argv.slice(2);
8
8
  const command = args[0];
9
9
  banner();
10
10
  const options = await loadOptions();
11
11
  if (command === 'dev') {
12
- await dev();
12
+ await dev(options);
13
13
  }
14
14
  else if (command === 'build') {
15
15
  await build();
@@ -6,8 +6,6 @@
6
6
  *
7
7
  * Given `/User/x/my-file.ts, /User/somewhere-else`
8
8
  * Returns `../x/my-file.ts`
9
- *
10
- * Can be passed an optional `replaceExtWith` param to replace the extension.
11
9
  */
12
- export declare const asRelativeImport: (targetPath: string, relativeToPath: string, replaceExtWith?: string) => string;
10
+ export declare const asRelativeImport: (targetPath: string, relativeToPath: string) => string;
13
11
  //# sourceMappingURL=asRelativeImport.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"asRelativeImport.d.ts","sourceRoot":"","sources":["../../src/transform/asRelativeImport.ts"],"names":[],"mappings":"AAGA;;;;;;;;;;GAUG;AACH,eAAO,MAAM,gBAAgB,GAAI,YAAY,MAAM,EAAE,gBAAgB,MAAM,EAAE,iBAAiB,MAAM,WAOnG,CAAA"}
1
+ {"version":3,"file":"asRelativeImport.d.ts","sourceRoot":"","sources":["../../src/transform/asRelativeImport.ts"],"names":[],"mappings":"AAGA;;;;;;;;GAQG;AACH,eAAO,MAAM,gBAAgB,GAAI,YAAY,MAAM,EAAE,gBAAgB,MAAM,WAO1E,CAAA"}
@@ -8,10 +8,8 @@ import path from "path";
8
8
  *
9
9
  * Given `/User/x/my-file.ts, /User/somewhere-else`
10
10
  * Returns `../x/my-file.ts`
11
- *
12
- * Can be passed an optional `replaceExtWith` param to replace the extension.
13
11
  */
14
- export const asRelativeImport = (targetPath, relativeToPath, replaceExtWith) => {
12
+ export const asRelativeImport = (targetPath, relativeToPath) => {
15
13
  const relativeToDirPath = fs.lstatSync(relativeToPath).isDirectory() ? relativeToPath : path.dirname(relativeToPath);
16
14
  const relative = path.relative(relativeToDirPath, targetPath);
17
15
  // Add leading dot slash
@@ -1,6 +1,6 @@
1
1
  import * as swc from "@swc/core";
2
2
  import { isTopLevelRsfFile } from "../isTopLevelRsfFile.js";
3
- import { debug } from "../../debug.js";
3
+ import { debug } from "../../utils/debug.js";
4
4
  import { getActionId } from "../getActionId.js";
5
5
  /**
6
6
  * Given a file that starts with 'use server', return a transformed client version of that file.
@@ -1,11 +1,7 @@
1
1
  import { Action } from "../../types.ts";
2
2
  /**
3
- * Create a typescript file that imports all actions. This can then be passed to a tsc to be processed into dist js files.
3
+ * Create a file that imports all actions.
4
4
  */
5
- export declare const generateActionRegistryTs: (actions: Action[], registryPath: string) => string;
6
- /**
7
- * Create a javascript file that imports all actions. This is used by the start command to load action functions when the server starts.
8
- */
9
- export declare const generateActionRegistryJs: (actions: Action[], relativeToDir: string) => string;
10
- export declare const generateEmptyActionRegistryJs: () => string;
5
+ export declare const generateActionRegistryTs: (actions: Action[], serverOutDir: string) => string;
6
+ export declare const generateEmptyActionRegistryTs: () => string;
11
7
  //# sourceMappingURL=generateActionRegistry.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"generateActionRegistry.d.ts","sourceRoot":"","sources":["../../../src/transform/server/generateActionRegistry.ts"],"names":[],"mappings":"AAAA,OAAO,EAAC,MAAM,EAAC,MAAM,gBAAgB,CAAC;AAKtC;;GAEG;AACH,eAAO,MAAM,wBAAwB,GAAI,SAAS,MAAM,EAAE,EAAE,cAAc,MAAM,KAAG,MAoBlF,CAAA;AAED;;GAEG;AACH,eAAO,MAAM,wBAAwB,GAAI,SAAS,MAAM,EAAE,EAAE,eAAe,MAAM,KAAG,MA2BnF,CAAA;AAED,eAAO,MAAM,6BAA6B,QAAO,MAIhD,CAAA"}
1
+ {"version":3,"file":"generateActionRegistry.d.ts","sourceRoot":"","sources":["../../../src/transform/server/generateActionRegistry.ts"],"names":[],"mappings":"AAAA,OAAO,EAAC,MAAM,EAAC,MAAM,gBAAgB,CAAC;AAGtC;;GAEG;AACH,eAAO,MAAM,wBAAwB,GAAI,SAAS,MAAM,EAAE,EAAE,cAAc,MAAM,KAAG,MA6BlF,CAAA;AAED,eAAO,MAAM,6BAA6B,QAAO,MAIhD,CAAA"}
@@ -1,16 +1,16 @@
1
1
  import { asRelativeImport } from "../asRelativeImport.js";
2
- import { replaceFileExt } from "../replaceFileExt.js";
3
2
  /**
4
- * Create a typescript file that imports all actions. This can then be passed to a tsc to be processed into dist js files.
3
+ * Create a file that imports all actions.
5
4
  */
6
- export const generateActionRegistryTs = (actions, registryPath) => {
5
+ export const generateActionRegistryTs = (actions, serverOutDir) => {
7
6
  const actionsWithRelativePaths = actions.map(action => {
8
7
  return {
9
8
  ...action,
10
- relativeSourceFilePath: asRelativeImport(action.sourceFilePath, registryPath),
9
+ relativeSourceFilePath: asRelativeImport(action.sourceFilePath, serverOutDir),
11
10
  };
12
11
  });
13
12
  let newCode = `// Generated by RSF Zero, do not modify
13
+
14
14
  `;
15
15
  for (const action of actionsWithRelativePaths) {
16
16
  if (action.name === 'default') {
@@ -19,30 +19,6 @@ export const generateActionRegistryTs = (actions, registryPath) => {
19
19
  }
20
20
  else {
21
21
  newCode += `import { ${action.name} as ${action.id} } from '${action.relativeSourceFilePath}';
22
- `;
23
- }
24
- }
25
- return newCode;
26
- };
27
- /**
28
- * Create a javascript file that imports all actions. This is used by the start command to load action functions when the server starts.
29
- */
30
- export const generateActionRegistryJs = (actions, relativeToDir) => {
31
- const actionsWithRelativePaths = actions.map(action => {
32
- return {
33
- ...action,
34
- relativeSourceFilePathAsJs: replaceFileExt(asRelativeImport(action.sourceFilePath, relativeToDir), '.js'),
35
- };
36
- });
37
- let newCode = `// Generated by RSF Zero, do not modify
38
- `;
39
- for (const action of actionsWithRelativePaths) {
40
- if (action.name === 'default') {
41
- newCode += `import ${action.id} from '${action.relativeSourceFilePathAsJs}';
42
- `;
43
- }
44
- else {
45
- newCode += `import { ${action.name} as ${action.id} } from '${action.relativeSourceFilePathAsJs}';
46
22
  `;
47
23
  }
48
24
  }
@@ -53,7 +29,7 @@ ${actionsWithRelativePaths.map(action => `"${action.id}": ${action.id},`).join('
53
29
  `;
54
30
  return newCode;
55
31
  };
56
- export const generateEmptyActionRegistryJs = () => {
32
+ export const generateEmptyActionRegistryTs = () => {
57
33
  return `// Generated by RSF Zero, do not modify
58
34
  export const actionRegistry = {};
59
35
  `;
@@ -0,0 +1,4 @@
1
+ import { Express } from "express";
2
+ import { RsfZeroConfig } from "./export-types.js";
3
+ export declare const customRoutes: (options: RsfZeroConfig, app: Express) => Promise<void>;
4
+ //# sourceMappingURL=customRoutes.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"customRoutes.d.ts","sourceRoot":"","sources":["../../src/utils/customRoutes.ts"],"names":[],"mappings":"AAAA,OAAO,EAAC,OAAO,EAAC,MAAM,SAAS,CAAC;AAEhC,OAAO,EAAC,aAAa,EAAC,MAAM,mBAAmB,CAAC;AAGhD,eAAO,MAAM,YAAY,GAAU,SAAS,aAAa,EAAE,KAAK,OAAO,kBAgCtE,CAAA"}
@@ -0,0 +1,36 @@
1
+ var __rewriteRelativeImportExtension = (this && this.__rewriteRelativeImportExtension) || function (path, preserveJsx) {
2
+ if (typeof path === "string" && /^\.\.?\//.test(path)) {
3
+ return path.replace(/\.(tsx)$|((?:\.d)?)((?:\.[^./]+?)?)\.([cm]?)ts$/i, function (m, tsx, d, ext, cm) {
4
+ return tsx ? preserveJsx ? ".jsx" : ".js" : d && (!ext || !cm) ? m : (d + ext + "." + cm.toLowerCase() + "js");
5
+ });
6
+ }
7
+ return path;
8
+ };
9
+ import path from 'path';
10
+ import { debug } from "./debug.js";
11
+ export const customRoutes = async (options, app) => {
12
+ if (options.routes) {
13
+ debug(`Routes config option found`);
14
+ if (!Array.isArray(options.routes)) {
15
+ throw new Error('Invalid routes option. Must be an array of strings.');
16
+ }
17
+ for (const routePath of options.routes) {
18
+ const absoluteRoutePath = path.isAbsolute(routePath)
19
+ ? routePath
20
+ : path.join(process.cwd(), routePath);
21
+ debug(`Loading custom route from: ${absoluteRoutePath}`);
22
+ const routeModule = await import(__rewriteRelativeImportExtension(absoluteRoutePath));
23
+ const routeExportNames = Object.keys(routeModule);
24
+ if (routeExportNames.length !== 1) {
25
+ throw new Error(`Route file ${routePath} must contain a single export.`);
26
+ }
27
+ const [firstExportName] = routeExportNames;
28
+ const firstExport = routeModule[firstExportName];
29
+ if (!(typeof firstExport === 'function')) {
30
+ throw new Error(`Route file ${routePath} must export a function`);
31
+ }
32
+ firstExport(app);
33
+ debug(`Route loaded successfully: ${routePath}`);
34
+ }
35
+ }
36
+ };
@@ -0,0 +1 @@
1
+ {"version":3,"file":"debug.d.ts","sourceRoot":"","sources":["../../src/utils/debug.ts"],"names":[],"mappings":"AAKA,eAAO,MAAM,KAAK,GAAI,SAAS,MAAM,EAAE,GAAG,OAAO,GAAG,EAAE,SAErD,CAAC"}
@@ -0,0 +1,7 @@
1
+ import type serveStatic from "serve-static";
2
+ export type { ActionRegistry } from "../types.ts";
3
+ export type RsfZeroConfig = {
4
+ startStatic?: serveStatic.ServeStaticOptions;
5
+ routes?: string[];
6
+ };
7
+ //# sourceMappingURL=export-types.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"export-types.d.ts","sourceRoot":"","sources":["../../src/utils/export-types.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,WAAW,MAAM,cAAc,CAAC;AAE5C,YAAY,EAAE,cAAc,EAAE,MAAM,aAAa,CAAC;AAElD,MAAM,MAAM,aAAa,GAAG;IAC1B,WAAW,CAAC,EAAE,WAAW,CAAC,kBAAkB,CAAC;IAC7C,MAAM,CAAC,EAAE,MAAM,EAAE,CAAC;CACnB,CAAA"}
@@ -0,0 +1,7 @@
1
+ import { RsfZeroConfig } from "./export-types.ts";
2
+ /**
3
+ * Load RSF options from rsf0-config.js at project root.
4
+ * Returns an empty object if no file is found or on safe failure.
5
+ */
6
+ export declare function loadOptions(): Promise<RsfZeroConfig>;
7
+ //# sourceMappingURL=options.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"options.d.ts","sourceRoot":"","sources":["../../src/utils/options.ts"],"names":[],"mappings":"AAIA,OAAO,EAAE,aAAa,EAAE,MAAM,mBAAmB,CAAC;AAelD;;;GAGG;AACH,wBAAsB,WAAW,IAAI,OAAO,CAAC,aAAa,CAAC,CAoB1D"}
package/package.json CHANGED
@@ -3,7 +3,7 @@
3
3
  "description": "A minimal micro-framework with React Server Functions support",
4
4
  "author": "Igor Nadj",
5
5
  "type": "module",
6
- "version": "0.2.0",
6
+ "version": "0.3.0",
7
7
  "repository": {
8
8
  "type": "git",
9
9
  "url": "https://github.com/IgorNadj/rsf-zero.git",
@@ -42,8 +42,8 @@
42
42
  "types": "./dist/lib/client.d.ts",
43
43
  "default": "./dist/lib/client.js"
44
44
  },
45
- "./server": {
46
- "types": "./dist/export-types.d.ts"
45
+ ".": {
46
+ "types": "./dist/utils/export-types.d.ts"
47
47
  }
48
48
  },
49
49
  "files": [
@@ -51,7 +51,7 @@
51
51
  ],
52
52
  "packageManager": "yarn@4.6.0",
53
53
  "engines": {
54
- "node": ">=22.14.0"
54
+ "node": ">=22.18.0"
55
55
  },
56
56
  "bin": "dist/cli.js"
57
57
  }
@@ -1 +0,0 @@
1
- {"version":3,"file":"debug.d.ts","sourceRoot":"","sources":["../src/debug.ts"],"names":[],"mappings":"AAKA,eAAO,MAAM,KAAK,GAAI,SAAS,MAAM,EAAE,GAAG,OAAO,GAAG,EAAE,SAErD,CAAC"}
@@ -1,5 +0,0 @@
1
- import type serveStatic from "serve-static";
2
- export type RsfZeroOptions = {
3
- startStatic?: serveStatic.ServeStaticOptions;
4
- };
5
- //# sourceMappingURL=export-types.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"export-types.d.ts","sourceRoot":"","sources":["../src/export-types.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,WAAW,MAAM,cAAc,CAAC;AAE5C,MAAM,MAAM,cAAc,GAAG;IAC3B,WAAW,CAAC,EAAE,WAAW,CAAC,kBAAkB,CAAC;CAC9C,CAAA"}
package/dist/options.d.ts DELETED
@@ -1,7 +0,0 @@
1
- import { RsfZeroOptions } from "./export-types.ts";
2
- /**
3
- * Load RSF options from rsf0-config.js at project root.
4
- * Returns an empty object if no file is found or on safe failure.
5
- */
6
- export declare function loadOptions(): Promise<RsfZeroOptions>;
7
- //# sourceMappingURL=options.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"options.d.ts","sourceRoot":"","sources":["../src/options.ts"],"names":[],"mappings":"AAIA,OAAO,EAAE,cAAc,EAAE,MAAM,mBAAmB,CAAC;AAenD;;;GAGG;AACH,wBAAsB,WAAW,IAAI,OAAO,CAAC,cAAc,CAAC,CAoB3D"}
@@ -1,2 +0,0 @@
1
- export declare const replaceFileExt: (path: string, newExt: string) => string;
2
- //# sourceMappingURL=replaceFileExt.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"replaceFileExt.d.ts","sourceRoot":"","sources":["../../src/transform/replaceFileExt.ts"],"names":[],"mappings":"AAGA,eAAO,MAAM,cAAc,GAAI,MAAM,MAAM,EAAE,QAAQ,MAAM,WAG1D,CAAA"}
@@ -1,5 +0,0 @@
1
- import { extname } from "./extname.js";
2
- export const replaceFileExt = (path, newExt) => {
3
- const originalExt = extname(path);
4
- return path.slice(0, -originalExt.length) + newExt;
5
- };
File without changes
File without changes
File without changes
File without changes