handoff-app 1.0.3 → 1.0.4
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/Changelog.md +10 -5
- package/dist/cli.js +0 -0
- package/dist/index.js +4 -1
- package/dist/transformers/plugins/ssr-render.js +4 -3
- package/dist/transformers/preview/component/api.js +3 -2
- package/dist/transformers/preview/component/builder.js +2 -1
- package/dist/transformers/utils/handlebars.js +3 -2
- package/package.json +1 -1
- package/src/app/components/Component/Preview.tsx +121 -121
- package/src/app/components/ComponentSearch.tsx +1 -1
- package/src/app/components/util/index.ts +17 -9
- package/src/app/pages/system/component/[component]/index.tsx +1 -1
- package/src/app/pages/system/index.tsx +2 -2
- package/src/app/pages/system/tokens/index.tsx +10 -10
- package/src/index.ts +3 -0
- package/src/transformers/plugins/ssr-render.ts +3 -3
- package/src/transformers/preview/component/api.ts +1 -1
- package/src/transformers/preview/component/builder.ts +1 -1
- package/src/transformers/utils/handlebars.ts +2 -2
- package/dist/commands/platform/init.d.ts +0 -6
- package/dist/commands/platform/init.js +0 -231
- package/dist/commands/platform/login.d.ts +0 -6
- package/dist/commands/platform/login.js +0 -108
- package/dist/commands/platform/logout.d.ts +0 -6
- package/dist/commands/platform/logout.js +0 -88
- package/dist/commands/platform/pull.d.ts +0 -8
- package/dist/commands/platform/pull.js +0 -112
- package/dist/commands/platform/push.d.ts +0 -8
- package/dist/commands/platform/push.js +0 -428
- package/dist/platform/client.d.ts +0 -122
- package/dist/platform/client.js +0 -228
- package/dist/platform/credentials.d.ts +0 -40
- package/dist/platform/credentials.js +0 -91
- package/dist/platform/sync.d.ts +0 -68
- package/dist/platform/sync.js +0 -349
|
@@ -363,7 +363,7 @@ const buildComponentSummary = (id: string, data: TransformComponentTokensResult)
|
|
|
363
363
|
tags: data.tags ? data.tags : [],
|
|
364
364
|
properties: data.properties,
|
|
365
365
|
previews: data.previews,
|
|
366
|
-
path:
|
|
366
|
+
path: `${process.env.HANDOFF_APP_BASE_PATH ?? ''}/api/component/${id}.json`,
|
|
367
367
|
};
|
|
368
368
|
};
|
|
369
369
|
|
|
@@ -60,8 +60,8 @@ export const createHandlebarsContext = (
|
|
|
60
60
|
previewData: { values?: any }
|
|
61
61
|
): HandlebarsContext => {
|
|
62
62
|
return {
|
|
63
|
-
style: `<link rel="stylesheet" href="/api/component/shared.css"><link rel="stylesheet" href="/api/component/${data.id}.css">\n<link rel="stylesheet" href="/assets/css/preview.css">`,
|
|
64
|
-
script: `<script src="/api/component/${data.id}.js"></script>\n<script src="/assets/js/preview.js"></script><script>var fields = ${JSON.stringify(data.properties)};</script>`,
|
|
63
|
+
style: `<link rel="stylesheet" href="${process.env.HANDOFF_APP_BASE_PATH ?? ''}/api/component/shared.css"><link rel="stylesheet" href="${process.env.HANDOFF_APP_BASE_PATH ?? ''}/api/component/${data.id}.css">\n<link rel="stylesheet" href="${process.env.HANDOFF_APP_BASE_PATH ?? ''}/assets/css/preview.css">`,
|
|
64
|
+
script: `<script src="${process.env.HANDOFF_APP_BASE_PATH ?? ''}/api/component/${data.id}.js"></script>\n<script src="${process.env.HANDOFF_APP_BASE_PATH ?? ''}/assets/js/preview.js"></script><script>var fields = ${JSON.stringify(data.properties)};</script>`,
|
|
65
65
|
properties: previewData.values || {},
|
|
66
66
|
fields: data.properties,
|
|
67
67
|
title: data.title,
|
|
@@ -1,231 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
-
if (k2 === undefined) k2 = k;
|
|
4
|
-
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
5
|
-
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
6
|
-
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
7
|
-
}
|
|
8
|
-
Object.defineProperty(o, k2, desc);
|
|
9
|
-
}) : (function(o, m, k, k2) {
|
|
10
|
-
if (k2 === undefined) k2 = k;
|
|
11
|
-
o[k2] = m[k];
|
|
12
|
-
}));
|
|
13
|
-
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
14
|
-
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
15
|
-
}) : function(o, v) {
|
|
16
|
-
o["default"] = v;
|
|
17
|
-
});
|
|
18
|
-
var __importStar = (this && this.__importStar) || function (mod) {
|
|
19
|
-
if (mod && mod.__esModule) return mod;
|
|
20
|
-
var result = {};
|
|
21
|
-
if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
|
|
22
|
-
__setModuleDefault(result, mod);
|
|
23
|
-
return result;
|
|
24
|
-
};
|
|
25
|
-
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
|
|
26
|
-
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
|
27
|
-
return new (P || (P = Promise))(function (resolve, reject) {
|
|
28
|
-
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
|
|
29
|
-
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
|
|
30
|
-
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
|
|
31
|
-
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
|
32
|
-
});
|
|
33
|
-
};
|
|
34
|
-
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
35
|
-
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
36
|
-
};
|
|
37
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
38
|
-
const p = __importStar(require("@clack/prompts"));
|
|
39
|
-
const chalk_1 = __importDefault(require("chalk"));
|
|
40
|
-
const fs_extra_1 = __importDefault(require("fs-extra"));
|
|
41
|
-
const path_1 = __importDefault(require("path"));
|
|
42
|
-
const client_1 = require("../../platform/client");
|
|
43
|
-
const credentials_1 = require("../../platform/credentials");
|
|
44
|
-
const DEFAULT_PLATFORM_URL = 'http://localhost:3000';
|
|
45
|
-
const CONFIG_FILES = ['handoff.config.json', 'handoff.config.js', 'handoff.config.cjs'];
|
|
46
|
-
const command = {
|
|
47
|
-
command: 'platform:init',
|
|
48
|
-
describe: 'Link this directory to a Handoff platform project',
|
|
49
|
-
builder: (yargs) => {
|
|
50
|
-
return yargs.option('url', {
|
|
51
|
-
type: 'string',
|
|
52
|
-
description: 'Platform URL',
|
|
53
|
-
default: process.env.HANDOFF_PLATFORM_URL || DEFAULT_PLATFORM_URL,
|
|
54
|
-
});
|
|
55
|
-
},
|
|
56
|
-
handler: (args) => __awaiter(void 0, void 0, void 0, function* () {
|
|
57
|
-
const baseUrl = (args.url || DEFAULT_PLATFORM_URL).replace(/\/+$/, '');
|
|
58
|
-
const workingDir = process.cwd();
|
|
59
|
-
p.intro(chalk_1.default.bold('Handoff Platform Init'));
|
|
60
|
-
// 1. Check login
|
|
61
|
-
const token = (0, credentials_1.getToken)(baseUrl);
|
|
62
|
-
if (!token) {
|
|
63
|
-
p.cancel(`Not logged in to ${baseUrl}. Run ${chalk_1.default.cyan('handoff-app platform:login')} first.`);
|
|
64
|
-
process.exit(1);
|
|
65
|
-
}
|
|
66
|
-
const spinner = p.spinner();
|
|
67
|
-
try {
|
|
68
|
-
// 2. Fetch project list
|
|
69
|
-
spinner.start('Fetching projects...');
|
|
70
|
-
const projects = yield (0, client_1.listProjects)(baseUrl, token);
|
|
71
|
-
spinner.stop('Projects loaded.');
|
|
72
|
-
if (projects.length === 0) {
|
|
73
|
-
p.cancel('No projects found. Create a project in the Handoff platform first.');
|
|
74
|
-
process.exit(1);
|
|
75
|
-
}
|
|
76
|
-
// 3. Interactive project selection
|
|
77
|
-
const projectId = yield p.select({
|
|
78
|
-
message: 'Select a project to link:',
|
|
79
|
-
options: projects.map((proj) => ({
|
|
80
|
-
value: proj.id,
|
|
81
|
-
label: `${proj.name} (${proj.orgName})`,
|
|
82
|
-
hint: `${proj.slug} — ${proj.role}`,
|
|
83
|
-
})),
|
|
84
|
-
});
|
|
85
|
-
if (p.isCancel(projectId)) {
|
|
86
|
-
p.cancel('Init cancelled.');
|
|
87
|
-
process.exit(0);
|
|
88
|
-
}
|
|
89
|
-
const selectedProject = projects.find((proj) => proj.id === projectId);
|
|
90
|
-
// 4. Check if a local config exists
|
|
91
|
-
const existingConfigFile = CONFIG_FILES.find((file) => fs_extra_1.default.existsSync(path_1.default.resolve(workingDir, file)));
|
|
92
|
-
if (!existingConfigFile) {
|
|
93
|
-
// No local config — pull it from the remote project
|
|
94
|
-
spinner.start('No local config found. Fetching config from platform...');
|
|
95
|
-
try {
|
|
96
|
-
const manifest = yield (0, client_1.getManifest)(baseUrl, token, selectedProject.id);
|
|
97
|
-
// Look for handoff.config.js in the manifest
|
|
98
|
-
const remoteConfigKey = Object.keys(manifest.files).find((key) => key === 'handoff.config.js' || key === 'handoff.config.json' || key === 'handoff.config.cjs');
|
|
99
|
-
if (remoteConfigKey) {
|
|
100
|
-
const content = yield (0, client_1.downloadFile)(baseUrl, token, selectedProject.id, remoteConfigKey);
|
|
101
|
-
const localConfigPath = path_1.default.resolve(workingDir, remoteConfigKey);
|
|
102
|
-
fs_extra_1.default.writeFileSync(localConfigPath, content);
|
|
103
|
-
spinner.stop(`Downloaded ${remoteConfigKey} from platform.`);
|
|
104
|
-
// Now inject the platform fields into it
|
|
105
|
-
yield injectPlatformFields(localConfigPath, selectedProject.id, baseUrl);
|
|
106
|
-
}
|
|
107
|
-
else {
|
|
108
|
-
spinner.stop('No remote config found either. Creating a new config.');
|
|
109
|
-
// Create a minimal config with just the platform fields
|
|
110
|
-
const configPath = path_1.default.resolve(workingDir, 'handoff.config.js');
|
|
111
|
-
const configContent = generateMinimalConfig(selectedProject.id, baseUrl);
|
|
112
|
-
fs_extra_1.default.writeFileSync(configPath, configContent);
|
|
113
|
-
}
|
|
114
|
-
}
|
|
115
|
-
catch (err) {
|
|
116
|
-
spinner.stop('Could not fetch remote config.');
|
|
117
|
-
// Fall back to creating a minimal config
|
|
118
|
-
const configPath = path_1.default.resolve(workingDir, 'handoff.config.js');
|
|
119
|
-
const configContent = generateMinimalConfig(selectedProject.id, baseUrl);
|
|
120
|
-
fs_extra_1.default.writeFileSync(configPath, configContent);
|
|
121
|
-
}
|
|
122
|
-
}
|
|
123
|
-
else {
|
|
124
|
-
// Local config exists — add/update platform fields
|
|
125
|
-
const configPath = path_1.default.resolve(workingDir, existingConfigFile);
|
|
126
|
-
yield injectPlatformFields(configPath, selectedProject.id, baseUrl);
|
|
127
|
-
}
|
|
128
|
-
p.note([
|
|
129
|
-
`Project: ${chalk_1.default.bold(selectedProject.name)}`,
|
|
130
|
-
`Organization: ${chalk_1.default.dim(selectedProject.orgName)}`,
|
|
131
|
-
`Project ID: ${chalk_1.default.dim(selectedProject.id)}`,
|
|
132
|
-
`Platform: ${chalk_1.default.dim(baseUrl)}`,
|
|
133
|
-
].join('\n'), 'Linked successfully');
|
|
134
|
-
p.outro(`Run ${chalk_1.default.cyan('handoff-app platform:pull')} to sync files from the platform.`);
|
|
135
|
-
}
|
|
136
|
-
catch (err) {
|
|
137
|
-
spinner.stop('Init failed.');
|
|
138
|
-
p.cancel(err.message || 'Init failed');
|
|
139
|
-
process.exit(1);
|
|
140
|
-
}
|
|
141
|
-
}),
|
|
142
|
-
};
|
|
143
|
-
/**
|
|
144
|
-
* Inject platformProjectId and platformUrl into an existing config file.
|
|
145
|
-
*
|
|
146
|
-
* For JSON files, parse and re-serialize.
|
|
147
|
-
* For JS/CJS files, use a regex approach to add/update the fields.
|
|
148
|
-
*/
|
|
149
|
-
function injectPlatformFields(configPath, projectId, platformUrl) {
|
|
150
|
-
return __awaiter(this, void 0, void 0, function* () {
|
|
151
|
-
const ext = path_1.default.extname(configPath);
|
|
152
|
-
if (ext === '.json') {
|
|
153
|
-
const config = fs_extra_1.default.readJsonSync(configPath);
|
|
154
|
-
config.platformProjectId = projectId;
|
|
155
|
-
config.platformUrl = platformUrl;
|
|
156
|
-
fs_extra_1.default.writeJsonSync(configPath, config, { spaces: 2 });
|
|
157
|
-
}
|
|
158
|
-
else {
|
|
159
|
-
// JS or CJS file — read as text, inject/replace fields
|
|
160
|
-
let content = fs_extra_1.default.readFileSync(configPath, 'utf8');
|
|
161
|
-
content = upsertConfigField(content, 'platformProjectId', JSON.stringify(projectId));
|
|
162
|
-
content = upsertConfigField(content, 'platformUrl', JSON.stringify(platformUrl));
|
|
163
|
-
fs_extra_1.default.writeFileSync(configPath, content, 'utf8');
|
|
164
|
-
}
|
|
165
|
-
});
|
|
166
|
-
}
|
|
167
|
-
/**
|
|
168
|
-
* Insert or replace a top-level field in a JS config export.
|
|
169
|
-
* Looks for `fieldName: ...` and replaces the value, or appends
|
|
170
|
-
* the field before the closing `};` of module.exports.
|
|
171
|
-
*/
|
|
172
|
-
function upsertConfigField(source, fieldName, value) {
|
|
173
|
-
// Pattern to match an existing field assignment (with optional trailing comma)
|
|
174
|
-
const existingPattern = new RegExp(`(${fieldName}\\s*:\\s*)([^,}\\n]+)(,?)`);
|
|
175
|
-
if (existingPattern.test(source)) {
|
|
176
|
-
return source.replace(existingPattern, `$1${value}$3`);
|
|
177
|
-
}
|
|
178
|
-
// Insert before the last `};` (end of module.exports)
|
|
179
|
-
// Handle both `module.exports = {` and `export default {` styles
|
|
180
|
-
// Also ensure the previous line ends with a comma so the JS stays valid
|
|
181
|
-
const closingBrace = /(\n)(};?\s*$)/;
|
|
182
|
-
if (closingBrace.test(source)) {
|
|
183
|
-
// Ensure the last property line before the closing brace has a trailing comma
|
|
184
|
-
source = ensureTrailingComma(source);
|
|
185
|
-
return source.replace(closingBrace, `$1 ${fieldName}: ${value},\n$2`);
|
|
186
|
-
}
|
|
187
|
-
// Fallback: just append as a comment warning
|
|
188
|
-
return source + `\n// Added by platform:init — could not auto-inject:\n// ${fieldName}: ${value}\n`;
|
|
189
|
-
}
|
|
190
|
-
/**
|
|
191
|
-
* Ensure the last property line before the closing `};` has a trailing comma.
|
|
192
|
-
* This prevents invalid JS when appending new properties to an object literal.
|
|
193
|
-
*/
|
|
194
|
-
function ensureTrailingComma(source) {
|
|
195
|
-
const lines = source.split('\n');
|
|
196
|
-
// Find the closing `};` or `}` at the start of a line (module.exports / export default)
|
|
197
|
-
let closingIdx = -1;
|
|
198
|
-
for (let i = lines.length - 1; i >= 0; i--) {
|
|
199
|
-
if (/^};?\s*$/.test(lines[i])) {
|
|
200
|
-
closingIdx = i;
|
|
201
|
-
break;
|
|
202
|
-
}
|
|
203
|
-
}
|
|
204
|
-
if (closingIdx <= 0)
|
|
205
|
-
return source;
|
|
206
|
-
// Walk backwards past blank lines and comment-only lines to find the last property line
|
|
207
|
-
let lastPropIdx = closingIdx - 1;
|
|
208
|
-
while (lastPropIdx >= 0 && (/^\s*$/.test(lines[lastPropIdx]) || /^\s*\/\//.test(lines[lastPropIdx]))) {
|
|
209
|
-
lastPropIdx--;
|
|
210
|
-
}
|
|
211
|
-
if (lastPropIdx < 0)
|
|
212
|
-
return source;
|
|
213
|
-
// Strip inline comments for the check, but preserve them in the output
|
|
214
|
-
const stripped = lines[lastPropIdx].replace(/\s*\/\/.*$/, '').trimEnd();
|
|
215
|
-
if (stripped.length > 0 && !stripped.endsWith(',') && !stripped.endsWith('{')) {
|
|
216
|
-
// Insert a comma after the last significant character, preserving any inline comment
|
|
217
|
-
lines[lastPropIdx] = lines[lastPropIdx].replace(/(\S)(\s*(?:\/\/.*)?)$/, '$1,$2');
|
|
218
|
-
}
|
|
219
|
-
return lines.join('\n');
|
|
220
|
-
}
|
|
221
|
-
/**
|
|
222
|
-
* Generate a minimal handoff.config.js with platform fields.
|
|
223
|
-
*/
|
|
224
|
-
function generateMinimalConfig(projectId, platformUrl) {
|
|
225
|
-
return `module.exports = {
|
|
226
|
-
platformProjectId: ${JSON.stringify(projectId)},
|
|
227
|
-
platformUrl: ${JSON.stringify(platformUrl)},
|
|
228
|
-
};
|
|
229
|
-
`;
|
|
230
|
-
}
|
|
231
|
-
exports.default = command;
|
|
@@ -1,108 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
-
if (k2 === undefined) k2 = k;
|
|
4
|
-
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
5
|
-
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
6
|
-
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
7
|
-
}
|
|
8
|
-
Object.defineProperty(o, k2, desc);
|
|
9
|
-
}) : (function(o, m, k, k2) {
|
|
10
|
-
if (k2 === undefined) k2 = k;
|
|
11
|
-
o[k2] = m[k];
|
|
12
|
-
}));
|
|
13
|
-
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
14
|
-
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
15
|
-
}) : function(o, v) {
|
|
16
|
-
o["default"] = v;
|
|
17
|
-
});
|
|
18
|
-
var __importStar = (this && this.__importStar) || function (mod) {
|
|
19
|
-
if (mod && mod.__esModule) return mod;
|
|
20
|
-
var result = {};
|
|
21
|
-
if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
|
|
22
|
-
__setModuleDefault(result, mod);
|
|
23
|
-
return result;
|
|
24
|
-
};
|
|
25
|
-
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
|
|
26
|
-
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
|
27
|
-
return new (P || (P = Promise))(function (resolve, reject) {
|
|
28
|
-
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
|
|
29
|
-
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
|
|
30
|
-
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
|
|
31
|
-
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
|
32
|
-
});
|
|
33
|
-
};
|
|
34
|
-
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
35
|
-
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
36
|
-
};
|
|
37
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
38
|
-
const p = __importStar(require("@clack/prompts"));
|
|
39
|
-
const chalk_1 = __importDefault(require("chalk"));
|
|
40
|
-
const child_process_1 = require("child_process");
|
|
41
|
-
const client_1 = require("../../platform/client");
|
|
42
|
-
const credentials_1 = require("../../platform/credentials");
|
|
43
|
-
const DEFAULT_PLATFORM_URL = 'http://localhost:3000';
|
|
44
|
-
const command = {
|
|
45
|
-
command: 'platform:login',
|
|
46
|
-
describe: 'Log in to the Handoff platform',
|
|
47
|
-
builder: (yargs) => {
|
|
48
|
-
return yargs.option('url', {
|
|
49
|
-
type: 'string',
|
|
50
|
-
description: 'Platform URL',
|
|
51
|
-
default: process.env.HANDOFF_PLATFORM_URL || DEFAULT_PLATFORM_URL,
|
|
52
|
-
});
|
|
53
|
-
},
|
|
54
|
-
handler: (args) => __awaiter(void 0, void 0, void 0, function* () {
|
|
55
|
-
const baseUrl = (args.url || DEFAULT_PLATFORM_URL).replace(/\/+$/, '');
|
|
56
|
-
p.intro(chalk_1.default.bold('Handoff Platform Login'));
|
|
57
|
-
const spinner = p.spinner();
|
|
58
|
-
try {
|
|
59
|
-
spinner.start('Initiating authentication...');
|
|
60
|
-
const deviceCode = yield (0, client_1.createDeviceCode)(baseUrl);
|
|
61
|
-
spinner.stop('Authentication initiated.');
|
|
62
|
-
// Display the user code prominently
|
|
63
|
-
p.note([
|
|
64
|
-
`Your one-time code: ${chalk_1.default.bold.cyan(deviceCode.userCode)}`,
|
|
65
|
-
'',
|
|
66
|
-
`Open this URL to sign in:`,
|
|
67
|
-
chalk_1.default.underline(`${deviceCode.verificationUrl}`),
|
|
68
|
-
].join('\n'), 'Authentication');
|
|
69
|
-
// Try to open the browser automatically
|
|
70
|
-
openBrowser(deviceCode.verificationUrl);
|
|
71
|
-
spinner.start('Waiting for approval (this will open in your browser)...');
|
|
72
|
-
const result = yield (0, client_1.pollForToken)(baseUrl, deviceCode.deviceCode, deviceCode.interval, deviceCode.expiresIn);
|
|
73
|
-
spinner.stop('Authentication approved!');
|
|
74
|
-
// Store the token
|
|
75
|
-
(0, credentials_1.setToken)(baseUrl, result.token, {
|
|
76
|
-
name: result.user.name,
|
|
77
|
-
email: result.user.email,
|
|
78
|
-
});
|
|
79
|
-
p.note([
|
|
80
|
-
`Logged in as ${chalk_1.default.bold(result.user.name || result.user.email)}`,
|
|
81
|
-
`Platform: ${chalk_1.default.dim(baseUrl)}`,
|
|
82
|
-
].join('\n'), 'Success');
|
|
83
|
-
p.outro('You can now use platform:init to link a project.');
|
|
84
|
-
}
|
|
85
|
-
catch (err) {
|
|
86
|
-
spinner.stop('Authentication failed.');
|
|
87
|
-
p.cancel(err.message || 'Login failed');
|
|
88
|
-
process.exit(1);
|
|
89
|
-
}
|
|
90
|
-
}),
|
|
91
|
-
};
|
|
92
|
-
/**
|
|
93
|
-
* Attempt to open a URL in the default browser.
|
|
94
|
-
* Fails silently — the user can always copy/paste the URL.
|
|
95
|
-
*/
|
|
96
|
-
function openBrowser(url) {
|
|
97
|
-
const command = process.platform === 'darwin'
|
|
98
|
-
? `open "${url}"`
|
|
99
|
-
: process.platform === 'win32'
|
|
100
|
-
? `start "" "${url}"`
|
|
101
|
-
: `xdg-open "${url}"`;
|
|
102
|
-
(0, child_process_1.exec)(command, (err) => {
|
|
103
|
-
if (err) {
|
|
104
|
-
// Silently ignore — user will use the printed URL
|
|
105
|
-
}
|
|
106
|
-
});
|
|
107
|
-
}
|
|
108
|
-
exports.default = command;
|
|
@@ -1,88 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
-
if (k2 === undefined) k2 = k;
|
|
4
|
-
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
5
|
-
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
6
|
-
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
7
|
-
}
|
|
8
|
-
Object.defineProperty(o, k2, desc);
|
|
9
|
-
}) : (function(o, m, k, k2) {
|
|
10
|
-
if (k2 === undefined) k2 = k;
|
|
11
|
-
o[k2] = m[k];
|
|
12
|
-
}));
|
|
13
|
-
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
14
|
-
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
15
|
-
}) : function(o, v) {
|
|
16
|
-
o["default"] = v;
|
|
17
|
-
});
|
|
18
|
-
var __importStar = (this && this.__importStar) || function (mod) {
|
|
19
|
-
if (mod && mod.__esModule) return mod;
|
|
20
|
-
var result = {};
|
|
21
|
-
if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
|
|
22
|
-
__setModuleDefault(result, mod);
|
|
23
|
-
return result;
|
|
24
|
-
};
|
|
25
|
-
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
|
|
26
|
-
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
|
27
|
-
return new (P || (P = Promise))(function (resolve, reject) {
|
|
28
|
-
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
|
|
29
|
-
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
|
|
30
|
-
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
|
|
31
|
-
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
|
32
|
-
});
|
|
33
|
-
};
|
|
34
|
-
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
35
|
-
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
36
|
-
};
|
|
37
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
38
|
-
const p = __importStar(require("@clack/prompts"));
|
|
39
|
-
const chalk_1 = __importDefault(require("chalk"));
|
|
40
|
-
const client_1 = require("../../platform/client");
|
|
41
|
-
const credentials_1 = require("../../platform/credentials");
|
|
42
|
-
const DEFAULT_PLATFORM_URL = 'http://localhost:3000';
|
|
43
|
-
const command = {
|
|
44
|
-
command: 'platform:logout',
|
|
45
|
-
describe: 'Log out from the Handoff platform',
|
|
46
|
-
builder: (yargs) => {
|
|
47
|
-
return yargs.option('url', {
|
|
48
|
-
type: 'string',
|
|
49
|
-
description: 'Platform URL',
|
|
50
|
-
default: process.env.HANDOFF_PLATFORM_URL || DEFAULT_PLATFORM_URL,
|
|
51
|
-
});
|
|
52
|
-
},
|
|
53
|
-
handler: (args) => __awaiter(void 0, void 0, void 0, function* () {
|
|
54
|
-
const baseUrl = (args.url || DEFAULT_PLATFORM_URL).replace(/\/+$/, '');
|
|
55
|
-
p.intro(chalk_1.default.bold('Handoff Platform Logout'));
|
|
56
|
-
const token = (0, credentials_1.getToken)(baseUrl);
|
|
57
|
-
if (!token) {
|
|
58
|
-
p.note(`Not currently logged in to ${chalk_1.default.dim(baseUrl)}.`, 'Info');
|
|
59
|
-
p.outro('Nothing to do.');
|
|
60
|
-
return;
|
|
61
|
-
}
|
|
62
|
-
const spinner = p.spinner();
|
|
63
|
-
try {
|
|
64
|
-
// Revoke the token on the server (best-effort)
|
|
65
|
-
spinner.start('Revoking token...');
|
|
66
|
-
try {
|
|
67
|
-
yield (0, client_1.revokeToken)(baseUrl, token);
|
|
68
|
-
}
|
|
69
|
-
catch (_a) {
|
|
70
|
-
// If the server is unreachable or the token is already invalid,
|
|
71
|
-
// still proceed to remove the local credential.
|
|
72
|
-
}
|
|
73
|
-
spinner.stop('Token revoked.');
|
|
74
|
-
// Remove from local credentials store
|
|
75
|
-
(0, credentials_1.removeToken)(baseUrl);
|
|
76
|
-
p.note(`Logged out from ${chalk_1.default.dim(baseUrl)}.`, 'Success');
|
|
77
|
-
p.outro('Local credentials removed.');
|
|
78
|
-
}
|
|
79
|
-
catch (err) {
|
|
80
|
-
spinner.stop('Logout encountered an issue.');
|
|
81
|
-
// Still remove the local token even if revocation fails
|
|
82
|
-
(0, credentials_1.removeToken)(baseUrl);
|
|
83
|
-
p.note(`Local credentials removed, but server revocation may have failed.`, 'Warning');
|
|
84
|
-
p.outro('You are logged out locally.');
|
|
85
|
-
}
|
|
86
|
-
}),
|
|
87
|
-
};
|
|
88
|
-
exports.default = command;
|
|
@@ -1,112 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
-
if (k2 === undefined) k2 = k;
|
|
4
|
-
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
5
|
-
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
6
|
-
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
7
|
-
}
|
|
8
|
-
Object.defineProperty(o, k2, desc);
|
|
9
|
-
}) : (function(o, m, k, k2) {
|
|
10
|
-
if (k2 === undefined) k2 = k;
|
|
11
|
-
o[k2] = m[k];
|
|
12
|
-
}));
|
|
13
|
-
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
14
|
-
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
15
|
-
}) : function(o, v) {
|
|
16
|
-
o["default"] = v;
|
|
17
|
-
});
|
|
18
|
-
var __importStar = (this && this.__importStar) || function (mod) {
|
|
19
|
-
if (mod && mod.__esModule) return mod;
|
|
20
|
-
var result = {};
|
|
21
|
-
if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
|
|
22
|
-
__setModuleDefault(result, mod);
|
|
23
|
-
return result;
|
|
24
|
-
};
|
|
25
|
-
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
|
|
26
|
-
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
|
27
|
-
return new (P || (P = Promise))(function (resolve, reject) {
|
|
28
|
-
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
|
|
29
|
-
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
|
|
30
|
-
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
|
|
31
|
-
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
|
32
|
-
});
|
|
33
|
-
};
|
|
34
|
-
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
35
|
-
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
36
|
-
};
|
|
37
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
38
|
-
const p = __importStar(require("@clack/prompts"));
|
|
39
|
-
const chalk_1 = __importDefault(require("chalk"));
|
|
40
|
-
const __1 = __importDefault(require("../../"));
|
|
41
|
-
const credentials_1 = require("../../platform/credentials");
|
|
42
|
-
const sync_1 = require("../../platform/sync");
|
|
43
|
-
const DEFAULT_PLATFORM_URL = 'http://localhost:3000';
|
|
44
|
-
const command = {
|
|
45
|
-
command: 'platform:pull',
|
|
46
|
-
describe: 'Pull project files from the Handoff platform',
|
|
47
|
-
builder: (yargs) => {
|
|
48
|
-
return yargs
|
|
49
|
-
.option('url', {
|
|
50
|
-
type: 'string',
|
|
51
|
-
description: 'Platform URL (overrides config)',
|
|
52
|
-
})
|
|
53
|
-
.option('force', {
|
|
54
|
-
alias: 'f',
|
|
55
|
-
type: 'boolean',
|
|
56
|
-
description: 'Overwrite all local files and delete orphaned files',
|
|
57
|
-
default: false,
|
|
58
|
-
})
|
|
59
|
-
.option('debug', {
|
|
60
|
-
alias: 'd',
|
|
61
|
-
type: 'boolean',
|
|
62
|
-
description: 'Enable debug mode',
|
|
63
|
-
});
|
|
64
|
-
},
|
|
65
|
-
handler: (args) => __awaiter(void 0, void 0, void 0, function* () {
|
|
66
|
-
const handoff = new __1.default(args.debug, args.force);
|
|
67
|
-
const config = handoff.config;
|
|
68
|
-
const baseUrl = (args.url || (config === null || config === void 0 ? void 0 : config.platformUrl) || process.env.HANDOFF_PLATFORM_URL || DEFAULT_PLATFORM_URL).replace(/\/+$/, '');
|
|
69
|
-
const projectId = config === null || config === void 0 ? void 0 : config.platformProjectId;
|
|
70
|
-
p.intro(chalk_1.default.bold('Handoff Platform Pull'));
|
|
71
|
-
if (!projectId) {
|
|
72
|
-
p.cancel(`No project linked. Run ${chalk_1.default.cyan('handoff-app platform:init')} first.`);
|
|
73
|
-
process.exit(1);
|
|
74
|
-
}
|
|
75
|
-
const token = (0, credentials_1.getToken)(baseUrl);
|
|
76
|
-
if (!token) {
|
|
77
|
-
p.cancel(`Not logged in to ${baseUrl}. Run ${chalk_1.default.cyan('handoff-app platform:login')} first.`);
|
|
78
|
-
process.exit(1);
|
|
79
|
-
}
|
|
80
|
-
const spinner = p.spinner();
|
|
81
|
-
try {
|
|
82
|
-
spinner.start('Pulling from platform...');
|
|
83
|
-
const result = yield (0, sync_1.pullProject)(baseUrl, token, projectId, handoff.workingPath, {
|
|
84
|
-
force: args.force,
|
|
85
|
-
onProgress: (msg) => spinner.message(msg),
|
|
86
|
-
});
|
|
87
|
-
spinner.stop('Pull complete.');
|
|
88
|
-
const summary = [
|
|
89
|
-
`Downloaded: ${chalk_1.default.green(String(result.downloaded.length))} file(s)`,
|
|
90
|
-
`Unchanged: ${chalk_1.default.dim(String(result.unchanged.length))} file(s)`,
|
|
91
|
-
];
|
|
92
|
-
if (result.deleted.length > 0) {
|
|
93
|
-
summary.push(`Deleted: ${chalk_1.default.red(String(result.deleted.length))} file(s)`);
|
|
94
|
-
}
|
|
95
|
-
summary.push(`Sync version: ${chalk_1.default.cyan(String(result.version))}`);
|
|
96
|
-
p.note(summary.join('\n'), 'Pull Summary');
|
|
97
|
-
if (result.downloaded.length > 0) {
|
|
98
|
-
p.log.info(chalk_1.default.dim('Downloaded files:'));
|
|
99
|
-
for (const file of result.downloaded) {
|
|
100
|
-
p.log.info(chalk_1.default.dim(` + ${file}`));
|
|
101
|
-
}
|
|
102
|
-
}
|
|
103
|
-
p.outro('Local project is up to date.');
|
|
104
|
-
}
|
|
105
|
-
catch (err) {
|
|
106
|
-
spinner.stop('Pull failed.');
|
|
107
|
-
p.cancel(err.message || 'Pull failed');
|
|
108
|
-
process.exit(1);
|
|
109
|
-
}
|
|
110
|
-
}),
|
|
111
|
-
};
|
|
112
|
-
exports.default = command;
|