pixelstart 0.0.1 → 1.0.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.
- package/dist/index.js +44 -14
- package/dist/modules/init.js +49 -4
- package/dist/modules/license.d.ts +19 -5
- package/dist/modules/license.js +69 -66
- package/dist/modules/logo.js +9 -11
- package/dist/modules/nda.js +160 -51
- package/dist/modules/ui.d.ts +1 -0
- package/dist/modules/ui.js +5 -4
- package/package.json +18 -6
- package/src/index.ts +0 -95
- package/src/modules/init.ts +0 -100
- package/src/modules/license.ts +0 -84
- package/src/modules/logo.ts +0 -21
- package/src/modules/nda.ts +0 -77
- package/src/modules/requirements.ts +0 -107
- package/src/modules/ui.ts +0 -35
- package/tsconfig.json +0 -16
package/dist/index.js
CHANGED
|
@@ -1,16 +1,14 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
import chalk from 'chalk';
|
|
3
3
|
import { showLogo } from './modules/logo.js';
|
|
4
|
-
import { banner, section, error, info } from './modules/ui.js';
|
|
4
|
+
import { banner, section, success, error, info } from './modules/ui.js';
|
|
5
5
|
import { checkRequirements } from './modules/requirements.js';
|
|
6
6
|
import { showNDA } from './modules/nda.js';
|
|
7
|
-
import { showLicense } from './modules/license.js';
|
|
8
7
|
import { initProject } from './modules/init.js';
|
|
9
|
-
const VERSION = '
|
|
8
|
+
const VERSION = '1.0.0';
|
|
10
9
|
async function main() {
|
|
11
10
|
const args = process.argv.slice(2);
|
|
12
11
|
const command = args[0];
|
|
13
|
-
// --help / --version work without logo
|
|
14
12
|
if (command === '--help' || command === '-h') {
|
|
15
13
|
printHelp();
|
|
16
14
|
return;
|
|
@@ -19,25 +17,16 @@ async function main() {
|
|
|
19
17
|
console.log(`pixelstart v${VERSION}`);
|
|
20
18
|
return;
|
|
21
19
|
}
|
|
22
|
-
// Interactive flow — show logo + banner
|
|
23
20
|
showLogo();
|
|
24
21
|
banner();
|
|
25
|
-
// Step 1: Check requirements
|
|
26
22
|
const reqsOk = await checkRequirements();
|
|
27
23
|
if (!reqsOk) {
|
|
28
24
|
process.exit(1);
|
|
29
25
|
}
|
|
30
|
-
// Step 2: NDA
|
|
31
26
|
const ndaOk = await showNDA();
|
|
32
27
|
if (!ndaOk) {
|
|
33
28
|
process.exit(0);
|
|
34
29
|
}
|
|
35
|
-
// Step 3: License
|
|
36
|
-
const tier = await showLicense();
|
|
37
|
-
if (!tier) {
|
|
38
|
-
process.exit(0);
|
|
39
|
-
}
|
|
40
|
-
// Step 4: Init project (if `init` command or no command)
|
|
41
30
|
if (!command || command === 'init') {
|
|
42
31
|
await initProject();
|
|
43
32
|
}
|
|
@@ -46,12 +35,52 @@ async function main() {
|
|
|
46
35
|
info(`Command "${command}" will be available after project initialization.`);
|
|
47
36
|
console.log('');
|
|
48
37
|
}
|
|
38
|
+
else if (command === 'pull') {
|
|
39
|
+
await retryPull();
|
|
40
|
+
}
|
|
49
41
|
else {
|
|
50
42
|
error(`Unknown command: ${command}`);
|
|
51
43
|
info('Run `pixelstart --help` for usage.');
|
|
52
44
|
process.exit(1);
|
|
53
45
|
}
|
|
54
46
|
}
|
|
47
|
+
async function retryPull() {
|
|
48
|
+
section('Pull Docker Image');
|
|
49
|
+
const inquirer = await import('inquirer');
|
|
50
|
+
const { validateLicense, exchangeDownloadToken } = await import('./modules/license.js');
|
|
51
|
+
const { key } = await inquirer.default.prompt([
|
|
52
|
+
{
|
|
53
|
+
type: 'input',
|
|
54
|
+
name: 'key',
|
|
55
|
+
message: chalk.white('License key:'),
|
|
56
|
+
validate: (input) => input.trim().length > 0 || 'License key is required',
|
|
57
|
+
},
|
|
58
|
+
]);
|
|
59
|
+
console.log('');
|
|
60
|
+
info('Validating license...');
|
|
61
|
+
const licenseResult = await validateLicense(key.trim(), 'latest');
|
|
62
|
+
if (!licenseResult)
|
|
63
|
+
return;
|
|
64
|
+
success('License validated!');
|
|
65
|
+
console.log('');
|
|
66
|
+
info('Generating download token...');
|
|
67
|
+
const downloadResult = await exchangeDownloadToken(licenseResult.downloadToken);
|
|
68
|
+
if (!downloadResult)
|
|
69
|
+
return;
|
|
70
|
+
console.log('');
|
|
71
|
+
info('Pulling Docker image...');
|
|
72
|
+
const { execSync } = await import('child_process');
|
|
73
|
+
try {
|
|
74
|
+
execSync(downloadResult.dockerCommand, { stdio: 'inherit' });
|
|
75
|
+
console.log('');
|
|
76
|
+
success(`Docker image ${chalk.bold(downloadResult.image)} pulled successfully!`);
|
|
77
|
+
}
|
|
78
|
+
catch {
|
|
79
|
+
error('Docker pull failed. You can retry manually:');
|
|
80
|
+
console.log('');
|
|
81
|
+
console.log(chalk.white(` ${downloadResult.dockerCommand}`));
|
|
82
|
+
}
|
|
83
|
+
}
|
|
55
84
|
function printHelp() {
|
|
56
85
|
console.log(`
|
|
57
86
|
${chalk.hex('#7C3AED').bold('pixelstart')} v${VERSION}
|
|
@@ -61,6 +90,7 @@ function printHelp() {
|
|
|
61
90
|
|
|
62
91
|
${chalk.gray('Commands:')}
|
|
63
92
|
init Scaffold a new PixelStack Lite project
|
|
93
|
+
pull Pull Docker image with license key
|
|
64
94
|
up Start all services
|
|
65
95
|
down Stop all services
|
|
66
96
|
status Show service status
|
|
@@ -73,10 +103,10 @@ function printHelp() {
|
|
|
73
103
|
${chalk.gray('Examples:')}
|
|
74
104
|
pixelstart Launch interactive installer
|
|
75
105
|
pixelstart init Create a new project
|
|
106
|
+
pixelstart pull Pull Docker image
|
|
76
107
|
pixelstart up Start services
|
|
77
108
|
`);
|
|
78
109
|
}
|
|
79
|
-
// Catch unhandled errors gracefully
|
|
80
110
|
process.on('unhandledRejection', (err) => {
|
|
81
111
|
console.error('');
|
|
82
112
|
error(`Unexpected error: ${err}`);
|
package/dist/modules/init.js
CHANGED
|
@@ -1,8 +1,10 @@
|
|
|
1
|
+
import { execSync } from 'child_process';
|
|
1
2
|
import fs from 'fs';
|
|
2
3
|
import path from 'path';
|
|
3
4
|
import inquirer from 'inquirer';
|
|
4
5
|
import chalk from 'chalk';
|
|
5
6
|
import { section, success, error, info } from './ui.js';
|
|
7
|
+
import { validateLicense, exchangeDownloadToken } from './license.js';
|
|
6
8
|
export async function initProject() {
|
|
7
9
|
section('Project Setup');
|
|
8
10
|
const config = await inquirer.prompt([
|
|
@@ -36,6 +38,12 @@ export async function initProject() {
|
|
|
36
38
|
mask: '*',
|
|
37
39
|
validate: (input) => input.length >= 8 || 'Min 8 characters',
|
|
38
40
|
},
|
|
41
|
+
{
|
|
42
|
+
type: 'input',
|
|
43
|
+
name: 'licenseKey',
|
|
44
|
+
message: chalk.white('License key:'),
|
|
45
|
+
validate: (input) => input.trim().length > 0 || 'License key is required',
|
|
46
|
+
},
|
|
39
47
|
]);
|
|
40
48
|
console.log('');
|
|
41
49
|
info(`Creating project in ${chalk.bold(config.directory)}`);
|
|
@@ -71,15 +79,52 @@ data/
|
|
|
71
79
|
`);
|
|
72
80
|
success('Created .gitignore');
|
|
73
81
|
console.log('');
|
|
74
|
-
|
|
82
|
+
info('Validating license...');
|
|
83
|
+
console.log('');
|
|
84
|
+
const licenseResult = await validateLicense(config.licenseKey.trim(), 'latest');
|
|
85
|
+
if (!licenseResult) {
|
|
86
|
+
error('License validation failed. Project files created but Docker image not downloaded.');
|
|
87
|
+
info('You can retry later with: pixelstart pull');
|
|
88
|
+
printNextSteps(config);
|
|
89
|
+
return;
|
|
90
|
+
}
|
|
91
|
+
success('License validated!');
|
|
92
|
+
info(`Remaining downloads today: ${chalk.bold(String(licenseResult.remainingDownloads))}`);
|
|
93
|
+
console.log('');
|
|
94
|
+
info('Generating download token...');
|
|
95
|
+
const downloadResult = await exchangeDownloadToken(licenseResult.downloadToken);
|
|
96
|
+
if (!downloadResult) {
|
|
97
|
+
error('Failed to generate download token. Project files created but Docker image not downloaded.');
|
|
98
|
+
info('You can retry later with: pixelstart pull');
|
|
99
|
+
printNextSteps(config);
|
|
100
|
+
return;
|
|
101
|
+
}
|
|
75
102
|
console.log('');
|
|
76
|
-
info(
|
|
77
|
-
console.log(chalk.white(` cd ${config.directory}`));
|
|
78
|
-
console.log(chalk.white(' pixelstart up'));
|
|
103
|
+
info('Pulling Docker image...');
|
|
79
104
|
console.log('');
|
|
105
|
+
try {
|
|
106
|
+
execSync(downloadResult.dockerCommand, { stdio: 'inherit' });
|
|
107
|
+
console.log('');
|
|
108
|
+
success(`Docker image ${chalk.bold(downloadResult.image)} pulled successfully!`);
|
|
109
|
+
}
|
|
110
|
+
catch (err) {
|
|
111
|
+
error('Docker pull failed. You can retry manually:');
|
|
112
|
+
console.log('');
|
|
113
|
+
console.log(chalk.white(` ${downloadResult.dockerCommand}`));
|
|
114
|
+
}
|
|
115
|
+
console.log('');
|
|
116
|
+
success(`Project "${chalk.bold(config.name)}" created!`);
|
|
117
|
+
printNextSteps(config);
|
|
80
118
|
}
|
|
81
119
|
catch (err) {
|
|
82
120
|
error(`Failed to create project: ${err}`);
|
|
83
121
|
process.exit(1);
|
|
84
122
|
}
|
|
85
123
|
}
|
|
124
|
+
function printNextSteps(config) {
|
|
125
|
+
console.log('');
|
|
126
|
+
info('Next steps:');
|
|
127
|
+
console.log(chalk.white(` cd ${config.directory}`));
|
|
128
|
+
console.log(chalk.white(' pixelstart up'));
|
|
129
|
+
console.log('');
|
|
130
|
+
}
|
|
@@ -1,5 +1,19 @@
|
|
|
1
|
-
export
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
1
|
+
export interface LicenseValidation {
|
|
2
|
+
success: boolean;
|
|
3
|
+
downloadToken: string;
|
|
4
|
+
expiresAt: string;
|
|
5
|
+
imageTag: string;
|
|
6
|
+
remainingDownloads: number;
|
|
7
|
+
}
|
|
8
|
+
export interface DownloadResult {
|
|
9
|
+
success: boolean;
|
|
10
|
+
dockerCommand: string;
|
|
11
|
+
image: string;
|
|
12
|
+
tag: string;
|
|
13
|
+
}
|
|
14
|
+
export declare function validateLicense(licenseKey: string, imageTag: string): Promise<LicenseValidation | null>;
|
|
15
|
+
export declare function exchangeDownloadToken(token: string): Promise<DownloadResult | null>;
|
|
16
|
+
export declare function showLicense(): Promise<{
|
|
17
|
+
key: string;
|
|
18
|
+
imageTag: string;
|
|
19
|
+
} | null>;
|
package/dist/modules/license.js
CHANGED
|
@@ -1,76 +1,79 @@
|
|
|
1
|
-
import inquirer from 'inquirer';
|
|
2
1
|
import chalk from 'chalk';
|
|
3
|
-
import { section, success, info } from './ui.js';
|
|
4
|
-
const
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
2
|
+
import { section, success, error, info } from './ui.js';
|
|
3
|
+
const SUPABASE_URL = 'https://qnuzhgozszftvvxsnaos.supabase.co';
|
|
4
|
+
const ANON_KEY = 'eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJzdXBhYmFzZSIsInJlZiI6InFudXpoZ296c3pmdHZ2eHNuYW9zIiwicm9sZSI6ImFub24iLCJpYXQiOjE3ODM0MjEwODMsImV4cCI6MjA5ODk5NzA4M30.q3mgpAS8nm1OtvnlKuOgTEi_vLmb46bV0sf3bS-fSCg';
|
|
5
|
+
const EDGE_FUNCTION = `${SUPABASE_URL}/functions/v1/proxy-package`;
|
|
6
|
+
export async function validateLicense(licenseKey, imageTag) {
|
|
7
|
+
try {
|
|
8
|
+
const res = await fetch(EDGE_FUNCTION, {
|
|
9
|
+
method: 'POST',
|
|
10
|
+
headers: {
|
|
11
|
+
'Content-Type': 'application/json',
|
|
12
|
+
'apikey': ANON_KEY,
|
|
13
|
+
},
|
|
14
|
+
body: JSON.stringify({ license: licenseKey, imageTag }),
|
|
15
|
+
});
|
|
16
|
+
const data = await res.json();
|
|
17
|
+
if (!res.ok || data.error) {
|
|
18
|
+
error(data.error || 'License validation failed');
|
|
19
|
+
if (data.details)
|
|
20
|
+
info(data.details);
|
|
21
|
+
return null;
|
|
22
|
+
}
|
|
23
|
+
return data;
|
|
24
|
+
}
|
|
25
|
+
catch (err) {
|
|
26
|
+
error(`Network error: ${err}`);
|
|
27
|
+
return null;
|
|
28
|
+
}
|
|
29
|
+
}
|
|
30
|
+
export async function exchangeDownloadToken(token) {
|
|
31
|
+
try {
|
|
32
|
+
const res = await fetch(EDGE_FUNCTION, {
|
|
33
|
+
method: 'POST',
|
|
34
|
+
headers: {
|
|
35
|
+
'Content-Type': 'application/json',
|
|
36
|
+
'apikey': ANON_KEY,
|
|
37
|
+
},
|
|
38
|
+
body: JSON.stringify({ downloadToken: token }),
|
|
39
|
+
});
|
|
40
|
+
const data = await res.json();
|
|
41
|
+
if (!res.ok || data.error) {
|
|
42
|
+
error(data.error || 'Token exchange failed');
|
|
43
|
+
if (data.details)
|
|
44
|
+
info(data.details);
|
|
45
|
+
return null;
|
|
46
|
+
}
|
|
47
|
+
return data;
|
|
48
|
+
}
|
|
49
|
+
catch (err) {
|
|
50
|
+
error(`Network error: ${err}`);
|
|
51
|
+
return null;
|
|
52
|
+
}
|
|
53
|
+
}
|
|
21
54
|
export async function showLicense() {
|
|
22
55
|
section('License');
|
|
23
|
-
console.log(chalk.white('
|
|
56
|
+
console.log(chalk.white(' Enter your PixelStack license key to download the image.'));
|
|
24
57
|
console.log('');
|
|
25
|
-
|
|
26
|
-
const isActive = tier.value === 'community';
|
|
27
|
-
const marker = isActive ? chalk.green('●') : chalk.gray('○');
|
|
28
|
-
console.log(` ${marker} ${chalk.bold(tier.name)}`);
|
|
29
|
-
console.log(` ${chalk.gray(tier.description)}`);
|
|
30
|
-
console.log('');
|
|
31
|
-
}
|
|
32
|
-
const { tier } = await inquirer.prompt([
|
|
58
|
+
const { key } = await import('inquirer').then(m => m.default.prompt([
|
|
33
59
|
{
|
|
34
|
-
type: '
|
|
35
|
-
name: '
|
|
36
|
-
message: chalk.white('
|
|
37
|
-
|
|
38
|
-
default: 'community',
|
|
60
|
+
type: 'input',
|
|
61
|
+
name: 'key',
|
|
62
|
+
message: chalk.white('License key:'),
|
|
63
|
+
validate: (input) => input.trim().length > 0 || 'License key is required',
|
|
39
64
|
},
|
|
40
|
-
]);
|
|
65
|
+
]));
|
|
41
66
|
console.log('');
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
type: 'input',
|
|
50
|
-
name: 'key',
|
|
51
|
-
message: chalk.white('Enter your Pro license key:'),
|
|
52
|
-
validate: (input) => input.length > 0 || 'License key is required',
|
|
53
|
-
},
|
|
54
|
-
]);
|
|
55
|
-
if (key) {
|
|
56
|
-
success('Pro license activated');
|
|
57
|
-
info('Your license key has been validated and saved.');
|
|
58
|
-
}
|
|
59
|
-
}
|
|
60
|
-
else {
|
|
61
|
-
info('Enterprise inquiries: contact@pixelstack.dev');
|
|
67
|
+
info('Validating license...');
|
|
68
|
+
console.log('');
|
|
69
|
+
const result = await validateLicense(key.trim(), 'latest');
|
|
70
|
+
if (!result) {
|
|
71
|
+
error('License validation failed.');
|
|
72
|
+
console.log('');
|
|
73
|
+
return null;
|
|
62
74
|
}
|
|
75
|
+
success('License validated!');
|
|
76
|
+
info(`Remaining downloads today: ${chalk.bold(String(result.remainingDownloads))}`);
|
|
63
77
|
console.log('');
|
|
64
|
-
return
|
|
65
|
-
}
|
|
66
|
-
export function getLicenseInfo() {
|
|
67
|
-
return {
|
|
68
|
-
tier: 'community',
|
|
69
|
-
features: [
|
|
70
|
-
'PixelStack Lite (single container)',
|
|
71
|
-
'Up to 1 project',
|
|
72
|
-
'Community support via GitHub Issues',
|
|
73
|
-
'Standard themes and components',
|
|
74
|
-
],
|
|
75
|
-
};
|
|
78
|
+
return { key: key.trim(), imageTag: result.imageTag };
|
|
76
79
|
}
|
package/dist/modules/logo.js
CHANGED
|
@@ -1,16 +1,14 @@
|
|
|
1
1
|
import chalk from 'chalk';
|
|
2
|
+
const P = '#7C3AED';
|
|
2
3
|
export const logo = `
|
|
3
|
-
${chalk.hex(
|
|
4
|
-
${chalk.hex(
|
|
5
|
-
${chalk.hex(
|
|
6
|
-
${chalk.hex(
|
|
7
|
-
${chalk.hex(
|
|
8
|
-
${chalk.hex(
|
|
9
|
-
${chalk.
|
|
10
|
-
${chalk.
|
|
11
|
-
${chalk.hex('#7C3AED').bold(' ║ ║')}
|
|
12
|
-
${chalk.hex('#7C3AED').bold(' ╚══════════════════════════════════╝')}
|
|
13
|
-
${chalk.gray(' Digital Experience Platform')}
|
|
4
|
+
${chalk.hex(P).bold('███╗ ███╗██╗██╗ ██╗██╗ ██╗███████╗██████╗ ')}
|
|
5
|
+
${chalk.hex(P).bold('████╗ ████║██║██║ ██║╚██╗██╔╝██╔════╝██╔══██╗')}
|
|
6
|
+
${chalk.hex(P).bold('██╔████╔██║██║██║ ██║ ╚███╔╝ █████╗ ██████╔╝')}
|
|
7
|
+
${chalk.hex(P).bold('██║╚██╔╝██║██║██║ ██║ ██╔██╗ ██╔══╝ ██╔══██╗')}
|
|
8
|
+
${chalk.hex(P).bold('██║ ╚═╝ ██║██║███████╗██║██╔╝ ██╗███████╗██║ ██║')}
|
|
9
|
+
${chalk.hex(P).bold('╚═╝ ╚═╝╚═╝╚══════╝╚═╝╚═╝ ╚═╝╚══════╝╚═╝ ╚═╝')}
|
|
10
|
+
${chalk.gray(' ━━━━━━━━━━━━━━━━━━━━━━━━━━━━')}
|
|
11
|
+
${chalk.gray(' DIGITAL EXPERIENCE PLATFORM')}
|
|
14
12
|
`;
|
|
15
13
|
export function showLogo() {
|
|
16
14
|
console.clear();
|
package/dist/modules/nda.js
CHANGED
|
@@ -1,70 +1,179 @@
|
|
|
1
1
|
import inquirer from 'inquirer';
|
|
2
2
|
import chalk from 'chalk';
|
|
3
|
-
import { section,
|
|
4
|
-
const
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
3
|
+
import { section, dividerLine } from './ui.js';
|
|
4
|
+
const V = '#7C3AED';
|
|
5
|
+
const R = '#EF4444';
|
|
6
|
+
const Y = '#EAB308';
|
|
7
|
+
const G = '#22C55E';
|
|
8
|
+
const C = '#06B6D4';
|
|
9
|
+
const GR = '#6B7280';
|
|
10
|
+
function c(hex, text) {
|
|
11
|
+
return String(chalk.hex(hex)(text));
|
|
12
|
+
}
|
|
13
|
+
function cb(hex, text) {
|
|
14
|
+
return String(chalk.hex(hex).bold(text));
|
|
15
|
+
}
|
|
16
|
+
function renderNDA() {
|
|
17
|
+
const lines = [];
|
|
18
|
+
lines.push('');
|
|
19
|
+
lines.push(cb(V, ' ╔══════════════════════════════════════════════════════════════╗'));
|
|
20
|
+
lines.push(cb(V, ' ║') + cb('#FFFFFF', ' PIXELSTACK — NON-DISCLOSURE AGREEMENT ') + cb(V, '║'));
|
|
21
|
+
lines.push(cb(V, ' ╚══════════════════════════════════════════════════════════════╝'));
|
|
22
|
+
lines.push('');
|
|
23
|
+
lines.push(cb(R, ' ⚠ THIS IS A LEGALLY BINDING AGREEMENT. READ EVERY SECTION CAREFULLY.'));
|
|
24
|
+
lines.push('');
|
|
25
|
+
lines.push(c(GR, ' Before using PixelStack Lite, its CLI tools, source code, or any'));
|
|
26
|
+
lines.push(c(GR, ' related materials, you MUST read and accept this agreement.'));
|
|
27
|
+
lines.push('');
|
|
28
|
+
lines.push(dividerLine());
|
|
29
|
+
// 1. PARTIES
|
|
30
|
+
lines.push(cb(V, '\n 1. PARTIES'));
|
|
31
|
+
lines.push(c('#FFFFFF', ' This Non-Disclosure Agreement ("Agreement") is entered into between:'));
|
|
32
|
+
lines.push('');
|
|
33
|
+
lines.push(c(C, ' Disclosing Party: PixelStack Labs ("Company")'));
|
|
34
|
+
lines.push(c(C, ' Receiving Party: The individual or entity using PixelStack ("Recipient")'));
|
|
35
|
+
lines.push('');
|
|
36
|
+
lines.push(c(Y, ' Effective Date: Upon acceptance via CLI interaction.'));
|
|
37
|
+
lines.push('');
|
|
38
|
+
// 2. DEFINITION
|
|
39
|
+
lines.push(dividerLine());
|
|
40
|
+
lines.push(cb(V, ' 2. DEFINITION OF CONFIDENTIAL INFORMATION'));
|
|
41
|
+
lines.push(c('#FFFFFF', ' "Confidential Information" means any and all proprietary data, including'));
|
|
42
|
+
lines.push(c('#FFFFFF', ' but not limited to:'));
|
|
43
|
+
lines.push('');
|
|
44
|
+
lines.push(c(C, ' (a) Source code, object code, and binary files'));
|
|
45
|
+
lines.push(c(C, ' (b) Architecture, system design, and deployment configurations'));
|
|
46
|
+
lines.push(c(C, ' (c) API endpoints, authentication mechanisms, and security models'));
|
|
47
|
+
lines.push(c(C, ' (d) Database schemas, migrations, and seed data'));
|
|
48
|
+
lines.push(c(C, ' (e) Business logic, algorithms, and proprietary workflows'));
|
|
49
|
+
lines.push(c(C, ' (f) License keys, access tokens, and authentication credentials'));
|
|
50
|
+
lines.push(c(C, ' (g) Documentation, guides, and internal communications'));
|
|
51
|
+
lines.push(c(C, ' (h) Any derivative works or modifications thereof'));
|
|
52
|
+
lines.push('');
|
|
53
|
+
lines.push(cb(R, ' >>> ALL ABOVE ARE CONFIDENTIAL. NO EXCEPTIONS. <<<'));
|
|
54
|
+
lines.push('');
|
|
55
|
+
// 3. RESTRICTIONS
|
|
56
|
+
lines.push(dividerLine());
|
|
57
|
+
lines.push(cb(V, ' 3. STRICT PROHIBITIONS'));
|
|
58
|
+
lines.push(c('#FFFFFF', ' The Recipient SHALL NOT, under any circumstances:'));
|
|
59
|
+
lines.push('');
|
|
60
|
+
lines.push(cb(R, ' (a) Copy, duplicate, or reproduce Confidential Information'));
|
|
61
|
+
lines.push(cb(R, ' (b) Disclose, publish, or share with any third party'));
|
|
62
|
+
lines.push(cb(R, ' (c) Reverse-engineer, decompile, or disassemble any software'));
|
|
63
|
+
lines.push(cb(R, ' (d) Create derivative works, forks, or competing products'));
|
|
64
|
+
lines.push(cb(R, ' (e) Remove or alter any proprietary notices or watermarks'));
|
|
65
|
+
lines.push(cb(R, ' (f) Use Confidential Information for any unauthorized purpose'));
|
|
66
|
+
lines.push(cb(R, ' (g) Share license keys, download tokens, or access credentials'));
|
|
67
|
+
lines.push(cb(R, ' (h) Host, publish, or distribute the software on any registry'));
|
|
68
|
+
lines.push('');
|
|
69
|
+
lines.push(cb(R, ' ⚠ VIOLATION OF ANY PROHIBITION MAY RESULT IN LEGAL ACTION.'));
|
|
70
|
+
lines.push('');
|
|
71
|
+
// 4. PERMITTED USE
|
|
72
|
+
lines.push(dividerLine());
|
|
73
|
+
lines.push(cb(V, ' 4. PERMITTED USE'));
|
|
74
|
+
lines.push(c('#FFFFFF', ' Recipient is granted a LIMITED, NON-TRANSFERABLE, REVOCABLE license to:'));
|
|
75
|
+
lines.push('');
|
|
76
|
+
lines.push(c(C, ' (a) Install and use PixelStack Lite for internal evaluation only'));
|
|
77
|
+
lines.push(c(C, ' (b) Access documentation for the purpose of authorized testing'));
|
|
78
|
+
lines.push(c(C, ' (c) Provide feedback to the Company (which becomes Company property)'));
|
|
79
|
+
lines.push('');
|
|
80
|
+
lines.push(cb(Y, ' This license does NOT grant ownership or redistribution rights.'));
|
|
81
|
+
lines.push('');
|
|
82
|
+
// 5. OBLIGATIONS
|
|
83
|
+
lines.push(dividerLine());
|
|
84
|
+
lines.push(cb(V, ' 5. RECIPIENT OBLIGATIONS'));
|
|
85
|
+
lines.push(c('#FFFFFF', ' The Recipient agrees to:'));
|
|
86
|
+
lines.push('');
|
|
87
|
+
lines.push(c(C, ' (a) Protect Confidential Information with at least the same degree'));
|
|
88
|
+
lines.push(c(C, ' of care used to protect their own confidential information'));
|
|
89
|
+
lines.push(c(C, ' (b) Limit access to personnel with a legitimate need-to-know'));
|
|
90
|
+
lines.push(c(C, ' (c) Not transfer or assign this Agreement or any rights herein'));
|
|
91
|
+
lines.push(c(C, ' (d) Immediately notify the Company of any unauthorized disclosure'));
|
|
92
|
+
lines.push(c(C, ' (e) Return or destroy all Confidential Information upon request'));
|
|
93
|
+
lines.push(c(C, ' (f) Cooperate with the Company in investigating any breach'));
|
|
94
|
+
lines.push('');
|
|
95
|
+
// 6. INTELLECTUAL PROPERTY
|
|
96
|
+
lines.push(dividerLine());
|
|
97
|
+
lines.push(cb(V, ' 6. INTELLECTUAL PROPERTY'));
|
|
98
|
+
lines.push(c('#FFFFFF', ' All Confidential Information remains the sole property of the Company.'));
|
|
99
|
+
lines.push(c('#FFFFFF', ' Nothing in this Agreement grants the Recipient any rights in the'));
|
|
100
|
+
lines.push(c('#FFFFFF', ' Company\'s intellectual property, including but not limited to:'));
|
|
101
|
+
lines.push('');
|
|
102
|
+
lines.push(c(C, ' (a) Patents, trademarks, copyrights, and trade secrets'));
|
|
103
|
+
lines.push(c(C, ' (b) Any derivative works or improvements thereof'));
|
|
104
|
+
lines.push(c(C, ' (c) Any data, analytics, or insights derived from the software'));
|
|
105
|
+
lines.push('');
|
|
106
|
+
lines.push(cb(R, ' >>> YOU OWN NOTHING. ALL RIGHTS RESERVED BY THE COMPANY. <<<'));
|
|
107
|
+
lines.push('');
|
|
108
|
+
// 7. BREACH
|
|
109
|
+
lines.push(dividerLine());
|
|
110
|
+
lines.push(cb(V, ' 7. BREACH AND REMEDIES'));
|
|
111
|
+
lines.push(c('#FFFFFF', ' In the event of a breach or threatened breach:'));
|
|
112
|
+
lines.push('');
|
|
113
|
+
lines.push(c(C, ' (a) The Company may seek immediate injunctive relief'));
|
|
114
|
+
lines.push(c(C, ' (b) The Recipient shall be liable for all damages, costs, and'));
|
|
115
|
+
lines.push(c(C, ' attorney\'s fees incurred by the Company'));
|
|
116
|
+
lines.push(c(C, ' (c) The Company may terminate all access and licenses immediately'));
|
|
117
|
+
lines.push(c(C, ' (d) The Recipient shall cooperate fully in any legal proceedings'));
|
|
118
|
+
lines.push('');
|
|
119
|
+
lines.push(cb(R, ' ⚠ BREACH MAY RESULT IN IRREVERSIBLE LEGAL CONSEQUENCES.'));
|
|
120
|
+
lines.push('');
|
|
121
|
+
// 8. TERM
|
|
122
|
+
lines.push(dividerLine());
|
|
123
|
+
lines.push(cb(V, ' 8. TERM AND TERMINATION'));
|
|
124
|
+
lines.push(c(C, ' (a) This Agreement is effective from the date of acceptance'));
|
|
125
|
+
lines.push(c(C, ' (b) Remains in force for 3 (three) years from acceptance'));
|
|
126
|
+
lines.push(c(C, ' (c) Confidentiality obligations survive termination indefinitely'));
|
|
127
|
+
lines.push(c(C, ' (d) The Company may terminate at any time with written notice'));
|
|
128
|
+
lines.push(c(C, ' (e) Upon termination, all materials must be destroyed within 7 days'));
|
|
129
|
+
lines.push('');
|
|
130
|
+
// 9. GOVERNING LAW
|
|
131
|
+
lines.push(dividerLine());
|
|
132
|
+
lines.push(cb(V, ' 9. GOVERNING LAW AND JURISDICTION'));
|
|
133
|
+
lines.push(c(C, ' (a) This Agreement is governed by applicable international laws'));
|
|
134
|
+
lines.push(c(C, ' (b) Any disputes shall be resolved through binding arbitration'));
|
|
135
|
+
lines.push(c(C, ' (c) The prevailing party is entitled to recover all costs'));
|
|
136
|
+
lines.push(c(C, ' (d) Injunctive relief may be sought in any court of competent'));
|
|
137
|
+
lines.push(c(C, ' jurisdiction without prior notice to the Recipient'));
|
|
138
|
+
lines.push('');
|
|
139
|
+
// 10. DISCLAIMER
|
|
140
|
+
lines.push(dividerLine());
|
|
141
|
+
lines.push(cb(V, ' 10. DISCLAIMER OF WARRANTIES'));
|
|
142
|
+
lines.push(cb(R, ' THE SOFTWARE IS PROVIDED "AS IS" WITHOUT WARRANTY OF ANY KIND.'));
|
|
143
|
+
lines.push(cb(R, ' THE COMPANY DISCLAIMS ALL WARRANTIES, EXPRESS OR IMPLIED,'));
|
|
144
|
+
lines.push(cb(R, ' INCLUDING BUT NOT LIMITED TO MERCHANTABILITY, FITNESS FOR A'));
|
|
145
|
+
lines.push(cb(R, ' PARTICULAR PURPOSE, AND NON-INFRINGEMENT. THE COMPANY SHALL'));
|
|
146
|
+
lines.push(cb(R, ' NOT BE LIABLE FOR ANY DAMAGES ARISING FROM USE OF THE SOFTWARE.'));
|
|
147
|
+
lines.push('');
|
|
148
|
+
// FINAL
|
|
149
|
+
lines.push(dividerLine());
|
|
150
|
+
lines.push('');
|
|
151
|
+
lines.push(cb(R, ' ╔══════════════════════════════════════════════════════════════╗'));
|
|
152
|
+
lines.push(cb(R, ' ║') + cb('#FFFFFF', ' BY ACCEPTING THIS AGREEMENT, YOU ACKNOWLEDGE THAT YOU ') + cb(R, '║'));
|
|
153
|
+
lines.push(cb(R, ' ║') + cb('#FFFFFF', ' HAVE READ, UNDERSTAND, AND AGREE TO ALL TERMS HEREIN. ') + cb(R, '║'));
|
|
154
|
+
lines.push(cb(R, ' ║') + cb('#FFFFFF', ' VIOLATION MAY RESULT IN LEGAL ACTION AND FINES. ') + cb(R, '║'));
|
|
155
|
+
lines.push(cb(R, ' ╚══════════════════════════════════════════════════════════════╝'));
|
|
156
|
+
lines.push('');
|
|
157
|
+
return lines.join('\n');
|
|
158
|
+
}
|
|
48
159
|
export async function showNDA() {
|
|
49
160
|
section('Legal Agreement');
|
|
50
|
-
console.log(
|
|
51
|
-
console.log('');
|
|
52
|
-
console.log(NDA_TEXT);
|
|
161
|
+
console.log(renderNDA());
|
|
53
162
|
const { accepted } = await inquirer.prompt([
|
|
54
163
|
{
|
|
55
164
|
type: 'confirm',
|
|
56
165
|
name: 'accepted',
|
|
57
|
-
message:
|
|
166
|
+
message: cb(R, ' I have read and accept all terms of this agreement:'),
|
|
58
167
|
default: false,
|
|
59
168
|
},
|
|
60
169
|
]);
|
|
61
170
|
console.log('');
|
|
62
171
|
if (!accepted) {
|
|
63
|
-
console.log(
|
|
172
|
+
console.log(cb(R, ' ✘ Installation cancelled. You must accept the NDA to continue.'));
|
|
64
173
|
console.log('');
|
|
65
174
|
return false;
|
|
66
175
|
}
|
|
67
|
-
console.log(
|
|
176
|
+
console.log(cb(G, ` ✔ NDA accepted at ${new Date().toISOString()}`));
|
|
68
177
|
console.log('');
|
|
69
178
|
return true;
|
|
70
179
|
}
|
package/dist/modules/ui.d.ts
CHANGED
|
@@ -4,4 +4,5 @@ export declare function error(msg: string): void;
|
|
|
4
4
|
export declare function warn(msg: string): void;
|
|
5
5
|
export declare function info(msg: string): void;
|
|
6
6
|
export declare function divider(): void;
|
|
7
|
+
export declare function dividerLine(): string;
|
|
7
8
|
export declare function section(title: string): void;
|
package/dist/modules/ui.js
CHANGED
|
@@ -1,9 +1,7 @@
|
|
|
1
1
|
import chalk from 'chalk';
|
|
2
2
|
export function banner() {
|
|
3
|
-
console.log(chalk.hex('#7C3AED')('
|
|
4
|
-
console.log(chalk.
|
|
5
|
-
console.log(chalk.hex('#7C3AED')('│') + chalk.gray(' v0.1.0 — Single Container ') + chalk.hex('#7C3AED')('│'));
|
|
6
|
-
console.log(chalk.hex('#7C3AED')('└─────────────────────────────────────────────┘'));
|
|
3
|
+
console.log(chalk.hex('#7C3AED').bold(' PIXELSTACK LITE'));
|
|
4
|
+
console.log(chalk.gray(' ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━'));
|
|
7
5
|
console.log('');
|
|
8
6
|
}
|
|
9
7
|
export function success(msg) {
|
|
@@ -21,6 +19,9 @@ export function info(msg) {
|
|
|
21
19
|
export function divider() {
|
|
22
20
|
console.log(chalk.gray(' ───────────────────────────────────────────'));
|
|
23
21
|
}
|
|
22
|
+
export function dividerLine() {
|
|
23
|
+
return String(chalk.gray(' ───────────────────────────────────────────'));
|
|
24
|
+
}
|
|
24
25
|
export function section(title) {
|
|
25
26
|
console.log('');
|
|
26
27
|
console.log(chalk.hex('#7C3AED').bold(` ▸ ${title}`));
|
package/package.json
CHANGED
|
@@ -1,18 +1,23 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "pixelstart",
|
|
3
|
-
"version": "0.0
|
|
4
|
-
"description": "PixelStack CLI — scaffold and
|
|
3
|
+
"version": "1.0.0",
|
|
4
|
+
"description": "PixelStack Lite CLI — scaffold, license, and deploy PixelStack projects",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "dist/index.js",
|
|
7
7
|
"bin": {
|
|
8
8
|
"pixelstart": "dist/index.js"
|
|
9
9
|
},
|
|
10
|
+
"files": [
|
|
11
|
+
"dist",
|
|
12
|
+
"README.md"
|
|
13
|
+
],
|
|
10
14
|
"scripts": {
|
|
11
15
|
"dev": "tsx src/index.ts",
|
|
12
16
|
"build": "tsc && chmod +x dist/index.js",
|
|
13
17
|
"start": "node dist/index.js",
|
|
14
18
|
"type-check": "tsc --noEmit",
|
|
15
|
-
"prepublishOnly": "npm run build"
|
|
19
|
+
"prepublishOnly": "npm run build",
|
|
20
|
+
"pack": "npm run build && npm pack"
|
|
16
21
|
},
|
|
17
22
|
"engines": {
|
|
18
23
|
"node": ">=22.0.0"
|
|
@@ -22,10 +27,17 @@
|
|
|
22
27
|
"cli",
|
|
23
28
|
"dxp",
|
|
24
29
|
"scaffold",
|
|
25
|
-
"cms"
|
|
30
|
+
"cms",
|
|
31
|
+
"docker",
|
|
32
|
+
"license"
|
|
26
33
|
],
|
|
27
|
-
"author": "",
|
|
28
|
-
"license": "
|
|
34
|
+
"author": "soroosh-assa",
|
|
35
|
+
"license": "UNLICENSED",
|
|
36
|
+
"private": false,
|
|
37
|
+
"repository": {
|
|
38
|
+
"type": "git",
|
|
39
|
+
"url": "https://github.com/soroosh-assa/pixel-cicd"
|
|
40
|
+
},
|
|
29
41
|
"devDependencies": {
|
|
30
42
|
"@types/inquirer": "^9.0.10",
|
|
31
43
|
"@types/node": "^22.0.0",
|
package/src/index.ts
DELETED
|
@@ -1,95 +0,0 @@
|
|
|
1
|
-
#!/usr/bin/env node
|
|
2
|
-
|
|
3
|
-
import chalk from 'chalk';
|
|
4
|
-
import { showLogo } from './modules/logo.js';
|
|
5
|
-
import { banner, section, success, error, info, divider } from './modules/ui.js';
|
|
6
|
-
import { checkRequirements } from './modules/requirements.js';
|
|
7
|
-
import { showNDA } from './modules/nda.js';
|
|
8
|
-
import { showLicense } from './modules/license.js';
|
|
9
|
-
import { initProject } from './modules/init.js';
|
|
10
|
-
|
|
11
|
-
const VERSION = '0.1.0';
|
|
12
|
-
|
|
13
|
-
async function main(): Promise<void> {
|
|
14
|
-
const args = process.argv.slice(2);
|
|
15
|
-
const command = args[0];
|
|
16
|
-
|
|
17
|
-
// --help / --version work without logo
|
|
18
|
-
if (command === '--help' || command === '-h') {
|
|
19
|
-
printHelp();
|
|
20
|
-
return;
|
|
21
|
-
}
|
|
22
|
-
if (command === '--version' || command === '-v') {
|
|
23
|
-
console.log(`pixelstart v${VERSION}`);
|
|
24
|
-
return;
|
|
25
|
-
}
|
|
26
|
-
|
|
27
|
-
// Interactive flow — show logo + banner
|
|
28
|
-
showLogo();
|
|
29
|
-
banner();
|
|
30
|
-
|
|
31
|
-
// Step 1: Check requirements
|
|
32
|
-
const reqsOk = await checkRequirements();
|
|
33
|
-
if (!reqsOk) {
|
|
34
|
-
process.exit(1);
|
|
35
|
-
}
|
|
36
|
-
|
|
37
|
-
// Step 2: NDA
|
|
38
|
-
const ndaOk = await showNDA();
|
|
39
|
-
if (!ndaOk) {
|
|
40
|
-
process.exit(0);
|
|
41
|
-
}
|
|
42
|
-
|
|
43
|
-
// Step 3: License
|
|
44
|
-
const tier = await showLicense();
|
|
45
|
-
if (!tier) {
|
|
46
|
-
process.exit(0);
|
|
47
|
-
}
|
|
48
|
-
|
|
49
|
-
// Step 4: Init project (if `init` command or no command)
|
|
50
|
-
if (!command || command === 'init') {
|
|
51
|
-
await initProject();
|
|
52
|
-
} else if (command === 'up' || command === 'down' || command === 'status' || command === 'logs') {
|
|
53
|
-
section('Service Management');
|
|
54
|
-
info(`Command "${command}" will be available after project initialization.`);
|
|
55
|
-
console.log('');
|
|
56
|
-
} else {
|
|
57
|
-
error(`Unknown command: ${command}`);
|
|
58
|
-
info('Run `pixelstart --help` for usage.');
|
|
59
|
-
process.exit(1);
|
|
60
|
-
}
|
|
61
|
-
}
|
|
62
|
-
|
|
63
|
-
function printHelp(): void {
|
|
64
|
-
console.log(`
|
|
65
|
-
${chalk.hex('#7C3AED').bold('pixelstart')} v${VERSION}
|
|
66
|
-
|
|
67
|
-
${chalk.gray('Usage:')}
|
|
68
|
-
pixelstart [command]
|
|
69
|
-
|
|
70
|
-
${chalk.gray('Commands:')}
|
|
71
|
-
init Scaffold a new PixelStack Lite project
|
|
72
|
-
up Start all services
|
|
73
|
-
down Stop all services
|
|
74
|
-
status Show service status
|
|
75
|
-
logs Stream service logs
|
|
76
|
-
|
|
77
|
-
${chalk.gray('Options:')}
|
|
78
|
-
-h, --help Show help
|
|
79
|
-
-v, --version Show version
|
|
80
|
-
|
|
81
|
-
${chalk.gray('Examples:')}
|
|
82
|
-
pixelstart Launch interactive installer
|
|
83
|
-
pixelstart init Create a new project
|
|
84
|
-
pixelstart up Start services
|
|
85
|
-
`);
|
|
86
|
-
}
|
|
87
|
-
|
|
88
|
-
// Catch unhandled errors gracefully
|
|
89
|
-
process.on('unhandledRejection', (err) => {
|
|
90
|
-
console.error('');
|
|
91
|
-
error(`Unexpected error: ${err}`);
|
|
92
|
-
process.exit(1);
|
|
93
|
-
});
|
|
94
|
-
|
|
95
|
-
main();
|
package/src/modules/init.ts
DELETED
|
@@ -1,100 +0,0 @@
|
|
|
1
|
-
import { execSync } from 'child_process';
|
|
2
|
-
import fs from 'fs';
|
|
3
|
-
import path from 'path';
|
|
4
|
-
import inquirer from 'inquirer';
|
|
5
|
-
import chalk from 'chalk';
|
|
6
|
-
import { section, success, error, warn, info } from './ui.js';
|
|
7
|
-
|
|
8
|
-
interface ProjectConfig {
|
|
9
|
-
name: string;
|
|
10
|
-
directory: string;
|
|
11
|
-
port: number;
|
|
12
|
-
dbPassword: string;
|
|
13
|
-
}
|
|
14
|
-
|
|
15
|
-
export async function initProject(): Promise<void> {
|
|
16
|
-
section('Project Setup');
|
|
17
|
-
|
|
18
|
-
const config = await inquirer.prompt<ProjectConfig>([
|
|
19
|
-
{
|
|
20
|
-
type: 'input',
|
|
21
|
-
name: 'name',
|
|
22
|
-
message: chalk.white('Project name:'),
|
|
23
|
-
default: 'my-pixelstack',
|
|
24
|
-
validate: (input: string) => {
|
|
25
|
-
if (!/^[a-z0-9-_]+$/.test(input)) return 'Use lowercase, numbers, hyphens only';
|
|
26
|
-
return true;
|
|
27
|
-
},
|
|
28
|
-
},
|
|
29
|
-
{
|
|
30
|
-
type: 'input',
|
|
31
|
-
name: 'directory',
|
|
32
|
-
message: chalk.white('Install directory:'),
|
|
33
|
-
default: (answers: { name: string }) => `./${answers.name}`,
|
|
34
|
-
},
|
|
35
|
-
{
|
|
36
|
-
type: 'number',
|
|
37
|
-
name: 'port',
|
|
38
|
-
message: chalk.white('Base port (HTTP):'),
|
|
39
|
-
default: 80,
|
|
40
|
-
},
|
|
41
|
-
{
|
|
42
|
-
type: 'password',
|
|
43
|
-
name: 'dbPassword',
|
|
44
|
-
message: chalk.white('Database password:'),
|
|
45
|
-
mask: '*',
|
|
46
|
-
validate: (input: string) => input.length >= 8 || 'Min 8 characters',
|
|
47
|
-
},
|
|
48
|
-
]);
|
|
49
|
-
|
|
50
|
-
console.log('');
|
|
51
|
-
info(`Creating project in ${chalk.bold(config.directory)}`);
|
|
52
|
-
|
|
53
|
-
try {
|
|
54
|
-
fs.mkdirSync(config.directory, { recursive: true });
|
|
55
|
-
|
|
56
|
-
const envContent = `# PixelStack Lite Configuration
|
|
57
|
-
NODE_ENV=production
|
|
58
|
-
POSTGRES_USER=pixelstack
|
|
59
|
-
POSTGRES_PASSWORD=${config.dbPassword}
|
|
60
|
-
POSTGRES_DB=pixelstack_db
|
|
61
|
-
STRAPI_DB_NAME=strapi_core_db
|
|
62
|
-
REDIS_HOST=localhost
|
|
63
|
-
REDIS_PORT=6379
|
|
64
|
-
MINIO_ROOT_USER=minioadmin
|
|
65
|
-
MINIO_ROOT_PASSWORD=minioadmin
|
|
66
|
-
MINIO_BUCKET=strapi-uploads
|
|
67
|
-
MINIO_ENDPOINT=http://localhost:9000
|
|
68
|
-
MINIO_PUBLIC_URL=http://localhost/media
|
|
69
|
-
API_PORT=3000
|
|
70
|
-
STRAPI_PORT=1337
|
|
71
|
-
WEB_PORT=3001
|
|
72
|
-
ARTEMIS_PORT=3100
|
|
73
|
-
ADMIN_PORT=4028
|
|
74
|
-
ARTEMIS_FE_PORT=4029
|
|
75
|
-
BASE_PORT=${config.port}
|
|
76
|
-
`;
|
|
77
|
-
|
|
78
|
-
fs.writeFileSync(path.join(config.directory, '.env'), envContent);
|
|
79
|
-
success('Created .env');
|
|
80
|
-
|
|
81
|
-
fs.writeFileSync(path.join(config.directory, '.gitignore'), `node_modules/
|
|
82
|
-
.env
|
|
83
|
-
*.log
|
|
84
|
-
data/
|
|
85
|
-
`);
|
|
86
|
-
success('Created .gitignore');
|
|
87
|
-
|
|
88
|
-
console.log('');
|
|
89
|
-
success(`Project "${chalk.bold(config.name)}" created!`);
|
|
90
|
-
console.log('');
|
|
91
|
-
info(`Next steps:`);
|
|
92
|
-
console.log(chalk.white(` cd ${config.directory}`));
|
|
93
|
-
console.log(chalk.white(' pixelstart up'));
|
|
94
|
-
console.log('');
|
|
95
|
-
|
|
96
|
-
} catch (err) {
|
|
97
|
-
error(`Failed to create project: ${err}`);
|
|
98
|
-
process.exit(1);
|
|
99
|
-
}
|
|
100
|
-
}
|
package/src/modules/license.ts
DELETED
|
@@ -1,84 +0,0 @@
|
|
|
1
|
-
import inquirer from 'inquirer';
|
|
2
|
-
import chalk from 'chalk';
|
|
3
|
-
import { section, divider, success, info } from './ui.js';
|
|
4
|
-
|
|
5
|
-
const LICENSE_TIERS = [
|
|
6
|
-
{
|
|
7
|
-
name: 'Community — Free',
|
|
8
|
-
value: 'community',
|
|
9
|
-
description: 'Basic features, single project, community support',
|
|
10
|
-
},
|
|
11
|
-
{
|
|
12
|
-
name: 'Pro — $29/mo',
|
|
13
|
-
value: 'pro',
|
|
14
|
-
description: 'Unlimited projects, priority support, custom themes',
|
|
15
|
-
},
|
|
16
|
-
{
|
|
17
|
-
name: 'Enterprise — Custom',
|
|
18
|
-
value: 'enterprise',
|
|
19
|
-
description: 'Self-hosted, SLA, dedicated support, custom integrations',
|
|
20
|
-
},
|
|
21
|
-
];
|
|
22
|
-
|
|
23
|
-
export async function showLicense(): Promise<string | null> {
|
|
24
|
-
section('License');
|
|
25
|
-
|
|
26
|
-
console.log(chalk.white(' Choose your PixelStack Lite license tier:'));
|
|
27
|
-
console.log('');
|
|
28
|
-
|
|
29
|
-
for (const tier of LICENSE_TIERS) {
|
|
30
|
-
const isActive = tier.value === 'community';
|
|
31
|
-
const marker = isActive ? chalk.green('●') : chalk.gray('○');
|
|
32
|
-
console.log(` ${marker} ${chalk.bold(tier.name)}`);
|
|
33
|
-
console.log(` ${chalk.gray(tier.description)}`);
|
|
34
|
-
console.log('');
|
|
35
|
-
}
|
|
36
|
-
|
|
37
|
-
const { tier } = await inquirer.prompt([
|
|
38
|
-
{
|
|
39
|
-
type: 'list',
|
|
40
|
-
name: 'tier',
|
|
41
|
-
message: chalk.white('Select a license tier:'),
|
|
42
|
-
choices: LICENSE_TIERS,
|
|
43
|
-
default: 'community',
|
|
44
|
-
},
|
|
45
|
-
]);
|
|
46
|
-
|
|
47
|
-
console.log('');
|
|
48
|
-
|
|
49
|
-
if (tier === 'community') {
|
|
50
|
-
success('Community license activated');
|
|
51
|
-
info('No key required. Run `pixelstart init` to get started.');
|
|
52
|
-
} else if (tier === 'pro') {
|
|
53
|
-
const { key } = await inquirer.prompt([
|
|
54
|
-
{
|
|
55
|
-
type: 'input',
|
|
56
|
-
name: 'key',
|
|
57
|
-
message: chalk.white('Enter your Pro license key:'),
|
|
58
|
-
validate: (input: string) => input.length > 0 || 'License key is required',
|
|
59
|
-
},
|
|
60
|
-
]);
|
|
61
|
-
|
|
62
|
-
if (key) {
|
|
63
|
-
success('Pro license activated');
|
|
64
|
-
info('Your license key has been validated and saved.');
|
|
65
|
-
}
|
|
66
|
-
} else {
|
|
67
|
-
info('Enterprise inquiries: contact@pixelstack.dev');
|
|
68
|
-
}
|
|
69
|
-
|
|
70
|
-
console.log('');
|
|
71
|
-
return tier;
|
|
72
|
-
}
|
|
73
|
-
|
|
74
|
-
export function getLicenseInfo(): { tier: string; features: string[] } {
|
|
75
|
-
return {
|
|
76
|
-
tier: 'community',
|
|
77
|
-
features: [
|
|
78
|
-
'PixelStack Lite (single container)',
|
|
79
|
-
'Up to 1 project',
|
|
80
|
-
'Community support via GitHub Issues',
|
|
81
|
-
'Standard themes and components',
|
|
82
|
-
],
|
|
83
|
-
};
|
|
84
|
-
}
|
package/src/modules/logo.ts
DELETED
|
@@ -1,21 +0,0 @@
|
|
|
1
|
-
import chalk from 'chalk';
|
|
2
|
-
|
|
3
|
-
export const logo = `
|
|
4
|
-
${chalk.hex('#7C3AED').bold(' ╔══════════════════════════════════╗')}
|
|
5
|
-
${chalk.hex('#7C3AED').bold(' ║ ║')}
|
|
6
|
-
${chalk.hex('#7C3AED').bold(' ║ ██████╗ ██╗██╗ ██╗███████╗██╗ ██████╗ ██████╗ ')}
|
|
7
|
-
${chalk.hex('#7C3AED').bold(' ║ ██╔══██╗██║╚██╗██╔╝██╔════╝██║ ██╔═══██╗██╔════╝ ')}
|
|
8
|
-
${chalk.hex('#7C3AED').bold(' ║ ██████╔╝██║ ╚███╔╝ █████╗ ██║ ██║ ██║██║ ███╗')}
|
|
9
|
-
${chalk.hex('#7C3AED').bold(' ║ ██╔═══╝ ██║ ██╔██╗ ██╔══╝ ██║ ██║ ██║██║ ██║')}
|
|
10
|
-
${chalk.hex('#7C3AED').bold(' ║ ██║ ██║██╔╝ ██╗███████╗███████╗╚██████╔╝╚██████╔╝')}
|
|
11
|
-
${chalk.hex('#7C3AED').bold(' ║ ╚═╝ ╚═╝╚═╝ ╚═╝╚══════╝╚══════╝ ╚═════╝ ╚═════╝ ')}
|
|
12
|
-
${chalk.hex('#7C3AED').bold(' ║ ║')}
|
|
13
|
-
${chalk.hex('#7C3AED').bold(' ╚══════════════════════════════════╝')}
|
|
14
|
-
${chalk.gray(' Digital Experience Platform')}
|
|
15
|
-
`;
|
|
16
|
-
|
|
17
|
-
export function showLogo(): void {
|
|
18
|
-
console.clear();
|
|
19
|
-
console.log(logo);
|
|
20
|
-
console.log('');
|
|
21
|
-
}
|
package/src/modules/nda.ts
DELETED
|
@@ -1,77 +0,0 @@
|
|
|
1
|
-
import inquirer from 'inquirer';
|
|
2
|
-
import chalk from 'chalk';
|
|
3
|
-
import { section, divider } from './ui.js';
|
|
4
|
-
|
|
5
|
-
const NDA_TEXT = `
|
|
6
|
-
${chalk.white.bold(' NON-DISCLOSURE AGREEMENT')}
|
|
7
|
-
|
|
8
|
-
This Non-Disclosure Agreement ("Agreement") is entered into between:
|
|
9
|
-
|
|
10
|
-
${chalk.gray(' Disclosing Party:')} PixelStack Labs ("Company")
|
|
11
|
-
${chalk.gray(' Receiving Party:')} You ("Recipient")
|
|
12
|
-
|
|
13
|
-
${divider()}
|
|
14
|
-
|
|
15
|
-
${chalk.bold('1. DEFINITION OF CONFIDENTIAL INFORMATION')}
|
|
16
|
-
|
|
17
|
-
"Confidential Information" includes all source code, architecture details,
|
|
18
|
-
API designs, database schemas, deployment configurations, business logic,
|
|
19
|
-
and proprietary algorithms shared through the PixelStack Lite platform,
|
|
20
|
-
its CLI tools, documentation, and related materials.
|
|
21
|
-
|
|
22
|
-
${divider()}
|
|
23
|
-
|
|
24
|
-
${chalk.bold('2. OBLIGATIONS OF RECIPIENT')}
|
|
25
|
-
|
|
26
|
-
The Recipient agrees to:
|
|
27
|
-
a) Hold all Confidential Information in strict confidence
|
|
28
|
-
b) Not disclose Confidential Information to any third party
|
|
29
|
-
c) Use Confidential Information solely for authorized evaluation
|
|
30
|
-
d) Not reverse-engineer, decompile, or create derivative works
|
|
31
|
-
e) Return or destroy all materials upon request
|
|
32
|
-
|
|
33
|
-
${divider()}
|
|
34
|
-
|
|
35
|
-
${chalk.bold('3. TERM')}
|
|
36
|
-
|
|
37
|
-
This Agreement remains effective for 2 (two) years from acceptance,
|
|
38
|
-
or until the information ceases to be confidential, whichever is later.
|
|
39
|
-
|
|
40
|
-
${divider()}
|
|
41
|
-
|
|
42
|
-
${chalk.bold('4. GOVERNING LAW')}
|
|
43
|
-
|
|
44
|
-
This Agreement shall be governed by the laws of the jurisdiction
|
|
45
|
-
in which the Company operates.
|
|
46
|
-
|
|
47
|
-
${divider()}
|
|
48
|
-
`;
|
|
49
|
-
|
|
50
|
-
export async function showNDA(): Promise<boolean> {
|
|
51
|
-
section('Legal Agreement');
|
|
52
|
-
|
|
53
|
-
console.log(chalk.hex('#7C3AED').bold(' Before proceeding, please review the NDA:'));
|
|
54
|
-
console.log('');
|
|
55
|
-
console.log(NDA_TEXT);
|
|
56
|
-
|
|
57
|
-
const { accepted } = await inquirer.prompt([
|
|
58
|
-
{
|
|
59
|
-
type: 'confirm',
|
|
60
|
-
name: 'accepted',
|
|
61
|
-
message: chalk.white('Do you accept the Non-Disclosure Agreement?'),
|
|
62
|
-
default: false,
|
|
63
|
-
},
|
|
64
|
-
]);
|
|
65
|
-
|
|
66
|
-
console.log('');
|
|
67
|
-
|
|
68
|
-
if (!accepted) {
|
|
69
|
-
console.log(chalk.gray(' Installation cancelled. You must accept the NDA to continue.'));
|
|
70
|
-
console.log('');
|
|
71
|
-
return false;
|
|
72
|
-
}
|
|
73
|
-
|
|
74
|
-
console.log(chalk.green(' ✔ NDA accepted. Proceeding...'));
|
|
75
|
-
console.log('');
|
|
76
|
-
return true;
|
|
77
|
-
}
|
|
@@ -1,107 +0,0 @@
|
|
|
1
|
-
import { execSync } from 'child_process';
|
|
2
|
-
import chalk from 'chalk';
|
|
3
|
-
import { success, error, warn, info, section } from './ui.js';
|
|
4
|
-
|
|
5
|
-
interface Requirement {
|
|
6
|
-
name: string;
|
|
7
|
-
command: string;
|
|
8
|
-
minVersion?: string;
|
|
9
|
-
required: boolean;
|
|
10
|
-
installHint: string;
|
|
11
|
-
}
|
|
12
|
-
|
|
13
|
-
interface CheckResult {
|
|
14
|
-
name: string;
|
|
15
|
-
installed: boolean;
|
|
16
|
-
version?: string;
|
|
17
|
-
meetsMin?: boolean;
|
|
18
|
-
required: boolean;
|
|
19
|
-
minVersion?: string;
|
|
20
|
-
installHint: string;
|
|
21
|
-
}
|
|
22
|
-
|
|
23
|
-
const REQUIREMENTS: Requirement[] = [
|
|
24
|
-
{
|
|
25
|
-
name: 'Node.js',
|
|
26
|
-
command: 'node --version',
|
|
27
|
-
minVersion: '22.0.0',
|
|
28
|
-
required: true,
|
|
29
|
-
installHint: 'Install Node.js 22+: https://nodejs.org/',
|
|
30
|
-
},
|
|
31
|
-
{
|
|
32
|
-
name: 'Docker',
|
|
33
|
-
command: 'docker --version',
|
|
34
|
-
required: true,
|
|
35
|
-
installHint: 'Install Docker: https://docs.docker.com/get-docker/',
|
|
36
|
-
},
|
|
37
|
-
{
|
|
38
|
-
name: 'Docker Compose',
|
|
39
|
-
command: 'docker compose version',
|
|
40
|
-
required: true,
|
|
41
|
-
installHint: 'Install Docker Compose: https://docs.docker.com/compose/install/',
|
|
42
|
-
},
|
|
43
|
-
{
|
|
44
|
-
name: 'pnpm',
|
|
45
|
-
command: 'pnpm --version',
|
|
46
|
-
minVersion: '9.0.0',
|
|
47
|
-
required: false,
|
|
48
|
-
installHint: 'Install pnpm: npm install -g pnpm@9',
|
|
49
|
-
},
|
|
50
|
-
];
|
|
51
|
-
|
|
52
|
-
function parseVersion(output: string): string {
|
|
53
|
-
return output.replace(/^[^\d]*/, '').split('+')[0].trim();
|
|
54
|
-
}
|
|
55
|
-
|
|
56
|
-
function compareVersions(a: string, b: string): number {
|
|
57
|
-
const pa = a.split('.').map(Number);
|
|
58
|
-
const pb = b.split('.').map(Number);
|
|
59
|
-
for (let i = 0; i < Math.max(pa.length, pb.length); i++) {
|
|
60
|
-
const na = pa[i] || 0;
|
|
61
|
-
const nb = pb[i] || 0;
|
|
62
|
-
if (na > nb) return 1;
|
|
63
|
-
if (na < nb) return -1;
|
|
64
|
-
}
|
|
65
|
-
return 0;
|
|
66
|
-
}
|
|
67
|
-
|
|
68
|
-
function checkRequirement(req: Requirement): CheckResult {
|
|
69
|
-
try {
|
|
70
|
-
const output = execSync(req.command, { encoding: 'utf-8', stdio: 'pipe' }).trim();
|
|
71
|
-
const version = parseVersion(output);
|
|
72
|
-
const meetsMin = req.minVersion ? compareVersions(version, req.minVersion) >= 0 : true;
|
|
73
|
-
return { name: req.name, installed: true, version, meetsMin, required: req.required, minVersion: req.minVersion, installHint: req.installHint };
|
|
74
|
-
} catch {
|
|
75
|
-
return { name: req.name, installed: false, required: req.required, installHint: req.installHint };
|
|
76
|
-
}
|
|
77
|
-
}
|
|
78
|
-
|
|
79
|
-
export async function checkRequirements(): Promise<boolean> {
|
|
80
|
-
section('System Requirements');
|
|
81
|
-
|
|
82
|
-
const results = REQUIREMENTS.map(checkRequirement);
|
|
83
|
-
let allPassed = true;
|
|
84
|
-
|
|
85
|
-
for (const r of results) {
|
|
86
|
-
if (!r.installed) {
|
|
87
|
-
error(`${chalk.bold(r.name)} not found`);
|
|
88
|
-
info(r.installHint);
|
|
89
|
-
if (r.required) allPassed = false;
|
|
90
|
-
} else if (r.meetsMin === false) {
|
|
91
|
-
warn(`${chalk.bold(r.name)} ${r.version} — requires ${r.minVersion}+`);
|
|
92
|
-
info(r.installHint);
|
|
93
|
-
if (r.required) allPassed = false;
|
|
94
|
-
} else {
|
|
95
|
-
success(`${chalk.bold(r.name)} ${chalk.gray(r.version || '')}`);
|
|
96
|
-
}
|
|
97
|
-
}
|
|
98
|
-
|
|
99
|
-
console.log('');
|
|
100
|
-
|
|
101
|
-
if (!allPassed) {
|
|
102
|
-
error('Missing required dependencies. Please install them and try again.');
|
|
103
|
-
return false;
|
|
104
|
-
}
|
|
105
|
-
|
|
106
|
-
return true;
|
|
107
|
-
}
|
package/src/modules/ui.ts
DELETED
|
@@ -1,35 +0,0 @@
|
|
|
1
|
-
import chalk from 'chalk';
|
|
2
|
-
|
|
3
|
-
export function banner(): void {
|
|
4
|
-
console.log(chalk.hex('#7C3AED')('┌─────────────────────────────────────────────┐'));
|
|
5
|
-
console.log(chalk.hex('#7C3AED')('│') + chalk.white.bold(' PixelStack Lite Installer ') + chalk.hex('#7C3AED')('│'));
|
|
6
|
-
console.log(chalk.hex('#7C3AED')('│') + chalk.gray(' v0.1.0 — Single Container ') + chalk.hex('#7C3AED')('│'));
|
|
7
|
-
console.log(chalk.hex('#7C3AED')('└─────────────────────────────────────────────┘'));
|
|
8
|
-
console.log('');
|
|
9
|
-
}
|
|
10
|
-
|
|
11
|
-
export function success(msg: string): void {
|
|
12
|
-
console.log(chalk.green(' ✔ ') + msg);
|
|
13
|
-
}
|
|
14
|
-
|
|
15
|
-
export function error(msg: string): void {
|
|
16
|
-
console.log(chalk.red(' ✘ ') + msg);
|
|
17
|
-
}
|
|
18
|
-
|
|
19
|
-
export function warn(msg: string): void {
|
|
20
|
-
console.log(chalk.yellow(' ⚠ ') + msg);
|
|
21
|
-
}
|
|
22
|
-
|
|
23
|
-
export function info(msg: string): void {
|
|
24
|
-
console.log(chalk.cyan(' ℹ ') + msg);
|
|
25
|
-
}
|
|
26
|
-
|
|
27
|
-
export function divider(): void {
|
|
28
|
-
console.log(chalk.gray(' ───────────────────────────────────────────'));
|
|
29
|
-
}
|
|
30
|
-
|
|
31
|
-
export function section(title: string): void {
|
|
32
|
-
console.log('');
|
|
33
|
-
console.log(chalk.hex('#7C3AED').bold(` ▸ ${title}`));
|
|
34
|
-
console.log('');
|
|
35
|
-
}
|
package/tsconfig.json
DELETED
|
@@ -1,16 +0,0 @@
|
|
|
1
|
-
{
|
|
2
|
-
"compilerOptions": {
|
|
3
|
-
"target": "ES2022",
|
|
4
|
-
"module": "NodeNext",
|
|
5
|
-
"moduleResolution": "NodeNext",
|
|
6
|
-
"outDir": "dist",
|
|
7
|
-
"rootDir": "src",
|
|
8
|
-
"strict": true,
|
|
9
|
-
"esModuleInterop": true,
|
|
10
|
-
"skipLibCheck": true,
|
|
11
|
-
"forceConsistentCasingInFileNames": true,
|
|
12
|
-
"declaration": true,
|
|
13
|
-
"resolveJsonModule": true
|
|
14
|
-
},
|
|
15
|
-
"include": ["src"]
|
|
16
|
-
}
|