@agility/create-next-app 1.0.0-beta.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/.claude/settings.json +7 -0
- package/.claude/settings.local.json +24 -0
- package/FEATURE_ROADMAP.md +343 -0
- package/README.md +205 -0
- package/TESTING.md +131 -0
- package/bin/create-agility-app.js +48 -0
- package/dist/agility/api-keys/generateApiKeys.d.ts +9 -0
- package/dist/agility/api-keys/generateApiKeys.d.ts.map +1 -0
- package/dist/agility/api-keys/generateApiKeys.js +99 -0
- package/dist/agility/api-keys/generateApiKeys.js.map +1 -0
- package/dist/agility/api-keys/getApiKeys.d.ts +9 -0
- package/dist/agility/api-keys/getApiKeys.d.ts.map +1 -0
- package/dist/agility/api-keys/getApiKeys.js +14 -0
- package/dist/agility/api-keys/getApiKeys.js.map +1 -0
- package/dist/agility/index.d.ts +3 -0
- package/dist/agility/index.d.ts.map +1 -0
- package/dist/agility/index.js +8 -0
- package/dist/agility/index.js.map +1 -0
- package/dist/agility/instance/createNewInstance.d.ts +8 -0
- package/dist/agility/instance/createNewInstance.d.ts.map +1 -0
- package/dist/agility/instance/createNewInstance.js +65 -0
- package/dist/agility/instance/createNewInstance.js.map +1 -0
- package/dist/agility/instance/getAvailableInstances.d.ts +8 -0
- package/dist/agility/instance/getAvailableInstances.d.ts.map +1 -0
- package/dist/agility/instance/getAvailableInstances.js +43 -0
- package/dist/agility/instance/getAvailableInstances.js.map +1 -0
- package/dist/agility/instance/manageInstance.d.ts +9 -0
- package/dist/agility/instance/manageInstance.d.ts.map +1 -0
- package/dist/agility/instance/manageInstance.js +82 -0
- package/dist/agility/instance/manageInstance.js.map +1 -0
- package/dist/agility/utils/getMgmtAPIUrl.d.ts +20 -0
- package/dist/agility/utils/getMgmtAPIUrl.d.ts.map +1 -0
- package/dist/agility/utils/getMgmtAPIUrl.js +61 -0
- package/dist/agility/utils/getMgmtAPIUrl.js.map +1 -0
- package/dist/auth/api-key/authenticateWithApiKey.d.ts +6 -0
- package/dist/auth/api-key/authenticateWithApiKey.d.ts.map +1 -0
- package/dist/auth/api-key/authenticateWithApiKey.js +28 -0
- package/dist/auth/api-key/authenticateWithApiKey.js.map +1 -0
- package/dist/auth/index.d.ts +3 -0
- package/dist/auth/index.d.ts.map +1 -0
- package/dist/auth/index.js +8 -0
- package/dist/auth/index.js.map +1 -0
- package/dist/auth/oauth/authenticate.d.ts +6 -0
- package/dist/auth/oauth/authenticate.d.ts.map +1 -0
- package/dist/auth/oauth/authenticate.js +162 -0
- package/dist/auth/oauth/authenticate.js.map +1 -0
- package/dist/auth/oauth/constants.d.ts +5 -0
- package/dist/auth/oauth/constants.d.ts.map +1 -0
- package/dist/auth/oauth/constants.js +9 -0
- package/dist/auth/oauth/constants.js.map +1 -0
- package/dist/auth/oauth/exchangeCodeForToken.d.ts +7 -0
- package/dist/auth/oauth/exchangeCodeForToken.d.ts.map +1 -0
- package/dist/auth/oauth/exchangeCodeForToken.js +39 -0
- package/dist/auth/oauth/exchangeCodeForToken.js.map +1 -0
- package/dist/cli/index.d.ts +3 -0
- package/dist/cli/index.d.ts.map +1 -0
- package/dist/cli/index.js +290 -0
- package/dist/cli/index.js.map +1 -0
- package/dist/cli/promptForMissingOptions.d.ts +8 -0
- package/dist/cli/promptForMissingOptions.d.ts.map +1 -0
- package/dist/cli/promptForMissingOptions.js +92 -0
- package/dist/cli/promptForMissingOptions.js.map +1 -0
- package/dist/config/env/createEnvFile.d.ts +6 -0
- package/dist/config/env/createEnvFile.d.ts.map +1 -0
- package/dist/config/env/createEnvFile.js +31 -0
- package/dist/config/env/createEnvFile.js.map +1 -0
- package/dist/config/index.d.ts +2 -0
- package/dist/config/index.d.ts.map +1 -0
- package/dist/config/index.js +6 -0
- package/dist/config/index.js.map +1 -0
- package/dist/config/mcp/createMcpConfig.d.ts +5 -0
- package/dist/config/mcp/createMcpConfig.d.ts.map +1 -0
- package/dist/config/mcp/createMcpConfig.js +32 -0
- package/dist/config/mcp/createMcpConfig.js.map +1 -0
- package/dist/config/packages/installAgilityPackages.d.ts +6 -0
- package/dist/config/packages/installAgilityPackages.d.ts.map +1 -0
- package/dist/config/packages/installAgilityPackages.js +61 -0
- package/dist/config/packages/installAgilityPackages.js.map +1 -0
- package/dist/config/setupProject.d.ts +8 -0
- package/dist/config/setupProject.d.ts.map +1 -0
- package/dist/config/setupProject.js +32 -0
- package/dist/config/setupProject.js.map +1 -0
- package/dist/create-next-app/createNextApp.d.ts +9 -0
- package/dist/create-next-app/createNextApp.d.ts.map +1 -0
- package/dist/create-next-app/createNextApp.js +83 -0
- package/dist/create-next-app/createNextApp.js.map +1 -0
- package/dist/create-next-app/index.d.ts +3 -0
- package/dist/create-next-app/index.d.ts.map +1 -0
- package/dist/create-next-app/index.js +8 -0
- package/dist/create-next-app/index.js.map +1 -0
- package/dist/scaffold/components/createPageComponents.d.ts +6 -0
- package/dist/scaffold/components/createPageComponents.d.ts.map +1 -0
- package/dist/scaffold/components/createPageComponents.js +62 -0
- package/dist/scaffold/components/createPageComponents.js.map +1 -0
- package/dist/scaffold/containers/createContainers.d.ts +6 -0
- package/dist/scaffold/containers/createContainers.d.ts.map +1 -0
- package/dist/scaffold/containers/createContainers.js +48 -0
- package/dist/scaffold/containers/createContainers.js.map +1 -0
- package/dist/scaffold/index.d.ts +2 -0
- package/dist/scaffold/index.d.ts.map +1 -0
- package/dist/scaffold/index.js +6 -0
- package/dist/scaffold/index.js.map +1 -0
- package/dist/scaffold/instance/createBlankInstance.d.ts +8 -0
- package/dist/scaffold/instance/createBlankInstance.d.ts.map +1 -0
- package/dist/scaffold/instance/createBlankInstance.js +51 -0
- package/dist/scaffold/instance/createBlankInstance.js.map +1 -0
- package/dist/scaffold/models/createContentModels.d.ts +6 -0
- package/dist/scaffold/models/createContentModels.d.ts.map +1 -0
- package/dist/scaffold/models/createContentModels.js +70 -0
- package/dist/scaffold/models/createContentModels.js.map +1 -0
- package/dist/templates/copyDirectory.d.ts +5 -0
- package/dist/templates/copyDirectory.d.ts.map +1 -0
- package/dist/templates/copyDirectory.js +28 -0
- package/dist/templates/copyDirectory.js.map +1 -0
- package/dist/templates/copyTemplates.d.ts +8 -0
- package/dist/templates/copyTemplates.d.ts.map +1 -0
- package/dist/templates/copyTemplates.js +58 -0
- package/dist/templates/copyTemplates.js.map +1 -0
- package/dist/templates/index.d.ts +2 -0
- package/dist/templates/index.d.ts.map +1 -0
- package/dist/templates/index.js +6 -0
- package/dist/templates/index.js.map +1 -0
- package/dist/types/index.d.ts +50 -0
- package/dist/types/index.d.ts.map +1 -0
- package/dist/types/index.js +3 -0
- package/dist/types/index.js.map +1 -0
- package/dist/utils/git.d.ts +9 -0
- package/dist/utils/git.d.ts.map +1 -0
- package/dist/utils/git.js +71 -0
- package/dist/utils/git.js.map +1 -0
- package/dist/utils/validation.d.ts +45 -0
- package/dist/utils/validation.d.ts.map +1 -0
- package/dist/utils/validation.js +180 -0
- package/dist/utils/validation.js.map +1 -0
- package/package.json +45 -0
- package/src/agility/api-keys/generateApiKeys.ts +100 -0
- package/src/agility/api-keys/getApiKeys.ts +13 -0
- package/src/agility/index.ts +3 -0
- package/src/agility/instance/createNewInstance.ts +67 -0
- package/src/agility/instance/getAvailableInstances.ts +49 -0
- package/src/agility/instance/manageInstance.ts +90 -0
- package/src/agility/utils/getMgmtAPIUrl.ts +68 -0
- package/src/auth/api-key/authenticateWithApiKey.ts +24 -0
- package/src/auth/index.ts +3 -0
- package/src/auth/oauth/authenticate.ts +165 -0
- package/src/auth/oauth/constants.ts +6 -0
- package/src/auth/oauth/exchangeCodeForToken.ts +43 -0
- package/src/cli/index.ts +281 -0
- package/src/cli/promptForMissingOptions.ts +104 -0
- package/src/config/env/createEnvFile.ts +30 -0
- package/src/config/index.ts +2 -0
- package/src/config/mcp/createMcpConfig.ts +30 -0
- package/src/config/packages/installAgilityPackages.ts +63 -0
- package/src/config/setupProject.ts +31 -0
- package/src/create-next-app/createNextApp.ts +75 -0
- package/src/create-next-app/index.ts +3 -0
- package/src/scaffold/components/createPageComponents.ts +74 -0
- package/src/scaffold/containers/createContainers.ts +55 -0
- package/src/scaffold/index.ts +2 -0
- package/src/scaffold/instance/createBlankInstance.ts +55 -0
- package/src/scaffold/models/createContentModels.ts +83 -0
- package/src/templates/copyDirectory.ts +24 -0
- package/src/templates/copyTemplates.ts +57 -0
- package/src/templates/index.ts +2 -0
- package/src/types/index.ts +55 -0
- package/src/utils/git.ts +74 -0
- package/src/utils/validation.ts +184 -0
- package/templates/.claude/QUICK-START.md +230 -0
- package/templates/.claude/README.md +32 -0
- package/templates/.claude/settings.json +8 -0
- package/templates/BLANK-INSTANCE-SETUP.md +375 -0
- package/templates/DEVELOPMENT.md +160 -0
- package/templates/EXAMPLE-PROMPTS.md +643 -0
- package/templates/PROMPTS.md +410 -0
- package/templates/README.md +281 -0
- package/templates/agents.md +429 -0
- package/templates/app/[locale]/[...slug]/error.tsx +17 -0
- package/templates/app/[locale]/[...slug]/not-found.tsx +9 -0
- package/templates/app/[locale]/[...slug]/page.tsx +102 -0
- package/templates/app/[locale]/layout.tsx +22 -0
- package/templates/app/[locale]/page.tsx +12 -0
- package/templates/app/api/dynamic-redirect/route.ts +24 -0
- package/templates/app/api/preview/exit/route.ts +34 -0
- package/templates/app/api/preview/route.ts +63 -0
- package/templates/app/api/revalidate/route.ts +118 -0
- package/templates/components/agility-components/RichTextArea.tsx +66 -0
- package/templates/components/agility-components/index.ts +30 -0
- package/templates/components/agility-pages/MainTemplate.tsx +36 -0
- package/templates/components/agility-pages/index.ts +11 -0
- package/templates/docs/01-agility-cms-overview.md +139 -0
- package/templates/docs/02-page-routing.md +251 -0
- package/templates/docs/03-creating-components.md +462 -0
- package/templates/docs/04-data-fetching.md +484 -0
- package/templates/docs/05-containers-and-lists.md +596 -0
- package/templates/docs/06-localization.md +561 -0
- package/templates/docs/07-caching-strategies.md +410 -0
- package/templates/docs/08-common-components.md +756 -0
- package/templates/docs/09-whats-included.md +279 -0
- package/templates/docs/10-mcp-server-setup.md +153 -0
- package/templates/docs/11-linked-nested-content.md +611 -0
- package/templates/docs/README.md +164 -0
- package/templates/lib/cms/getAgilityContext.ts +28 -0
- package/templates/lib/cms/getAgilityPage.ts +51 -0
- package/templates/lib/cms/getAgilitySDK.ts +22 -0
- package/templates/lib/cms/getContentItem.ts +20 -0
- package/templates/lib/cms/getContentList.ts +19 -0
- package/templates/lib/cms/getRedirections.ts +85 -0
- package/templates/lib/cms/getSitemapFlat.ts +19 -0
- package/templates/lib/cms/getSitemapNested.ts +19 -0
- package/templates/lib/env.ts +99 -0
- package/templates/lib/i18n/config.ts +28 -0
- package/templates/proxy.ts +101 -0
- package/tsconfig.json +21 -0
|
@@ -0,0 +1,180 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
+
};
|
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
exports.validateProjectName = validateProjectName;
|
|
7
|
+
exports.checkDirectoryExists = checkDirectoryExists;
|
|
8
|
+
exports.isDirectoryEmpty = isDirectoryEmpty;
|
|
9
|
+
exports.validateProjectPath = validateProjectPath;
|
|
10
|
+
exports.isGitInstalled = isGitInstalled;
|
|
11
|
+
exports.displayValidationError = displayValidationError;
|
|
12
|
+
exports.checkDiskSpace = checkDiskSpace;
|
|
13
|
+
exports.validateNodeVersion = validateNodeVersion;
|
|
14
|
+
const fs_1 = __importDefault(require("fs"));
|
|
15
|
+
const path_1 = __importDefault(require("path"));
|
|
16
|
+
const chalk_1 = __importDefault(require("chalk"));
|
|
17
|
+
/**
|
|
18
|
+
* Reserved names that cannot be used as project names
|
|
19
|
+
*/
|
|
20
|
+
const RESERVED_NAMES = [
|
|
21
|
+
'node_modules',
|
|
22
|
+
'package.json',
|
|
23
|
+
'package-lock.json',
|
|
24
|
+
'yarn.lock',
|
|
25
|
+
'pnpm-lock.yaml',
|
|
26
|
+
'bun.lockb',
|
|
27
|
+
'.git',
|
|
28
|
+
'.env',
|
|
29
|
+
'.env.local',
|
|
30
|
+
'dist',
|
|
31
|
+
'build',
|
|
32
|
+
'out',
|
|
33
|
+
'test',
|
|
34
|
+
'tests',
|
|
35
|
+
'__tests__',
|
|
36
|
+
'public',
|
|
37
|
+
'static',
|
|
38
|
+
'src',
|
|
39
|
+
'lib',
|
|
40
|
+
'components',
|
|
41
|
+
'app',
|
|
42
|
+
'pages',
|
|
43
|
+
];
|
|
44
|
+
/**
|
|
45
|
+
* Validates a project name
|
|
46
|
+
*/
|
|
47
|
+
function validateProjectName(projectName) {
|
|
48
|
+
// Check if empty
|
|
49
|
+
if (!projectName || projectName.trim().length === 0) {
|
|
50
|
+
return {
|
|
51
|
+
valid: false,
|
|
52
|
+
message: 'Project name cannot be empty',
|
|
53
|
+
};
|
|
54
|
+
}
|
|
55
|
+
// Check for valid characters (lowercase letters, numbers, hyphens, underscores)
|
|
56
|
+
if (!/^[a-z0-9-_]+$/i.test(projectName)) {
|
|
57
|
+
return {
|
|
58
|
+
valid: false,
|
|
59
|
+
message: 'Project name can only contain letters, numbers, hyphens (-), and underscores (_)',
|
|
60
|
+
};
|
|
61
|
+
}
|
|
62
|
+
// Check if it starts with a dot
|
|
63
|
+
if (projectName.startsWith('.')) {
|
|
64
|
+
return {
|
|
65
|
+
valid: false,
|
|
66
|
+
message: 'Project name cannot start with a dot (.)',
|
|
67
|
+
};
|
|
68
|
+
}
|
|
69
|
+
// Check if it starts with a number
|
|
70
|
+
if (/^\d/.test(projectName)) {
|
|
71
|
+
return {
|
|
72
|
+
valid: false,
|
|
73
|
+
message: 'Project name cannot start with a number',
|
|
74
|
+
};
|
|
75
|
+
}
|
|
76
|
+
// Check for reserved names
|
|
77
|
+
if (RESERVED_NAMES.includes(projectName.toLowerCase())) {
|
|
78
|
+
return {
|
|
79
|
+
valid: false,
|
|
80
|
+
message: `"${projectName}" is a reserved name and cannot be used`,
|
|
81
|
+
};
|
|
82
|
+
}
|
|
83
|
+
return { valid: true };
|
|
84
|
+
}
|
|
85
|
+
/**
|
|
86
|
+
* Checks if a directory already exists
|
|
87
|
+
*/
|
|
88
|
+
function checkDirectoryExists(projectPath) {
|
|
89
|
+
return fs_1.default.existsSync(projectPath);
|
|
90
|
+
}
|
|
91
|
+
/**
|
|
92
|
+
* Checks if directory is empty
|
|
93
|
+
*/
|
|
94
|
+
function isDirectoryEmpty(projectPath) {
|
|
95
|
+
if (!fs_1.default.existsSync(projectPath)) {
|
|
96
|
+
return true;
|
|
97
|
+
}
|
|
98
|
+
const files = fs_1.default.readdirSync(projectPath);
|
|
99
|
+
return files.length === 0 || files.every(file => file === '.git');
|
|
100
|
+
}
|
|
101
|
+
/**
|
|
102
|
+
* Validates that we can create a project at the given path
|
|
103
|
+
*/
|
|
104
|
+
function validateProjectPath(projectPath) {
|
|
105
|
+
const exists = checkDirectoryExists(projectPath);
|
|
106
|
+
if (exists) {
|
|
107
|
+
const isEmpty = isDirectoryEmpty(projectPath);
|
|
108
|
+
if (!isEmpty) {
|
|
109
|
+
return {
|
|
110
|
+
valid: false,
|
|
111
|
+
message: `Directory "${path_1.default.basename(projectPath)}" already exists and is not empty.\nPlease choose a different project name or remove the existing directory.`,
|
|
112
|
+
};
|
|
113
|
+
}
|
|
114
|
+
}
|
|
115
|
+
// Check write permissions of parent directory
|
|
116
|
+
const parentDir = path_1.default.dirname(projectPath);
|
|
117
|
+
try {
|
|
118
|
+
fs_1.default.accessSync(parentDir, fs_1.default.constants.W_OK);
|
|
119
|
+
}
|
|
120
|
+
catch (error) {
|
|
121
|
+
return {
|
|
122
|
+
valid: false,
|
|
123
|
+
message: `No write permission in directory "${parentDir}".\nPlease check your permissions or choose a different location.`,
|
|
124
|
+
};
|
|
125
|
+
}
|
|
126
|
+
return { valid: true };
|
|
127
|
+
}
|
|
128
|
+
/**
|
|
129
|
+
* Check if git is installed
|
|
130
|
+
*/
|
|
131
|
+
function isGitInstalled() {
|
|
132
|
+
try {
|
|
133
|
+
const { execSync } = require('child_process');
|
|
134
|
+
execSync('git --version', { stdio: 'ignore' });
|
|
135
|
+
return true;
|
|
136
|
+
}
|
|
137
|
+
catch {
|
|
138
|
+
return false;
|
|
139
|
+
}
|
|
140
|
+
}
|
|
141
|
+
/**
|
|
142
|
+
* Displays validation error with helpful formatting
|
|
143
|
+
*/
|
|
144
|
+
function displayValidationError(message) {
|
|
145
|
+
console.error('\n' + chalk_1.default.red('✖') + ' ' + chalk_1.default.red.bold('Validation Error'));
|
|
146
|
+
console.error(chalk_1.default.red(message));
|
|
147
|
+
console.error();
|
|
148
|
+
}
|
|
149
|
+
/**
|
|
150
|
+
* Check available disk space (basic check)
|
|
151
|
+
*/
|
|
152
|
+
function checkDiskSpace() {
|
|
153
|
+
try {
|
|
154
|
+
const os = require('os');
|
|
155
|
+
// Basic check - Next.js projects typically need at least 500MB
|
|
156
|
+
const REQUIRED_SPACE_MB = 500;
|
|
157
|
+
const tmpdir = os.tmpdir();
|
|
158
|
+
// This is a rough check - not perfect but better than nothing
|
|
159
|
+
return { hasSpace: true };
|
|
160
|
+
}
|
|
161
|
+
catch {
|
|
162
|
+
// If we can't check, assume it's okay
|
|
163
|
+
return { hasSpace: true };
|
|
164
|
+
}
|
|
165
|
+
}
|
|
166
|
+
/**
|
|
167
|
+
* Validate Node.js version
|
|
168
|
+
*/
|
|
169
|
+
function validateNodeVersion() {
|
|
170
|
+
const currentVersion = process.version;
|
|
171
|
+
const majorVersion = parseInt(currentVersion.split('.')[0].slice(1), 10);
|
|
172
|
+
if (majorVersion < 18) {
|
|
173
|
+
return {
|
|
174
|
+
valid: false,
|
|
175
|
+
message: `Node.js 18.0.0 or higher is required. You are using ${currentVersion}.\nPlease upgrade Node.js: https://nodejs.org/`,
|
|
176
|
+
};
|
|
177
|
+
}
|
|
178
|
+
return { valid: true };
|
|
179
|
+
}
|
|
180
|
+
//# sourceMappingURL=validation.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"validation.js","sourceRoot":"","sources":["../../src/utils/validation.ts"],"names":[],"mappings":"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"}
|
package/package.json
ADDED
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@agility/create-next-app",
|
|
3
|
+
"version": "1.0.0-beta.2",
|
|
4
|
+
"description": "Create a new Next.js project with Agility CMS integration",
|
|
5
|
+
"main": "dist/cli/index.js",
|
|
6
|
+
"bin": {
|
|
7
|
+
"create-agility-app": "./bin/create-agility-app.js"
|
|
8
|
+
},
|
|
9
|
+
"scripts": {
|
|
10
|
+
"clean": "rm -rf dist",
|
|
11
|
+
"build": "npm run clean && tsc",
|
|
12
|
+
"dev": "tsx src/cli/index.ts",
|
|
13
|
+
"test": "tsx src/cli/index.ts test-app --typescript --tailwind",
|
|
14
|
+
"prepublishOnly": "npm run build"
|
|
15
|
+
},
|
|
16
|
+
"keywords": [
|
|
17
|
+
"nextjs",
|
|
18
|
+
"agility",
|
|
19
|
+
"cms",
|
|
20
|
+
"cli",
|
|
21
|
+
"scaffold"
|
|
22
|
+
],
|
|
23
|
+
"author": "",
|
|
24
|
+
"license": "MIT",
|
|
25
|
+
"dependencies": {
|
|
26
|
+
"@agility/content-fetch": "^2.0.9",
|
|
27
|
+
"boxen": "^8.0.1",
|
|
28
|
+
"chalk": "^5.3.0",
|
|
29
|
+
"commander": "^11.1.0",
|
|
30
|
+
"inquirer": "^9.2.15",
|
|
31
|
+
"open": "^10.1.0",
|
|
32
|
+
"ora": "^8.0.1",
|
|
33
|
+
"update-notifier": "^7.3.1"
|
|
34
|
+
},
|
|
35
|
+
"devDependencies": {
|
|
36
|
+
"@types/inquirer": "^9.0.7",
|
|
37
|
+
"@types/node": "^20.0.0",
|
|
38
|
+
"@types/update-notifier": "^6.0.8",
|
|
39
|
+
"tsx": "^4.7.0",
|
|
40
|
+
"typescript": "^5.0.0"
|
|
41
|
+
},
|
|
42
|
+
"engines": {
|
|
43
|
+
"node": ">=18.0.0"
|
|
44
|
+
}
|
|
45
|
+
}
|
|
@@ -0,0 +1,100 @@
|
|
|
1
|
+
import ora from 'ora';
|
|
2
|
+
import chalk from 'chalk';
|
|
3
|
+
import type { ApiKeys } from '../../types';
|
|
4
|
+
import { getMgmtOAuthUrl } from '../utils/getMgmtAPIUrl';
|
|
5
|
+
|
|
6
|
+
/**
|
|
7
|
+
* Gets API keys for an Agility instance
|
|
8
|
+
* @param accessToken - OAuth access token
|
|
9
|
+
* @param instanceGuid - Instance GUID
|
|
10
|
+
* @returns Object with fetch and preview API keys
|
|
11
|
+
*/
|
|
12
|
+
export async function generateApiKeys(accessToken: string, instanceGuid: string): Promise<ApiKeys> {
|
|
13
|
+
const spinner = ora('Fetching API keys...').start();
|
|
14
|
+
|
|
15
|
+
try {
|
|
16
|
+
const oauthBaseUrl = getMgmtOAuthUrl({ guid: instanceGuid });
|
|
17
|
+
|
|
18
|
+
// Get Fetch API Key
|
|
19
|
+
const fetchKeyUrl = `${oauthBaseUrl}GetFetchKey?guid=${instanceGuid}`;
|
|
20
|
+
const fetchKeyResponse = await fetch(fetchKeyUrl, {
|
|
21
|
+
method: 'GET',
|
|
22
|
+
headers: {
|
|
23
|
+
'Authorization': `Bearer ${accessToken}`,
|
|
24
|
+
'Content-Type': 'application/json',
|
|
25
|
+
},
|
|
26
|
+
});
|
|
27
|
+
|
|
28
|
+
if (!fetchKeyResponse.ok) {
|
|
29
|
+
const errorText = await fetchKeyResponse.text();
|
|
30
|
+
let errorMessage = `Failed to get Fetch Key: ${fetchKeyResponse.status} ${fetchKeyResponse.statusText}`;
|
|
31
|
+
try {
|
|
32
|
+
const errorJson = JSON.parse(errorText);
|
|
33
|
+
if (errorJson.message) {
|
|
34
|
+
errorMessage += ` - ${errorJson.message}`;
|
|
35
|
+
} else {
|
|
36
|
+
errorMessage += ` - ${errorText}`;
|
|
37
|
+
}
|
|
38
|
+
} catch {
|
|
39
|
+
errorMessage += ` - ${errorText}`;
|
|
40
|
+
}
|
|
41
|
+
throw new Error(errorMessage);
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
const fetchKey = await fetchKeyResponse.text();
|
|
45
|
+
if (!fetchKey) {
|
|
46
|
+
throw new Error('No Fetch Key received from API');
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
// Get Preview API Key
|
|
50
|
+
const previewKeyUrl = `${oauthBaseUrl}GetPreviewKey?guid=${instanceGuid}`;
|
|
51
|
+
|
|
52
|
+
const previewKeyResponse = await fetch(previewKeyUrl, {
|
|
53
|
+
method: 'GET',
|
|
54
|
+
headers: {
|
|
55
|
+
'Authorization': `Bearer ${accessToken}`,
|
|
56
|
+
'Content-Type': 'application/json',
|
|
57
|
+
},
|
|
58
|
+
});
|
|
59
|
+
|
|
60
|
+
if (!previewKeyResponse.ok) {
|
|
61
|
+
const errorText = await previewKeyResponse.text();
|
|
62
|
+
let errorMessage = `Failed to get Preview Key: ${previewKeyResponse.status} ${previewKeyResponse.statusText}`;
|
|
63
|
+
try {
|
|
64
|
+
const errorJson = JSON.parse(errorText);
|
|
65
|
+
if (errorJson.message) {
|
|
66
|
+
errorMessage += ` - ${errorJson.message}`;
|
|
67
|
+
} else {
|
|
68
|
+
errorMessage += ` - ${errorText}`;
|
|
69
|
+
}
|
|
70
|
+
} catch {
|
|
71
|
+
errorMessage += ` - ${errorText}`;
|
|
72
|
+
}
|
|
73
|
+
throw new Error(errorMessage);
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
const previewKey = await previewKeyResponse.text();
|
|
77
|
+
if (!previewKey) {
|
|
78
|
+
throw new Error('No Preview Key received from API');
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
spinner.succeed('API keys retrieved');
|
|
82
|
+
|
|
83
|
+
return {
|
|
84
|
+
fetchKey,
|
|
85
|
+
previewKey,
|
|
86
|
+
securityKey: '' // Security key is typically not needed for basic setup
|
|
87
|
+
};
|
|
88
|
+
} catch (error) {
|
|
89
|
+
spinner.fail('Failed to get API keys');
|
|
90
|
+
if (error instanceof Error) {
|
|
91
|
+
console.error(chalk.red(`Error: ${error.message}`));
|
|
92
|
+
// Log additional details if available
|
|
93
|
+
if (error instanceof Error && 'cause' in error) {
|
|
94
|
+
console.error(chalk.gray(`Details: ${JSON.stringify(error.cause)}`));
|
|
95
|
+
}
|
|
96
|
+
}
|
|
97
|
+
throw error;
|
|
98
|
+
}
|
|
99
|
+
}
|
|
100
|
+
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import type { ApiKeys } from '../../types';
|
|
2
|
+
import { generateApiKeys } from './generateApiKeys';
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* Gets API keys for an existing instance
|
|
6
|
+
* @param accessToken - OAuth access token
|
|
7
|
+
* @param instanceGuid - Instance GUID
|
|
8
|
+
* @returns Object with fetch and preview API keys
|
|
9
|
+
*/
|
|
10
|
+
export async function getApiKeys(accessToken: string, instanceGuid: string): Promise<ApiKeys> {
|
|
11
|
+
return generateApiKeys(accessToken, instanceGuid);
|
|
12
|
+
}
|
|
13
|
+
|
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
import inquirer from 'inquirer';
|
|
2
|
+
import ora from 'ora';
|
|
3
|
+
import type { InstanceData } from '../../types';
|
|
4
|
+
import { generateApiKeys } from '../api-keys/generateApiKeys';
|
|
5
|
+
|
|
6
|
+
/**
|
|
7
|
+
* Creates a new blank Agility instance
|
|
8
|
+
* @param accessToken - OAuth access token
|
|
9
|
+
* @returns Instance data with GUID and API keys
|
|
10
|
+
*/
|
|
11
|
+
export async function createNewInstance(accessToken: string): Promise<InstanceData> {
|
|
12
|
+
const spinner = ora('Creating new Agility instance...').start();
|
|
13
|
+
|
|
14
|
+
try {
|
|
15
|
+
// Prompt for instance name
|
|
16
|
+
const answers = await inquirer.prompt<{ instanceName: string }>([
|
|
17
|
+
{
|
|
18
|
+
type: 'input',
|
|
19
|
+
name: 'instanceName',
|
|
20
|
+
message: 'Enter a name for your new instance:',
|
|
21
|
+
default: 'My Agility Instance',
|
|
22
|
+
validate: (input: string) => {
|
|
23
|
+
if (!input || input.trim().length === 0) {
|
|
24
|
+
return 'Instance name is required';
|
|
25
|
+
}
|
|
26
|
+
return true;
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
]);
|
|
30
|
+
|
|
31
|
+
spinner.text = 'Creating instance...';
|
|
32
|
+
|
|
33
|
+
// In a real implementation, this would call Agility's API to create an instance
|
|
34
|
+
// For now, we'll use a placeholder that would need to be implemented
|
|
35
|
+
// const instance = await createAgilityInstance(accessToken, answers.instanceName);
|
|
36
|
+
|
|
37
|
+
// For now, we'll prompt for the instance GUID manually
|
|
38
|
+
const guidAnswer = await inquirer.prompt<{ instanceGuid: string }>([
|
|
39
|
+
{
|
|
40
|
+
type: 'input',
|
|
41
|
+
name: 'instanceGuid',
|
|
42
|
+
message: 'Enter the instance GUID (you can find this in Agility CMS):',
|
|
43
|
+
validate: (input: string) => {
|
|
44
|
+
if (!input || input.trim().length === 0) {
|
|
45
|
+
return 'Instance GUID is required';
|
|
46
|
+
}
|
|
47
|
+
return true;
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
]);
|
|
51
|
+
|
|
52
|
+
spinner.succeed('Instance ready');
|
|
53
|
+
|
|
54
|
+
// Generate API keys
|
|
55
|
+
const apiKeys = await generateApiKeys(accessToken, guidAnswer.instanceGuid);
|
|
56
|
+
|
|
57
|
+
return {
|
|
58
|
+
guid: guidAnswer.instanceGuid,
|
|
59
|
+
name: answers.instanceName,
|
|
60
|
+
apiKeys
|
|
61
|
+
};
|
|
62
|
+
} catch (error) {
|
|
63
|
+
spinner.fail('Failed to create instance');
|
|
64
|
+
throw error;
|
|
65
|
+
}
|
|
66
|
+
}
|
|
67
|
+
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
import chalk from 'chalk';
|
|
2
|
+
import type { Instance } from '../../types';
|
|
3
|
+
import { getMgmtAPIUrl } from '../utils/getMgmtAPIUrl';
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
* Gets available Agility instances for the authenticated user
|
|
7
|
+
* @param accessToken - OAuth access token
|
|
8
|
+
* @returns Array of instances
|
|
9
|
+
*/
|
|
10
|
+
export async function getAvailableInstances(accessToken: string): Promise<Instance[]> {
|
|
11
|
+
try {
|
|
12
|
+
// Use the Agility Management API to get current user and their instances
|
|
13
|
+
// Note: We don't have a GUID yet, so we use the default URL
|
|
14
|
+
const apiBaseUrl = getMgmtAPIUrl();
|
|
15
|
+
const response = await fetch(`${apiBaseUrl}users/me`, {
|
|
16
|
+
method: 'GET',
|
|
17
|
+
headers: {
|
|
18
|
+
'Authorization': `Bearer ${accessToken}`,
|
|
19
|
+
'Content-Type': 'application/json',
|
|
20
|
+
},
|
|
21
|
+
});
|
|
22
|
+
|
|
23
|
+
if (!response.ok) {
|
|
24
|
+
throw new Error(`Failed to get user info: ${response.status} ${response.statusText}`);
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
const userData = await response.json() as {
|
|
28
|
+
websiteAccess?: Array<{
|
|
29
|
+
websiteName: string;
|
|
30
|
+
displayName: string;
|
|
31
|
+
guid: string;
|
|
32
|
+
orgName?: string;
|
|
33
|
+
}>;
|
|
34
|
+
};
|
|
35
|
+
|
|
36
|
+
// Convert websiteAccess to instances
|
|
37
|
+
const instances: Instance[] = (userData.websiteAccess || []).map(access => ({
|
|
38
|
+
name: access.displayName || access.websiteName,
|
|
39
|
+
guid: access.guid,
|
|
40
|
+
org: access.orgName,
|
|
41
|
+
}));
|
|
42
|
+
|
|
43
|
+
return instances;
|
|
44
|
+
} catch (error) {
|
|
45
|
+
console.warn(chalk.yellow('Could not fetch instances from API'));
|
|
46
|
+
throw error;
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
|
|
@@ -0,0 +1,90 @@
|
|
|
1
|
+
import inquirer from 'inquirer';
|
|
2
|
+
import chalk from 'chalk';
|
|
3
|
+
import ora from 'ora';
|
|
4
|
+
import type { InstanceData, CliOptions } from '../../types';
|
|
5
|
+
import { getAvailableInstances } from './getAvailableInstances';
|
|
6
|
+
import { generateApiKeys } from '../api-keys/generateApiKeys';
|
|
7
|
+
|
|
8
|
+
/**
|
|
9
|
+
* Manages Agility CMS instance selection from existing instances
|
|
10
|
+
* @param accessToken - OAuth access token
|
|
11
|
+
* @param options - CLI options
|
|
12
|
+
* @returns Instance data with GUID and API keys
|
|
13
|
+
*/
|
|
14
|
+
export async function manageInstance(accessToken: string, options: CliOptions): Promise<InstanceData> {
|
|
15
|
+
const spinner = ora('Fetching Agility instances...').start();
|
|
16
|
+
|
|
17
|
+
try {
|
|
18
|
+
// Fetch available instances using the Management API
|
|
19
|
+
const instances = await getAvailableInstances(accessToken);
|
|
20
|
+
|
|
21
|
+
spinner.succeed(`Found ${instances.length} instance(s)`);
|
|
22
|
+
|
|
23
|
+
if (instances.length === 0) {
|
|
24
|
+
throw new Error('No Agility CMS instances found. Please create an instance in Agility CMS first, or skip the connection for now.');
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
// Group instances by organization
|
|
28
|
+
const instancesByOrg = new Map<string, typeof instances>();
|
|
29
|
+
for (const inst of instances) {
|
|
30
|
+
const orgName = inst.org || 'No Organization';
|
|
31
|
+
if (!instancesByOrg.has(orgName)) {
|
|
32
|
+
instancesByOrg.set(orgName, []);
|
|
33
|
+
}
|
|
34
|
+
instancesByOrg.get(orgName)!.push(inst);
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
// Sort organizations alphabetically
|
|
38
|
+
const sortedOrgs = Array.from(instancesByOrg.keys()).sort();
|
|
39
|
+
|
|
40
|
+
// Build choices with organization grouping
|
|
41
|
+
const instanceChoices: Array<{ name: string; value: string } | inquirer.Separator> = [];
|
|
42
|
+
|
|
43
|
+
for (const orgName of sortedOrgs) {
|
|
44
|
+
// Add separator for organization (except for first one)
|
|
45
|
+
if (instanceChoices.length > 0) {
|
|
46
|
+
instanceChoices.push(new inquirer.Separator());
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
// Add organization header
|
|
50
|
+
instanceChoices.push(new inquirer.Separator(chalk.cyan(` ${orgName}`)));
|
|
51
|
+
|
|
52
|
+
// Add instances for this organization
|
|
53
|
+
const orgInstances = instancesByOrg.get(orgName)!;
|
|
54
|
+
for (const inst of orgInstances) {
|
|
55
|
+
instanceChoices.push({
|
|
56
|
+
name: ` - ${inst.name} (${inst.guid})`,
|
|
57
|
+
value: inst.guid
|
|
58
|
+
});
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
const selected = await inquirer.prompt<{ instanceGuid: string }>([
|
|
63
|
+
{
|
|
64
|
+
type: 'list',
|
|
65
|
+
name: 'instanceGuid',
|
|
66
|
+
message: 'Select an instance:',
|
|
67
|
+
choices: instanceChoices
|
|
68
|
+
}
|
|
69
|
+
]);
|
|
70
|
+
|
|
71
|
+
// Find the selected instance to get its name
|
|
72
|
+
const selectedInstance = instances.find(inst => inst.guid === selected.instanceGuid);
|
|
73
|
+
if (!selectedInstance) {
|
|
74
|
+
throw new Error('Selected instance not found');
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
// Generate API keys for selected instance
|
|
78
|
+
const apiKeys = await generateApiKeys(accessToken, selected.instanceGuid);
|
|
79
|
+
|
|
80
|
+
return {
|
|
81
|
+
guid: selected.instanceGuid,
|
|
82
|
+
name: selectedInstance.name,
|
|
83
|
+
apiKeys
|
|
84
|
+
};
|
|
85
|
+
} catch (error) {
|
|
86
|
+
spinner.fail('Failed to manage instance');
|
|
87
|
+
throw error;
|
|
88
|
+
}
|
|
89
|
+
}
|
|
90
|
+
|
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
interface Props {
|
|
2
|
+
/**
|
|
3
|
+
* The instance guid (optional - if not provided, uses default URL)
|
|
4
|
+
*/
|
|
5
|
+
guid?: string;
|
|
6
|
+
}
|
|
7
|
+
|
|
8
|
+
/**
|
|
9
|
+
* Gets the management API base URL based on the instance GUID
|
|
10
|
+
* @param guid - The instance GUID (optional - if not provided, uses default URL)
|
|
11
|
+
* @returns The base URL for the management API
|
|
12
|
+
*/
|
|
13
|
+
export const getMgmtAPIUrl = ({ guid }: Props = {}): string => {
|
|
14
|
+
const baseUrlSuffixes: { [key: string]: string } = {
|
|
15
|
+
u: '',
|
|
16
|
+
c: '-ca',
|
|
17
|
+
e: '-eu',
|
|
18
|
+
a: '-aus',
|
|
19
|
+
d: '-dev'
|
|
20
|
+
};
|
|
21
|
+
|
|
22
|
+
// If no GUID provided, use default URL
|
|
23
|
+
if (!guid || guid.length === 0) {
|
|
24
|
+
return `https://mgmt.aglty.io/api/v1/`;
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
const env = guid.substring(guid.length - 1);
|
|
28
|
+
|
|
29
|
+
// New format of guid
|
|
30
|
+
if (baseUrlSuffixes.hasOwnProperty(env)) {
|
|
31
|
+
return `https://mgmt${baseUrlSuffixes[env]}.aglty.io/api/v1/`;
|
|
32
|
+
} else {
|
|
33
|
+
// use default url
|
|
34
|
+
return `https://mgmt.aglty.io/api/v1/`;
|
|
35
|
+
}
|
|
36
|
+
};
|
|
37
|
+
|
|
38
|
+
/**
|
|
39
|
+
* Gets the management OAuth base URL based on the instance GUID
|
|
40
|
+
* @param guid - The instance GUID (optional - if not provided, uses default URL)
|
|
41
|
+
* @returns The base URL for the management OAuth endpoints
|
|
42
|
+
*/
|
|
43
|
+
export const getMgmtOAuthUrl = ({ guid }: Props = {}): string => {
|
|
44
|
+
const baseUrlSuffixes: { [key: string]: string } = {
|
|
45
|
+
u: '',
|
|
46
|
+
c: '-ca',
|
|
47
|
+
e: '-eu',
|
|
48
|
+
a: '-aus',
|
|
49
|
+
d: '-dev',
|
|
50
|
+
us2: 'usa2'
|
|
51
|
+
};
|
|
52
|
+
|
|
53
|
+
// If no GUID provided, use default URL
|
|
54
|
+
if (!guid || guid.length === 0) {
|
|
55
|
+
return `https://mgmt.aglty.io/oauth/`;
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
const env = guid.substring(guid.length - 1);
|
|
59
|
+
|
|
60
|
+
// New format of guid
|
|
61
|
+
if (baseUrlSuffixes.hasOwnProperty(env)) {
|
|
62
|
+
return `https://mgmt${baseUrlSuffixes[env]}.aglty.io/oauth/`;
|
|
63
|
+
} else {
|
|
64
|
+
// use default url
|
|
65
|
+
return `https://mgmt.aglty.io/oauth/`;
|
|
66
|
+
}
|
|
67
|
+
};
|
|
68
|
+
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
import inquirer from 'inquirer';
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Alternative: Manual API key input if OAuth is not available
|
|
5
|
+
* @returns API key or access token
|
|
6
|
+
*/
|
|
7
|
+
export async function authenticateWithApiKey(): Promise<string> {
|
|
8
|
+
const answers = await inquirer.prompt<{ apiKey: string }>([
|
|
9
|
+
{
|
|
10
|
+
type: 'input',
|
|
11
|
+
name: 'apiKey',
|
|
12
|
+
message: 'Enter your Agility CMS API key:',
|
|
13
|
+
validate: (input: string) => {
|
|
14
|
+
if (!input || input.trim().length === 0) {
|
|
15
|
+
return 'API key is required';
|
|
16
|
+
}
|
|
17
|
+
return true;
|
|
18
|
+
}
|
|
19
|
+
}
|
|
20
|
+
]);
|
|
21
|
+
|
|
22
|
+
return answers.apiKey;
|
|
23
|
+
}
|
|
24
|
+
|