@coze-arch/cli 0.0.6-alpha.dd6b66 → 0.0.7
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/lib/__templates__/nuxt-vue/nuxt.config.ts +0 -13
- package/lib/cli.js +169 -1137
- package/package.json +1 -2
package/lib/cli.js
CHANGED
|
@@ -15,7 +15,6 @@ var fs$1 = require('fs/promises');
|
|
|
15
15
|
var os = require('os');
|
|
16
16
|
var jsYaml = require('js-yaml');
|
|
17
17
|
var toml = require('@iarna/toml');
|
|
18
|
-
var fastGlob = require('fast-glob');
|
|
19
18
|
var child_process = require('child_process');
|
|
20
19
|
var addFormats = require('ajv-formats');
|
|
21
20
|
var Ajv = require('ajv');
|
|
@@ -1491,7 +1490,7 @@ var browserClient = createBaseClient();
|
|
|
1491
1490
|
|
|
1492
1491
|
|
|
1493
1492
|
|
|
1494
|
-
const log$
|
|
1493
|
+
const log$2 = debug('slardar:transport');
|
|
1495
1494
|
// eslint-disable-next-line @typescript-eslint/no-empty-function
|
|
1496
1495
|
const noop = () => {};
|
|
1497
1496
|
|
|
@@ -1511,22 +1510,22 @@ const noop = () => {};
|
|
|
1511
1510
|
function makeRequest(options) {
|
|
1512
1511
|
const { url, method, data, success = noop, fail = noop, getResponseText = noop } = options;
|
|
1513
1512
|
|
|
1514
|
-
log$
|
|
1513
|
+
log$2('Making %s request to %s', method, url);
|
|
1515
1514
|
if (data) {
|
|
1516
|
-
log$
|
|
1515
|
+
log$2('Request data: %s', data.slice(0, 200));
|
|
1517
1516
|
}
|
|
1518
1517
|
|
|
1519
1518
|
// 检查 URL 是否有效
|
|
1520
1519
|
if (!url || typeof url !== 'string') {
|
|
1521
1520
|
const error = new Error(`Invalid URL: ${url}`);
|
|
1522
|
-
log$
|
|
1521
|
+
log$2('Invalid URL provided: %o', url);
|
|
1523
1522
|
fail(error);
|
|
1524
1523
|
return;
|
|
1525
1524
|
}
|
|
1526
1525
|
|
|
1527
1526
|
try {
|
|
1528
1527
|
const urlObj = new URL(url);
|
|
1529
|
-
log$
|
|
1528
|
+
log$2('Parsed URL - protocol: %s, hostname: %s, port: %s, path: %s',
|
|
1530
1529
|
urlObj.protocol, urlObj.hostname, urlObj.port, urlObj.pathname);
|
|
1531
1530
|
|
|
1532
1531
|
const isHttps = urlObj.protocol === 'https:';
|
|
@@ -1544,34 +1543,34 @@ function makeRequest(options) {
|
|
|
1544
1543
|
},
|
|
1545
1544
|
},
|
|
1546
1545
|
res => {
|
|
1547
|
-
log$
|
|
1546
|
+
log$2('Response callback triggered: status=%s', res.statusCode);
|
|
1548
1547
|
let responseText = '';
|
|
1549
1548
|
|
|
1550
1549
|
res.on('data', chunk => {
|
|
1551
|
-
log$
|
|
1550
|
+
log$2('Response data chunk received: %s bytes', chunk.length);
|
|
1552
1551
|
responseText += chunk.toString();
|
|
1553
1552
|
});
|
|
1554
1553
|
|
|
1555
1554
|
res.on('end', () => {
|
|
1556
|
-
log$
|
|
1557
|
-
log$
|
|
1555
|
+
log$2('Response end event fired');
|
|
1556
|
+
log$2('Response received: status=%s, body=%s', res.statusCode, responseText.slice(0, 200));
|
|
1558
1557
|
getResponseText(responseText);
|
|
1559
1558
|
|
|
1560
1559
|
try {
|
|
1561
1560
|
if (res.statusCode && res.statusCode >= 400) {
|
|
1562
|
-
log$
|
|
1561
|
+
log$2('Request failed with status %s: %s', res.statusCode, responseText);
|
|
1563
1562
|
fail(new Error(responseText || res.statusMessage || 'Request failed'));
|
|
1564
1563
|
} else if (responseText) {
|
|
1565
1564
|
// eslint-disable-next-line no-restricted-syntax -- Parsing trusted Slardar API responses
|
|
1566
1565
|
const result = JSON.parse(responseText);
|
|
1567
|
-
log$
|
|
1566
|
+
log$2('Request succeeded');
|
|
1568
1567
|
success(result);
|
|
1569
1568
|
} else {
|
|
1570
|
-
log$
|
|
1569
|
+
log$2('Request succeeded with empty response');
|
|
1571
1570
|
success({});
|
|
1572
1571
|
}
|
|
1573
1572
|
} catch (e) {
|
|
1574
|
-
log$
|
|
1573
|
+
log$2('Failed to parse response: %s', (e ).message);
|
|
1575
1574
|
fail(e );
|
|
1576
1575
|
}
|
|
1577
1576
|
});
|
|
@@ -1579,12 +1578,12 @@ function makeRequest(options) {
|
|
|
1579
1578
|
);
|
|
1580
1579
|
|
|
1581
1580
|
req.on('error', err => {
|
|
1582
|
-
log$
|
|
1581
|
+
log$2('Request error: %s', err.message);
|
|
1583
1582
|
fail(err);
|
|
1584
1583
|
});
|
|
1585
1584
|
|
|
1586
1585
|
req.on('timeout', () => {
|
|
1587
|
-
log$
|
|
1586
|
+
log$2('Request timeout');
|
|
1588
1587
|
req.destroy();
|
|
1589
1588
|
fail(new Error('Request timeout'));
|
|
1590
1589
|
});
|
|
@@ -1595,7 +1594,7 @@ function makeRequest(options) {
|
|
|
1595
1594
|
|
|
1596
1595
|
req.end();
|
|
1597
1596
|
} catch (e) {
|
|
1598
|
-
log$
|
|
1597
|
+
log$2('Exception during request: %s', (e ).message);
|
|
1599
1598
|
fail(e );
|
|
1600
1599
|
}
|
|
1601
1600
|
}
|
|
@@ -1606,14 +1605,14 @@ function makeRequest(options) {
|
|
|
1606
1605
|
function createNodeTransport() {
|
|
1607
1606
|
return {
|
|
1608
1607
|
get(options) {
|
|
1609
|
-
log$
|
|
1608
|
+
log$2('Transport GET called: %s', options.url);
|
|
1610
1609
|
makeRequest({
|
|
1611
1610
|
method: 'GET',
|
|
1612
1611
|
...options,
|
|
1613
1612
|
});
|
|
1614
1613
|
},
|
|
1615
1614
|
post({ url, data }) {
|
|
1616
|
-
log$
|
|
1615
|
+
log$2('Transport POST called: %s', url);
|
|
1617
1616
|
makeRequest({
|
|
1618
1617
|
method: 'POST',
|
|
1619
1618
|
url,
|
|
@@ -1627,14 +1626,14 @@ function createNodeTransport() {
|
|
|
1627
1626
|
};
|
|
1628
1627
|
}
|
|
1629
1628
|
|
|
1630
|
-
function _nullishCoalesce$3(lhs, rhsFn) { if (lhs != null) { return lhs; } else { return rhsFn(); } } function _optionalChain$
|
|
1629
|
+
function _nullishCoalesce$3(lhs, rhsFn) { if (lhs != null) { return lhs; } else { return rhsFn(); } } function _optionalChain$6(ops) { let lastAccessLHS = undefined; let value = ops[0]; let i = 1; while (i < ops.length) { const op = ops[i]; const fn = ops[i + 1]; i += 2; if ((op === 'optionalAccess' || op === 'optionalCall') && value == null) { return undefined; } if (op === 'access' || op === 'optionalAccess') { lastAccessLHS = value; value = fn(value); } else if (op === 'call' || op === 'optionalCall') { value = fn((...args) => value.call(lastAccessLHS, ...args)); lastAccessLHS = undefined; } } return value; }/**
|
|
1631
1630
|
* Slardar CLI Reporter 主类
|
|
1632
1631
|
* 封装 @slardar/base 的初始化和上报逻辑
|
|
1633
1632
|
*/
|
|
1634
1633
|
|
|
1635
1634
|
// 创建 debug 实例
|
|
1636
1635
|
// 使用方式: DEBUG=slardar:* your-cli-command
|
|
1637
|
-
const log$
|
|
1636
|
+
const log$1 = debug('slardar:reporter');
|
|
1638
1637
|
|
|
1639
1638
|
/**
|
|
1640
1639
|
* Slardar CLI Reporter
|
|
@@ -1659,12 +1658,12 @@ class SlardarCLIReporter {constructor() { SlardarCLIReporter.prototype.__init.ca
|
|
|
1659
1658
|
*/
|
|
1660
1659
|
setup(config) {
|
|
1661
1660
|
if (this.initialized) {
|
|
1662
|
-
log$
|
|
1661
|
+
log$1('Already initialized, skipping setup');
|
|
1663
1662
|
return;
|
|
1664
1663
|
}
|
|
1665
1664
|
|
|
1666
1665
|
try {
|
|
1667
|
-
log$
|
|
1666
|
+
log$1('Initializing Slardar with config:', {
|
|
1668
1667
|
bid: config.bid,
|
|
1669
1668
|
release: config.release,
|
|
1670
1669
|
env: config.env,
|
|
@@ -1697,17 +1696,17 @@ class SlardarCLIReporter {constructor() { SlardarCLIReporter.prototype.__init.ca
|
|
|
1697
1696
|
|
|
1698
1697
|
// 添加 send 钩子来追踪事件上报
|
|
1699
1698
|
this.client.on('send', (ev) => {
|
|
1700
|
-
log$
|
|
1699
|
+
log$1(
|
|
1701
1700
|
'send hook called for event: %s',
|
|
1702
|
-
(_optionalChain$
|
|
1701
|
+
(_optionalChain$6([ev, 'optionalAccess', _ => _.ev_type]) ) || 'unknown',
|
|
1703
1702
|
);
|
|
1704
1703
|
});
|
|
1705
1704
|
|
|
1706
1705
|
this.client.start();
|
|
1707
1706
|
this.initialized = true;
|
|
1708
|
-
log$
|
|
1707
|
+
log$1('Slardar initialized successfully');
|
|
1709
1708
|
} catch (error) {
|
|
1710
|
-
log$
|
|
1709
|
+
log$1('Failed to initialize:', error);
|
|
1711
1710
|
}
|
|
1712
1711
|
}
|
|
1713
1712
|
|
|
@@ -1716,7 +1715,7 @@ class SlardarCLIReporter {constructor() { SlardarCLIReporter.prototype.__init.ca
|
|
|
1716
1715
|
*/
|
|
1717
1716
|
ensureInitialized() {
|
|
1718
1717
|
if (!this.initialized) {
|
|
1719
|
-
log$
|
|
1718
|
+
log$1('Not initialized, call setup() first');
|
|
1720
1719
|
return false;
|
|
1721
1720
|
}
|
|
1722
1721
|
return true;
|
|
@@ -1738,7 +1737,7 @@ class SlardarCLIReporter {constructor() { SlardarCLIReporter.prototype.__init.ca
|
|
|
1738
1737
|
}
|
|
1739
1738
|
|
|
1740
1739
|
try {
|
|
1741
|
-
log$
|
|
1740
|
+
log$1('Sending event:', { name, metrics, categories });
|
|
1742
1741
|
|
|
1743
1742
|
// 过滤掉 undefined 值以满足 Slardar 类型要求
|
|
1744
1743
|
const cleanMetrics = metrics
|
|
@@ -1757,13 +1756,13 @@ class SlardarCLIReporter {constructor() { SlardarCLIReporter.prototype.__init.ca
|
|
|
1757
1756
|
)
|
|
1758
1757
|
: undefined;
|
|
1759
1758
|
|
|
1760
|
-
_optionalChain$
|
|
1759
|
+
_optionalChain$6([this, 'access', _2 => _2.client, 'access', _3 => _3.sendEvent, 'optionalCall', _4 => _4({
|
|
1761
1760
|
name,
|
|
1762
1761
|
metrics: cleanMetrics ,
|
|
1763
1762
|
categories: cleanCategories ,
|
|
1764
1763
|
})]);
|
|
1765
1764
|
} catch (error) {
|
|
1766
|
-
log$
|
|
1765
|
+
log$1('Failed to send event:', error);
|
|
1767
1766
|
}
|
|
1768
1767
|
}
|
|
1769
1768
|
|
|
@@ -1783,7 +1782,7 @@ class SlardarCLIReporter {constructor() { SlardarCLIReporter.prototype.__init.ca
|
|
|
1783
1782
|
}
|
|
1784
1783
|
|
|
1785
1784
|
try {
|
|
1786
|
-
log$
|
|
1785
|
+
log$1('Sending log:', { level, message, extra });
|
|
1787
1786
|
// 使用 sendEvent 发送日志事件
|
|
1788
1787
|
this.sendEvent('cli_log', undefined, {
|
|
1789
1788
|
level,
|
|
@@ -1791,7 +1790,7 @@ class SlardarCLIReporter {constructor() { SlardarCLIReporter.prototype.__init.ca
|
|
|
1791
1790
|
...extra,
|
|
1792
1791
|
});
|
|
1793
1792
|
} catch (error) {
|
|
1794
|
-
log$
|
|
1793
|
+
log$1('Failed to send log:', error);
|
|
1795
1794
|
}
|
|
1796
1795
|
}
|
|
1797
1796
|
|
|
@@ -1825,19 +1824,19 @@ class SlardarCLIReporter {constructor() { SlardarCLIReporter.prototype.__init.ca
|
|
|
1825
1824
|
},
|
|
1826
1825
|
};
|
|
1827
1826
|
|
|
1828
|
-
log$
|
|
1827
|
+
log$1('Reporting JS error:', {
|
|
1829
1828
|
name: error.name,
|
|
1830
1829
|
message: error.message.slice(0, 100),
|
|
1831
|
-
stack: _optionalChain$
|
|
1830
|
+
stack: _optionalChain$6([error, 'access', _5 => _5.stack, 'optionalAccess', _6 => _6.slice, 'call', _7 => _7(0, 200)]),
|
|
1832
1831
|
extra,
|
|
1833
1832
|
source,
|
|
1834
1833
|
});
|
|
1835
1834
|
|
|
1836
1835
|
// 使用 Slardar 的 js_error 事件类型,这样会显示在 JS 错误总览页面
|
|
1837
1836
|
this.client.report(errorEvent);
|
|
1838
|
-
log$
|
|
1837
|
+
log$1('JS error reported successfully');
|
|
1839
1838
|
} catch (err) {
|
|
1840
|
-
log$
|
|
1839
|
+
log$1('Failed to report error:', err);
|
|
1841
1840
|
}
|
|
1842
1841
|
}
|
|
1843
1842
|
|
|
@@ -1848,7 +1847,7 @@ class SlardarCLIReporter {constructor() { SlardarCLIReporter.prototype.__init.ca
|
|
|
1848
1847
|
if (!this.ensureInitialized()) {
|
|
1849
1848
|
return;
|
|
1850
1849
|
}
|
|
1851
|
-
_optionalChain$
|
|
1850
|
+
_optionalChain$6([this, 'access', _8 => _8.client, 'access', _9 => _9.context, 'optionalAccess', _10 => _10.set, 'call', _11 => _11(key, value)]);
|
|
1852
1851
|
}
|
|
1853
1852
|
|
|
1854
1853
|
/**
|
|
@@ -1858,8 +1857,8 @@ class SlardarCLIReporter {constructor() { SlardarCLIReporter.prototype.__init.ca
|
|
|
1858
1857
|
if (!this.ensureInitialized()) {
|
|
1859
1858
|
return;
|
|
1860
1859
|
}
|
|
1861
|
-
log$
|
|
1862
|
-
_optionalChain$
|
|
1860
|
+
log$1('Merging context:', context);
|
|
1861
|
+
_optionalChain$6([this, 'access', _12 => _12.client, 'access', _13 => _13.context, 'optionalAccess', _14 => _14.merge, 'call', _15 => _15(context)]);
|
|
1863
1862
|
}
|
|
1864
1863
|
|
|
1865
1864
|
/**
|
|
@@ -1869,7 +1868,7 @@ class SlardarCLIReporter {constructor() { SlardarCLIReporter.prototype.__init.ca
|
|
|
1869
1868
|
if (!this.ensureInitialized()) {
|
|
1870
1869
|
return;
|
|
1871
1870
|
}
|
|
1872
|
-
_optionalChain$
|
|
1871
|
+
_optionalChain$6([this, 'access', _16 => _16.client, 'access', _17 => _17.context, 'optionalAccess', _18 => _18.delete, 'call', _19 => _19(key)]);
|
|
1873
1872
|
}
|
|
1874
1873
|
|
|
1875
1874
|
/**
|
|
@@ -1879,7 +1878,7 @@ class SlardarCLIReporter {constructor() { SlardarCLIReporter.prototype.__init.ca
|
|
|
1879
1878
|
if (!this.ensureInitialized()) {
|
|
1880
1879
|
return;
|
|
1881
1880
|
}
|
|
1882
|
-
_optionalChain$
|
|
1881
|
+
_optionalChain$6([this, 'access', _20 => _20.client, 'access', _21 => _21.context, 'optionalAccess', _22 => _22.clear, 'call', _23 => _23()]);
|
|
1883
1882
|
}
|
|
1884
1883
|
|
|
1885
1884
|
/**
|
|
@@ -1895,7 +1894,7 @@ class SlardarCLIReporter {constructor() { SlardarCLIReporter.prototype.__init.ca
|
|
|
1895
1894
|
}
|
|
1896
1895
|
|
|
1897
1896
|
try {
|
|
1898
|
-
log$
|
|
1897
|
+
log$1('Updating config:', config);
|
|
1899
1898
|
this.client.config({
|
|
1900
1899
|
userId: config.userId,
|
|
1901
1900
|
release: config.release,
|
|
@@ -1903,7 +1902,7 @@ class SlardarCLIReporter {constructor() { SlardarCLIReporter.prototype.__init.ca
|
|
|
1903
1902
|
env: config.env,
|
|
1904
1903
|
});
|
|
1905
1904
|
} catch (error) {
|
|
1906
|
-
log$
|
|
1905
|
+
log$1('Failed to update config:', error);
|
|
1907
1906
|
}
|
|
1908
1907
|
}
|
|
1909
1908
|
|
|
@@ -1915,11 +1914,11 @@ class SlardarCLIReporter {constructor() { SlardarCLIReporter.prototype.__init.ca
|
|
|
1915
1914
|
if (!this.ensureInitialized()) {
|
|
1916
1915
|
return;
|
|
1917
1916
|
}
|
|
1918
|
-
log$
|
|
1919
|
-
_optionalChain$
|
|
1920
|
-
log$
|
|
1917
|
+
log$1('Flushing Slardar data...');
|
|
1918
|
+
_optionalChain$6([this, 'access', _24 => _24.client, 'access', _25 => _25.getSender, 'optionalCall', _26 => _26(), 'optionalAccess', _27 => _27.flush, 'call', _28 => _28()]);
|
|
1919
|
+
log$1('Waiting %dms for events to be sent...', waitMs);
|
|
1921
1920
|
await new Promise(resolve => setTimeout(resolve, waitMs));
|
|
1922
|
-
log$
|
|
1921
|
+
log$1('Slardar data flushed');
|
|
1923
1922
|
}
|
|
1924
1923
|
|
|
1925
1924
|
/**
|
|
@@ -1935,7 +1934,7 @@ class SlardarCLIReporter {constructor() { SlardarCLIReporter.prototype.__init.ca
|
|
|
1935
1934
|
*/
|
|
1936
1935
|
const reporter = new SlardarCLIReporter();
|
|
1937
1936
|
|
|
1938
|
-
function _optionalChain$
|
|
1937
|
+
function _optionalChain$5(ops) { let lastAccessLHS = undefined; let value = ops[0]; let i = 1; while (i < ops.length) { const op = ops[i]; const fn = ops[i + 1]; i += 2; if ((op === 'optionalAccess' || op === 'optionalCall') && value == null) { return undefined; } if (op === 'access' || op === 'optionalAccess') { lastAccessLHS = value; value = fn(value); } else if (op === 'call' || op === 'optionalCall') { value = fn((...args) => value.call(lastAccessLHS, ...args)); lastAccessLHS = undefined; } } return value; }
|
|
1939
1938
|
|
|
1940
1939
|
|
|
1941
1940
|
|
|
@@ -1995,11 +1994,11 @@ const EventBuilder = {
|
|
|
1995
1994
|
name: CLI_EVENTS.CLI_COMMAND,
|
|
1996
1995
|
categories: {
|
|
1997
1996
|
command,
|
|
1998
|
-
args: _optionalChain$
|
|
1997
|
+
args: _optionalChain$5([options, 'optionalAccess', _ => _.args]),
|
|
1999
1998
|
status: 'running' ,
|
|
2000
|
-
..._optionalChain$
|
|
1999
|
+
..._optionalChain$5([options, 'optionalAccess', _2 => _2.categories]),
|
|
2001
2000
|
},
|
|
2002
|
-
metrics: _optionalChain$
|
|
2001
|
+
metrics: _optionalChain$5([options, 'optionalAccess', _3 => _3.metrics]),
|
|
2003
2002
|
};
|
|
2004
2003
|
},
|
|
2005
2004
|
|
|
@@ -2020,13 +2019,13 @@ const EventBuilder = {
|
|
|
2020
2019
|
name: CLI_EVENTS.CLI_COMMAND_COMPLETE,
|
|
2021
2020
|
categories: {
|
|
2022
2021
|
command,
|
|
2023
|
-
args: _optionalChain$
|
|
2022
|
+
args: _optionalChain$5([options, 'optionalAccess', _4 => _4.args]),
|
|
2024
2023
|
status: success ? ('success' ) : ('fail' ),
|
|
2025
|
-
..._optionalChain$
|
|
2024
|
+
..._optionalChain$5([options, 'optionalAccess', _5 => _5.categories]),
|
|
2026
2025
|
},
|
|
2027
2026
|
metrics: {
|
|
2028
2027
|
duration,
|
|
2029
|
-
...(_optionalChain$
|
|
2028
|
+
...(_optionalChain$5([options, 'optionalAccess', _6 => _6.errorCode]) && { errorCode: options.errorCode }),
|
|
2030
2029
|
},
|
|
2031
2030
|
};
|
|
2032
2031
|
},
|
|
@@ -2047,12 +2046,12 @@ const EventBuilder = {
|
|
|
2047
2046
|
name: CLI_EVENTS.NETWORK_REQUEST,
|
|
2048
2047
|
categories: {
|
|
2049
2048
|
url,
|
|
2050
|
-
method: _optionalChain$
|
|
2051
|
-
statusCode: _optionalChain$
|
|
2052
|
-
status: _optionalChain$
|
|
2049
|
+
method: _optionalChain$5([options, 'optionalAccess', _7 => _7.method]) || 'GET',
|
|
2050
|
+
statusCode: _optionalChain$5([options, 'optionalAccess', _8 => _8.statusCode, 'optionalAccess', _9 => _9.toString, 'call', _10 => _10()]),
|
|
2051
|
+
status: _optionalChain$5([options, 'optionalAccess', _11 => _11.success]) ? ('success' ) : ('fail' ),
|
|
2053
2052
|
},
|
|
2054
2053
|
metrics: {
|
|
2055
|
-
duration: _optionalChain$
|
|
2054
|
+
duration: _optionalChain$5([options, 'optionalAccess', _12 => _12.duration]),
|
|
2056
2055
|
},
|
|
2057
2056
|
};
|
|
2058
2057
|
},
|
|
@@ -2074,11 +2073,11 @@ const EventBuilder = {
|
|
|
2074
2073
|
categories: {
|
|
2075
2074
|
operation,
|
|
2076
2075
|
filePath,
|
|
2077
|
-
status: _optionalChain$
|
|
2076
|
+
status: _optionalChain$5([options, 'optionalAccess', _13 => _13.success]) ? ('success' ) : ('fail' ),
|
|
2078
2077
|
},
|
|
2079
2078
|
metrics: {
|
|
2080
|
-
duration: _optionalChain$
|
|
2081
|
-
fileSize: _optionalChain$
|
|
2079
|
+
duration: _optionalChain$5([options, 'optionalAccess', _14 => _14.duration]),
|
|
2080
|
+
fileSize: _optionalChain$5([options, 'optionalAccess', _15 => _15.fileSize]),
|
|
2082
2081
|
},
|
|
2083
2082
|
};
|
|
2084
2083
|
},
|
|
@@ -2106,7 +2105,7 @@ const EventBuilder = {
|
|
|
2106
2105
|
};
|
|
2107
2106
|
|
|
2108
2107
|
var name = "@coze-arch/cli";
|
|
2109
|
-
var version = "0.0.
|
|
2108
|
+
var version = "0.0.7";
|
|
2110
2109
|
var description = "coze coding devtools cli";
|
|
2111
2110
|
var license = "MIT";
|
|
2112
2111
|
var author = "fanwenjie.fe@bytedance.com";
|
|
@@ -2146,7 +2145,6 @@ var dependencies = {
|
|
|
2146
2145
|
commander: "~12.1.0",
|
|
2147
2146
|
debug: "^4.3.7",
|
|
2148
2147
|
ejs: "^3.1.10",
|
|
2149
|
-
"fast-glob": "^3.3.3",
|
|
2150
2148
|
"js-yaml": "^4.1.0",
|
|
2151
2149
|
minimist: "^1.2.5",
|
|
2152
2150
|
shelljs: "^0.10.0"
|
|
@@ -2207,11 +2205,11 @@ var packageJson = {
|
|
|
2207
2205
|
cozePublishConfig: cozePublishConfig
|
|
2208
2206
|
};
|
|
2209
2207
|
|
|
2210
|
-
function _optionalChain$
|
|
2208
|
+
function _optionalChain$4(ops) { let lastAccessLHS = undefined; let value = ops[0]; let i = 1; while (i < ops.length) { const op = ops[i]; const fn = ops[i + 1]; i += 2; if ((op === 'optionalAccess' || op === 'optionalCall') && value == null) { return undefined; } if (op === 'access' || op === 'optionalAccess') { lastAccessLHS = value; value = fn(value); } else if (op === 'call' || op === 'optionalCall') { value = fn((...args) => value.call(lastAccessLHS, ...args)); lastAccessLHS = undefined; } } return value; }/**
|
|
2211
2209
|
* Slardar 监控初始化和上报
|
|
2212
2210
|
*/
|
|
2213
2211
|
|
|
2214
|
-
const log
|
|
2212
|
+
const log = debug('slardar:cli');
|
|
2215
2213
|
|
|
2216
2214
|
/**
|
|
2217
2215
|
* 安全执行函数包装器
|
|
@@ -2224,18 +2222,18 @@ function safeRun(
|
|
|
2224
2222
|
) {
|
|
2225
2223
|
return ((...args) => {
|
|
2226
2224
|
try {
|
|
2227
|
-
log
|
|
2225
|
+
log('Calling Slardar function: %s', name);
|
|
2228
2226
|
const result = fn(...args);
|
|
2229
2227
|
|
|
2230
2228
|
// 如果是 Promise,处理异步错误
|
|
2231
2229
|
if (result instanceof Promise) {
|
|
2232
2230
|
return result
|
|
2233
2231
|
.then(res => {
|
|
2234
|
-
log
|
|
2232
|
+
log('Slardar function %s completed', name);
|
|
2235
2233
|
return res;
|
|
2236
2234
|
})
|
|
2237
2235
|
.catch(error => {
|
|
2238
|
-
log
|
|
2236
|
+
log(
|
|
2239
2237
|
'Slardar function %s failed: %s',
|
|
2240
2238
|
name,
|
|
2241
2239
|
(error ).message,
|
|
@@ -2244,11 +2242,11 @@ function safeRun(
|
|
|
2244
2242
|
});
|
|
2245
2243
|
}
|
|
2246
2244
|
|
|
2247
|
-
log
|
|
2245
|
+
log('Slardar function %s completed', name);
|
|
2248
2246
|
return result;
|
|
2249
2247
|
} catch (error) {
|
|
2250
2248
|
// Slardar 上报失败不应影响 CLI 正常运行,但要记录错误
|
|
2251
|
-
log
|
|
2249
|
+
log('Slardar function %s failed: %s', name, (error ).message);
|
|
2252
2250
|
}
|
|
2253
2251
|
}) ;
|
|
2254
2252
|
}
|
|
@@ -2310,11 +2308,11 @@ const reportCommandComplete = safeRun(
|
|
|
2310
2308
|
,
|
|
2311
2309
|
) => {
|
|
2312
2310
|
const event = EventBuilder.cliCommandComplete(command, success, duration, {
|
|
2313
|
-
args: _optionalChain$
|
|
2314
|
-
errorCode: _optionalChain$
|
|
2311
|
+
args: _optionalChain$4([options, 'optionalAccess', _ => _.args]),
|
|
2312
|
+
errorCode: _optionalChain$4([options, 'optionalAccess', _2 => _2.errorCode]),
|
|
2315
2313
|
categories: {
|
|
2316
|
-
...(_optionalChain$
|
|
2317
|
-
..._optionalChain$
|
|
2314
|
+
...(_optionalChain$4([options, 'optionalAccess', _3 => _3.errorMessage]) && { errorMessage: options.errorMessage }),
|
|
2315
|
+
..._optionalChain$4([options, 'optionalAccess', _4 => _4.categories]),
|
|
2318
2316
|
},
|
|
2319
2317
|
});
|
|
2320
2318
|
reporter.sendEvent(event.name, event.metrics, event.categories);
|
|
@@ -2342,7 +2340,7 @@ const flushSlardar = safeRun('flushSlardar', async () => {
|
|
|
2342
2340
|
await reporter.flush();
|
|
2343
2341
|
});
|
|
2344
2342
|
|
|
2345
|
-
function _nullishCoalesce$2(lhs, rhsFn) { if (lhs != null) { return lhs; } else { return rhsFn(); } } function _optionalChain$
|
|
2343
|
+
function _nullishCoalesce$2(lhs, rhsFn) { if (lhs != null) { return lhs; } else { return rhsFn(); } } function _optionalChain$3(ops) { let lastAccessLHS = undefined; let value = ops[0]; let i = 1; while (i < ops.length) { const op = ops[i]; const fn = ops[i + 1]; i += 2; if ((op === 'optionalAccess' || op === 'optionalCall') && value == null) { return undefined; } if (op === 'access' || op === 'optionalAccess') { lastAccessLHS = value; value = fn(value); } else if (op === 'call' || op === 'optionalCall') { value = fn((...args) => value.call(lastAccessLHS, ...args)); lastAccessLHS = undefined; } } return value; }var LogLevel; (function (LogLevel) {
|
|
2346
2344
|
const ERROR = 0; LogLevel[LogLevel["ERROR"] = ERROR] = "ERROR";
|
|
2347
2345
|
const WARN = 1; LogLevel[LogLevel["WARN"] = WARN] = "WARN";
|
|
2348
2346
|
const SUCCESS = 2; LogLevel[LogLevel["SUCCESS"] = SUCCESS] = "SUCCESS";
|
|
@@ -2389,7 +2387,7 @@ class Logger {
|
|
|
2389
2387
|
return level;
|
|
2390
2388
|
}
|
|
2391
2389
|
|
|
2392
|
-
const envLevel = _optionalChain$
|
|
2390
|
+
const envLevel = _optionalChain$3([process, 'access', _ => _.env, 'access', _2 => _2.LOG_LEVEL, 'optionalAccess', _3 => _3.toLowerCase, 'call', _4 => _4()]);
|
|
2393
2391
|
if (envLevel && envLevel in LOG_LEVEL_MAP) {
|
|
2394
2392
|
return LOG_LEVEL_MAP[envLevel];
|
|
2395
2393
|
}
|
|
@@ -2401,7 +2399,7 @@ class Logger {
|
|
|
2401
2399
|
// 简单检测:Node.js 环境且支持 TTY
|
|
2402
2400
|
return (
|
|
2403
2401
|
typeof process !== 'undefined' &&
|
|
2404
|
-
_optionalChain$
|
|
2402
|
+
_optionalChain$3([process, 'access', _5 => _5.stdout, 'optionalAccess', _6 => _6.isTTY]) === true &&
|
|
2405
2403
|
process.env.NO_COLOR === undefined
|
|
2406
2404
|
);
|
|
2407
2405
|
}
|
|
@@ -2802,7 +2800,7 @@ const executeWarmup = async (options) => {
|
|
|
2802
2800
|
/**
|
|
2803
2801
|
* 注册 warmup 命令到 program
|
|
2804
2802
|
*/
|
|
2805
|
-
const registerCommand$
|
|
2803
|
+
const registerCommand$4 = program => {
|
|
2806
2804
|
program
|
|
2807
2805
|
.command('warmup')
|
|
2808
2806
|
.description('Pre-install dependencies for templates to speed up init')
|
|
@@ -2812,76 +2810,6 @@ const registerCommand$5 = program => {
|
|
|
2812
2810
|
});
|
|
2813
2811
|
};
|
|
2814
2812
|
|
|
2815
|
-
// ABOUTME: Temporary paths utility for Coze CLI
|
|
2816
|
-
// ABOUTME: Provides centralized management of temporary directories and files
|
|
2817
|
-
|
|
2818
|
-
|
|
2819
|
-
/**
|
|
2820
|
-
* Base Coze directory in user's home
|
|
2821
|
-
* Used for storing CLI-related temporary files, logs, and cache
|
|
2822
|
-
* Default: ~/.coze
|
|
2823
|
-
*/
|
|
2824
|
-
const COZE_HOME_DIR = '.coze';
|
|
2825
|
-
|
|
2826
|
-
/**
|
|
2827
|
-
* Logs directory name
|
|
2828
|
-
* Default: .coze-logs
|
|
2829
|
-
*/
|
|
2830
|
-
const LOGS_DIR = '.coze-logs';
|
|
2831
|
-
|
|
2832
|
-
/**
|
|
2833
|
-
* Get the Coze home directory path
|
|
2834
|
-
* Can be customized via COZE_HOME environment variable
|
|
2835
|
-
*
|
|
2836
|
-
* @returns Absolute path to Coze home directory (default: ~/.coze)
|
|
2837
|
-
*/
|
|
2838
|
-
const getCozeHome = () =>
|
|
2839
|
-
process.env.COZE_HOME || path.join(os.homedir(), COZE_HOME_DIR);
|
|
2840
|
-
|
|
2841
|
-
/**
|
|
2842
|
-
* Get the logs directory path
|
|
2843
|
-
* Can be customized via COZE_LOG_DIR environment variable
|
|
2844
|
-
*
|
|
2845
|
-
* @returns Absolute path to logs directory (default: ~/.coze-logs)
|
|
2846
|
-
*/
|
|
2847
|
-
const getCozeLogsDir = () =>
|
|
2848
|
-
process.env.COZE_LOG_DIR || path.join(os.homedir(), LOGS_DIR);
|
|
2849
|
-
|
|
2850
|
-
/**
|
|
2851
|
-
* Get path for a specific file/directory within Coze home
|
|
2852
|
-
*
|
|
2853
|
-
* @param relativePath - Relative path within Coze home directory
|
|
2854
|
-
* @returns Absolute path to the file/directory
|
|
2855
|
-
*
|
|
2856
|
-
* @example
|
|
2857
|
-
* ```ts
|
|
2858
|
-
* // Get routes file path
|
|
2859
|
-
* const routesPath = getCozeFilePath('routes.json');
|
|
2860
|
-
* // Returns: ~/.coze/routes.json
|
|
2861
|
-
*
|
|
2862
|
-
* // Get cache directory
|
|
2863
|
-
* const cacheDir = getCozeFilePath('cache');
|
|
2864
|
-
* // Returns: ~/.coze/cache
|
|
2865
|
-
* ```
|
|
2866
|
-
*/
|
|
2867
|
-
const getCozeFilePath = (relativePath) =>
|
|
2868
|
-
path.join(getCozeHome(), relativePath);
|
|
2869
|
-
|
|
2870
|
-
/**
|
|
2871
|
-
* Get path for a log file
|
|
2872
|
-
*
|
|
2873
|
-
* @param filename - Log file name
|
|
2874
|
-
* @returns Absolute path to the log file
|
|
2875
|
-
*
|
|
2876
|
-
* @example
|
|
2877
|
-
* ```ts
|
|
2878
|
-
* const devLog = getCozeLogPath('dev.log');
|
|
2879
|
-
* // Returns: ~/.coze-logs/dev.log
|
|
2880
|
-
* ```
|
|
2881
|
-
*/
|
|
2882
|
-
const getCozeLogPath = (filename) =>
|
|
2883
|
-
path.join(getCozeLogsDir(), filename);
|
|
2884
|
-
|
|
2885
2813
|
// ABOUTME: This file implements the update command for coze CLI
|
|
2886
2814
|
// ABOUTME: It wraps pnpm update/install to update package dependencies with logging support
|
|
2887
2815
|
|
|
@@ -2892,22 +2820,29 @@ const getCozeLogPath = (filename) =>
|
|
|
2892
2820
|
*/
|
|
2893
2821
|
const LOG_FILE_NAME$1 = 'update.log';
|
|
2894
2822
|
|
|
2823
|
+
/**
|
|
2824
|
+
* 获取日志目录
|
|
2825
|
+
* 优先使用环境变量 COZE_LOG_DIR,否则使用 ~/.coze-logs
|
|
2826
|
+
*/
|
|
2827
|
+
const getLogDir$1 = () =>
|
|
2828
|
+
process.env.COZE_LOG_DIR || path.join(os.homedir(), '.coze-logs');
|
|
2829
|
+
|
|
2895
2830
|
/**
|
|
2896
2831
|
* 解析日志文件路径
|
|
2897
2832
|
* - 如果是绝对路径,直接使用
|
|
2898
|
-
* - 如果是相对路径,基于
|
|
2899
|
-
* -
|
|
2833
|
+
* - 如果是相对路径,基于 getLogDir() + 相对路径
|
|
2834
|
+
* - 如果为空,使用 getLogDir() + LOG_FILE_NAME
|
|
2900
2835
|
*/
|
|
2901
2836
|
const resolveLogFilePath$1 = (logFile) => {
|
|
2902
2837
|
if (!logFile) {
|
|
2903
|
-
return
|
|
2838
|
+
return path.join(getLogDir$1(), LOG_FILE_NAME$1);
|
|
2904
2839
|
}
|
|
2905
2840
|
|
|
2906
2841
|
if (path.isAbsolute(logFile)) {
|
|
2907
2842
|
return logFile;
|
|
2908
2843
|
}
|
|
2909
2844
|
|
|
2910
|
-
return
|
|
2845
|
+
return path.join(getLogDir$1(), logFile);
|
|
2911
2846
|
};
|
|
2912
2847
|
|
|
2913
2848
|
/**
|
|
@@ -3081,7 +3016,6 @@ const handleUpdateError = (
|
|
|
3081
3016
|
/**
|
|
3082
3017
|
* 执行 update 命令的内部实现
|
|
3083
3018
|
*/
|
|
3084
|
-
// eslint-disable-next-line max-lines-per-function
|
|
3085
3019
|
const executeUpdate = (
|
|
3086
3020
|
packageName,
|
|
3087
3021
|
options
|
|
@@ -3214,7 +3148,7 @@ const executeUpdate = (
|
|
|
3214
3148
|
/**
|
|
3215
3149
|
* 注册 update 命令到 program
|
|
3216
3150
|
*/
|
|
3217
|
-
const registerCommand$
|
|
3151
|
+
const registerCommand$3 = program => {
|
|
3218
3152
|
program
|
|
3219
3153
|
.command('update <package>')
|
|
3220
3154
|
.description('Update a package dependency')
|
|
@@ -3240,7 +3174,7 @@ const registerCommand$4 = program => {
|
|
|
3240
3174
|
});
|
|
3241
3175
|
};
|
|
3242
3176
|
|
|
3243
|
-
function _optionalChain$
|
|
3177
|
+
function _optionalChain$2(ops) { let lastAccessLHS = undefined; let value = ops[0]; let i = 1; while (i < ops.length) { const op = ops[i]; const fn = ops[i + 1]; i += 2; if ((op === 'optionalAccess' || op === 'optionalCall') && value == null) { return undefined; } if (op === 'access' || op === 'optionalAccess') { lastAccessLHS = value; value = fn(value); } else if (op === 'call' || op === 'optionalCall') { value = fn((...args) => value.call(lastAccessLHS, ...args)); lastAccessLHS = undefined; } } return value; }/* eslint-disable @typescript-eslint/no-explicit-any */
|
|
3244
3178
|
// Safe JSON parsing utilities with type safety and error handling
|
|
3245
3179
|
// Provides fallback values, validation, and error monitoring capabilities
|
|
3246
3180
|
|
|
@@ -3312,16 +3246,7 @@ function safeJsonParse(
|
|
|
3312
3246
|
|
|
3313
3247
|
if (arguments.length === 2) {
|
|
3314
3248
|
// safeJsonParse(input, options) or safeJsonParse(input, defaultValue)
|
|
3315
|
-
|
|
3316
|
-
defaultValueOrOptions &&
|
|
3317
|
-
typeof defaultValueOrOptions === 'object' &&
|
|
3318
|
-
('onError' in defaultValueOrOptions ||
|
|
3319
|
-
'validate' in defaultValueOrOptions ||
|
|
3320
|
-
'throwOnValidationError' in defaultValueOrOptions)
|
|
3321
|
-
) {
|
|
3322
|
-
options = defaultValueOrOptions ;
|
|
3323
|
-
defaultValue = undefined;
|
|
3324
|
-
} else {
|
|
3249
|
+
{
|
|
3325
3250
|
defaultValue = defaultValueOrOptions ;
|
|
3326
3251
|
options = undefined;
|
|
3327
3252
|
}
|
|
@@ -3340,12 +3265,12 @@ function safeJsonParse(
|
|
|
3340
3265
|
const parsed = JSON.parse(String(input));
|
|
3341
3266
|
|
|
3342
3267
|
// Optional validation
|
|
3343
|
-
if (_optionalChain$
|
|
3268
|
+
if (_optionalChain$2([options, 'optionalAccess', _ => _.validate])) {
|
|
3344
3269
|
if (options.validate(parsed)) {
|
|
3345
3270
|
return parsed;
|
|
3346
3271
|
} else {
|
|
3347
3272
|
const validationError = new Error('JSON validation failed');
|
|
3348
|
-
_optionalChain$
|
|
3273
|
+
_optionalChain$2([options, 'access', _2 => _2.onError, 'optionalCall', _3 => _3(validationError, input)]);
|
|
3349
3274
|
|
|
3350
3275
|
if (options.throwOnValidationError) {
|
|
3351
3276
|
throw validationError;
|
|
@@ -3357,15 +3282,15 @@ function safeJsonParse(
|
|
|
3357
3282
|
return parsed;
|
|
3358
3283
|
} catch (error) {
|
|
3359
3284
|
// Re-throw validation errors when throwOnValidationError is true
|
|
3360
|
-
if (error instanceof Error && error.message === 'JSON validation failed' && _optionalChain$
|
|
3285
|
+
if (error instanceof Error && error.message === 'JSON validation failed' && _optionalChain$2([options, 'optionalAccess', _4 => _4.throwOnValidationError])) {
|
|
3361
3286
|
throw error;
|
|
3362
3287
|
}
|
|
3363
|
-
_optionalChain$
|
|
3288
|
+
_optionalChain$2([options, 'optionalAccess', _5 => _5.onError, 'optionalCall', _6 => _6(error , input)]);
|
|
3364
3289
|
return defaultValue;
|
|
3365
3290
|
}
|
|
3366
3291
|
}
|
|
3367
3292
|
|
|
3368
|
-
function _optionalChain$
|
|
3293
|
+
function _optionalChain$1(ops) { let lastAccessLHS = undefined; let value = ops[0]; let i = 1; while (i < ops.length) { const op = ops[i]; const fn = ops[i + 1]; i += 2; if ((op === 'optionalAccess' || op === 'optionalCall') && value == null) { return undefined; } if (op === 'access' || op === 'optionalAccess') { lastAccessLHS = value; value = fn(value); } else if (op === 'call' || op === 'optionalCall') { value = fn((...args) => value.call(lastAccessLHS, ...args)); lastAccessLHS = undefined; } } return value; }
|
|
3369
3294
|
|
|
3370
3295
|
|
|
3371
3296
|
/**
|
|
@@ -3455,13 +3380,13 @@ const getCommandConfig = (
|
|
|
3455
3380
|
// 根据命令名称映射到配置路径
|
|
3456
3381
|
switch (commandName) {
|
|
3457
3382
|
case 'dev':
|
|
3458
|
-
commandConfig = _optionalChain$
|
|
3383
|
+
commandConfig = _optionalChain$1([config, 'access', _ => _.dev, 'optionalAccess', _2 => _2.run]);
|
|
3459
3384
|
break;
|
|
3460
3385
|
case 'build':
|
|
3461
|
-
commandConfig = _optionalChain$
|
|
3386
|
+
commandConfig = _optionalChain$1([config, 'access', _3 => _3.deploy, 'optionalAccess', _4 => _4.build]);
|
|
3462
3387
|
break;
|
|
3463
3388
|
case 'start':
|
|
3464
|
-
commandConfig = _optionalChain$
|
|
3389
|
+
commandConfig = _optionalChain$1([config, 'access', _5 => _5.deploy, 'optionalAccess', _6 => _6.run]);
|
|
3465
3390
|
break;
|
|
3466
3391
|
default:
|
|
3467
3392
|
throw new Error(`Unknown command: ${commandName}`);
|
|
@@ -3689,7 +3614,7 @@ const executeFix = async (
|
|
|
3689
3614
|
/**
|
|
3690
3615
|
* 注册 fix 命令到 program
|
|
3691
3616
|
*/
|
|
3692
|
-
const registerCommand$
|
|
3617
|
+
const registerCommand$2 = program => {
|
|
3693
3618
|
program
|
|
3694
3619
|
.command('fix')
|
|
3695
3620
|
.description(
|
|
@@ -3704,28 +3629,35 @@ const registerCommand$3 = program => {
|
|
|
3704
3629
|
});
|
|
3705
3630
|
};
|
|
3706
3631
|
|
|
3707
|
-
function _nullishCoalesce$1(lhs, rhsFn) { if (lhs != null) { return lhs; } else { return rhsFn(); } } function _optionalChain
|
|
3632
|
+
function _nullishCoalesce$1(lhs, rhsFn) { if (lhs != null) { return lhs; } else { return rhsFn(); } } function _optionalChain(ops) { let lastAccessLHS = undefined; let value = ops[0]; let i = 1; while (i < ops.length) { const op = ops[i]; const fn = ops[i + 1]; i += 2; if ((op === 'optionalAccess' || op === 'optionalCall') && value == null) { return undefined; } if (op === 'access' || op === 'optionalAccess') { lastAccessLHS = value; value = fn(value); } else if (op === 'call' || op === 'optionalCall') { value = fn((...args) => value.call(lastAccessLHS, ...args)); lastAccessLHS = undefined; } } return value; }
|
|
3708
3633
|
/**
|
|
3709
3634
|
* 日志文件名常量
|
|
3710
3635
|
*/
|
|
3711
3636
|
const LOG_FILE_NAME = 'dev.log';
|
|
3712
3637
|
|
|
3638
|
+
/**
|
|
3639
|
+
* 获取日志目录
|
|
3640
|
+
* 优先使用环境变量 COZE_LOG_DIR,否则使用 ~/.coze-logs
|
|
3641
|
+
*/
|
|
3642
|
+
const getLogDir = () =>
|
|
3643
|
+
process.env.COZE_LOG_DIR || path.join(os.homedir(), '.coze-logs');
|
|
3644
|
+
|
|
3713
3645
|
/**
|
|
3714
3646
|
* 解析日志文件路径
|
|
3715
3647
|
* - 如果是绝对路径,直接使用
|
|
3716
|
-
* - 如果是相对路径,基于
|
|
3717
|
-
* -
|
|
3648
|
+
* - 如果是相对路径,基于 getLogDir() + 相对路径
|
|
3649
|
+
* - 如果为空,使用 getLogDir() + LOG_FILE_NAME
|
|
3718
3650
|
*/
|
|
3719
3651
|
const resolveLogFilePath = (logFile) => {
|
|
3720
3652
|
if (!logFile) {
|
|
3721
|
-
return
|
|
3653
|
+
return path.join(getLogDir(), LOG_FILE_NAME);
|
|
3722
3654
|
}
|
|
3723
3655
|
|
|
3724
3656
|
if (path.isAbsolute(logFile)) {
|
|
3725
3657
|
return logFile;
|
|
3726
3658
|
}
|
|
3727
3659
|
|
|
3728
|
-
return
|
|
3660
|
+
return path.join(getLogDir(), logFile);
|
|
3729
3661
|
};
|
|
3730
3662
|
|
|
3731
3663
|
/**
|
|
@@ -3796,86 +3728,82 @@ const executeRun = async (
|
|
|
3796
3728
|
}
|
|
3797
3729
|
|
|
3798
3730
|
// 将输出同时写入控制台和日志文件
|
|
3799
|
-
_optionalChain
|
|
3731
|
+
_optionalChain([childProcess, 'access', _ => _.stdout, 'optionalAccess', _2 => _2.on, 'call', _3 => _3('data', (data) => {
|
|
3800
3732
|
process.stdout.write(data);
|
|
3801
3733
|
logStream.write(data);
|
|
3802
3734
|
})]);
|
|
3803
3735
|
|
|
3804
|
-
_optionalChain
|
|
3736
|
+
_optionalChain([childProcess, 'access', _4 => _4.stderr, 'optionalAccess', _5 => _5.on, 'call', _6 => _6('data', (data) => {
|
|
3805
3737
|
process.stderr.write(data);
|
|
3806
3738
|
logStream.write(data);
|
|
3807
3739
|
})]);
|
|
3808
3740
|
|
|
3809
|
-
|
|
3810
|
-
|
|
3811
|
-
childProcess.on('close', (code, signal) => {
|
|
3812
|
-
logStream.end();
|
|
3813
|
-
|
|
3814
|
-
if (code !== 0) {
|
|
3815
|
-
const errorMessage = `Command exited with code ${_nullishCoalesce$1(code, () => ( 'unknown'))}${signal ? ` and signal ${signal}` : ''}`;
|
|
3816
|
-
logger.error(errorMessage);
|
|
3817
|
-
logger.error(`Check log file for details: ${logFilePath}`);
|
|
3818
|
-
|
|
3819
|
-
// 上报命令失败
|
|
3820
|
-
reportError(new Error(errorMessage), {
|
|
3821
|
-
command: commandName,
|
|
3822
|
-
exitCode: String(_nullishCoalesce$1(code, () => ( 'unknown'))),
|
|
3823
|
-
signal: _nullishCoalesce$1(signal, () => ( 'none')),
|
|
3824
|
-
logFile: logFilePath,
|
|
3825
|
-
});
|
|
3826
|
-
reportCommandComplete(commandName, false, Date.now() - cmdStartTime, {
|
|
3827
|
-
args: JSON.stringify(options),
|
|
3828
|
-
errorCode: _nullishCoalesce$1(code, () => ( 1)),
|
|
3829
|
-
errorMessage,
|
|
3830
|
-
});
|
|
3831
|
-
flushSlardar()
|
|
3832
|
-
.then(() => {
|
|
3833
|
-
process.exit(code || 1);
|
|
3834
|
-
})
|
|
3835
|
-
.catch(() => {
|
|
3836
|
-
// Catch any errors in the promise chain to prevent unhandled rejections
|
|
3837
|
-
process.exit(code || 1);
|
|
3838
|
-
});
|
|
3839
|
-
} else {
|
|
3840
|
-
logger.success('Command completed successfully');
|
|
3841
|
-
logger.info(`Log file: ${logFilePath}`);
|
|
3842
|
-
|
|
3843
|
-
// 上报命令成功
|
|
3844
|
-
reportCommandComplete(commandName, true, Date.now() - cmdStartTime, {
|
|
3845
|
-
args: JSON.stringify(options),
|
|
3846
|
-
});
|
|
3847
|
-
// flush 由 main 函数统一处理
|
|
3848
|
-
resolve();
|
|
3849
|
-
}
|
|
3850
|
-
});
|
|
3741
|
+
childProcess.on('close', (code, signal) => {
|
|
3742
|
+
logStream.end();
|
|
3851
3743
|
|
|
3852
|
-
|
|
3853
|
-
|
|
3854
|
-
logger.error(
|
|
3855
|
-
|
|
3856
|
-
logger.error(`Stack trace:\n${error.stack}`);
|
|
3857
|
-
}
|
|
3858
|
-
logStream.end();
|
|
3744
|
+
if (code !== 0) {
|
|
3745
|
+
const errorMessage = `Command exited with code ${_nullishCoalesce$1(code, () => ( 'unknown'))}${signal ? ` and signal ${signal}` : ''}`;
|
|
3746
|
+
logger.error(errorMessage);
|
|
3747
|
+
logger.error(`Check log file for details: ${logFilePath}`);
|
|
3859
3748
|
|
|
3860
|
-
//
|
|
3861
|
-
reportError(
|
|
3749
|
+
// 上报命令失败
|
|
3750
|
+
reportError(new Error(errorMessage), {
|
|
3862
3751
|
command: commandName,
|
|
3863
|
-
|
|
3752
|
+
exitCode: String(_nullishCoalesce$1(code, () => ( 'unknown'))),
|
|
3753
|
+
signal: _nullishCoalesce$1(signal, () => ( 'none')),
|
|
3754
|
+
logFile: logFilePath,
|
|
3864
3755
|
});
|
|
3865
3756
|
reportCommandComplete(commandName, false, Date.now() - cmdStartTime, {
|
|
3866
3757
|
args: JSON.stringify(options),
|
|
3867
|
-
errorCode: 1,
|
|
3868
|
-
errorMessage
|
|
3758
|
+
errorCode: _nullishCoalesce$1(code, () => ( 1)),
|
|
3759
|
+
errorMessage,
|
|
3869
3760
|
});
|
|
3870
3761
|
flushSlardar()
|
|
3871
3762
|
.then(() => {
|
|
3872
|
-
process.exit(1);
|
|
3763
|
+
process.exit(code || 1);
|
|
3873
3764
|
})
|
|
3874
3765
|
.catch(() => {
|
|
3875
3766
|
// Catch any errors in the promise chain to prevent unhandled rejections
|
|
3876
|
-
process.exit(1);
|
|
3767
|
+
process.exit(code || 1);
|
|
3877
3768
|
});
|
|
3769
|
+
} else {
|
|
3770
|
+
logger.success('Command completed successfully');
|
|
3771
|
+
logger.info(`Log file: ${logFilePath}`);
|
|
3772
|
+
|
|
3773
|
+
// 上报命令成功
|
|
3774
|
+
reportCommandComplete(commandName, true, Date.now() - cmdStartTime, {
|
|
3775
|
+
args: JSON.stringify(options),
|
|
3776
|
+
});
|
|
3777
|
+
// flush 由 main 函数统一处理
|
|
3778
|
+
}
|
|
3779
|
+
});
|
|
3780
|
+
|
|
3781
|
+
childProcess.on('error', (error) => {
|
|
3782
|
+
logger.error('Failed to execute command:');
|
|
3783
|
+
logger.error(`Error: ${error.message}`);
|
|
3784
|
+
if (error.stack) {
|
|
3785
|
+
logger.error(`Stack trace:\n${error.stack}`);
|
|
3786
|
+
}
|
|
3787
|
+
logStream.end();
|
|
3788
|
+
|
|
3789
|
+
// 上报错误
|
|
3790
|
+
reportError(error, {
|
|
3791
|
+
command: commandName,
|
|
3792
|
+
type: 'child_process_error',
|
|
3793
|
+
});
|
|
3794
|
+
reportCommandComplete(commandName, false, Date.now() - cmdStartTime, {
|
|
3795
|
+
args: JSON.stringify(options),
|
|
3796
|
+
errorCode: 1,
|
|
3797
|
+
errorMessage: error.message,
|
|
3878
3798
|
});
|
|
3799
|
+
flushSlardar()
|
|
3800
|
+
.then(() => {
|
|
3801
|
+
process.exit(1);
|
|
3802
|
+
})
|
|
3803
|
+
.catch(() => {
|
|
3804
|
+
// Catch any errors in the promise chain to prevent unhandled rejections
|
|
3805
|
+
process.exit(1);
|
|
3806
|
+
});
|
|
3879
3807
|
});
|
|
3880
3808
|
} catch (error) {
|
|
3881
3809
|
const err = error instanceof Error ? error : new Error(String(error));
|
|
@@ -3906,7 +3834,7 @@ const executeRun = async (
|
|
|
3906
3834
|
/**
|
|
3907
3835
|
* 注册 dev/build/start 命令到 program
|
|
3908
3836
|
*/
|
|
3909
|
-
const registerCommand$
|
|
3837
|
+
const registerCommand$1 = program => {
|
|
3910
3838
|
// dev 命令
|
|
3911
3839
|
program
|
|
3912
3840
|
.command('dev')
|
|
@@ -3935,901 +3863,6 @@ const registerCommand$2 = program => {
|
|
|
3935
3863
|
});
|
|
3936
3864
|
};
|
|
3937
3865
|
|
|
3938
|
-
// ABOUTME: Nuxt route scanner
|
|
3939
|
-
// ABOUTME: Scans Nuxt file-based routing structure to extract page and server routes
|
|
3940
|
-
|
|
3941
|
-
|
|
3942
|
-
|
|
3943
|
-
|
|
3944
|
-
const log$4 = debug('coze:routes:nuxt');
|
|
3945
|
-
|
|
3946
|
-
/**
|
|
3947
|
-
* Convert Nuxt file path to route path
|
|
3948
|
-
* Examples:
|
|
3949
|
-
* - pages/index.vue -> /
|
|
3950
|
-
* - app/pages/index.vue -> /
|
|
3951
|
-
* - src/pages/index.vue -> /
|
|
3952
|
-
* - src/app/pages/index.vue -> /
|
|
3953
|
-
* - pages/blog/[id].vue -> /blog/[id]
|
|
3954
|
-
* - server/api/users.ts -> /api/users
|
|
3955
|
-
* - server/routes/webhook.ts -> /webhook
|
|
3956
|
-
*/
|
|
3957
|
-
const nuxtFilePathToRoute = (
|
|
3958
|
-
filePath,
|
|
3959
|
-
type,
|
|
3960
|
-
) => {
|
|
3961
|
-
let route;
|
|
3962
|
-
|
|
3963
|
-
if (type === 'page') {
|
|
3964
|
-
// Remove pages prefix (supports all variations) and .vue extension
|
|
3965
|
-
route = filePath
|
|
3966
|
-
.replace(/^src\/app\/pages\//, '') // src/app/pages/
|
|
3967
|
-
.replace(/^src\/pages\//, '') // src/pages/
|
|
3968
|
-
.replace(/^app\/pages\//, '') // app/pages/
|
|
3969
|
-
.replace(/^pages\//, '') // pages/
|
|
3970
|
-
.replace(/\.vue$/, '')
|
|
3971
|
-
.replace(/\/index$/, ''); // Remove trailing /index
|
|
3972
|
-
|
|
3973
|
-
// Handle index.vue at root (becomes empty string)
|
|
3974
|
-
if (route === 'index') {
|
|
3975
|
-
return '/';
|
|
3976
|
-
}
|
|
3977
|
-
} else {
|
|
3978
|
-
// API routes - support both server/ and src/server/
|
|
3979
|
-
if (filePath.includes('/api/')) {
|
|
3980
|
-
route = `/api/${filePath
|
|
3981
|
-
.replace(/^src\/server\/api\//, '')
|
|
3982
|
-
.replace(/^server\/api\//, '')
|
|
3983
|
-
.replace(/\.(ts|js)$/, '')}`;
|
|
3984
|
-
} else {
|
|
3985
|
-
// server/routes - support both server/ and src/server/
|
|
3986
|
-
route = `/${filePath
|
|
3987
|
-
.replace(/^src\/server\/routes\//, '')
|
|
3988
|
-
.replace(/^server\/routes\//, '')
|
|
3989
|
-
.replace(/\.(ts|js)$/, '')}`;
|
|
3990
|
-
}
|
|
3991
|
-
}
|
|
3992
|
-
|
|
3993
|
-
// Handle root route
|
|
3994
|
-
if (route === '' || route === '/') {
|
|
3995
|
-
return '/';
|
|
3996
|
-
}
|
|
3997
|
-
|
|
3998
|
-
// Ensure leading slash
|
|
3999
|
-
if (!route.startsWith('/')) {
|
|
4000
|
-
route = `/${route}`;
|
|
4001
|
-
}
|
|
4002
|
-
|
|
4003
|
-
return route;
|
|
4004
|
-
};
|
|
4005
|
-
|
|
4006
|
-
/**
|
|
4007
|
-
* Normalize Nuxt route path to standard format
|
|
4008
|
-
* Converts Nuxt dynamic segments to standard format:
|
|
4009
|
-
* - [id] -> :id
|
|
4010
|
-
* - [...slug] -> :slug*
|
|
4011
|
-
*/
|
|
4012
|
-
const normalizeRoutePath$1 = (routePath) =>
|
|
4013
|
-
routePath
|
|
4014
|
-
.replace(/\[\.\.\.(\w+)\]/g, ':$1*') // [...slug] -> :slug*
|
|
4015
|
-
.replace(/\[(\w+)\]/g, ':$1'); // [id] -> :id
|
|
4016
|
-
/**
|
|
4017
|
-
* Extract dynamic parameter names from route path
|
|
4018
|
-
*/
|
|
4019
|
-
const extractParams$1 = (routePath) => {
|
|
4020
|
-
const params = [];
|
|
4021
|
-
const patterns = [
|
|
4022
|
-
/\[\.\.\.(\w+)\]/g, // [...slug]
|
|
4023
|
-
/\[(\w+)\]/g, // [id]
|
|
4024
|
-
];
|
|
4025
|
-
|
|
4026
|
-
patterns.forEach(pattern => {
|
|
4027
|
-
const matches = routePath.matchAll(pattern);
|
|
4028
|
-
for (const match of matches) {
|
|
4029
|
-
params.push(match[1]);
|
|
4030
|
-
}
|
|
4031
|
-
});
|
|
4032
|
-
|
|
4033
|
-
return params;
|
|
4034
|
-
};
|
|
4035
|
-
|
|
4036
|
-
/**
|
|
4037
|
-
* Scan Nuxt routes from pages and server directories
|
|
4038
|
-
*
|
|
4039
|
-
* Supports multiple directory structures:
|
|
4040
|
-
* - **Page routes**:
|
|
4041
|
-
* - pages/**\/*.vue (default)
|
|
4042
|
-
* - app/pages/**\/*.vue (Nuxt 3 app directory)
|
|
4043
|
-
* - src/pages/**\/*.vue (srcDir: 'src/')
|
|
4044
|
-
* - src/app/pages/**\/*.vue (srcDir: 'src/' + app directory)
|
|
4045
|
-
*
|
|
4046
|
-
* - **API routes**:
|
|
4047
|
-
* - server/api/**\/*.{ts,js} (default)
|
|
4048
|
-
* - src/server/api/**\/*.{ts,js} (srcDir: 'src/')
|
|
4049
|
-
*
|
|
4050
|
-
* - **Server routes**:
|
|
4051
|
-
* - server/routes/**\/*.{ts,js} (default)
|
|
4052
|
-
* - src/server/routes/**\/*.{ts,js} (srcDir: 'src/')
|
|
4053
|
-
*
|
|
4054
|
-
* Excludes:
|
|
4055
|
-
* - layouts/ directories - Layout components (NOT routes)
|
|
4056
|
-
* - app.vue, error.vue - Special files (NOT regular routes)
|
|
4057
|
-
*
|
|
4058
|
-
* @param cwd - Current working directory
|
|
4059
|
-
* @returns List of detected routes
|
|
4060
|
-
*/
|
|
4061
|
-
const scanNuxtRoutes = async (cwd) => {
|
|
4062
|
-
log$4('Scanning Nuxt routes in:', cwd);
|
|
4063
|
-
const routes = [];
|
|
4064
|
-
|
|
4065
|
-
// Scan page routes - support multiple directory structures:
|
|
4066
|
-
// - pages/ (default)
|
|
4067
|
-
// - app/pages/ (Nuxt 3 app directory)
|
|
4068
|
-
// - src/pages/ (srcDir: 'src/')
|
|
4069
|
-
// - src/app/pages/ (srcDir: 'src/' + app directory)
|
|
4070
|
-
const pageFiles = await fastGlob.glob(
|
|
4071
|
-
['{pages,app/pages,src/pages,src/app/pages}/**/*.vue'],
|
|
4072
|
-
{
|
|
4073
|
-
cwd,
|
|
4074
|
-
ignore: [
|
|
4075
|
-
'**/node_modules/**',
|
|
4076
|
-
'**/.nuxt/**',
|
|
4077
|
-
'**/dist/**',
|
|
4078
|
-
'**/.output/**',
|
|
4079
|
-
// Exclude layouts directory (not routes)
|
|
4080
|
-
'**/layouts/**',
|
|
4081
|
-
'app/layouts/**',
|
|
4082
|
-
'src/layouts/**',
|
|
4083
|
-
'src/app/layouts/**',
|
|
4084
|
-
// Exclude special files
|
|
4085
|
-
'app.vue',
|
|
4086
|
-
'error.vue',
|
|
4087
|
-
'src/app.vue',
|
|
4088
|
-
'src/error.vue',
|
|
4089
|
-
],
|
|
4090
|
-
onlyFiles: true,
|
|
4091
|
-
followSymbolicLinks: false,
|
|
4092
|
-
},
|
|
4093
|
-
);
|
|
4094
|
-
|
|
4095
|
-
log$4('Found %d page files', pageFiles.length);
|
|
4096
|
-
|
|
4097
|
-
routes.push(
|
|
4098
|
-
...pageFiles.map(file => {
|
|
4099
|
-
const routePath = nuxtFilePathToRoute(file, 'page');
|
|
4100
|
-
const isDynamic = routePath.includes('[');
|
|
4101
|
-
const params = extractParams$1(routePath);
|
|
4102
|
-
|
|
4103
|
-
return {
|
|
4104
|
-
path: normalizeRoutePath$1(routePath),
|
|
4105
|
-
rawPath: routePath,
|
|
4106
|
-
dynamic: isDynamic,
|
|
4107
|
-
params,
|
|
4108
|
-
type: 'page' ,
|
|
4109
|
-
file,
|
|
4110
|
-
framework: 'nuxt' ,
|
|
4111
|
-
};
|
|
4112
|
-
}),
|
|
4113
|
-
);
|
|
4114
|
-
|
|
4115
|
-
// Scan API routes - support both server/ and src/server/
|
|
4116
|
-
const apiFiles = await fastGlob.glob('{server,src/server}/api/**/*.{ts,js}', {
|
|
4117
|
-
cwd,
|
|
4118
|
-
ignore: ['**/node_modules/**', '**/dist/**', '**/.output/**'],
|
|
4119
|
-
onlyFiles: true,
|
|
4120
|
-
followSymbolicLinks: false,
|
|
4121
|
-
});
|
|
4122
|
-
|
|
4123
|
-
log$4('Found %d API files', apiFiles.length);
|
|
4124
|
-
|
|
4125
|
-
routes.push(
|
|
4126
|
-
...apiFiles.map(file => {
|
|
4127
|
-
const routePath = nuxtFilePathToRoute(file, 'api');
|
|
4128
|
-
const isDynamic = routePath.includes('[');
|
|
4129
|
-
const params = extractParams$1(routePath);
|
|
4130
|
-
|
|
4131
|
-
return {
|
|
4132
|
-
path: normalizeRoutePath$1(routePath),
|
|
4133
|
-
rawPath: routePath,
|
|
4134
|
-
dynamic: isDynamic,
|
|
4135
|
-
params,
|
|
4136
|
-
type: 'api' ,
|
|
4137
|
-
file,
|
|
4138
|
-
framework: 'nuxt' ,
|
|
4139
|
-
};
|
|
4140
|
-
}),
|
|
4141
|
-
);
|
|
4142
|
-
|
|
4143
|
-
// Scan server routes - support both server/ and src/server/
|
|
4144
|
-
const serverRouteFiles = await fastGlob.glob(
|
|
4145
|
-
'{server,src/server}/routes/**/*.{ts,js}',
|
|
4146
|
-
{
|
|
4147
|
-
cwd,
|
|
4148
|
-
ignore: ['**/node_modules/**', '**/dist/**', '**/.output/**'],
|
|
4149
|
-
onlyFiles: true,
|
|
4150
|
-
followSymbolicLinks: false,
|
|
4151
|
-
},
|
|
4152
|
-
);
|
|
4153
|
-
|
|
4154
|
-
log$4('Found %d server route files', serverRouteFiles.length);
|
|
4155
|
-
|
|
4156
|
-
routes.push(
|
|
4157
|
-
...serverRouteFiles.map(file => {
|
|
4158
|
-
const routePath = nuxtFilePathToRoute(file, 'api');
|
|
4159
|
-
const isDynamic = routePath.includes('[');
|
|
4160
|
-
const params = extractParams$1(routePath);
|
|
4161
|
-
|
|
4162
|
-
return {
|
|
4163
|
-
path: normalizeRoutePath$1(routePath),
|
|
4164
|
-
rawPath: routePath,
|
|
4165
|
-
dynamic: isDynamic,
|
|
4166
|
-
params,
|
|
4167
|
-
type: 'api' ,
|
|
4168
|
-
file,
|
|
4169
|
-
framework: 'nuxt' ,
|
|
4170
|
-
};
|
|
4171
|
-
}),
|
|
4172
|
-
);
|
|
4173
|
-
|
|
4174
|
-
log$4('Total routes found: %d', routes.length);
|
|
4175
|
-
return routes;
|
|
4176
|
-
};
|
|
4177
|
-
|
|
4178
|
-
// ABOUTME: Next.js route scanner
|
|
4179
|
-
// ABOUTME: Scans Next.js App Router file structure to extract routes
|
|
4180
|
-
|
|
4181
|
-
|
|
4182
|
-
|
|
4183
|
-
|
|
4184
|
-
const log$3 = debug('coze:routes:nextjs');
|
|
4185
|
-
|
|
4186
|
-
/**
|
|
4187
|
-
* Convert Next.js file path to route path
|
|
4188
|
-
* Examples:
|
|
4189
|
-
* - src/app/page.tsx -> /
|
|
4190
|
-
* - src/app/blog/page.tsx -> /blog
|
|
4191
|
-
* - src/app/blog/[id]/page.tsx -> /blog/[id]
|
|
4192
|
-
* - src/app/api/users/route.ts -> /api/users
|
|
4193
|
-
*/
|
|
4194
|
-
const filePathToRoute = (filePath) => {
|
|
4195
|
-
// Remove src/app prefix and file extension
|
|
4196
|
-
let route = filePath
|
|
4197
|
-
.replace(/^src\/app/, '')
|
|
4198
|
-
.replace(/\/(page|route|layout)\.(tsx?|jsx?)$/, '');
|
|
4199
|
-
|
|
4200
|
-
// Handle root route
|
|
4201
|
-
if (route === '' || route === '/') {
|
|
4202
|
-
return '/';
|
|
4203
|
-
}
|
|
4204
|
-
|
|
4205
|
-
// Ensure leading slash
|
|
4206
|
-
if (!route.startsWith('/')) {
|
|
4207
|
-
route = `/${route}`;
|
|
4208
|
-
}
|
|
4209
|
-
|
|
4210
|
-
return route;
|
|
4211
|
-
};
|
|
4212
|
-
|
|
4213
|
-
/**
|
|
4214
|
-
* Normalize route path to standard format
|
|
4215
|
-
* Converts Next.js dynamic segments to standard format:
|
|
4216
|
-
* - [id] -> :id
|
|
4217
|
-
* - [...slug] -> :slug*
|
|
4218
|
-
* - [[...slug]] -> :slug*?
|
|
4219
|
-
*/
|
|
4220
|
-
const normalizeRoutePath = (routePath) =>
|
|
4221
|
-
routePath
|
|
4222
|
-
.replace(/\[\[\.\.\.(\w+)\]\]/g, ':$1*?') // [[...slug]] -> :slug*?
|
|
4223
|
-
.replace(/\[\.\.\.(\w+)\]/g, ':$1*') // [...slug] -> :slug*
|
|
4224
|
-
.replace(/\[(\w+)\]/g, ':$1'); // [id] -> :id
|
|
4225
|
-
/**
|
|
4226
|
-
* Extract dynamic parameter names from route path
|
|
4227
|
-
* Note: Uses Set to avoid duplicates when patterns overlap (e.g., [[...slug]])
|
|
4228
|
-
*/
|
|
4229
|
-
const extractParams = (routePath) => {
|
|
4230
|
-
const paramsSet = new Set();
|
|
4231
|
-
const patterns = [
|
|
4232
|
-
/\[\[\.\.\.(\w+)\]\]/g, // [[...slug]]
|
|
4233
|
-
/\[\.\.\.(\w+)\]/g, // [...slug]
|
|
4234
|
-
/\[(\w+)\]/g, // [id]
|
|
4235
|
-
];
|
|
4236
|
-
|
|
4237
|
-
patterns.forEach(pattern => {
|
|
4238
|
-
const matches = routePath.matchAll(pattern);
|
|
4239
|
-
for (const match of matches) {
|
|
4240
|
-
paramsSet.add(match[1]);
|
|
4241
|
-
}
|
|
4242
|
-
});
|
|
4243
|
-
|
|
4244
|
-
return Array.from(paramsSet);
|
|
4245
|
-
};
|
|
4246
|
-
|
|
4247
|
-
/**
|
|
4248
|
-
* Determine route type based on file name
|
|
4249
|
-
*/
|
|
4250
|
-
const getRouteType = (filePath) => {
|
|
4251
|
-
if (filePath.includes('/route.')) {
|
|
4252
|
-
return 'api';
|
|
4253
|
-
}
|
|
4254
|
-
return 'page';
|
|
4255
|
-
};
|
|
4256
|
-
|
|
4257
|
-
/**
|
|
4258
|
-
* Scan Next.js App Router routes from app/ or src/app/ directory
|
|
4259
|
-
*
|
|
4260
|
-
* Scans for:
|
|
4261
|
-
* - page.tsx/jsx/ts/js - Page routes
|
|
4262
|
-
* - route.ts/js - API routes
|
|
4263
|
-
*
|
|
4264
|
-
* Note: layout.tsx, loading.tsx, error.tsx are NOT routes, they are UI components
|
|
4265
|
-
*/
|
|
4266
|
-
const scanAppRouter = async (cwd) => {
|
|
4267
|
-
log$3('Scanning App Router routes');
|
|
4268
|
-
|
|
4269
|
-
const files = await fastGlob.glob('{app,src/app}/**/{page,route}.{tsx,ts,jsx,js}', {
|
|
4270
|
-
cwd,
|
|
4271
|
-
ignore: [
|
|
4272
|
-
'**/node_modules/**',
|
|
4273
|
-
'**/.next/**',
|
|
4274
|
-
'**/dist/**',
|
|
4275
|
-
'**/build/**',
|
|
4276
|
-
'**/.turbo/**',
|
|
4277
|
-
],
|
|
4278
|
-
onlyFiles: true,
|
|
4279
|
-
followSymbolicLinks: false,
|
|
4280
|
-
});
|
|
4281
|
-
|
|
4282
|
-
log$3('Found %d App Router files', files.length);
|
|
4283
|
-
|
|
4284
|
-
return files.map(file => {
|
|
4285
|
-
const routePath = filePathToRoute(file);
|
|
4286
|
-
const isDynamic = routePath.includes('[');
|
|
4287
|
-
const params = extractParams(routePath);
|
|
4288
|
-
|
|
4289
|
-
return {
|
|
4290
|
-
path: normalizeRoutePath(routePath),
|
|
4291
|
-
rawPath: routePath,
|
|
4292
|
-
dynamic: isDynamic,
|
|
4293
|
-
params,
|
|
4294
|
-
type: getRouteType(file),
|
|
4295
|
-
file,
|
|
4296
|
-
framework: 'nextjs',
|
|
4297
|
-
};
|
|
4298
|
-
});
|
|
4299
|
-
};
|
|
4300
|
-
|
|
4301
|
-
/**
|
|
4302
|
-
* Convert Pages Router file path to route path
|
|
4303
|
-
* Examples:
|
|
4304
|
-
* - pages/index.tsx -> /
|
|
4305
|
-
* - src/pages/index.tsx -> /
|
|
4306
|
-
* - pages/blog/[id].tsx -> /blog/[id]
|
|
4307
|
-
* - pages/api/users.ts -> /api/users
|
|
4308
|
-
*/
|
|
4309
|
-
const pagesFilePathToRoute = (filePath) => {
|
|
4310
|
-
// Remove pages prefix and file extension
|
|
4311
|
-
let route = filePath
|
|
4312
|
-
.replace(/^src\/pages\//, '')
|
|
4313
|
-
.replace(/^pages\//, '')
|
|
4314
|
-
.replace(/\.(tsx?|jsx?)$/, '')
|
|
4315
|
-
.replace(/\/index$/, ''); // pages/blog/index.tsx -> /blog
|
|
4316
|
-
|
|
4317
|
-
// Handle root index
|
|
4318
|
-
if (route === 'index' || route === '') {
|
|
4319
|
-
return '/';
|
|
4320
|
-
}
|
|
4321
|
-
|
|
4322
|
-
// Ensure leading slash
|
|
4323
|
-
if (!route.startsWith('/')) {
|
|
4324
|
-
route = `/${route}`;
|
|
4325
|
-
}
|
|
4326
|
-
|
|
4327
|
-
return route;
|
|
4328
|
-
};
|
|
4329
|
-
|
|
4330
|
-
/**
|
|
4331
|
-
* Determine if a Pages Router file is an API route
|
|
4332
|
-
*/
|
|
4333
|
-
const isPagesApiRoute = (filePath) =>
|
|
4334
|
-
filePath.includes('/api/') || !!filePath.match(/\/(pages|src\/pages)\/api\//);
|
|
4335
|
-
|
|
4336
|
-
/**
|
|
4337
|
-
* Scan Next.js Pages Router routes from pages/ or src/pages/ directory
|
|
4338
|
-
*
|
|
4339
|
-
* Scans for:
|
|
4340
|
-
* - pages/**\/*.tsx/jsx/ts/js - Page routes
|
|
4341
|
-
* - pages/api/**\/*.ts/js - API routes
|
|
4342
|
-
*
|
|
4343
|
-
* Note: _app.tsx, _document.tsx, _error.tsx are special files, NOT routes
|
|
4344
|
-
*/
|
|
4345
|
-
const scanPagesRouter = async (cwd) => {
|
|
4346
|
-
log$3('Scanning Pages Router routes');
|
|
4347
|
-
|
|
4348
|
-
const files = await fastGlob.glob('{pages,src/pages}/**/*.{tsx,ts,jsx,js}', {
|
|
4349
|
-
cwd,
|
|
4350
|
-
ignore: [
|
|
4351
|
-
'**/node_modules/**',
|
|
4352
|
-
'**/.next/**',
|
|
4353
|
-
'**/dist/**',
|
|
4354
|
-
'**/build/**',
|
|
4355
|
-
'**/.turbo/**',
|
|
4356
|
-
// Exclude special Next.js files (these are NOT routes)
|
|
4357
|
-
'**/_app.{tsx,ts,jsx,js}',
|
|
4358
|
-
'**/_document.{tsx,ts,jsx,js}',
|
|
4359
|
-
'**/_error.{tsx,ts,jsx,js}',
|
|
4360
|
-
'**/middleware.{ts,js}',
|
|
4361
|
-
],
|
|
4362
|
-
onlyFiles: true,
|
|
4363
|
-
followSymbolicLinks: false,
|
|
4364
|
-
});
|
|
4365
|
-
|
|
4366
|
-
log$3('Found %d Pages Router files', files.length);
|
|
4367
|
-
|
|
4368
|
-
return files.map(file => {
|
|
4369
|
-
const routePath = pagesFilePathToRoute(file);
|
|
4370
|
-
const isDynamic = routePath.includes('[');
|
|
4371
|
-
const params = extractParams(routePath);
|
|
4372
|
-
|
|
4373
|
-
return {
|
|
4374
|
-
path: normalizeRoutePath(routePath),
|
|
4375
|
-
rawPath: routePath,
|
|
4376
|
-
dynamic: isDynamic,
|
|
4377
|
-
params,
|
|
4378
|
-
type: isPagesApiRoute(file) ? 'api' : 'page',
|
|
4379
|
-
file,
|
|
4380
|
-
framework: 'nextjs',
|
|
4381
|
-
};
|
|
4382
|
-
});
|
|
4383
|
-
};
|
|
4384
|
-
|
|
4385
|
-
/**
|
|
4386
|
-
* Scan Next.js routes - supports both App Router and Pages Router
|
|
4387
|
-
*
|
|
4388
|
-
* Next.js supports two routing systems that can coexist:
|
|
4389
|
-
* 1. **App Router** (Next.js 13+): app/ or src/app/
|
|
4390
|
-
* - page.tsx/jsx/ts/js - Page routes
|
|
4391
|
-
* - route.ts/js - API routes
|
|
4392
|
-
*
|
|
4393
|
-
* 2. **Pages Router** (Traditional): pages/ or src/pages/
|
|
4394
|
-
* - **\/*.tsx/jsx/ts/js - Page routes
|
|
4395
|
-
* - api/**\/*.ts/js - API routes
|
|
4396
|
-
*
|
|
4397
|
-
* @param cwd - Current working directory
|
|
4398
|
-
* @returns List of detected routes from both routing systems
|
|
4399
|
-
*/
|
|
4400
|
-
const scanNextjsRoutes = async (cwd) => {
|
|
4401
|
-
log$3('Scanning Next.js routes in:', cwd);
|
|
4402
|
-
|
|
4403
|
-
// Scan both routing systems in parallel
|
|
4404
|
-
const [appRoutes, pagesRoutes] = await Promise.all([
|
|
4405
|
-
scanAppRouter(cwd),
|
|
4406
|
-
scanPagesRouter(cwd),
|
|
4407
|
-
]);
|
|
4408
|
-
|
|
4409
|
-
const totalRoutes = [...appRoutes, ...pagesRoutes];
|
|
4410
|
-
log$3(
|
|
4411
|
-
'Total routes found: %d (App Router: %d, Pages Router: %d)',
|
|
4412
|
-
totalRoutes.length,
|
|
4413
|
-
appRoutes.length,
|
|
4414
|
-
pagesRoutes.length,
|
|
4415
|
-
);
|
|
4416
|
-
|
|
4417
|
-
return totalRoutes;
|
|
4418
|
-
};
|
|
4419
|
-
|
|
4420
|
-
// ABOUTME: Route manifest file writer
|
|
4421
|
-
// ABOUTME: Writes route data to JSON file with proper formatting and directory creation
|
|
4422
|
-
|
|
4423
|
-
|
|
4424
|
-
|
|
4425
|
-
|
|
4426
|
-
/**
|
|
4427
|
-
* Calculate route statistics
|
|
4428
|
-
*/
|
|
4429
|
-
const calculateStats = (routes) => {
|
|
4430
|
-
const dynamic = routes.filter(r => r.dynamic).length;
|
|
4431
|
-
const staticCount = routes.length - dynamic;
|
|
4432
|
-
|
|
4433
|
-
return {
|
|
4434
|
-
total: routes.length,
|
|
4435
|
-
dynamic,
|
|
4436
|
-
static: staticCount,
|
|
4437
|
-
};
|
|
4438
|
-
};
|
|
4439
|
-
|
|
4440
|
-
/**
|
|
4441
|
-
* Resolve output file path
|
|
4442
|
-
* - Relative path: resolve based on cwd
|
|
4443
|
-
* - Absolute path: use as-is
|
|
4444
|
-
*/
|
|
4445
|
-
const resolveOutputPath = (cwd, outputPath) =>
|
|
4446
|
-
path.isAbsolute(outputPath) ? outputPath : path.join(cwd, outputPath);
|
|
4447
|
-
|
|
4448
|
-
/**
|
|
4449
|
-
* Ensure parent directory exists
|
|
4450
|
-
* Handles edge cases like existing files with same name
|
|
4451
|
-
*/
|
|
4452
|
-
const ensureDir$1 = (filePath) => {
|
|
4453
|
-
const dir = path.dirname(filePath);
|
|
4454
|
-
|
|
4455
|
-
// If directory already exists, verify it's actually a directory
|
|
4456
|
-
if (fs.existsSync(dir)) {
|
|
4457
|
-
const stats = fs.statSync(dir);
|
|
4458
|
-
if (!stats.isDirectory()) {
|
|
4459
|
-
throw new Error(`Path exists but is not a directory: ${dir}`);
|
|
4460
|
-
}
|
|
4461
|
-
return; // Directory exists and is valid
|
|
4462
|
-
}
|
|
4463
|
-
|
|
4464
|
-
// Create directory with recursive option (equivalent to mkdir -p)
|
|
4465
|
-
fs.mkdirSync(dir, { recursive: true });
|
|
4466
|
-
};
|
|
4467
|
-
|
|
4468
|
-
// JSON.stringify indent size
|
|
4469
|
-
const JSON_INDENT = 2;
|
|
4470
|
-
|
|
4471
|
-
/**
|
|
4472
|
-
* Write route manifest to JSON file
|
|
4473
|
-
*
|
|
4474
|
-
* @param cwd - Current working directory (not used when outputPath is absolute)
|
|
4475
|
-
* @param routes - List of routes to write
|
|
4476
|
-
* @param templateType - Framework type
|
|
4477
|
-
* @param outputPath - Output file path (absolute or relative to cwd)
|
|
4478
|
-
*/
|
|
4479
|
-
const writeRoutesFile = (
|
|
4480
|
-
cwd,
|
|
4481
|
-
routes,
|
|
4482
|
-
templateType,
|
|
4483
|
-
outputPath,
|
|
4484
|
-
) => {
|
|
4485
|
-
try {
|
|
4486
|
-
const resolvedPath = resolveOutputPath(cwd, outputPath);
|
|
4487
|
-
|
|
4488
|
-
// Ensure parent directory exists
|
|
4489
|
-
ensureDir$1(resolvedPath);
|
|
4490
|
-
|
|
4491
|
-
// Build manifest
|
|
4492
|
-
const manifest = {
|
|
4493
|
-
framework: templateType,
|
|
4494
|
-
generatedAt: new Date().toISOString(),
|
|
4495
|
-
routes,
|
|
4496
|
-
stats: calculateStats(routes),
|
|
4497
|
-
};
|
|
4498
|
-
|
|
4499
|
-
// Write to file with pretty formatting
|
|
4500
|
-
fs.writeFileSync(
|
|
4501
|
-
resolvedPath,
|
|
4502
|
-
JSON.stringify(manifest, null, JSON_INDENT),
|
|
4503
|
-
'utf-8',
|
|
4504
|
-
);
|
|
4505
|
-
} catch (error) {
|
|
4506
|
-
// Wrap error with context for better debugging
|
|
4507
|
-
const errorMessage = error instanceof Error ? error.message : String(error);
|
|
4508
|
-
throw new Error(`Failed to write routes file: ${errorMessage}`);
|
|
4509
|
-
}
|
|
4510
|
-
};
|
|
4511
|
-
|
|
4512
|
-
/**
|
|
4513
|
-
* Get the absolute path of the output file
|
|
4514
|
-
* Useful for logging and testing
|
|
4515
|
-
*/
|
|
4516
|
-
const getOutputFilePath = (cwd, outputPath) =>
|
|
4517
|
-
resolveOutputPath(cwd, outputPath);
|
|
4518
|
-
|
|
4519
|
-
// ABOUTME: Template type detection logic
|
|
4520
|
-
// ABOUTME: Detects framework type by checking config files and package.json dependencies
|
|
4521
|
-
|
|
4522
|
-
|
|
4523
|
-
|
|
4524
|
-
|
|
4525
|
-
const log$2 = debug('coze:routes:detect');
|
|
4526
|
-
|
|
4527
|
-
/**
|
|
4528
|
-
* Check if any of the specified files exist
|
|
4529
|
-
*/
|
|
4530
|
-
const hasFile = (cwd, ...files) =>
|
|
4531
|
-
files.some(file => fs.existsSync(path.join(cwd, file)));
|
|
4532
|
-
|
|
4533
|
-
/**
|
|
4534
|
-
* Detect template type by checking config files and package.json dependencies
|
|
4535
|
-
*
|
|
4536
|
-
* Detection rules (priority order):
|
|
4537
|
-
* 1. Next.js (highest) - has `next` dependency + next.config.{js,mjs,ts}
|
|
4538
|
-
* 2. Nuxt - has `nuxt` dependency + nuxt.config.{ts,js,mjs}
|
|
4539
|
-
* 3. Vite (lowest) - has `vite` + `express` dependencies + vite.config.{ts,js,mjs}
|
|
4540
|
-
*
|
|
4541
|
-
* @param cwd - Current working directory
|
|
4542
|
-
* @returns Template type or null if detection fails
|
|
4543
|
-
*/
|
|
4544
|
-
const detectTemplate = (cwd) => {
|
|
4545
|
-
log$2('Detecting template type in:', cwd);
|
|
4546
|
-
|
|
4547
|
-
const pkgPath = path.join(cwd, 'package.json');
|
|
4548
|
-
|
|
4549
|
-
if (!fs.existsSync(pkgPath)) {
|
|
4550
|
-
log$2('package.json not found');
|
|
4551
|
-
return null;
|
|
4552
|
-
}
|
|
4553
|
-
|
|
4554
|
-
try {
|
|
4555
|
-
const pkgContent = fs.readFileSync(pkgPath, 'utf-8');
|
|
4556
|
-
// eslint-disable-next-line no-restricted-syntax
|
|
4557
|
-
const pkg = JSON.parse(pkgContent)
|
|
4558
|
-
|
|
4559
|
-
|
|
4560
|
-
;
|
|
4561
|
-
const deps = { ...pkg.dependencies, ...pkg.devDependencies };
|
|
4562
|
-
log$2('Dependencies found:', Object.keys(deps).length, 'packages');
|
|
4563
|
-
|
|
4564
|
-
// 1. Next.js - highest priority
|
|
4565
|
-
const hasNextDep = !!deps.next;
|
|
4566
|
-
const hasNextConfig = hasFile(
|
|
4567
|
-
cwd,
|
|
4568
|
-
'next.config.js',
|
|
4569
|
-
'next.config.mjs',
|
|
4570
|
-
'next.config.ts',
|
|
4571
|
-
);
|
|
4572
|
-
log$2('Next.js check - dependency:', hasNextDep, 'config:', hasNextConfig);
|
|
4573
|
-
|
|
4574
|
-
if (hasNextDep && hasNextConfig) {
|
|
4575
|
-
log$2('✓ Detected: nextjs');
|
|
4576
|
-
return 'nextjs';
|
|
4577
|
-
}
|
|
4578
|
-
|
|
4579
|
-
// 2. Nuxt - second priority
|
|
4580
|
-
const hasNuxtDep = !!deps.nuxt;
|
|
4581
|
-
const hasNuxtConfig = hasFile(
|
|
4582
|
-
cwd,
|
|
4583
|
-
'nuxt.config.ts',
|
|
4584
|
-
'nuxt.config.js',
|
|
4585
|
-
'nuxt.config.mjs',
|
|
4586
|
-
);
|
|
4587
|
-
log$2('Nuxt check - dependency:', hasNuxtDep, 'config:', hasNuxtConfig);
|
|
4588
|
-
|
|
4589
|
-
if (hasNuxtDep && hasNuxtConfig) {
|
|
4590
|
-
log$2('✓ Detected: nuxt');
|
|
4591
|
-
return 'nuxt';
|
|
4592
|
-
}
|
|
4593
|
-
|
|
4594
|
-
// 3. Vite - lowest priority (requires both vite and express)
|
|
4595
|
-
const hasViteDep = !!deps.vite;
|
|
4596
|
-
const hasExpressDep = !!deps.express;
|
|
4597
|
-
const hasViteConfig = hasFile(
|
|
4598
|
-
cwd,
|
|
4599
|
-
'vite.config.ts',
|
|
4600
|
-
'vite.config.js',
|
|
4601
|
-
'vite.config.mjs',
|
|
4602
|
-
);
|
|
4603
|
-
log$2(
|
|
4604
|
-
'Vite check - vite dep:',
|
|
4605
|
-
hasViteDep,
|
|
4606
|
-
'express dep:',
|
|
4607
|
-
hasExpressDep,
|
|
4608
|
-
'config:',
|
|
4609
|
-
hasViteConfig,
|
|
4610
|
-
);
|
|
4611
|
-
|
|
4612
|
-
if (hasViteDep && hasExpressDep && hasViteConfig) {
|
|
4613
|
-
log$2('✓ Detected: vite');
|
|
4614
|
-
return 'vite';
|
|
4615
|
-
}
|
|
4616
|
-
|
|
4617
|
-
log$2('✗ No template detected');
|
|
4618
|
-
return null;
|
|
4619
|
-
} catch (error) {
|
|
4620
|
-
// Invalid package.json or other errors
|
|
4621
|
-
log$2('Error during detection:', error);
|
|
4622
|
-
return null;
|
|
4623
|
-
}
|
|
4624
|
-
};
|
|
4625
|
-
|
|
4626
|
-
// ABOUTME: Route scanner main entry point
|
|
4627
|
-
// ABOUTME: Orchestrates template detection, route scanning, and polling-based updates
|
|
4628
|
-
|
|
4629
|
-
|
|
4630
|
-
const log$1 = debug('coze:routes:scanner');
|
|
4631
|
-
|
|
4632
|
-
/**
|
|
4633
|
-
* Scan routes based on template type
|
|
4634
|
-
*/
|
|
4635
|
-
const scanRoutes = async (
|
|
4636
|
-
cwd,
|
|
4637
|
-
templateType,
|
|
4638
|
-
) => {
|
|
4639
|
-
switch (templateType) {
|
|
4640
|
-
case 'nextjs':
|
|
4641
|
-
return scanNextjsRoutes(cwd);
|
|
4642
|
-
case 'nuxt':
|
|
4643
|
-
return scanNuxtRoutes(cwd);
|
|
4644
|
-
case 'vite':
|
|
4645
|
-
return [];
|
|
4646
|
-
default:
|
|
4647
|
-
return [];
|
|
4648
|
-
}
|
|
4649
|
-
};
|
|
4650
|
-
|
|
4651
|
-
/**
|
|
4652
|
-
* Detect and validate template type
|
|
4653
|
-
* @returns Template type or null if invalid/unsupported
|
|
4654
|
-
*/
|
|
4655
|
-
const detectAndValidateTemplate = (cwd) => {
|
|
4656
|
-
log$1('Detecting template type');
|
|
4657
|
-
const templateType = detectTemplate(cwd);
|
|
4658
|
-
|
|
4659
|
-
if (!templateType) {
|
|
4660
|
-
log$1('No template type detected');
|
|
4661
|
-
logger.warn('Unable to detect template type, skipping route scanning');
|
|
4662
|
-
return null;
|
|
4663
|
-
}
|
|
4664
|
-
|
|
4665
|
-
log$1('Template detected:', templateType);
|
|
4666
|
-
|
|
4667
|
-
if (templateType === 'vite') {
|
|
4668
|
-
log$1('Skipping Vite template - not supported');
|
|
4669
|
-
return null;
|
|
4670
|
-
}
|
|
4671
|
-
|
|
4672
|
-
return templateType;
|
|
4673
|
-
};
|
|
4674
|
-
|
|
4675
|
-
/**
|
|
4676
|
-
* Scan routes once without starting polling
|
|
4677
|
-
* Used by the standalone `coze routes` command
|
|
4678
|
-
*
|
|
4679
|
-
* @param cwd - Current working directory
|
|
4680
|
-
* @param options - Scanning options (output path, etc.)
|
|
4681
|
-
* @returns Route manifest with routes and metadata
|
|
4682
|
-
*/
|
|
4683
|
-
const scanRoutesOnce = async (
|
|
4684
|
-
cwd,
|
|
4685
|
-
options = {},
|
|
4686
|
-
|
|
4687
|
-
|
|
4688
|
-
|
|
4689
|
-
|
|
4690
|
-
) => {
|
|
4691
|
-
try {
|
|
4692
|
-
log$1('scanRoutesOnce called with cwd:', cwd, 'options:', options);
|
|
4693
|
-
|
|
4694
|
-
// Default output to ~/.coze/routes.json (user home), can be overridden via options or env var
|
|
4695
|
-
const defaultOutputPath =
|
|
4696
|
-
process.env.COZE_ROUTES_OUTPUT || getCozeFilePath('routes.json');
|
|
4697
|
-
const { outputPath = defaultOutputPath } = options;
|
|
4698
|
-
|
|
4699
|
-
// Step 1: Detect and validate template
|
|
4700
|
-
const templateType = detectAndValidateTemplate(cwd);
|
|
4701
|
-
if (!templateType) {
|
|
4702
|
-
return null;
|
|
4703
|
-
}
|
|
4704
|
-
|
|
4705
|
-
// Step 2: Perform scan
|
|
4706
|
-
log$1('Performing route scan');
|
|
4707
|
-
const routes = await scanRoutes(cwd, templateType);
|
|
4708
|
-
log$1('Scan found %d routes', routes.length);
|
|
4709
|
-
|
|
4710
|
-
// Step 3: Write to file
|
|
4711
|
-
log$1('Writing routes to file:', outputPath);
|
|
4712
|
-
writeRoutesFile(cwd, routes, templateType, outputPath);
|
|
4713
|
-
|
|
4714
|
-
const outputFilePath = getOutputFilePath(cwd, outputPath);
|
|
4715
|
-
log$1('Routes written to: %s (%d routes)', outputFilePath, routes.length);
|
|
4716
|
-
|
|
4717
|
-
return {
|
|
4718
|
-
routes,
|
|
4719
|
-
templateType,
|
|
4720
|
-
outputPath: outputFilePath,
|
|
4721
|
-
};
|
|
4722
|
-
} catch (error) {
|
|
4723
|
-
log$1('ERROR in scanRoutesOnce:', error);
|
|
4724
|
-
throw error;
|
|
4725
|
-
}
|
|
4726
|
-
};
|
|
4727
|
-
|
|
4728
|
-
function _optionalChain(ops) { let lastAccessLHS = undefined; let value = ops[0]; let i = 1; while (i < ops.length) { const op = ops[i]; const fn = ops[i + 1]; i += 2; if ((op === 'optionalAccess' || op === 'optionalCall') && value == null) { return undefined; } if (op === 'access' || op === 'optionalAccess') { lastAccessLHS = value; value = fn(value); } else if (op === 'call' || op === 'optionalCall') { value = fn((...args) => value.call(lastAccessLHS, ...args)); lastAccessLHS = undefined; } } return value; }// Route manifest generation command
|
|
4729
|
-
|
|
4730
|
-
|
|
4731
|
-
const log = debug('coze:routes');
|
|
4732
|
-
|
|
4733
|
-
/**
|
|
4734
|
-
* Execute routes command implementation
|
|
4735
|
-
*/
|
|
4736
|
-
const executeRoutes = async (
|
|
4737
|
-
options = {},
|
|
4738
|
-
) => {
|
|
4739
|
-
const startTime = Date.now();
|
|
4740
|
-
|
|
4741
|
-
try {
|
|
4742
|
-
// Report command start
|
|
4743
|
-
reportCommandStart('routes');
|
|
4744
|
-
|
|
4745
|
-
const cwd = process.cwd();
|
|
4746
|
-
const projectFolder = options.directory
|
|
4747
|
-
? path.resolve(cwd, options.directory)
|
|
4748
|
-
: cwd;
|
|
4749
|
-
|
|
4750
|
-
log('Scanning routes in: %s', projectFolder);
|
|
4751
|
-
|
|
4752
|
-
// Scan routes once (no polling)
|
|
4753
|
-
const result = await scanRoutesOnce(projectFolder, {
|
|
4754
|
-
outputPath: options.output,
|
|
4755
|
-
});
|
|
4756
|
-
|
|
4757
|
-
if (!result) {
|
|
4758
|
-
logger.error(
|
|
4759
|
-
'❌ Unable to scan routes - unsupported or undetected template',
|
|
4760
|
-
);
|
|
4761
|
-
logger.error('\nSupported templates:');
|
|
4762
|
-
logger.error(' - Next.js (App Router)');
|
|
4763
|
-
logger.error(' - Nuxt');
|
|
4764
|
-
process.exit(1);
|
|
4765
|
-
}
|
|
4766
|
-
|
|
4767
|
-
const { routes, templateType, outputPath } = result;
|
|
4768
|
-
|
|
4769
|
-
// Read and parse the generated manifest file
|
|
4770
|
-
const manifestContent = fs.readFileSync(outputPath, 'utf-8');
|
|
4771
|
-
const manifest = safeJsonParse(manifestContent, {
|
|
4772
|
-
framework: templateType,
|
|
4773
|
-
generatedAt: new Date().toISOString(),
|
|
4774
|
-
routes: [],
|
|
4775
|
-
stats: { total: 0, dynamic: 0, static: 0 },
|
|
4776
|
-
});
|
|
4777
|
-
|
|
4778
|
-
const JSON_INDENT = 2;
|
|
4779
|
-
|
|
4780
|
-
// Output pure JSON to stdout (can be piped to other tools like jq)
|
|
4781
|
-
console.log(JSON.stringify(manifest, null, JSON_INDENT));
|
|
4782
|
-
|
|
4783
|
-
// Log execution details to debug
|
|
4784
|
-
const duration = Date.now() - startTime;
|
|
4785
|
-
log('✓ Routes generated successfully');
|
|
4786
|
-
log(' File: %s', outputPath);
|
|
4787
|
-
log(' Framework: %s', templateType);
|
|
4788
|
-
log(' Total routes: %d', routes.length);
|
|
4789
|
-
log(' 执行时间: %dms', duration);
|
|
4790
|
-
|
|
4791
|
-
// Report command completion
|
|
4792
|
-
reportCommandComplete('routes', true, duration, {
|
|
4793
|
-
categories: {
|
|
4794
|
-
framework: templateType,
|
|
4795
|
-
routeCount: String(routes.length),
|
|
4796
|
-
outputPath,
|
|
4797
|
-
},
|
|
4798
|
-
});
|
|
4799
|
-
} catch (error) {
|
|
4800
|
-
logger.error('❌ Failed to generate routes:');
|
|
4801
|
-
logger.error(error instanceof Error ? error.message : String(error));
|
|
4802
|
-
|
|
4803
|
-
// Report error
|
|
4804
|
-
reportError(error instanceof Error ? error : new Error(String(error)), {
|
|
4805
|
-
command: 'routes',
|
|
4806
|
-
context: 'route-generation',
|
|
4807
|
-
});
|
|
4808
|
-
|
|
4809
|
-
process.exit(1);
|
|
4810
|
-
}
|
|
4811
|
-
};
|
|
4812
|
-
|
|
4813
|
-
/**
|
|
4814
|
-
* Register routes command to program
|
|
4815
|
-
*/
|
|
4816
|
-
const registerCommand$1 = program => {
|
|
4817
|
-
program
|
|
4818
|
-
.command('routes')
|
|
4819
|
-
.description('Generate routes manifest for the current project')
|
|
4820
|
-
.argument(
|
|
4821
|
-
'[directory]',
|
|
4822
|
-
'Target directory to scan (defaults to current directory)',
|
|
4823
|
-
)
|
|
4824
|
-
.option(
|
|
4825
|
-
'-o, --output <path>',
|
|
4826
|
-
'Output file path (defaults to ~/.coze/routes.json)',
|
|
4827
|
-
)
|
|
4828
|
-
.action(async (directory, options) => {
|
|
4829
|
-
await executeRoutes({ directory, output: _optionalChain([options, 'optionalAccess', _ => _.output]) });
|
|
4830
|
-
});
|
|
4831
|
-
};
|
|
4832
|
-
|
|
4833
3866
|
/**
|
|
4834
3867
|
* 在后台启动一个独立的子进程
|
|
4835
3868
|
* 类似于 `setsid command args >/dev/null 2>&1 &`
|
|
@@ -6111,11 +5144,10 @@ const registerCommand = program => {
|
|
|
6111
5144
|
|
|
6112
5145
|
const commands = [
|
|
6113
5146
|
registerCommand,
|
|
5147
|
+
registerCommand$1,
|
|
5148
|
+
registerCommand$4,
|
|
6114
5149
|
registerCommand$2,
|
|
6115
|
-
registerCommand$5,
|
|
6116
5150
|
registerCommand$3,
|
|
6117
|
-
registerCommand$4,
|
|
6118
|
-
registerCommand$1,
|
|
6119
5151
|
];
|
|
6120
5152
|
|
|
6121
5153
|
const main = async () => {
|