@explorer02/cfm-survey-sdk 0.0.1 → 0.0.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/cli/const.d.ts +10 -0
- package/dist/cli/const.d.ts.map +1 -0
- package/dist/cli/const.js +13 -0
- package/dist/cli/const.js.map +1 -0
- package/dist/cli/constants.d.ts +9 -0
- package/dist/cli/constants.js +12 -0
- package/dist/cli/deploy.d.ts.map +1 -1
- package/dist/cli/deploy.js +10 -189
- package/dist/cli/deploy.js.map +1 -1
- package/dist/cli/index.js +8 -10
- package/dist/cli/index.js.map +1 -1
- package/dist/cli/utils/exec.d.ts +4 -0
- package/dist/cli/utils/exec.d.ts.map +1 -0
- package/dist/cli/utils/exec.js +41 -0
- package/dist/cli/utils/exec.js.map +1 -0
- package/dist/cli/utils/nodeCheck.d.ts +2 -0
- package/dist/cli/utils/nodeCheck.d.ts.map +1 -0
- package/dist/cli/utils/nodeCheck.js +64 -0
- package/dist/cli/utils/nodeCheck.js.map +1 -0
- package/dist/cli/utils/prompts.d.ts +2 -0
- package/dist/cli/utils/prompts.d.ts.map +1 -0
- package/dist/cli/utils/prompts.js +29 -0
- package/dist/cli/utils/prompts.js.map +1 -0
- package/dist/cli/utils/vercelCliCheck.d.ts +6 -0
- package/dist/cli/utils/vercelCliCheck.d.ts.map +1 -0
- package/dist/cli/utils/vercelCliCheck.js +38 -0
- package/dist/cli/utils/vercelCliCheck.js.map +1 -0
- package/dist/cli/utils/vercelDeploy.d.ts +2 -0
- package/dist/cli/utils/vercelDeploy.d.ts.map +1 -0
- package/dist/cli/utils/vercelDeploy.js +21 -0
- package/dist/cli/utils/vercelDeploy.js.map +1 -0
- package/dist/cli/utils/vercelLoginCheck.d.ts +2 -0
- package/dist/cli/utils/vercelLoginCheck.d.ts.map +1 -0
- package/dist/cli/utils/vercelLoginCheck.js +42 -0
- package/dist/cli/utils/vercelLoginCheck.js.map +1 -0
- package/package.json +8 -2
- package/postinstall.js +40 -0
- package/templates/AGENT.md +1219 -0
- package/src/analytics/analyticsTracker.ts +0 -48
- package/src/analytics/types.ts +0 -80
- package/src/cli/deploy.ts +0 -205
- package/src/cli/index.ts +0 -33
- package/src/fetchSurvey/internalTypes.ts +0 -80
- package/src/fetchSurvey/logger/fetchLogger.ts +0 -34
- package/src/fetchSurvey/logger/mapperLogger.ts +0 -13
- package/src/fetchSurvey/telemetry/fetchTelemetry.ts +0 -26
- package/src/fetchSurvey/types.ts +0 -82
- package/src/fetchSurvey/useFetchSurvey.ts +0 -126
- package/src/fetchSurvey/utils/constants.ts +0 -11
- package/src/fetchSurvey/utils/extractSurveyLanguages.ts +0 -63
- package/src/fetchSurvey/utils/index.ts +0 -7
- package/src/fetchSurvey/utils/mapSurveyPages.ts +0 -35
- package/src/fetchSurvey/utils/mappers/index.ts +0 -2
- package/src/fetchSurvey/utils/mappers/questionMapper.ts +0 -213
- package/src/fetchSurvey/utils/mappers/surveyMapper.ts +0 -69
- package/src/fetchSurvey/utils/url.ts +0 -21
- package/src/index.ts +0 -6
- package/src/logger/logger.ts +0 -71
- package/src/queryClient.ts +0 -67
- package/src/submitSurvey/logger/resolutionLogger.ts +0 -13
- package/src/submitSurvey/logger/submitLogger.ts +0 -51
- package/src/submitSurvey/telemetry/submitTelemetry.ts +0 -33
- package/src/submitSurvey/types.ts +0 -51
- package/src/submitSurvey/useSubmitResponse.ts +0 -111
- package/src/submitSurvey/utils/constants.ts +0 -4
- package/src/submitSurvey/utils/formatters.ts +0 -33
- package/src/submitSurvey/utils/index.ts +0 -4
- package/src/submitSurvey/utils/url.ts +0 -17
- package/src/submitSurvey/utils/validation.ts +0 -48
- package/src/surveyPagination/actions/index.ts +0 -4
- package/src/surveyPagination/actions/useOnBack.ts +0 -37
- package/src/surveyPagination/actions/useOnChange.ts +0 -16
- package/src/surveyPagination/actions/useOnNext.ts +0 -99
- package/src/surveyPagination/actions/useOnSubmit.ts +0 -137
- package/src/surveyPagination/dispatchers/index.ts +0 -3
- package/src/surveyPagination/dispatchers/useCheckBacktrackChanges.ts +0 -35
- package/src/surveyPagination/dispatchers/useTrackOptionalSkips.ts +0 -21
- package/src/surveyPagination/dispatchers/useTrackPageTime.ts +0 -13
- package/src/surveyPagination/effects/index.ts +0 -2
- package/src/surveyPagination/effects/useResetPageStartTime.ts +0 -10
- package/src/surveyPagination/effects/useTrackMaxVisitedPage.ts +0 -12
- package/src/surveyPagination/logger/navigationLogger.ts +0 -25
- package/src/surveyPagination/logger/validationLogger.ts +0 -17
- package/src/surveyPagination/telemetry/pageTelemetry.ts +0 -22
- package/src/surveyPagination/telemetry/sessionTelemetry.ts +0 -55
- package/src/surveyPagination/types.ts +0 -42
- package/src/surveyPagination/useSurveyPagination.ts +0 -109
- package/src/surveyPagination/utils/index.ts +0 -2
- package/src/surveyPagination/utils/scroll.ts +0 -62
- package/src/surveyPagination/utils/validation.ts +0 -62
- package/src/surveyProgress/useSurveyProgress.ts +0 -42
- package/src/surveyProgress/utils/index.ts +0 -1
- package/src/surveyProgress/utils/progress.ts +0 -61
- package/src/surveySDK/constants.ts +0 -9
- package/src/surveySDK/types.ts +0 -22
- package/src/surveySDK/useSurveySDK.ts +0 -109
- package/tsconfig.json +0 -13
|
@@ -1,48 +0,0 @@
|
|
|
1
|
-
import { sdkLogger } from '../logger/logger';
|
|
2
|
-
import type { AnalyticsEvent } from './types';
|
|
3
|
-
|
|
4
|
-
export function trackEvent(event: AnalyticsEvent) {
|
|
5
|
-
if (event.eventName === 'survey_session_summary') {
|
|
6
|
-
const {
|
|
7
|
-
completed,
|
|
8
|
-
totalDurationMs,
|
|
9
|
-
maxVisitedPageIndex,
|
|
10
|
-
totalQuestionsCount,
|
|
11
|
-
answeredQuestionsCount,
|
|
12
|
-
skippedQuestionsCount,
|
|
13
|
-
skippedQuestionIds,
|
|
14
|
-
validationErrorsCount,
|
|
15
|
-
backtrackCount,
|
|
16
|
-
} = event.metadata;
|
|
17
|
-
|
|
18
|
-
// Always log to console with Heading as ANALYTICS
|
|
19
|
-
sdkLogger.analytics(`Event: ${event.eventName} - SESSION SUMMARY TABLE:`);
|
|
20
|
-
|
|
21
|
-
const summaryTable = [
|
|
22
|
-
{ Metric: 'Completion Status', Value: completed ? 'COMPLETED ✅' : 'ABANDONED ❌' },
|
|
23
|
-
{ Metric: 'Total Time Spent', Value: `${(totalDurationMs / 1000).toFixed(2)} seconds` },
|
|
24
|
-
{ Metric: 'Max Page Index Reached', Value: `${maxVisitedPageIndex}` },
|
|
25
|
-
{ Metric: 'Total Questions', Value: totalQuestionsCount },
|
|
26
|
-
{ Metric: 'Answered Questions', Value: answeredQuestionsCount },
|
|
27
|
-
{ Metric: 'Skipped Optional Questions', Value: skippedQuestionsCount },
|
|
28
|
-
{ Metric: 'Skipped Question IDs', Value: skippedQuestionIds.join(', ') || 'None' },
|
|
29
|
-
{ Metric: 'Validation Errors Triggered', Value: validationErrorsCount },
|
|
30
|
-
{ Metric: 'Backtrack Count', Value: backtrackCount },
|
|
31
|
-
{
|
|
32
|
-
Metric: 'Validation Error History',
|
|
33
|
-
Value:
|
|
34
|
-
event.metadata.validationHistory
|
|
35
|
-
?.map(
|
|
36
|
-
h =>
|
|
37
|
-
`[Page ${h.pageIndex}] Attempt ${h.attemptNumber}: ${Object.keys(h.errors).join(', ')}`
|
|
38
|
-
)
|
|
39
|
-
.join(' | ') || 'NO Validation Erros Occurred',
|
|
40
|
-
},
|
|
41
|
-
];
|
|
42
|
-
|
|
43
|
-
console.table(summaryTable);
|
|
44
|
-
} else {
|
|
45
|
-
// Always log to console with Heading as ANALYTICS
|
|
46
|
-
sdkLogger.analytics(`Event: ${event.eventName}`, event.metadata);
|
|
47
|
-
}
|
|
48
|
-
}
|
package/src/analytics/types.ts
DELETED
|
@@ -1,80 +0,0 @@
|
|
|
1
|
-
export type AnalyticsEvent =
|
|
2
|
-
| {
|
|
3
|
-
eventName: 'survey_fetch_latency';
|
|
4
|
-
metadata: {
|
|
5
|
-
durationMs: number;
|
|
6
|
-
status: number | string;
|
|
7
|
-
success: boolean;
|
|
8
|
-
url: string;
|
|
9
|
-
payloadSize?: string;
|
|
10
|
-
};
|
|
11
|
-
}
|
|
12
|
-
| {
|
|
13
|
-
eventName: 'survey_submit_latency';
|
|
14
|
-
metadata: {
|
|
15
|
-
durationMs: number;
|
|
16
|
-
status: number | string;
|
|
17
|
-
success: boolean;
|
|
18
|
-
url: string;
|
|
19
|
-
requestSize?: string;
|
|
20
|
-
responseSize?: string;
|
|
21
|
-
};
|
|
22
|
-
}
|
|
23
|
-
| {
|
|
24
|
-
eventName: 'api_error';
|
|
25
|
-
metadata: {
|
|
26
|
-
apiName: string;
|
|
27
|
-
status: number | string;
|
|
28
|
-
url: string;
|
|
29
|
-
errorMessage: string;
|
|
30
|
-
};
|
|
31
|
-
}
|
|
32
|
-
| {
|
|
33
|
-
eventName: 'optional_question_skipped';
|
|
34
|
-
metadata: {
|
|
35
|
-
questionId: string;
|
|
36
|
-
pageIndex: number;
|
|
37
|
-
};
|
|
38
|
-
}
|
|
39
|
-
| {
|
|
40
|
-
eventName: 'backtrack_revisited';
|
|
41
|
-
metadata: {
|
|
42
|
-
fromPageIndex: number;
|
|
43
|
-
toPageIndex: number;
|
|
44
|
-
changedAnswers: Record<string, { oldValue: any; newValue: any }>;
|
|
45
|
-
};
|
|
46
|
-
}
|
|
47
|
-
| {
|
|
48
|
-
eventName: 'validation_error';
|
|
49
|
-
metadata: {
|
|
50
|
-
pageIndex: number;
|
|
51
|
-
errors: Record<string, string>;
|
|
52
|
-
attemptNumber: number;
|
|
53
|
-
};
|
|
54
|
-
}
|
|
55
|
-
| {
|
|
56
|
-
eventName: 'page_time_spent';
|
|
57
|
-
metadata: {
|
|
58
|
-
pageIndex: number;
|
|
59
|
-
durationMs: number;
|
|
60
|
-
};
|
|
61
|
-
}
|
|
62
|
-
| {
|
|
63
|
-
eventName: 'survey_session_summary';
|
|
64
|
-
metadata: {
|
|
65
|
-
maxVisitedPageIndex: number;
|
|
66
|
-
totalDurationMs: number;
|
|
67
|
-
completed: boolean;
|
|
68
|
-
totalQuestionsCount: number;
|
|
69
|
-
answeredQuestionsCount: number;
|
|
70
|
-
skippedQuestionsCount: number;
|
|
71
|
-
skippedQuestionIds: string[];
|
|
72
|
-
validationErrorsCount: number;
|
|
73
|
-
backtrackCount: number;
|
|
74
|
-
validationHistory: Array<{
|
|
75
|
-
pageIndex: number;
|
|
76
|
-
errors: Record<string, string>;
|
|
77
|
-
attemptNumber: number;
|
|
78
|
-
}>;
|
|
79
|
-
};
|
|
80
|
-
};
|
package/src/cli/deploy.ts
DELETED
|
@@ -1,205 +0,0 @@
|
|
|
1
|
-
import { execSync, spawn } from 'child_process';
|
|
2
|
-
import readline from 'readline/promises';
|
|
3
|
-
import { stdin as input, stdout as output } from 'process';
|
|
4
|
-
import path from 'path';
|
|
5
|
-
|
|
6
|
-
const colors = {
|
|
7
|
-
reset: '\x1b[0m',
|
|
8
|
-
bold: '\x1b[1m',
|
|
9
|
-
green: '\x1b[32m',
|
|
10
|
-
red: '\x1b[31m',
|
|
11
|
-
cyan: '\x1b[36m',
|
|
12
|
-
yellow: '\x1b[33m',
|
|
13
|
-
dim: '\x1b[2m',
|
|
14
|
-
};
|
|
15
|
-
|
|
16
|
-
// Simple interactive prompt using Node.js built-in readline
|
|
17
|
-
async function askQuestion(query: string): Promise<string> {
|
|
18
|
-
const rl = readline.createInterface({ input, output });
|
|
19
|
-
try {
|
|
20
|
-
return (await rl.question(query)).trim();
|
|
21
|
-
} finally {
|
|
22
|
-
rl.close();
|
|
23
|
-
}
|
|
24
|
-
}
|
|
25
|
-
|
|
26
|
-
// Check if a shell executable is available in the user's system PATH
|
|
27
|
-
function hasCommand(cmd: string): boolean {
|
|
28
|
-
try {
|
|
29
|
-
const checkCmd = process.platform === 'win32' ? `where ${cmd}` : `command -v ${cmd}`;
|
|
30
|
-
execSync(checkCmd, { stdio: 'ignore' });
|
|
31
|
-
return true;
|
|
32
|
-
} catch {
|
|
33
|
-
return false;
|
|
34
|
-
}
|
|
35
|
-
}
|
|
36
|
-
|
|
37
|
-
// Execute a command synchronously and capture output/return code
|
|
38
|
-
function runCommandSync(cmd: string, args: string[]): boolean {
|
|
39
|
-
try {
|
|
40
|
-
const fullCmd = `${cmd} ${args.join(' ')}`;
|
|
41
|
-
execSync(fullCmd, { stdio: 'inherit', shell: true } as any);
|
|
42
|
-
return true;
|
|
43
|
-
} catch {
|
|
44
|
-
return false;
|
|
45
|
-
}
|
|
46
|
-
}
|
|
47
|
-
|
|
48
|
-
// Spawn an interactive command that inherits stdin/stdout/stderr
|
|
49
|
-
function runCommandInteractive(cmd: string, args: string[]): Promise<number | null> {
|
|
50
|
-
return new Promise((resolve) => {
|
|
51
|
-
const child = spawn(cmd, args, {
|
|
52
|
-
stdio: 'inherit',
|
|
53
|
-
shell: true,
|
|
54
|
-
});
|
|
55
|
-
|
|
56
|
-
child.on('close', (code) => {
|
|
57
|
-
resolve(code);
|
|
58
|
-
});
|
|
59
|
-
});
|
|
60
|
-
}
|
|
61
|
-
|
|
62
|
-
// Main deployment wrapper
|
|
63
|
-
export async function runDeployment() {
|
|
64
|
-
console.log(`\n${colors.bold}${colors.cyan}🚀 Starting CFM Vercel Deployment...${colors.reset}\n`);
|
|
65
|
-
|
|
66
|
-
// --- STEP 1: NODE.JS VERSION CHECK & AUTOMATED UPGRADE ---
|
|
67
|
-
const majorVersion = parseInt(process.version.slice(1).split('.')[0], 10);
|
|
68
|
-
console.log(`${colors.dim}Step 1/4: Checking Node.js version (current: ${process.version})...${colors.reset}`);
|
|
69
|
-
|
|
70
|
-
if (majorVersion < 18) {
|
|
71
|
-
console.log(`⚠️ ${colors.yellow}Outdated Node.js version detected. v18.0.0 or higher is required.${colors.reset}`);
|
|
72
|
-
|
|
73
|
-
const isWin = process.platform === 'win32';
|
|
74
|
-
const isMac = process.platform === 'darwin';
|
|
75
|
-
|
|
76
|
-
if (isWin) {
|
|
77
|
-
if (hasCommand('winget')) {
|
|
78
|
-
console.log(`\n📦 ${colors.green}winget package manager found! Installing Node.js v18+ in background...${colors.reset}`);
|
|
79
|
-
const success = runCommandSync('winget', ['upgrade', 'OpenJS.NodeJS', '--silent', '--accept-package-agreements', '--accept-source-agreements']);
|
|
80
|
-
if (success) {
|
|
81
|
-
console.log(`\n✔ ${colors.green}Node.js installation triggered successfully. Please restart your terminal/command-prompt for changes to take effect.${colors.reset}\n`);
|
|
82
|
-
process.exit(0);
|
|
83
|
-
} else {
|
|
84
|
-
console.log(`\n❌ ${colors.red}winget update failed. Please update Node.js manually at https://nodejs.org/${colors.reset}\n`);
|
|
85
|
-
process.exit(1);
|
|
86
|
-
}
|
|
87
|
-
} else {
|
|
88
|
-
console.log(`\n❌ ${colors.red}winget package manager is not installed on this system.${colors.reset}`);
|
|
89
|
-
console.log(`${colors.bold}👉 To proceed, please either:${colors.reset}`);
|
|
90
|
-
console.log(` 1. Install winget (App Installer) from the Microsoft Store.`);
|
|
91
|
-
console.log(` 2. Or manually download and install Node.js (v18+) from: https://nodejs.org/\n`);
|
|
92
|
-
process.exit(1);
|
|
93
|
-
}
|
|
94
|
-
} else if (isMac) {
|
|
95
|
-
if (hasCommand('brew')) {
|
|
96
|
-
console.log(`\n📦 ${colors.green}Homebrew package manager found! Installing Node.js v18+ in background...${colors.reset}`);
|
|
97
|
-
const success = runCommandSync('brew', ['install', 'node']);
|
|
98
|
-
if (success) {
|
|
99
|
-
console.log(`\n✔ ${colors.green}Node.js installed successfully via Homebrew.${colors.reset}\n`);
|
|
100
|
-
} else {
|
|
101
|
-
console.log(`\n❌ ${colors.red}Homebrew installation failed. Please install Node.js manually at https://nodejs.org/${colors.reset}\n`);
|
|
102
|
-
process.exit(1);
|
|
103
|
-
}
|
|
104
|
-
} else {
|
|
105
|
-
console.log(`\n❌ ${colors.red}Homebrew package manager (brew) is not installed on this system.${colors.reset}`);
|
|
106
|
-
console.log(`${colors.bold}👉 To proceed, please either:${colors.reset}`);
|
|
107
|
-
console.log(` 1. Install Homebrew by running the following command in your terminal:`);
|
|
108
|
-
console.log(` ${colors.cyan}/bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh)"${colors.reset}`);
|
|
109
|
-
console.log(` 2. Or manually download and install Node.js (v18+) from: https://nodejs.org/\n`);
|
|
110
|
-
process.exit(1);
|
|
111
|
-
}
|
|
112
|
-
} else {
|
|
113
|
-
console.log(`\n❌ ${colors.red}Please install or update Node.js to v18+ using your system's package manager.${colors.reset}\n`);
|
|
114
|
-
process.exit(1);
|
|
115
|
-
}
|
|
116
|
-
} else {
|
|
117
|
-
console.log(`✔ ${colors.green}Node.js version (v${majorVersion}) is sufficient.${colors.reset}`);
|
|
118
|
-
}
|
|
119
|
-
|
|
120
|
-
// --- STEP 2: VERCEL CLI VERIFICATION ---
|
|
121
|
-
console.log(`\n${colors.dim}Step 2/4: Checking Vercel CLI...${colors.reset}`);
|
|
122
|
-
let vercelCmd = 'vercel';
|
|
123
|
-
let useNpx = false;
|
|
124
|
-
|
|
125
|
-
if (!hasCommand('vercel')) {
|
|
126
|
-
console.log(`❓ ${colors.yellow}Vercel CLI was not found on your system.${colors.reset}`);
|
|
127
|
-
const answer = await askQuestion(`👉 Would you like to install Vercel CLI globally? (Y/n): `);
|
|
128
|
-
|
|
129
|
-
if (answer.toLowerCase() === 'y' || answer === '') {
|
|
130
|
-
console.log(`\n📥 ${colors.cyan}Installing Vercel CLI globally... (npm install -g vercel)${colors.reset}`);
|
|
131
|
-
const success = runCommandSync('npm', ['install', '-g', 'vercel']);
|
|
132
|
-
if (success && hasCommand('vercel')) {
|
|
133
|
-
console.log(`✔ ${colors.green}Vercel CLI installed successfully!${colors.reset}`);
|
|
134
|
-
} else {
|
|
135
|
-
console.log(`\n⚠️ ${colors.yellow}Global installation failed or permissions restricted.${colors.reset}`);
|
|
136
|
-
console.log(`ℹ ${colors.dim}Falling back: Running Vercel dynamically via npx.${colors.reset}`);
|
|
137
|
-
vercelCmd = 'npx --yes vercel';
|
|
138
|
-
useNpx = true;
|
|
139
|
-
}
|
|
140
|
-
} else {
|
|
141
|
-
console.log(`ℹ ${colors.dim}Skipping global installation. Running Vercel dynamically via npx.${colors.reset}`);
|
|
142
|
-
vercelCmd = 'npx --yes vercel';
|
|
143
|
-
useNpx = true;
|
|
144
|
-
}
|
|
145
|
-
} else {
|
|
146
|
-
console.log(`✔ ${colors.green}Vercel CLI is installed!${colors.reset}`);
|
|
147
|
-
}
|
|
148
|
-
|
|
149
|
-
// --- STEP 3: VERCEL LOGIN CHECK ---
|
|
150
|
-
console.log(`\n${colors.dim}Step 3/4: Checking Vercel Login...${colors.reset}`);
|
|
151
|
-
|
|
152
|
-
// Use VERCEL_TOKEN if available
|
|
153
|
-
const hasToken = !!process.env.VERCEL_TOKEN;
|
|
154
|
-
let loggedIn = false;
|
|
155
|
-
|
|
156
|
-
if (hasToken) {
|
|
157
|
-
console.log(`✔ ${colors.green}VERCEL_TOKEN environment variable detected. Skipping login check.${colors.reset}`);
|
|
158
|
-
loggedIn = true;
|
|
159
|
-
} else {
|
|
160
|
-
try {
|
|
161
|
-
// Execute vercel whoami to check active session
|
|
162
|
-
const checkCmd = useNpx ? 'npx --yes vercel whoami' : 'vercel whoami';
|
|
163
|
-
execSync(checkCmd, { stdio: 'ignore', shell: true } as any);
|
|
164
|
-
loggedIn = true;
|
|
165
|
-
console.log(`✔ ${colors.green}Logged in!${colors.reset}`);
|
|
166
|
-
} catch {
|
|
167
|
-
loggedIn = false;
|
|
168
|
-
}
|
|
169
|
-
}
|
|
170
|
-
|
|
171
|
-
if (!loggedIn) {
|
|
172
|
-
console.log(`🔑 ${colors.yellow}Not logged in to Vercel.${colors.reset}`);
|
|
173
|
-
await askQuestion(`👉 Press [Enter] to login to Vercel... `);
|
|
174
|
-
|
|
175
|
-
const loginArgs = ['login'];
|
|
176
|
-
const loginCmd = useNpx ? 'npx' : 'vercel';
|
|
177
|
-
const finalArgs = useNpx ? ['--yes', 'vercel', ...loginArgs] : loginArgs;
|
|
178
|
-
|
|
179
|
-
const exitCode = await runCommandInteractive(loginCmd, finalArgs);
|
|
180
|
-
if (exitCode !== 0) {
|
|
181
|
-
throw new Error('Vercel login failed or was aborted.');
|
|
182
|
-
}
|
|
183
|
-
console.log(`\n✔ ${colors.green}Logged in successfully!${colors.reset}`);
|
|
184
|
-
}
|
|
185
|
-
|
|
186
|
-
// --- STEP 4: PRODUCTION DEPLOYMENT ---
|
|
187
|
-
console.log(`\n${colors.dim}Step 4/4: Deploying project to production...${colors.reset}`);
|
|
188
|
-
|
|
189
|
-
const deployArgs = ['--prod', '--yes'];
|
|
190
|
-
if (hasToken) {
|
|
191
|
-
deployArgs.push('--token', process.env.VERCEL_TOKEN!);
|
|
192
|
-
}
|
|
193
|
-
|
|
194
|
-
const deployCmd = useNpx ? 'npx' : 'vercel';
|
|
195
|
-
const finalDeployArgs = useNpx ? ['--yes', 'vercel', ...deployArgs] : deployArgs;
|
|
196
|
-
|
|
197
|
-
console.log(`${colors.cyan}⚡ Running deployment in: ${process.cwd()}${colors.reset}\n`);
|
|
198
|
-
|
|
199
|
-
const deployExitCode = await runCommandInteractive(deployCmd, finalDeployArgs);
|
|
200
|
-
if (deployExitCode !== 0) {
|
|
201
|
-
throw new Error('Vercel deployment failed.');
|
|
202
|
-
}
|
|
203
|
-
|
|
204
|
-
console.log(`\n${colors.bold}${colors.green}🎉 Deployment completed successfully!${colors.reset}\n`);
|
|
205
|
-
}
|
package/src/cli/index.ts
DELETED
|
@@ -1,33 +0,0 @@
|
|
|
1
|
-
#!/usr/bin/env node
|
|
2
|
-
|
|
3
|
-
import { runDeployment } from './deploy';
|
|
4
|
-
|
|
5
|
-
const args = process.argv.slice(2);
|
|
6
|
-
const command = args[0];
|
|
7
|
-
|
|
8
|
-
const colors = {
|
|
9
|
-
reset: '\x1b[0m',
|
|
10
|
-
bold: '\x1b[1m',
|
|
11
|
-
green: '\x1b[32m',
|
|
12
|
-
red: '\x1b[31m',
|
|
13
|
-
cyan: '\x1b[36m',
|
|
14
|
-
yellow: '\x1b[33m',
|
|
15
|
-
};
|
|
16
|
-
|
|
17
|
-
async function main() {
|
|
18
|
-
if (command === 'deploy') {
|
|
19
|
-
try {
|
|
20
|
-
await runDeployment();
|
|
21
|
-
} catch (error: any) {
|
|
22
|
-
console.error(`\n${colors.red}❌ Error: ${error.message || error}${colors.reset}`);
|
|
23
|
-
process.exit(1);
|
|
24
|
-
}
|
|
25
|
-
} else {
|
|
26
|
-
console.log(`\n${colors.bold}${colors.cyan}CFM SDK CLI Tool${colors.reset}`);
|
|
27
|
-
console.log(`\nUsage:`);
|
|
28
|
-
console.log(` npx cfm-sdk deploy - Deploy the current project to Vercel`);
|
|
29
|
-
process.exit(0);
|
|
30
|
-
}
|
|
31
|
-
}
|
|
32
|
-
|
|
33
|
-
main();
|
|
@@ -1,80 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Raw API option/answer detail received from the remote survey config service.
|
|
3
|
-
*/
|
|
4
|
-
export type ApiAnswerDetail = {
|
|
5
|
-
// Option text label
|
|
6
|
-
answerText?: string;
|
|
7
|
-
// Whether the option should be hidden from UI render
|
|
8
|
-
hidden?: boolean;
|
|
9
|
-
// Additional metadata, such as hint/label flags for the scale boundaries
|
|
10
|
-
additional?: { isHintText?: boolean };
|
|
11
|
-
// Translations keyed by language code
|
|
12
|
-
translations?: Record<
|
|
13
|
-
string,
|
|
14
|
-
{
|
|
15
|
-
answerText?: string;
|
|
16
|
-
}
|
|
17
|
-
>;
|
|
18
|
-
};
|
|
19
|
-
|
|
20
|
-
/**
|
|
21
|
-
* Raw API question model representing the survey structure returned by the remote service.
|
|
22
|
-
*/
|
|
23
|
-
export type ApiQuestion = {
|
|
24
|
-
// Backend question unique ID
|
|
25
|
-
id?: string;
|
|
26
|
-
// Type identifier from API (e.g. "RATING", "SCALE", "TEXTFIELD", "MCQ")
|
|
27
|
-
answerType?: string;
|
|
28
|
-
// Primary text string for the question
|
|
29
|
-
questionText?: string;
|
|
30
|
-
// Rich HTML content representing the question text (fallback)
|
|
31
|
-
questionRichText?: string;
|
|
32
|
-
// List of answer options and scale hints
|
|
33
|
-
answerDetails?: ApiAnswerDetail[];
|
|
34
|
-
// Translations keyed by language code
|
|
35
|
-
translations?: Record<
|
|
36
|
-
string,
|
|
37
|
-
{
|
|
38
|
-
questionText?: string;
|
|
39
|
-
questionRichText?: string;
|
|
40
|
-
}
|
|
41
|
-
>;
|
|
42
|
-
// Configuration details for validation and other key-value settings
|
|
43
|
-
questionConfigs?: {
|
|
44
|
-
key: string;
|
|
45
|
-
value?: string[];
|
|
46
|
-
childConfigs?: {
|
|
47
|
-
key: string;
|
|
48
|
-
value?: string[];
|
|
49
|
-
}[];
|
|
50
|
-
translations?: Record<
|
|
51
|
-
string,
|
|
52
|
-
{
|
|
53
|
-
value?: string[];
|
|
54
|
-
valueRichText?: string[];
|
|
55
|
-
}
|
|
56
|
-
>;
|
|
57
|
-
}[];
|
|
58
|
-
};
|
|
59
|
-
|
|
60
|
-
/**
|
|
61
|
-
* Root envelope returned by the remote survey API endpoint.
|
|
62
|
-
*/
|
|
63
|
-
export type ApiResponse = {
|
|
64
|
-
// Unique distribution instance token/identifier
|
|
65
|
-
instanceId?: string;
|
|
66
|
-
// Localized survey language code
|
|
67
|
-
surveyLanguage?: string;
|
|
68
|
-
// Flat questions list if provided directly
|
|
69
|
-
questions?: ApiQuestion[];
|
|
70
|
-
// Multi-page survey page/question configurations
|
|
71
|
-
pages?: { questions?: ApiQuestion[] }[];
|
|
72
|
-
// Direct Data Transfer Object wrapping the full details from custom survey service
|
|
73
|
-
cfmSurveyDTO?: {
|
|
74
|
-
id?: string;
|
|
75
|
-
baseLanguage?: string;
|
|
76
|
-
surveyPages?: {
|
|
77
|
-
questionHolders?: { question?: ApiQuestion }[];
|
|
78
|
-
}[];
|
|
79
|
-
};
|
|
80
|
-
};
|
|
@@ -1,34 +0,0 @@
|
|
|
1
|
-
import { sdkLogger } from '../../logger/logger';
|
|
2
|
-
|
|
3
|
-
export function logFetchStart(url: string): void {
|
|
4
|
-
sdkLogger.info('Starting survey layout API fetch...', { url });
|
|
5
|
-
}
|
|
6
|
-
|
|
7
|
-
export function logFetchPerfFailure(durationMs: number, status: number | string, url: string): void {
|
|
8
|
-
sdkLogger.perf({
|
|
9
|
-
apiName: 'GET Survey Layout',
|
|
10
|
-
durationMs,
|
|
11
|
-
status,
|
|
12
|
-
url,
|
|
13
|
-
success: false,
|
|
14
|
-
});
|
|
15
|
-
}
|
|
16
|
-
|
|
17
|
-
export function logFetchPerfSuccess(durationMs: number, status: number, url: string, payloadSize: string): void {
|
|
18
|
-
sdkLogger.perf({
|
|
19
|
-
apiName: 'GET Survey Layout',
|
|
20
|
-
durationMs,
|
|
21
|
-
status,
|
|
22
|
-
url,
|
|
23
|
-
payloadSize,
|
|
24
|
-
success: true,
|
|
25
|
-
});
|
|
26
|
-
}
|
|
27
|
-
|
|
28
|
-
export function logFetchSuccess(apiResponse: any): void {
|
|
29
|
-
sdkLogger.success('Raw survey layout fetched successfully', apiResponse);
|
|
30
|
-
}
|
|
31
|
-
|
|
32
|
-
export function logFetchError(err: any): void {
|
|
33
|
-
sdkLogger.error('Failed to fetch raw survey layout', err);
|
|
34
|
-
}
|
|
@@ -1,13 +0,0 @@
|
|
|
1
|
-
import { sdkLogger } from '../../logger/logger';
|
|
2
|
-
|
|
3
|
-
export function logMapWarning(): void {
|
|
4
|
-
sdkLogger.warn('Cannot map survey: apiResponse is null or undefined');
|
|
5
|
-
}
|
|
6
|
-
|
|
7
|
-
export function logMapSuccess(mappedSurvey: any): void {
|
|
8
|
-
sdkLogger.success('Mapped survey layout successfully', mappedSurvey);
|
|
9
|
-
}
|
|
10
|
-
|
|
11
|
-
export function logMapError(err: any): void {
|
|
12
|
-
sdkLogger.error('Failed to map survey layout', err);
|
|
13
|
-
}
|
|
@@ -1,26 +0,0 @@
|
|
|
1
|
-
import { trackEvent } from '../../analytics/analyticsTracker';
|
|
2
|
-
|
|
3
|
-
export function trackFetchLatency(durationMs: number, status: number, url: string, payloadSize: string): void {
|
|
4
|
-
trackEvent({
|
|
5
|
-
eventName: 'survey_fetch_latency',
|
|
6
|
-
metadata: {
|
|
7
|
-
durationMs,
|
|
8
|
-
status,
|
|
9
|
-
success: true,
|
|
10
|
-
url,
|
|
11
|
-
payloadSize,
|
|
12
|
-
},
|
|
13
|
-
});
|
|
14
|
-
}
|
|
15
|
-
|
|
16
|
-
export function trackFetchError(status: number | string, url: string, errorMessage: string): void {
|
|
17
|
-
trackEvent({
|
|
18
|
-
eventName: 'api_error',
|
|
19
|
-
metadata: {
|
|
20
|
-
apiName: 'GET Survey Layout',
|
|
21
|
-
status,
|
|
22
|
-
url,
|
|
23
|
-
errorMessage,
|
|
24
|
-
},
|
|
25
|
-
});
|
|
26
|
-
}
|
package/src/fetchSurvey/types.ts
DELETED
|
@@ -1,82 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Types representing survey option selections (e.g., choice options in a question).
|
|
3
|
-
*/
|
|
4
|
-
export type SurveyOption = {
|
|
5
|
-
// The user-facing text for this option
|
|
6
|
-
label: string;
|
|
7
|
-
// The actual backend/value representation of this option
|
|
8
|
-
value: string | number;
|
|
9
|
-
// Optional background/text color associated with this option, used for ratings
|
|
10
|
-
color?: string;
|
|
11
|
-
};
|
|
12
|
-
|
|
13
|
-
/**
|
|
14
|
-
* Types representing a processed question from the survey.
|
|
15
|
-
*/
|
|
16
|
-
export type SurveyQuestion = {
|
|
17
|
-
// Unique identifier for the question
|
|
18
|
-
id: string;
|
|
19
|
-
// User-facing text or rich content of the question
|
|
20
|
-
text: string;
|
|
21
|
-
// The simplified input control/question type
|
|
22
|
-
type: 'rating' | 'radio' | 'text';
|
|
23
|
-
// The list of choices/options available to answer this question
|
|
24
|
-
options: SurveyOption[];
|
|
25
|
-
// Optional label representing the minimum bound (e.g., "Not Likely") for rating scales
|
|
26
|
-
minLabel?: string;
|
|
27
|
-
// Optional label representing the middle bound for rating scales
|
|
28
|
-
midLabel?: string;
|
|
29
|
-
// Optional label representing the maximum bound (e.g., "Extremely Likely") for rating scales
|
|
30
|
-
maxLabel?: string;
|
|
31
|
-
// Optional target index position for the middle label (e.g., 7.5)
|
|
32
|
-
midLabelIndex?: number;
|
|
33
|
-
// Optional max character count allowed for text input
|
|
34
|
-
maxCharacterCount?: number;
|
|
35
|
-
// Optional flag indicating if the question is required
|
|
36
|
-
required?: boolean;
|
|
37
|
-
// Optional custom error message when the required question is unanswered
|
|
38
|
-
requiredErrorMessage?: string;
|
|
39
|
-
// Optional placeholder text for text area inputs
|
|
40
|
-
placeholder?: string;
|
|
41
|
-
};
|
|
42
|
-
|
|
43
|
-
/**
|
|
44
|
-
* Type representing a survey page.
|
|
45
|
-
*/
|
|
46
|
-
export type SurveyPageData = {
|
|
47
|
-
// Unique identifier for the page
|
|
48
|
-
id: string;
|
|
49
|
-
// Optional page title
|
|
50
|
-
title?: string;
|
|
51
|
-
// List of questions on this page
|
|
52
|
-
questions: SurveyQuestion[];
|
|
53
|
-
};
|
|
54
|
-
|
|
55
|
-
export type SurveyLanguage = {
|
|
56
|
-
code: string;
|
|
57
|
-
name: string;
|
|
58
|
-
};
|
|
59
|
-
|
|
60
|
-
/**
|
|
61
|
-
* Type representing the fully parsed and normalized Survey structure.
|
|
62
|
-
*/
|
|
63
|
-
export type Survey = {
|
|
64
|
-
// Unique survey identifier
|
|
65
|
-
id: string;
|
|
66
|
-
// The locale/language string of this survey
|
|
67
|
-
language: string;
|
|
68
|
-
// All available languages in the survey
|
|
69
|
-
languages: SurveyLanguage[];
|
|
70
|
-
// The list of pages that form the survey
|
|
71
|
-
pages: SurveyPageData[];
|
|
72
|
-
};
|
|
73
|
-
|
|
74
|
-
/**
|
|
75
|
-
* Type representing the session state for a survey response.
|
|
76
|
-
*/
|
|
77
|
-
export type SurveySession = {
|
|
78
|
-
// The distribution/instance identifier from the survey configuration
|
|
79
|
-
instanceId: string;
|
|
80
|
-
// Language code of the active session
|
|
81
|
-
language: string;
|
|
82
|
-
};
|