@statezero/core 0.2.15 → 0.2.17

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 (139) hide show
  1. package/LICENSE +116 -116
  2. package/dist/adaptors/vue/composables.js +4 -4
  3. package/dist/cli/commands/syncActions.js +193 -187
  4. package/dist/cli/commands/syncModels.js +391 -391
  5. package/dist/core/eventReceivers.d.ts +1 -2
  6. package/dist/core/eventReceivers.js +16 -16
  7. package/dist/flavours/django/f.js +1 -1
  8. package/dist/flavours/django/model.js +1 -1
  9. package/dist/flavours/django/operationFactory.d.ts +1 -1
  10. package/dist/flavours/django/operationFactory.js +1 -1
  11. package/dist/flavours/django/serializers.d.ts +9 -0
  12. package/dist/flavours/django/serializers.js +31 -0
  13. package/dist/index.d.ts +2 -1
  14. package/dist/index.js +4 -1
  15. package/dist/syncEngine/metrics/metricOptCalcs.js +1 -1
  16. package/dist/syncEngine/registries/metricRegistry.d.ts +1 -1
  17. package/dist/syncEngine/registries/metricRegistry.js +3 -3
  18. package/dist/syncEngine/stores/metricStore.d.ts +1 -1
  19. package/dist/syncEngine/stores/metricStore.js +1 -1
  20. package/dist/syncEngine/stores/operation.d.ts +1 -1
  21. package/dist/syncEngine/stores/operation.js +1 -1
  22. package/dist/syncEngine/stores/reactivity.d.ts +3 -3
  23. package/dist/syncEngine/stores/utils.js +1 -1
  24. package/dist/syncEngine/sync.d.ts +2 -1
  25. package/dist/syncEngine/sync.js +10 -9
  26. package/package.json +126 -126
  27. package/readme.md +210 -210
  28. package/dist/actions/backend1/django_app/calculate-hash.d.ts +0 -57
  29. package/dist/actions/backend1/django_app/calculate-hash.js +0 -77
  30. package/dist/actions/backend1/django_app/get-current-username.d.ts +0 -29
  31. package/dist/actions/backend1/django_app/get-current-username.js +0 -62
  32. package/dist/actions/backend1/django_app/get-server-status.d.ts +0 -38
  33. package/dist/actions/backend1/django_app/get-server-status.js +0 -65
  34. package/dist/actions/backend1/django_app/get-user-info.d.ts +0 -44
  35. package/dist/actions/backend1/django_app/get-user-info.js +0 -67
  36. package/dist/actions/backend1/django_app/index.d.ts +0 -6
  37. package/dist/actions/backend1/django_app/index.js +0 -6
  38. package/dist/actions/backend1/django_app/process-data.d.ts +0 -51
  39. package/dist/actions/backend1/django_app/process-data.js +0 -75
  40. package/dist/actions/backend1/django_app/send-notification.d.ts +0 -55
  41. package/dist/actions/backend1/django_app/send-notification.js +0 -78
  42. package/dist/actions/backend1/index.d.ts +0 -1
  43. package/dist/actions/backend1/index.js +0 -1
  44. package/dist/actions/default/django_app/calculate-hash.d.ts +0 -57
  45. package/dist/actions/default/django_app/calculate-hash.js +0 -77
  46. package/dist/actions/default/django_app/get-current-username.d.ts +0 -29
  47. package/dist/actions/default/django_app/get-current-username.js +0 -62
  48. package/dist/actions/default/django_app/get-server-status.d.ts +0 -38
  49. package/dist/actions/default/django_app/get-server-status.js +0 -65
  50. package/dist/actions/default/django_app/get-user-info.d.ts +0 -44
  51. package/dist/actions/default/django_app/get-user-info.js +0 -67
  52. package/dist/actions/default/django_app/index.d.ts +0 -6
  53. package/dist/actions/default/django_app/index.js +0 -6
  54. package/dist/actions/default/django_app/process-data.d.ts +0 -51
  55. package/dist/actions/default/django_app/process-data.js +0 -75
  56. package/dist/actions/default/django_app/send-notification.d.ts +0 -55
  57. package/dist/actions/default/django_app/send-notification.js +0 -78
  58. package/dist/actions/default/index.d.ts +0 -1
  59. package/dist/actions/default/index.js +0 -1
  60. package/dist/actions/index.d.ts +0 -1
  61. package/dist/actions/index.js +0 -5
  62. package/dist/models/backend1/django_app/comprehensivemodel.d.ts +0 -47
  63. package/dist/models/backend1/django_app/comprehensivemodel.js +0 -71
  64. package/dist/models/backend1/django_app/custompkmodel.d.ts +0 -44
  65. package/dist/models/backend1/django_app/custompkmodel.js +0 -69
  66. package/dist/models/backend1/django_app/dailyrate.d.ts +0 -47
  67. package/dist/models/backend1/django_app/dailyrate.js +0 -71
  68. package/dist/models/backend1/django_app/deepmodellevel1.d.ts +0 -47
  69. package/dist/models/backend1/django_app/deepmodellevel1.js +0 -72
  70. package/dist/models/backend1/django_app/deepmodellevel2.d.ts +0 -47
  71. package/dist/models/backend1/django_app/deepmodellevel2.js +0 -71
  72. package/dist/models/backend1/django_app/deepmodellevel3.d.ts +0 -44
  73. package/dist/models/backend1/django_app/deepmodellevel3.js +0 -69
  74. package/dist/models/backend1/django_app/dummymodel.d.ts +0 -47
  75. package/dist/models/backend1/django_app/dummymodel.js +0 -71
  76. package/dist/models/backend1/django_app/dummyrelatedmodel.d.ts +0 -44
  77. package/dist/models/backend1/django_app/dummyrelatedmodel.js +0 -69
  78. package/dist/models/backend1/django_app/filetest.d.ts +0 -44
  79. package/dist/models/backend1/django_app/filetest.js +0 -69
  80. package/dist/models/backend1/django_app/index.d.ts +0 -16
  81. package/dist/models/backend1/django_app/index.js +0 -16
  82. package/dist/models/backend1/django_app/modelwithcustompkrelation.d.ts +0 -47
  83. package/dist/models/backend1/django_app/modelwithcustompkrelation.js +0 -71
  84. package/dist/models/backend1/django_app/namefiltercustompkmodel.d.ts +0 -44
  85. package/dist/models/backend1/django_app/namefiltercustompkmodel.js +0 -69
  86. package/dist/models/backend1/django_app/order.d.ts +0 -47
  87. package/dist/models/backend1/django_app/order.js +0 -71
  88. package/dist/models/backend1/django_app/orderitem.d.ts +0 -47
  89. package/dist/models/backend1/django_app/orderitem.js +0 -72
  90. package/dist/models/backend1/django_app/product.d.ts +0 -47
  91. package/dist/models/backend1/django_app/product.js +0 -71
  92. package/dist/models/backend1/django_app/productcategory.d.ts +0 -44
  93. package/dist/models/backend1/django_app/productcategory.js +0 -69
  94. package/dist/models/backend1/django_app/rateplan.d.ts +0 -44
  95. package/dist/models/backend1/django_app/rateplan.js +0 -69
  96. package/dist/models/backend1/fileobject.d.ts +0 -4
  97. package/dist/models/backend1/fileobject.js +0 -9
  98. package/dist/models/backend1/index.d.ts +0 -2
  99. package/dist/models/backend1/index.js +0 -2
  100. package/dist/models/default/django_app/comprehensivemodel.d.ts +0 -47
  101. package/dist/models/default/django_app/comprehensivemodel.js +0 -71
  102. package/dist/models/default/django_app/custompkmodel.d.ts +0 -44
  103. package/dist/models/default/django_app/custompkmodel.js +0 -69
  104. package/dist/models/default/django_app/dailyrate.d.ts +0 -47
  105. package/dist/models/default/django_app/dailyrate.js +0 -71
  106. package/dist/models/default/django_app/deepmodellevel1.d.ts +0 -47
  107. package/dist/models/default/django_app/deepmodellevel1.js +0 -72
  108. package/dist/models/default/django_app/deepmodellevel2.d.ts +0 -47
  109. package/dist/models/default/django_app/deepmodellevel2.js +0 -71
  110. package/dist/models/default/django_app/deepmodellevel3.d.ts +0 -44
  111. package/dist/models/default/django_app/deepmodellevel3.js +0 -69
  112. package/dist/models/default/django_app/dummymodel.d.ts +0 -47
  113. package/dist/models/default/django_app/dummymodel.js +0 -71
  114. package/dist/models/default/django_app/dummyrelatedmodel.d.ts +0 -44
  115. package/dist/models/default/django_app/dummyrelatedmodel.js +0 -69
  116. package/dist/models/default/django_app/filetest.d.ts +0 -44
  117. package/dist/models/default/django_app/filetest.js +0 -69
  118. package/dist/models/default/django_app/index.d.ts +0 -16
  119. package/dist/models/default/django_app/index.js +0 -16
  120. package/dist/models/default/django_app/modelwithcustompkrelation.d.ts +0 -47
  121. package/dist/models/default/django_app/modelwithcustompkrelation.js +0 -71
  122. package/dist/models/default/django_app/namefiltercustompkmodel.d.ts +0 -44
  123. package/dist/models/default/django_app/namefiltercustompkmodel.js +0 -69
  124. package/dist/models/default/django_app/order.d.ts +0 -47
  125. package/dist/models/default/django_app/order.js +0 -71
  126. package/dist/models/default/django_app/orderitem.d.ts +0 -47
  127. package/dist/models/default/django_app/orderitem.js +0 -72
  128. package/dist/models/default/django_app/product.d.ts +0 -47
  129. package/dist/models/default/django_app/product.js +0 -71
  130. package/dist/models/default/django_app/productcategory.d.ts +0 -44
  131. package/dist/models/default/django_app/productcategory.js +0 -69
  132. package/dist/models/default/django_app/rateplan.d.ts +0 -44
  133. package/dist/models/default/django_app/rateplan.js +0 -69
  134. package/dist/models/default/fileobject.d.ts +0 -4
  135. package/dist/models/default/fileobject.js +0 -9
  136. package/dist/models/default/index.d.ts +0 -2
  137. package/dist/models/default/index.js +0 -2
  138. package/dist/models/index.d.ts +0 -1
  139. package/dist/models/index.js +0 -5
@@ -92,149 +92,153 @@ Handlebars.registerHelper("formatJsDoc", function (text) {
92
92
  .map((line) => ` * ${line}`)
93
93
  .join("\n");
94
94
  });
95
- const JS_ACTION_TEMPLATE = `/**
96
- * This file was auto-generated. Do not make direct changes to the file.
97
- * Action: {{title}}
98
- * App: {{app}}
99
- */
100
-
101
- import axios from 'axios';
102
- import { z } from 'zod';
103
- import { configInstance, parseStateZeroError } from '{{modulePath}}';
104
-
105
- {{#if inputSchemaString}}
106
- /**
107
- * Zod schema for the input of {{functionName}}.
108
- * NOTE: This is an object schema for validating the data payload.
109
- */
110
- export const {{functionName}}InputSchema = z.object({ {{{inputSchemaString}}} });
111
- {{/if}}
112
-
113
- {{#if responseSchemaString}}
114
- /**
115
- * Zod schema for the response of {{functionName}}.
116
- */
117
- export const {{functionName}}ResponseSchema = z.object({ {{{responseSchemaString}}} });
118
- {{/if}}
119
-
120
- /**
121
- {{#if docstring}}
122
- {{{formatJsDoc docstring}}}
123
- *
124
- {{else}}
125
- * {{title}}
126
- {{/if}}
127
- {{#each tsDocParams}}
128
- * @param {{{this.type}}} {{this.name}} - {{this.description}}
129
- {{/each}}
130
- * @param {Object} [axiosOverrides] - Allows overriding Axios request parameters.
131
- * @returns {Promise<Object>} A promise that resolves with the action's result.
132
- */
133
- export async function {{functionName}}({{{jsFunctionParams}}}) {
134
- // Construct the data payload from the function arguments
135
- {{#if payloadProperties}}
136
- const payload = {
137
- {{{payloadProperties}}}
138
- };
139
- {{else}}
140
- const payload = {};
141
- {{/if}}
142
-
143
- const config = configInstance.getConfig();
144
- const backend = config.backendConfigs['{{configKey}}'];
145
-
146
- if (!backend) {
147
- throw new Error(\`No backend configuration found for key: {{configKey}}\`);
148
- }
149
-
150
- const baseUrl = backend.API_URL.replace(/\\/+$/, '');
151
- const actionUrl = \`\${baseUrl}/actions/{{actionName}}/\`;
152
- const headers = backend.getAuthHeaders ? backend.getAuthHeaders() : {};
153
-
154
- try {
155
- const response = await axios.post(actionUrl, payload, {
156
- headers: { 'Content-Type': 'application/json', ...headers },
157
- ...axiosOverrides,
158
- });
159
-
160
- {{#if responseSchemaString}}
161
- return {{functionName}}ResponseSchema.parse(response.data);
162
- {{else}}
163
- return response.data;
164
- {{/if}}
165
- } catch (error) {
166
- if (error instanceof z.ZodError) {
167
- throw new Error(\`{{title}} failed: Invalid response from server. Details: \${error.message}\`);
168
- }
169
-
170
- if (error.response && error.response.data) {
171
- const parsedError = parseStateZeroError(error.response.data);
172
-
173
- if (Error.captureStackTrace) {
174
- Error.captureStackTrace(parsedError, {{functionName}});
175
- }
176
-
177
- throw parsedError;
178
- } else if (error.request) {
179
- throw new Error(\`{{title}} failed: No response received from server.\`);
180
- } else {
181
- throw new Error(\`{{title}} failed: \${error.message}\`);
182
- }
183
- }
184
- }
185
-
186
- export default {{functionName}};
187
-
188
- {{functionName}}.actionName = '{{actionName}}';
189
- {{functionName}}.title = '{{title}}';
190
- {{functionName}}.app = {{#if app}}'{{app}}'{{else}}null{{/if}};
191
- {{functionName}}.permissions = [{{#each permissions}}'{{this}}'{{#unless @last}}, {{/unless}}{{/each}}];
192
- {{functionName}}.configKey = '{{configKey}}';
95
+ const JS_ACTION_TEMPLATE = `/**
96
+ * This file was auto-generated. Do not make direct changes to the file.
97
+ * Action: {{title}}
98
+ * App: {{app}}
99
+ */
100
+
101
+ import axios from 'axios';
102
+ import { z } from 'zod';
103
+ import { configInstance, parseStateZeroError, serializeActionPayload } from '{{modulePath}}';
104
+ import actionSchema from './{{schemaFileName}}' assert { type: 'json' };
105
+
106
+ {{#if inputSchemaString}}
107
+ /**
108
+ * Zod schema for the input of {{functionName}}.
109
+ * NOTE: This is an object schema for validating the data payload.
110
+ */
111
+ export const {{functionName}}InputSchema = z.object({ {{{inputSchemaString}}} });
112
+ {{/if}}
113
+
114
+ {{#if responseSchemaString}}
115
+ /**
116
+ * Zod schema for the response of {{functionName}}.
117
+ */
118
+ export const {{functionName}}ResponseSchema = z.object({ {{{responseSchemaString}}} });
119
+ {{/if}}
120
+
121
+ /**
122
+ {{#if docstring}}
123
+ {{{formatJsDoc docstring}}}
124
+ *
125
+ {{else}}
126
+ * {{title}}
127
+ {{/if}}
128
+ {{#each tsDocParams}}
129
+ * @param {{{this.type}}} {{this.name}} - {{this.description}}
130
+ {{/each}}
131
+ * @param {Object} [axiosOverrides] - Allows overriding Axios request parameters.
132
+ * @returns {Promise<Object>} A promise that resolves with the action's result.
133
+ */
134
+ export async function {{functionName}}({{{jsFunctionParams}}}) {
135
+ // Construct the data payload from the function arguments
136
+ {{#if payloadProperties}}
137
+ const rawPayload = {
138
+ {{{payloadProperties}}}
139
+ };
140
+ {{else}}
141
+ const rawPayload = {};
142
+ {{/if}}
143
+
144
+ // Serialize payload - handles model instances (extracts PK), files, dates, etc.
145
+ const payload = serializeActionPayload(rawPayload, actionSchema.input_properties);
146
+
147
+ const config = configInstance.getConfig();
148
+ const backend = config.backendConfigs['{{configKey}}'];
149
+
150
+ if (!backend) {
151
+ throw new Error(\`No backend configuration found for key: {{configKey}}\`);
152
+ }
153
+
154
+ const baseUrl = backend.API_URL.replace(/\\/+$/, '');
155
+ const actionUrl = \`\${baseUrl}/actions/{{actionName}}/\`;
156
+ const headers = backend.getAuthHeaders ? backend.getAuthHeaders() : {};
157
+
158
+ try {
159
+ const response = await axios.post(actionUrl, payload, {
160
+ headers: { 'Content-Type': 'application/json', ...headers },
161
+ ...axiosOverrides,
162
+ });
163
+
164
+ {{#if responseSchemaString}}
165
+ return {{functionName}}ResponseSchema.parse(response.data);
166
+ {{else}}
167
+ return response.data;
168
+ {{/if}}
169
+ } catch (error) {
170
+ if (error instanceof z.ZodError) {
171
+ throw new Error(\`{{title}} failed: Invalid response from server. Details: \${error.message}\`);
172
+ }
173
+
174
+ if (error.response && error.response.data) {
175
+ const parsedError = parseStateZeroError(error.response.data);
176
+
177
+ if (Error.captureStackTrace) {
178
+ Error.captureStackTrace(parsedError, {{functionName}});
179
+ }
180
+
181
+ throw parsedError;
182
+ } else if (error.request) {
183
+ throw new Error(\`{{title}} failed: No response received from server.\`);
184
+ } else {
185
+ throw new Error(\`{{title}} failed: \${error.message}\`);
186
+ }
187
+ }
188
+ }
189
+
190
+ export default {{functionName}};
191
+
192
+ {{functionName}}.actionName = '{{actionName}}';
193
+ {{functionName}}.title = '{{title}}';
194
+ {{functionName}}.app = {{#if app}}'{{app}}'{{else}}null{{/if}};
195
+ {{functionName}}.permissions = [{{#each permissions}}'{{this}}'{{#unless @last}}, {{/unless}}{{/each}}];
196
+ {{functionName}}.configKey = '{{configKey}}';
193
197
  `;
194
- const TS_ACTION_DECLARATION_TEMPLATE = `/**
195
- * This file was auto-generated. Do not make direct changes to the file.
196
- * Action: {{title}}
197
- * App: {{app}}
198
- */
199
- import { z } from 'zod';
200
- import { AxiosRequestConfig } from 'axios';
201
-
202
- {{#if inputTsSchemaString}}
203
- export type {{functionName}}Input = { {{{inputTsSchemaString}}} };
204
- {{/if}}
205
-
206
- {{#if responseTsSchemaString}}
207
- export type {{functionName}}Response = { {{{responseTsSchemaString}}} };
208
- {{else}}
209
- export type {{functionName}}Response = any;
210
- {{/if}}
211
-
212
- /**
213
- {{#if docstring}}
214
- {{{formatJsDoc docstring}}}
215
- *
216
- {{else}}
217
- * {{title}}
218
- {{/if}}
219
- {{#each tsDocParams}}
220
- * @param {{{this.type}}} {{this.name}} - {{this.description}}
221
- {{/each}}
222
- * @param {AxiosRequestConfig} [axiosOverrides] - Allows overriding Axios request parameters.
223
- * @returns {Promise<{{functionName}}Response>} A promise that resolves with the action's result.
224
- */
225
- export declare function {{functionName}}(
226
- {{{tsFunctionParams}}}
227
- ): Promise<{{functionName}}Response>;
228
-
229
- export default {{functionName}};
230
-
231
- export declare namespace {{functionName}} {
232
- export const actionName: string;
233
- export const title: string;
234
- export const app: string | null;
235
- export const permissions: string[];
236
- export const configKey: string;
237
- }
198
+ const TS_ACTION_DECLARATION_TEMPLATE = `/**
199
+ * This file was auto-generated. Do not make direct changes to the file.
200
+ * Action: {{title}}
201
+ * App: {{app}}
202
+ */
203
+ import { z } from 'zod';
204
+ import { AxiosRequestConfig } from 'axios';
205
+
206
+ {{#if inputTsSchemaString}}
207
+ export type {{functionName}}Input = { {{{inputTsSchemaString}}} };
208
+ {{/if}}
209
+
210
+ {{#if responseTsSchemaString}}
211
+ export type {{functionName}}Response = { {{{responseTsSchemaString}}} };
212
+ {{else}}
213
+ export type {{functionName}}Response = any;
214
+ {{/if}}
215
+
216
+ /**
217
+ {{#if docstring}}
218
+ {{{formatJsDoc docstring}}}
219
+ *
220
+ {{else}}
221
+ * {{title}}
222
+ {{/if}}
223
+ {{#each tsDocParams}}
224
+ * @param {{{this.type}}} {{this.name}} - {{this.description}}
225
+ {{/each}}
226
+ * @param {AxiosRequestConfig} [axiosOverrides] - Allows overriding Axios request parameters.
227
+ * @returns {Promise<{{functionName}}Response>} A promise that resolves with the action's result.
228
+ */
229
+ export declare function {{functionName}}(
230
+ {{{tsFunctionParams}}}
231
+ ): Promise<{{functionName}}Response>;
232
+
233
+ export default {{functionName}};
234
+
235
+ export declare namespace {{functionName}} {
236
+ export const actionName: string;
237
+ export const title: string;
238
+ export const app: string | null;
239
+ export const permissions: string[];
240
+ export const configKey: string;
241
+ }
238
242
  `;
239
243
  const jsActionTemplate = Handlebars.compile(JS_ACTION_TEMPLATE);
240
244
  const dtsActionTemplate = Handlebars.compile(TS_ACTION_DECLARATION_TEMPLATE);
@@ -444,10 +448,12 @@ async function generateActionFile(backend, actionName, actionDefinition) {
444
448
  // Always include the backend key as the top-level folder
445
449
  const outDir = path.join(backend.GENERATED_ACTIONS_DIR, backend.NAME, appName);
446
450
  await fs.mkdir(outDir, { recursive: true });
447
- const templateData = prepareActionTemplateData(modulePath, functionName, actionName, actionDefinition, backend.NAME);
448
451
  const fileName = _.kebabCase(actionName);
452
+ const schemaFileName = `${fileName}.schema.json`;
453
+ const templateData = prepareActionTemplateData(modulePath, functionName, actionName, actionDefinition, backend.NAME);
454
+ templateData.schemaFileName = schemaFileName;
449
455
  // Write the raw schema file (like models do)
450
- const schemaFilePath = path.join(outDir, `${fileName}.schema.json`);
456
+ const schemaFilePath = path.join(outDir, schemaFileName);
451
457
  await fs.writeFile(schemaFilePath, JSON.stringify(actionDefinition, null, 2));
452
458
  // Write JS and TS files
453
459
  const jsFilePath = path.join(outDir, `${fileName}.js`);
@@ -495,11 +501,11 @@ async function generateActionRegistry(generatedFiles, backendConfigs) {
495
501
  allSchemaImports.add(schemaImportStatement);
496
502
  schemasByBackend[backendKey][file.action] = schemaImportName;
497
503
  }
498
- let registryContent = `/**
499
- * This file was auto-generated. Do not make direct changes to the file.
500
- * It provides a registry of all generated actions.
501
- */
502
-
504
+ let registryContent = `/**
505
+ * This file was auto-generated. Do not make direct changes to the file.
506
+ * It provides a registry of all generated actions.
507
+ */
508
+
503
509
  `;
504
510
  // Add action imports
505
511
  registryContent += Array.from(allImports).sort().join("\n") + "\n\n";
@@ -527,35 +533,35 @@ async function generateActionRegistry(generatedFiles, backendConfigs) {
527
533
  registryContent += ` }${index < arr.length - 1 ? "," : ""}\n`;
528
534
  });
529
535
  registryContent += `};\n\n`;
530
- registryContent += `/**
531
- * Get an action function by name and config key
532
- * @param {string} actionName - The name of the action
533
- * @param {string} configKey - The backend config key
534
- * @returns {Function|null} The action function or null if not found
535
- */
536
- export function getAction(actionName, configKey) {
537
- const action = ACTION_REGISTRY[configKey]?.[actionName];
538
- if (!action) {
539
- console.warn(\`Action '\${actionName}' not found for config key '\${configKey}'.\`);
540
- return null;
541
- }
542
- return action;
543
- }
544
-
545
- /**
546
- * Get the full schema for an action
547
- * @param {string} actionName - The name of the action
548
- * @param {string} configKey - The backend config key
549
- * @returns {Object|null} The action schema or null if not found
550
- */
551
- export function getSchema(actionName, configKey) {
552
- const schema = SCHEMA_REGISTRY[configKey]?.[actionName];
553
- if (!schema) {
554
- console.warn(\`Schema for action '\${actionName}' not found for config key '\${configKey}'.\`);
555
- return null;
556
- }
557
- return schema;
558
- }
536
+ registryContent += `/**
537
+ * Get an action function by name and config key
538
+ * @param {string} actionName - The name of the action
539
+ * @param {string} configKey - The backend config key
540
+ * @returns {Function|null} The action function or null if not found
541
+ */
542
+ export function getAction(actionName, configKey) {
543
+ const action = ACTION_REGISTRY[configKey]?.[actionName];
544
+ if (!action) {
545
+ console.warn(\`Action '\${actionName}' not found for config key '\${configKey}'.\`);
546
+ return null;
547
+ }
548
+ return action;
549
+ }
550
+
551
+ /**
552
+ * Get the full schema for an action
553
+ * @param {string} actionName - The name of the action
554
+ * @param {string} configKey - The backend config key
555
+ * @returns {Object|null} The action schema or null if not found
556
+ */
557
+ export function getSchema(actionName, configKey) {
558
+ const schema = SCHEMA_REGISTRY[configKey]?.[actionName];
559
+ if (!schema) {
560
+ console.warn(\`Schema for action '\${actionName}' not found for config key '\${configKey}'.\`);
561
+ return null;
562
+ }
563
+ return schema;
564
+ }
559
565
  `;
560
566
  const registryFilePath = path.join(process.cwd(), "action-registry.js");
561
567
  await fs.writeFile(registryFilePath, registryContent);
@@ -563,8 +569,8 @@ export function getSchema(actionName, configKey) {
563
569
  }
564
570
  async function generateAppLevelIndexFiles(generatedFiles, backendConfigs) {
565
571
  const filesByBackend = _.groupBy(generatedFiles, "backend");
566
- const indexTemplate = Handlebars.compile(`{{#each files}}
567
- export * from '{{this.relativePath}}';
572
+ const indexTemplate = Handlebars.compile(`{{#each files}}
573
+ export * from '{{this.relativePath}}';
568
574
  {{/each}}`);
569
575
  for (const backendName in filesByBackend) {
570
576
  const backendFiles = filesByBackend[backendName];
@@ -583,7 +589,7 @@ export * from '{{this.relativePath}}';
583
589
  const indexContent = indexTemplate({ files: appIndexExports }).trim();
584
590
  await fs.writeFile(path.join(appDir, "index.js"), indexContent);
585
591
  await fs.writeFile(path.join(appDir, "index.d.ts"), indexContent);
586
- rootExports.push(`export * from './${appName}';`);
592
+ rootExports.push(`export * from './${appName}/index.js';`);
587
593
  }
588
594
  const rootIndexContent = rootExports.sort().join("\n");
589
595
  // Include backend key in the path for root index files
@@ -606,12 +612,12 @@ async function generateDefaultBackendIndex(backendConfigs) {
606
612
  const defaultBackend = backendConfigs['default'];
607
613
  const actionsDir = defaultBackend.GENERATED_ACTIONS_DIR;
608
614
  // Create top-level index files that re-export from default
609
- const indexContent = `/**
610
- * This file was auto-generated. Do not make direct changes to the file.
611
- * Re-exports from the 'default' backend for backwards compatibility.
612
- */
613
-
614
- export * from './default/index';
615
+ const indexContent = `/**
616
+ * This file was auto-generated. Do not make direct changes to the file.
617
+ * Re-exports from the 'default' backend for backwards compatibility.
618
+ */
619
+
620
+ export * from './default/index.js';
615
621
  `;
616
622
  const jsIndexPath = path.join(actionsDir, 'index.js');
617
623
  const dtsIndexPath = path.join(actionsDir, 'index.d.ts');