at-builder 1.4.4 → 1.5.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.
@@ -1,86 +0,0 @@
1
- {
2
- "name": "at-builder",
3
- "version": "1.3.0",
4
- "main": "bin/index.js",
5
- "bin": {
6
- "atb": "bin/index.js"
7
- },
8
- "scripts": {
9
- "build:atb": "tsc",
10
- "build:atb:dev": "tsc -w",
11
- "atb:build:prod": "cross-env NODE_ENV=production webpack",
12
- "atb:build:dev": "webpack -- -w",
13
- "atb:build:dev:puppeteer": "webpack -- -w & npm run atb:puppeteer",
14
- "atb:puppeteer": "node puppeteer.js $b",
15
- "atb:plop:new:activity": "plop page",
16
- "atb:build:deploy": "node lib/at-deploy.js",
17
- "atb:build:sync": "node lib/at-sync.js"
18
- },
19
- "author": "Upendra Sengar <upendrasengar456@gmail.com>",
20
- "license": "MIT",
21
- "dependencies": {
22
- "@babel/core": "^7.26.9",
23
- "@babel/eslint-parser": "^7.26.8",
24
- "@babel/plugin-proposal-class-properties": "^7.18.6",
25
- "@babel/plugin-syntax-dynamic-import": "^7.8.3",
26
- "@babel/plugin-transform-runtime": "^7.18.9",
27
- "@babel/preset-env": "^7.18.9",
28
- "@babel/preset-react": "^7.18.6",
29
- "@eslint/js": "^9.20.0",
30
- "@types/node": "^22.13.2",
31
- "async": "^3.2.3",
32
- "axios": "^1.12.2",
33
- "babel-loader": "^9.2.1",
34
- "babel-plugin-transform-async-to-generator": "^6.24.1",
35
- "build": "^0.1.4",
36
- "chokidar": "^4.0.3",
37
- "cli-color": "^2.0.3",
38
- "commander": "^13.1.0",
39
- "cross-env": "^7.0.3",
40
- "css-loader": "^7.1.2",
41
- "dotenv": "16.4.5",
42
- "eslint": "^9.20.1",
43
- "eslint-webpack-plugin": "^4.2.0",
44
- "globals": "^15.15.0",
45
- "inquirer": "^12.4.1",
46
- "kleur": "^4.1.5",
47
- "plop": "^4.0.1",
48
- "postcss": "^8.4.12",
49
- "postcss-loader": "^8.1.1",
50
- "postcss-preset-env": "^10.1.4",
51
- "puppeteer": "^24.2.0",
52
- "querystring": "^0.2.1",
53
- "readline": "^1.3.0",
54
- "sass": "^1.53.0",
55
- "sass-loader": "^16.0.4",
56
- "style-loader": "^4.0.0",
57
- "terser-webpack-plugin": "^5.3.3",
58
- "ts-loader": "^9.3.1",
59
- "typescript": "^5.7.3",
60
- "typescript-eslint": "^8.24.1",
61
- "webpack": "^5.72.0",
62
- "webpack-cli": "^6.0.1",
63
- "wrapper-webpack-plugin": "^2.1.0"
64
- },
65
- "description": "[![npm version](https://badge.fury.io/js/at-builder.svg)](https://www.npmjs.com/package/at-builder) [![License](https://img.shields.io/badge/license-MIT-blue.svg)](LICENSE)",
66
- "directories": {
67
- "lib": "lib",
68
- "test": "test"
69
- },
70
- "devDependencies": {
71
- "@babel/runtime": "^7.29.2"
72
- },
73
- "repository": {
74
- "type": "git",
75
- "url": "git+https://github.com/upesenga/at-builder.git"
76
- },
77
- "keywords": [],
78
- "bugs": {
79
- "url": "https://github.com/upesenga/at-builder/issues"
80
- },
81
- "homepage": "https://github.com/upesenga/at-builder#readme",
82
- "engines": {
83
- "node": ">=16.0.0"
84
- },
85
- "packageManager": "yarn@1.22.22+sha1.ac34549e6aa8e7ead463a7407e1c7390f61a6610"
86
- }
@@ -1,321 +0,0 @@
1
- import path from "path";
2
- import fs from "fs";
3
- import clc from "cli-color";
4
-
5
- /**
6
- * Reads and returns the version from package.json
7
- * @returns {Promise<string>} The version of the package
8
- */
9
- export const getVersion = async () => {
10
- const packageJSONPath = path.resolve(__dirname, "../../package.json");
11
- try {
12
- const content = await fs.promises.readFile(packageJSONPath, { encoding: "utf8" });
13
- const config = JSON.parse(content);
14
- return config.version;
15
- } catch (error) {
16
- console.error(clc.red("Error reading package.json or parsing JSON"));
17
- process.exit(1); // Exit the process if package.json is not found or malformed
18
- }
19
- };
20
-
21
- exports.getVersion = getVersion;
22
-
23
- /**
24
- * Helper function for formatting colorized text
25
- * @param {string} text The text to format
26
- * @param {string} color The color for the text
27
- * @param {boolean} bold Whether to make the text bold
28
- * @param {boolean} underline Whether to underline the text
29
- * @returns {string} The formatted text
30
- */
31
- const formatText = (text: string, color: string = "white", bold: boolean = false, underline: boolean = false): string => {
32
- let formattedText = text;
33
-
34
- // Apply color
35
- const colorFn = clc[color as keyof typeof clc];
36
- if (typeof colorFn === 'function') {
37
- formattedText = colorFn(text);
38
- }
39
-
40
- // Apply formatting
41
- if (bold) formattedText = clc.bold(formattedText);
42
- if (underline) formattedText = clc.underline(formattedText);
43
-
44
- return formattedText;
45
- };
46
-
47
- /**
48
- * Returns help information with commands and usage
49
- * @returns {Promise<string>} The help text
50
- */
51
- export const getHelpInfo = async () => {
52
- const version = await getVersion();
53
-
54
- return `
55
- ${formatText(`🎯 at-builder`, 'cyan', true)} ${formatText(`v${version}`, 'gray')}
56
-
57
- ${formatText("Adobe Target Activity Development CLI", 'white', true)}
58
-
59
- A streamlined command-line tool for creating, building, and deploying Adobe Target
60
- A/B testing activities with modern web technologies.
61
-
62
- ${formatText("USAGE", 'yellow', true)}
63
- ${formatText("atb", 'cyan')} ${formatText("<command> [options]", 'gray')}
64
-
65
- ${formatText("COMMANDS", 'yellow', true)}
66
- ${formatText("init", 'cyan', true)} Initialize project with .env configuration and templates
67
- ${formatText("new", 'cyan', true)} Create a new Adobe Target activity with variations
68
- ${formatText("build", 'cyan', true)} Build activity for development
69
- ${formatText("build --prod", 'cyan', true)} Build for production deployment
70
- ${formatText("dev", 'cyan', true)} Start development server with file watching
71
- ${formatText("dev --browser", 'cyan', true)} Start development server and open in browser
72
- ${formatText("deploy", 'cyan', true)} Deploy activity to Adobe Target
73
- ${formatText("deploy --dry-run", 'cyan', true)} Deploy in dry-run mode without actual deployment
74
- ${formatText("deploy --force", 'cyan', true)} Override the 60s post-deploy cooldown lock
75
- ${formatText("sync", 'cyan', true)} Sync build.config.json with the AT activity (pages, experiences, names)
76
- ${formatText("sync --scaffold", 'cyan', true)} Sync and auto-create any missing variation folders with boilerplate
77
- ${formatText("doctor", 'cyan', true)} Diagnose and fix project configuration issues
78
- ${formatText("doctor --fix", 'cyan', true)} Automatically fix detected configuration issues
79
- ${formatText("install-extension", 'cyan', true)} Install the at-builder extension from the Marketplace (default: VSCode)
80
- ${formatText("install-extension --editor agy", 'cyan', true)} Install into Antigravity IDE (also: cursor, codium, etc.)
81
-
82
- ${formatText("GLOBAL OPTIONS", 'yellow', true)}
83
- ${formatText("-v, --verbose", 'green')} Enable detailed logging
84
- ${formatText("-V, --version", 'green')} Display version information
85
- ${formatText("-h, --help", 'green')} Show help information
86
-
87
- ${formatText("EXAMPLES", 'yellow', true)}
88
- ${formatText("# Initialize new project", 'gray')}
89
- ${formatText("atb init", 'white')}
90
-
91
- ${formatText("# Create new activity", 'gray')}
92
- ${formatText("atb new", 'white')}
93
-
94
- ${formatText("# Development build with hot reload", 'gray')}
95
- ${formatText("atb build", 'white')}
96
-
97
- ${formatText("# Production build for Adobe Target deployment", 'gray')}
98
- ${formatText("atb build --prod", 'white')}
99
-
100
- ${formatText("# Development server with browser", 'gray')}
101
- ${formatText("atb dev --browser", 'white')}
102
-
103
- ${formatText("# Deploy to Adobe Target", 'gray')}
104
- ${formatText("atb deploy", 'white')}
105
-
106
- ${formatText("# Deploy in dry-run mode", 'gray')}
107
- ${formatText("atb deploy --dry-run", 'white')}
108
-
109
- ${formatText("# Sync build.config.json from Adobe Target", 'gray')}
110
- ${formatText("atb sync", 'white')}
111
-
112
- ${formatText("# Sync and scaffold missing variation folders", 'gray')}
113
- ${formatText("atb sync --scaffold", 'white')}
114
-
115
- ${formatText("# Check project configuration", 'gray')}
116
- ${formatText("atb doctor", 'white')}
117
-
118
- ${formatText("# Auto-fix configuration issues", 'gray')}
119
- ${formatText("atb doctor --fix", 'white')}
120
-
121
- ${formatText("WORKFLOW", 'yellow', true)}
122
- ${formatText("1.", 'cyan')} Run ${formatText("atb init", 'white')} to set up project configuration
123
- ${formatText("2.", 'cyan')} Run ${formatText("atb new", 'white')} to create activity templates
124
- ${formatText("3.", 'cyan')} Develop variations in ${formatText("/Activities/{name}/Variation-*/", 'gray')}
125
- ${formatText("4.", 'cyan')} Run ${formatText("atb build", 'white')} for development testing
126
- ${formatText("5.", 'cyan')} Run ${formatText("atb build --prod", 'white')} for Adobe Target deployment
127
- ${formatText("6.", 'cyan')} Run ${formatText("atb deploy", 'white')} to deploy to Adobe Target
128
-
129
- ${formatText("SUPPORT", 'yellow', true)}
130
- Repository: ${formatText("https://github.com/upesenga/at-builder", 'blue')}
131
- Issues: ${formatText("https://github.com/upesenga/at-builder/issues", 'blue')}
132
- License: ${formatText("MIT", 'green')}
133
- `;
134
- };
135
-
136
-
137
- export const setupEnv = async (basePath) => {
138
- // Path to the .env file
139
- const envPath = path.join(basePath, '.env');
140
-
141
- // Check if the .env file exists
142
- if (!fs.existsSync(envPath)) {
143
- // Define the content of the .env file
144
- const envContent = `
145
- ACTIVITIES_BASE_FOLDER="Activities"
146
- ACTIVITY_FOLDER_NAME=""
147
- PUPPETEER_LANDING_PAGE=""
148
- TARGET_URL=""
149
- LOGIN_URL=""
150
-
151
- # Dev-server selection (used by \`atb dev --browser\`).
152
- # Edit and save while puppeteer is running to hot-swap the previewed bundle.
153
- # PAGE is only meaningful for multi-page activities — leave empty otherwise.
154
- VARIATION="Variation-1"
155
- PAGE=""
156
-
157
- NODE_ENV="development"
158
- VERBOSE=false
159
-
160
- # Build wrapper config.
161
- # TARGET_BUILD_PREFIX customizes the window flag baked into each build —
162
- # rendered as window.\${TARGET_BUILD_PREFIX}_\${contentHash}_\${hash}. Defaults
163
- # to "TargetBuild" when empty. Useful when multiple at-builder activities
164
- # end up loaded on the same page and you want each project's flag namespaced.
165
- TARGET_BUILD_PREFIX=""
166
-
167
- # Adobe Target Deployment Configuration
168
- # ADOBE_TENANT is your AT tenant slug — find it in the AT URL after "mc.adobe.io/".
169
- ADOBE_TENANT=""
170
- ADOBE_CLIENT_ID=""
171
- ADOBE_CLIENT_SECRET=""
172
- `;
173
- // Write the content to the .env file
174
- fs.writeFileSync(envPath, envContent.trim(), 'utf8');
175
- console.log('.env file created successfully!');
176
- } else {
177
- console.log('.env file already exists!');
178
- }
179
- // watch-config.json is no longer scaffolded by `atb init` — VARIATION/PAGE
180
- // now live in .env. Existing projects with a watch-config.json keep working
181
- // (puppeteer.js prefers it with a deprecation warning); `atb doctor --fix`
182
- // migrates the values into .env and deletes the legacy file.
183
- createAdobeConfig(basePath);
184
- createGitignore(basePath);
185
- }
186
-
187
- /**
188
- * Default .gitignore content for at-builder consumer projects.
189
- *
190
- * Shared between `atb init` (via setupEnv) and `atb doctor --fix` so the two
191
- * paths stay in lockstep. Covers secrets, deploy-runtime artifacts, build
192
- * output, and OS noise. Does NOT ignore the Activities folder — those are the
193
- * user's source files and should be committed.
194
- */
195
- export const GITIGNORE_TEMPLATE = `# Dependencies
196
- node_modules/
197
-
198
- # Environment / secrets — never commit
199
- .env
200
- .env.local
201
-
202
- # Adobe Target deploy runtime (cooldown lock written by \`atb deploy\`)
203
- .deploy-lock
204
-
205
- # Build output (regenerated by \`atb build\`)
206
- dist/
207
-
208
- # OS noise
209
- .DS_Store
210
-
211
- # Editor / local-history
212
- .history/
213
-
214
- # Logs
215
- *.log
216
- npm-debug.log*
217
- `;
218
-
219
- const createGitignore = (basePath) => {
220
- const gitignorePath = path.join(basePath, '.gitignore');
221
-
222
- if (!fs.existsSync(gitignorePath)) {
223
- fs.writeFileSync(gitignorePath, GITIGNORE_TEMPLATE, 'utf8');
224
- console.log('.gitignore file created successfully!');
225
- } else {
226
- console.log('.gitignore file already exists!');
227
- }
228
- }
229
-
230
-
231
- const createWatchConfig = (basePath) => {
232
-
233
- // Path to the watch-config.json file
234
- const watchConfigPath = path.join(basePath, 'watch-config.json');
235
-
236
- // Default content for watch-config.json.
237
- // VARIATION : which variation/experience to preview in `atb dev --browser`
238
- // PAGE : leave empty for single-page activities; set to the page
239
- // subfolder name (e.g. "Global", "Cart") for multi-page.
240
- // Editing this file mid-session hot-swaps the preview.
241
- const watchConfigContent = {
242
- "VARIATION": "Variation-1",
243
- "PAGE": ""
244
- };
245
-
246
- // Check if the watch-config.json file already exists
247
- if (!fs.existsSync(watchConfigPath)) {
248
- fs.writeFileSync(watchConfigPath, JSON.stringify(watchConfigContent, null, 2), 'utf8');
249
- console.log('watch-config.json file created successfully!');
250
- } else {
251
- console.log('watch-config.json file already exists!');
252
- }
253
- }
254
-
255
- const createAdobeConfig = (basePath) => {
256
- // Path to the adobe.config.js file
257
- const adobeConfigPath = path.join(basePath, 'adobe.config.js');
258
-
259
- // Default content for adobe.config.js
260
- const adobeConfigContent = `/**
261
- * Adobe Target API Configuration
262
- *
263
- * Used by at-sync.js and at-deploy.js. BASE_URL is the activities root —
264
- * callers append \`\${activityType}/\${activityId}\` (e.g. ab/12345, xt/67890).
265
- *
266
- * ADOBE_TENANT comes from the consumer .env. Both at-sync and at-deploy load
267
- * dotenv before requiring this file, so process.env is populated by the time
268
- * BASE_URL is built.
269
- */
270
-
271
- const TENANT = process.env.ADOBE_TENANT || 'YOUR_TENANT';
272
-
273
- module.exports = {
274
- BASE_URL: \`https://mc.adobe.io/\${TENANT}/target/activities/\`,
275
- IMS_TOKEN_URL: 'https://ims-na1.adobelogin.com/ims/token/v3',
276
- IMS_SCOPE: 'openid,AdobeID,target_sdk,additional_info.projectedProductContext'
277
- };`;
278
-
279
- // Check if the adobe.config.js file already exists
280
- if (!fs.existsSync(adobeConfigPath)) {
281
- fs.writeFileSync(adobeConfigPath, adobeConfigContent, 'utf8');
282
- console.log('adobe.config.js file created successfully!');
283
- } else {
284
- console.log('adobe.config.js file already exists!');
285
- }
286
- }
287
-
288
- /**
289
- * Reads and returns environment variables from the specified .env file.
290
- *
291
- * Throws if the file is missing or unreadable. Callers decide whether
292
- * to surface the failure — printing here would spam every `atb` run from
293
- * a directory that doesn't have a `.env` (e.g. `atb --version` from /tmp).
294
- *
295
- * @param basePath - The base path where the .env file is located
296
- * @returns Object containing environment variables
297
- */
298
- export const getENV = async (basePath: string) => {
299
- const envPath = path.join(basePath, '.env');
300
- if (!fs.existsSync(envPath)) {
301
- throw new Error('.env file not found');
302
- }
303
-
304
- const envContent = await fs.promises.readFile(envPath, { encoding: 'utf8' });
305
-
306
- const envVars: { [key: string]: string } = {};
307
- envContent.split('\n').forEach(line => {
308
- line = line.trim();
309
- // Skip empty lines and comments
310
- if (line && !line.startsWith('#')) {
311
- const [key, ...valueParts] = line.split('=');
312
- if (key) {
313
- const value = valueParts.join('=').trim();
314
- // Remove quotes if present
315
- envVars[key.trim()] = value.replace(/^["'](.*)["']$/, '$1');
316
- }
317
- }
318
- });
319
-
320
- return envVars;
321
- };