next-workflow-builder 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.
@@ -0,0 +1,546 @@
1
+ import {
2
+ CODEGEN_REGISTRY_FILE,
3
+ GITIGNORE_FILE,
4
+ LEADING_WHITESPACE_PATTERN,
5
+ OUTPUT_CONFIGS_FILE,
6
+ OUTPUT_FILE,
7
+ PLUGINS_DIR,
8
+ STEP_REGISTRY_FILE,
9
+ SYSTEM_INTEGRATION_TYPES,
10
+ TYPES_FILE
11
+ } from "./chunk-OQHML4II.js";
12
+ import {
13
+ computeActionId,
14
+ getAllIntegrations,
15
+ getIntegrationTypes
16
+ } from "./chunk-Z3BJJYHM.js";
17
+
18
+ // src/plugins/discover.ts
19
+ import { createJiti } from "jiti";
20
+ import { existsSync, mkdirSync, readdirSync, readFileSync, statSync, writeFileSync } from "fs";
21
+ import { dirname, join, relative } from "path";
22
+ import ts from "typescript";
23
+ async function formatCode(code) {
24
+ try {
25
+ const prettier = await import("prettier");
26
+ return await prettier.format(code, { parser: "typescript" });
27
+ } catch (error) {
28
+ console.warn(" Warning: Failed to format generated code:", error);
29
+ return code;
30
+ }
31
+ }
32
+ var generatedCodegenTemplates = /* @__PURE__ */ new Map();
33
+ function generateIndexFile(plugins) {
34
+ const imports = plugins.map((plugin) => `import "./${plugin}";`).join("\n");
35
+ const content = `/**
36
+ * Plugins Index (Auto-Generated)
37
+ *
38
+ * This file is automatically generated by scripts/discover-plugins.ts
39
+ * DO NOT EDIT MANUALLY - your changes will be overwritten!
40
+ *
41
+ * To add a new integration:
42
+ * 1. Create a new directory in plugins/ (e.g., plugins/my-integration/)
43
+ * 2. Add your plugin files (index.tsx, steps/, codegen/, etc.)
44
+ * 3. Run: pnpm discover-plugins (or it runs automatically on build)
45
+ *
46
+ * To remove an integration:
47
+ * 1. Delete the plugin directory
48
+ * 2. Run: pnpm discover-plugins (or it runs automatically on build)
49
+ */
50
+
51
+ // Side-effect imports: each plugin calls registerIntegration() on import
52
+ ${imports || "// No plugins discovered"}
53
+
54
+ // Re-export registry utilities so consuming apps can import from "@/plugins"
55
+ export {
56
+ computeActionId,
57
+ findActionById,
58
+ flattenConfigFields,
59
+ generateAIActionPrompts,
60
+ getActionsByCategory,
61
+ getAllActions,
62
+ getAllDependencies,
63
+ getAllEnvVars,
64
+ getAllIntegrations,
65
+ getCredentialMapping,
66
+ getDependenciesForActions,
67
+ getIntegration,
68
+ getIntegrationLabels,
69
+ getIntegrationTypes,
70
+ getPluginEnvVars,
71
+ getSortedIntegrationTypes,
72
+ isFieldGroup,
73
+ parseActionId,
74
+ registerIntegration,
75
+ } from "next-workflow-builder/plugins";
76
+
77
+ export type {
78
+ ActionConfigField,
79
+ ActionConfigFieldBase,
80
+ ActionConfigFieldGroup,
81
+ ActionWithFullId,
82
+ IntegrationPlugin,
83
+ PluginAction,
84
+ } from "next-workflow-builder/plugins";
85
+ `;
86
+ writeFileSync(OUTPUT_FILE, content, "utf-8");
87
+ }
88
+ async function generateTypesFile() {
89
+ const typesDir = dirname(TYPES_FILE);
90
+ if (!existsSync(typesDir)) {
91
+ mkdirSync(typesDir, { recursive: true });
92
+ }
93
+ const pluginTypes = getIntegrationTypes();
94
+ const allTypes = [...pluginTypes, ...SYSTEM_INTEGRATION_TYPES].sort();
95
+ const unionType = allTypes.map((t) => ` | "${t}"`).join("\n");
96
+ const content = `/**
97
+ * Integration Types (Auto-Generated)
98
+ *
99
+ * This file is automatically generated by scripts/discover-plugins.ts
100
+ * DO NOT EDIT MANUALLY - your changes will be overwritten!
101
+ *
102
+ * To add a new integration type:
103
+ * 1. Create a plugin in plugins/ directory, OR
104
+ * 2. Add a system integration to SYSTEM_INTEGRATION_TYPES in discover-plugins.ts
105
+ * 3. Run: pnpm discover-plugins
106
+ *
107
+ * Generated types: ${allTypes.join(", ")}
108
+ */
109
+
110
+ // Integration type union - plugins + system integrations
111
+ export type IntegrationType =
112
+ ${unionType};
113
+
114
+ // Generic config type - plugins define their own keys via formFields[].configKey
115
+ export type IntegrationConfig = Record<string, string | undefined>;
116
+ `;
117
+ writeFileSync(TYPES_FILE, content, "utf-8");
118
+ console.log(
119
+ `Generated lib/types/integration.ts with ${allTypes.length} type(s)`
120
+ );
121
+ }
122
+ function generateCodegenRegistry() {
123
+ const entries = Array.from(generatedCodegenTemplates.entries());
124
+ if (entries.length === 0) {
125
+ console.log("No codegen templates generated");
126
+ return;
127
+ }
128
+ const templateEntries = entries.map(([actionId, { template }]) => {
129
+ const escapedTemplate = template.replace(/\\/g, "\\\\").replace(/`/g, "\\`").replace(/\$\{/g, "\\${");
130
+ return ` "${actionId}": \`${escapedTemplate}\`,`;
131
+ }).join("\n\n");
132
+ const content = `/**
133
+ * Codegen Registry (Auto-Generated)
134
+ *
135
+ * This file is automatically generated by scripts/discover-plugins.ts
136
+ * DO NOT EDIT MANUALLY - your changes will be overwritten!
137
+ *
138
+ * Contains auto-generated codegen templates for steps with stepHandler.
139
+ * These templates are used when exporting workflows to standalone projects.
140
+ *
141
+ * Generated templates: ${entries.length}
142
+ */
143
+
144
+ /**
145
+ * Auto-generated codegen templates
146
+ * Maps action IDs to their generated export code templates
147
+ */
148
+ export const AUTO_GENERATED_TEMPLATES: Record<string, string> = {
149
+ ${templateEntries}
150
+ };
151
+
152
+ /**
153
+ * Get the auto-generated codegen template for an action
154
+ */
155
+ export function getAutoGeneratedTemplate(actionId: string): string | undefined {
156
+ return AUTO_GENERATED_TEMPLATES[actionId];
157
+ }
158
+ `;
159
+ writeFileSync(CODEGEN_REGISTRY_FILE, content, "utf-8");
160
+ console.log(
161
+ `Generated lib/codegen-registry.ts with ${entries.length} template(s)`
162
+ );
163
+ }
164
+ async function generateStepRegistry() {
165
+ const integrations = getAllIntegrations();
166
+ const stepEntries = [];
167
+ for (const integration of integrations) {
168
+ for (const action of integration.actions) {
169
+ const fullActionId = computeActionId(integration.type, action.slug);
170
+ stepEntries.push({
171
+ actionId: fullActionId,
172
+ label: action.label,
173
+ integration: integration.type,
174
+ stepImportPath: action.stepImportPath,
175
+ stepFunction: action.stepFunction
176
+ });
177
+ }
178
+ }
179
+ const importerEntries = stepEntries.flatMap(({ actionId, integration, stepImportPath, stepFunction }) => {
180
+ return [
181
+ ` "${actionId}": {
182
+ importer: () => import("@/plugins/${integration}/steps/${stepImportPath}"),
183
+ stepFunction: "${stepFunction}",
184
+ },`
185
+ ];
186
+ }).join("\n");
187
+ const labelEntries = stepEntries.map(({ actionId, label }) => ` "${actionId}": "${label}",`).join("\n");
188
+ const content = `/**
189
+ * Step Registry (Auto-Generated)
190
+ *
191
+ * This file is automatically generated by scripts/discover-plugins.ts
192
+ * DO NOT EDIT MANUALLY - your changes will be overwritten!
193
+ *
194
+ * This registry enables dynamic step imports that are statically analyzable
195
+ * by the bundler. Each action type maps to its step importer function.
196
+ *
197
+ * Generated entries: ${stepEntries.length}
198
+ */
199
+
200
+ // biome-ignore lint/suspicious/noExplicitAny: Dynamic step module types - step functions take any input
201
+ export type StepFunction = (input: any) => Promise<any>;
202
+
203
+ // Step modules may contain the step function plus other exports (types, constants, etc.)
204
+ // biome-ignore lint/suspicious/noExplicitAny: Dynamic module with mixed exports
205
+ export type StepModule = Record<string, any>;
206
+
207
+ export type StepImporter = {
208
+ importer: () => Promise<StepModule>;
209
+ stepFunction: string;
210
+ };
211
+
212
+ /**
213
+ * Plugin step importers - maps action types to their step import functions
214
+ * These imports are statically analyzable by the bundler
215
+ */
216
+ export const PLUGIN_STEP_IMPORTERS: Record<string, StepImporter> = {
217
+ ${importerEntries}
218
+ };
219
+
220
+ /**
221
+ * Action labels - maps action IDs to human-readable labels
222
+ * Used for displaying friendly names in the UI (e.g., Runs tab)
223
+ */
224
+ export const ACTION_LABELS: Record<string, string> = {
225
+ ${labelEntries}
226
+ };
227
+
228
+ /**
229
+ * Get a step importer for an action type
230
+ */
231
+ export function getStepImporter(actionType: string): StepImporter | undefined {
232
+ return PLUGIN_STEP_IMPORTERS[actionType];
233
+ }
234
+
235
+ /**
236
+ * Get the human-readable label for an action type
237
+ */
238
+ export function getActionLabel(actionType: string): string | undefined {
239
+ return ACTION_LABELS[actionType];
240
+ }
241
+ `;
242
+ writeFileSync(STEP_REGISTRY_FILE, content, "utf-8");
243
+ console.log(
244
+ `Generated lib/step-registry.ts with ${stepEntries.length} step(s)`
245
+ );
246
+ }
247
+ async function generateOutputDisplayConfigs() {
248
+ const integrations = getAllIntegrations();
249
+ const outputConfigs = [];
250
+ for (const integration of integrations) {
251
+ for (const action of integration.actions) {
252
+ if (action.outputConfig && action.outputConfig.type !== "component") {
253
+ outputConfigs.push({
254
+ actionId: computeActionId(integration.type, action.slug),
255
+ type: action.outputConfig.type,
256
+ field: action.outputConfig.field
257
+ });
258
+ }
259
+ }
260
+ }
261
+ const outputConfigEntries = outputConfigs.map(
262
+ ({ actionId, type, field }) => ` "${actionId}": { type: "${type}", field: "${field}" },`
263
+ ).join("\n");
264
+ const content = `/**
265
+ * Output Display Configs (Auto-Generated)
266
+ *
267
+ * This file is automatically generated by scripts/discover-plugins.ts
268
+ * DO NOT EDIT MANUALLY - your changes will be overwritten!
269
+ *
270
+ * This file is CLIENT-SAFE and can be imported in client components.
271
+ * It maps action IDs to their output display configuration.
272
+ *
273
+ * Generated configs: ${outputConfigs.length}
274
+ */
275
+
276
+ export type OutputDisplayConfig = {
277
+ type: "image" | "video" | "url";
278
+ field: string;
279
+ };
280
+
281
+ /**
282
+ * Output display configs - maps action IDs to their display configuration
283
+ * Used for rendering outputs in the workflow runs panel
284
+ */
285
+ export const OUTPUT_DISPLAY_CONFIGS: Record<string, OutputDisplayConfig> = {
286
+ ${outputConfigEntries}
287
+ };
288
+
289
+ /**
290
+ * Get the output display config for an action type
291
+ */
292
+ export function getOutputDisplayConfig(actionType: string): OutputDisplayConfig | undefined {
293
+ return OUTPUT_DISPLAY_CONFIGS[actionType];
294
+ }
295
+ `;
296
+ writeFileSync(OUTPUT_CONFIGS_FILE, content, "utf-8");
297
+ console.log(
298
+ `Generated lib/output-display-configs.ts with ${outputConfigs.length} config(s)`
299
+ );
300
+ }
301
+ function shouldIncludeImport(moduleSpec, importText) {
302
+ if (moduleSpec.startsWith("@/") || moduleSpec.startsWith(".")) {
303
+ return false;
304
+ }
305
+ if (importText.includes("server-only")) {
306
+ return false;
307
+ }
308
+ return true;
309
+ }
310
+ function extractFunctionInfo(node, sourceCode) {
311
+ if (!(node.name && node.body)) {
312
+ return null;
313
+ }
314
+ const params = node.parameters.map((p) => sourceCode.slice(p.pos, p.end).trim()).join(", ");
315
+ const returnType = node.type ? sourceCode.slice(node.type.pos, node.type.end).trim() : "Promise<unknown>";
316
+ const body = sourceCode.slice(node.body.pos, node.body.end).trim();
317
+ return {
318
+ name: node.name.text,
319
+ params,
320
+ returnType,
321
+ body
322
+ };
323
+ }
324
+ function createEmptyAnalysis() {
325
+ return {
326
+ hasExportCore: false,
327
+ integrationType: null,
328
+ coreFunction: null,
329
+ inputTypes: [],
330
+ imports: []
331
+ };
332
+ }
333
+ function processExportedVariable(decl, result) {
334
+ if (!ts.isIdentifier(decl.name)) {
335
+ return;
336
+ }
337
+ const name = decl.name.text;
338
+ const init = decl.initializer;
339
+ if (name === "_integrationType" && init && ts.isStringLiteral(init)) {
340
+ result.integrationType = init.text;
341
+ }
342
+ }
343
+ function processVariableStatement(node, result) {
344
+ const isExported = node.modifiers?.some(
345
+ (m) => m.kind === ts.SyntaxKind.ExportKeyword
346
+ );
347
+ if (!isExported) {
348
+ return;
349
+ }
350
+ for (const decl of node.declarationList.declarations) {
351
+ processExportedVariable(decl, result);
352
+ }
353
+ }
354
+ function shouldIncludeType(typeName) {
355
+ return typeName.endsWith("Result") || typeName.endsWith("Credentials") || typeName.endsWith("CoreInput");
356
+ }
357
+ function processTypeAlias(node, sourceCode, result) {
358
+ if (shouldIncludeType(node.name.text)) {
359
+ result.inputTypes.push(sourceCode.slice(node.pos, node.end).trim());
360
+ }
361
+ }
362
+ function processImportDeclaration(node, sourceCode, result) {
363
+ const spec = node.moduleSpecifier;
364
+ if (!ts.isStringLiteral(spec)) {
365
+ return;
366
+ }
367
+ const importText = sourceCode.slice(node.pos, node.end).trim();
368
+ if (shouldIncludeImport(spec.text, importText)) {
369
+ result.imports.push(importText);
370
+ }
371
+ }
372
+ function processNode(node, sourceCode, result) {
373
+ if (ts.isVariableStatement(node)) {
374
+ processVariableStatement(node, result);
375
+ return;
376
+ }
377
+ if (ts.isTypeAliasDeclaration(node)) {
378
+ processTypeAlias(node, sourceCode, result);
379
+ return;
380
+ }
381
+ if (ts.isImportDeclaration(node)) {
382
+ processImportDeclaration(node, sourceCode, result);
383
+ return;
384
+ }
385
+ if (ts.isFunctionDeclaration(node) && node.name?.text === "stepHandler") {
386
+ result.hasExportCore = true;
387
+ result.coreFunction = extractFunctionInfo(node, sourceCode);
388
+ }
389
+ }
390
+ function analyzeStepFile(filePath) {
391
+ const result = createEmptyAnalysis();
392
+ if (!existsSync(filePath)) {
393
+ return result;
394
+ }
395
+ const sourceCode = readFileSync(filePath, "utf-8");
396
+ const sourceFile = ts.createSourceFile(
397
+ filePath,
398
+ sourceCode,
399
+ ts.ScriptTarget.Latest,
400
+ true
401
+ );
402
+ ts.forEachChild(sourceFile, (node) => {
403
+ processNode(node, sourceCode, result);
404
+ });
405
+ return result;
406
+ }
407
+ async function generateCodegenTemplate(stepFilePath, stepFunctionName) {
408
+ const analysis = analyzeStepFile(stepFilePath);
409
+ if (!(analysis.hasExportCore && analysis.coreFunction)) {
410
+ return null;
411
+ }
412
+ const { coreFunction, integrationType, inputTypes, imports } = analysis;
413
+ let innerBody = coreFunction.body.trim();
414
+ if (innerBody.startsWith("{")) {
415
+ innerBody = innerBody.slice(1);
416
+ }
417
+ if (innerBody.endsWith("}")) {
418
+ innerBody = innerBody.slice(0, -1);
419
+ }
420
+ innerBody = innerBody.trim();
421
+ const inputType = coreFunction.params.split(",")[0].replace(LEADING_WHITESPACE_PATTERN, "").split(":")[1]?.trim() || "unknown";
422
+ const rawTemplate = `${imports.join("\n")}
423
+ import { fetchCredentials } from './lib/credential-helper';
424
+
425
+ function getErrorMessage(error: unknown): string {
426
+ if (error instanceof Error) return error.message;
427
+ return String(error);
428
+ }
429
+
430
+ ${inputTypes.join("\n\n")}
431
+
432
+ export async function ${stepFunctionName}(input: ${inputType}): ${coreFunction.returnType} {
433
+ "use step";
434
+ const credentials = await fetchCredentials("${integrationType || "unknown"}");
435
+ ${innerBody}
436
+ }`;
437
+ return await formatCode(rawTemplate);
438
+ }
439
+ async function processStepFilesForCodegen() {
440
+ const integrations = getAllIntegrations();
441
+ for (const integration of integrations) {
442
+ for (const action of integration.actions) {
443
+ const stepFilePath = join(
444
+ PLUGINS_DIR,
445
+ integration.type,
446
+ "steps",
447
+ `${action.stepImportPath}.ts`
448
+ );
449
+ const template = await generateCodegenTemplate(
450
+ stepFilePath,
451
+ action.stepFunction
452
+ );
453
+ if (template) {
454
+ const actionId = computeActionId(integration.type, action.slug);
455
+ generatedCodegenTemplates.set(actionId, {
456
+ template,
457
+ integrationType: integration.type
458
+ });
459
+ console.log(` Generated codegen template for ${actionId}`);
460
+ }
461
+ }
462
+ }
463
+ }
464
+ function ensureGitignore() {
465
+ const SECTION_HEADER = "\n# Auto-generated by discover-plugins";
466
+ const filesToIgnore = [
467
+ TYPES_FILE,
468
+ CODEGEN_REGISTRY_FILE,
469
+ STEP_REGISTRY_FILE,
470
+ OUTPUT_CONFIGS_FILE,
471
+ OUTPUT_FILE
472
+ ];
473
+ const relativePaths = filesToIgnore.map((file) => relative(process.cwd(), file));
474
+ let content = "";
475
+ if (existsSync(GITIGNORE_FILE)) {
476
+ content = readFileSync(GITIGNORE_FILE, "utf-8");
477
+ }
478
+ const existingLines = new Set(content.split("\n").map((line) => line.trim()));
479
+ const newEntries = relativePaths.filter((entry) => !existingLines.has(entry));
480
+ if (newEntries.length > 0) {
481
+ let textToAppend = "";
482
+ if (content.length > 0 && !content.endsWith("\n")) {
483
+ textToAppend += "\n";
484
+ }
485
+ if (!content.includes(SECTION_HEADER)) {
486
+ textToAppend += `${SECTION_HEADER}
487
+ `;
488
+ }
489
+ textToAppend += newEntries.join("\n") + "\n";
490
+ writeFileSync(GITIGNORE_FILE, content + textToAppend, "utf-8");
491
+ console.log(`Updated .gitignore with ${newEntries.length} new file(s).`);
492
+ }
493
+ }
494
+ async function discoverPlugins() {
495
+ console.log("Discovering plugins...");
496
+ const entries = readdirSync(PLUGINS_DIR);
497
+ const plugins = entries.filter((entry) => {
498
+ if (entry.startsWith("_") || entry.startsWith(".") || entry === "index.ts" || entry === "registry.ts") {
499
+ return false;
500
+ }
501
+ const fullPath = join(PLUGINS_DIR, entry);
502
+ try {
503
+ return statSync(fullPath).isDirectory();
504
+ } catch {
505
+ return false;
506
+ }
507
+ }).sort();
508
+ if (plugins.length === 0) {
509
+ console.log("No plugins found in plugins/ directory");
510
+ } else {
511
+ console.log(`Found ${plugins.length} plugin(s):`);
512
+ for (const plugin of plugins) {
513
+ console.log(` - ${plugin}`);
514
+ }
515
+ }
516
+ ensureGitignore();
517
+ console.log("Generating plugins/index.ts...");
518
+ generateIndexFile(plugins);
519
+ if (plugins.length > 0) {
520
+ console.log("Registering plugins...\n");
521
+ const jiti = createJiti(import.meta.url, { jsx: true });
522
+ for (const plugin of plugins) {
523
+ try {
524
+ await jiti.import(join(PLUGINS_DIR, plugin));
525
+ console.log(` Registered: ${plugin}`);
526
+ } catch (error) {
527
+ console.warn(` Warning: Failed to import plugin ${plugin}:`, error);
528
+ }
529
+ }
530
+ }
531
+ console.log("Generating lib/types/integration.ts...");
532
+ await generateTypesFile();
533
+ console.log("Generating lib/step-registry.ts...");
534
+ await generateStepRegistry();
535
+ console.log("Generating lib/output-display-configs.ts...");
536
+ await generateOutputDisplayConfigs();
537
+ console.log("\nProcessing step files for codegen templates...");
538
+ await processStepFilesForCodegen();
539
+ console.log("Generating lib/codegen-registry.ts...");
540
+ generateCodegenRegistry();
541
+ console.log("Done! Plugin registry updated.\n");
542
+ }
543
+
544
+ export {
545
+ discoverPlugins
546
+ };
@@ -0,0 +1,51 @@
1
+ import {
2
+ getIntegrationById
3
+ } from "./chunk-BNYDOC3I.js";
4
+ import {
5
+ getCredentialMapping,
6
+ getIntegration
7
+ } from "./chunk-Z3BJJYHM.js";
8
+
9
+ // src/server/lib/credential-fetcher.ts
10
+ var SYSTEM_CREDENTIAL_MAPPERS = {
11
+ database: (config) => {
12
+ const creds = {};
13
+ if (config.url) {
14
+ creds.DATABASE_URL = config.url;
15
+ }
16
+ return creds;
17
+ }
18
+ };
19
+ function mapIntegrationConfig(integrationType, config) {
20
+ const systemMapper = SYSTEM_CREDENTIAL_MAPPERS[integrationType];
21
+ if (systemMapper) {
22
+ return systemMapper(config);
23
+ }
24
+ const plugin = getIntegration(integrationType);
25
+ if (plugin) {
26
+ return getCredentialMapping(plugin, config);
27
+ }
28
+ return {};
29
+ }
30
+ async function fetchCredentials(integrationId) {
31
+ console.log("[Credential Fetcher] Fetching integration:", integrationId);
32
+ const integration = await getIntegrationById(integrationId);
33
+ if (!integration) {
34
+ console.log("[Credential Fetcher] Integration not found");
35
+ return {};
36
+ }
37
+ console.log("[Credential Fetcher] Found integration:", integration.type);
38
+ const credentials = mapIntegrationConfig(
39
+ integration.type,
40
+ integration.config
41
+ );
42
+ console.log(
43
+ "[Credential Fetcher] Returning credentials for type:",
44
+ integration.type
45
+ );
46
+ return credentials;
47
+ }
48
+
49
+ export {
50
+ fetchCredentials
51
+ };
@@ -0,0 +1,71 @@
1
+ // src/server/lib/utils.ts
2
+ function getErrorMessage(error) {
3
+ if (error === null || error === void 0) {
4
+ return "Unknown error";
5
+ }
6
+ if (error instanceof Error) {
7
+ if (error.cause && error.cause instanceof Error) {
8
+ return `${error.message}: ${error.cause.message}`;
9
+ }
10
+ return error.message;
11
+ }
12
+ if (typeof error === "string") {
13
+ return error;
14
+ }
15
+ if (typeof error === "object") {
16
+ const obj = error;
17
+ if (typeof obj.message === "string" && obj.message) {
18
+ return obj.message;
19
+ }
20
+ if (obj.responseBody && typeof obj.responseBody === "object") {
21
+ const body = obj.responseBody;
22
+ if (typeof body.error === "string") {
23
+ return body.error;
24
+ }
25
+ if (body.error && typeof body.error === "object" && typeof body.error.message === "string") {
26
+ return body.error.message;
27
+ }
28
+ }
29
+ if (typeof obj.error === "string" && obj.error) {
30
+ return obj.error;
31
+ }
32
+ if (obj.error && typeof obj.error === "object") {
33
+ const nestedError = obj.error;
34
+ if (typeof nestedError.message === "string") {
35
+ return nestedError.message;
36
+ }
37
+ }
38
+ if (obj.data && typeof obj.data === "object") {
39
+ const data = obj.data;
40
+ if (typeof data.error === "string") {
41
+ return data.error;
42
+ }
43
+ if (typeof data.message === "string") {
44
+ return data.message;
45
+ }
46
+ }
47
+ if (typeof obj.reason === "string" && obj.reason) {
48
+ return obj.reason;
49
+ }
50
+ if (typeof obj.statusText === "string" && obj.statusText) {
51
+ const status = typeof obj.status === "number" ? ` (${obj.status})` : "";
52
+ return `${obj.statusText}${status}`;
53
+ }
54
+ try {
55
+ const stringified = JSON.stringify(error, null, 0);
56
+ if (stringified && stringified !== "{}" && stringified.length < 500) {
57
+ return stringified;
58
+ }
59
+ } catch {
60
+ }
61
+ const toString = Object.prototype.toString.call(error);
62
+ if (toString !== "[object Object]") {
63
+ return toString;
64
+ }
65
+ }
66
+ return "Unknown error";
67
+ }
68
+
69
+ export {
70
+ getErrorMessage
71
+ };
@@ -0,0 +1,36 @@
1
+ // src/server/constants.ts
2
+ import { join } from "path";
3
+ var CWD = process.cwd();
4
+ var PLUGINS_DIR = join(CWD, "plugins");
5
+ var LIB_DIR = join(CWD, "lib");
6
+ var OUTPUT_FILE = join(PLUGINS_DIR, "index.ts");
7
+ var TYPES_FILE = join(LIB_DIR, "types", "integration.ts");
8
+ var GITIGNORE_FILE = join(CWD, ".gitignore");
9
+ var STEP_REGISTRY_FILE = join(LIB_DIR, "step-registry.ts");
10
+ var OUTPUT_CONFIGS_FILE = join(LIB_DIR, "output-display-configs.ts");
11
+ var CODEGEN_REGISTRY_FILE = join(LIB_DIR, "codegen-registry.ts");
12
+ var SYSTEM_INTEGRATION_TYPES = ["database"];
13
+ var LEADING_WHITESPACE_PATTERN = /^\s*/;
14
+ var BOILERPLATE_PATH = join(".", "lib", "next-boilerplate");
15
+ var CODEGEN_TEMPLATES_PATH = join(process.cwd(), "lib", "codegen-templates");
16
+ var NON_ALPHANUMERIC_REGEX = /[^a-zA-Z0-9\s]/g;
17
+ var WHITESPACE_SPLIT_REGEX = /\s+/;
18
+ var TEMPLATE_EXPORT_REGEX = /export default `([\s\S]*)`/;
19
+ var IS_PRODUCTION = process.env.NODE_ENV === "production";
20
+
21
+ export {
22
+ PLUGINS_DIR,
23
+ OUTPUT_FILE,
24
+ TYPES_FILE,
25
+ GITIGNORE_FILE,
26
+ STEP_REGISTRY_FILE,
27
+ OUTPUT_CONFIGS_FILE,
28
+ CODEGEN_REGISTRY_FILE,
29
+ SYSTEM_INTEGRATION_TYPES,
30
+ LEADING_WHITESPACE_PATTERN,
31
+ BOILERPLATE_PATH,
32
+ CODEGEN_TEMPLATES_PATH,
33
+ NON_ALPHANUMERIC_REGEX,
34
+ WHITESPACE_SPLIT_REGEX,
35
+ TEMPLATE_EXPORT_REGEX
36
+ };