@coze-arch/cli 0.0.36-alpha.3ab612 → 0.0.36-alpha.4e6503
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/README.md +104 -68
- package/lib/__templates__/expo/.cozeproj/scripts/dev_run.sh +19 -80
- package/lib/__templates__/expo/.cozeproj/scripts/prod_run.sh +1 -1
- package/lib/__templates__/expo/.cozeproj/scripts/server_dev_run.sh +1 -1
- package/lib/__templates__/expo/client/metro.config.js +1 -3
- package/lib/__templates__/expo/pnpm-lock.yaml +5 -5
- package/lib/__templates__/expo/server/package.json +2 -2
- package/lib/__templates__/expo/server/src/index.ts +1 -1
- package/lib/__templates__/expo/template.config.js +2 -11
- package/lib/__templates__/native-static/.coze +0 -2
- package/lib/__templates__/nextjs/.coze +0 -5
- package/lib/__templates__/nextjs/package.json +1 -1
- package/lib/__templates__/nextjs/pnpm-lock.yaml +5 -5
- package/lib/__templates__/nextjs/scripts/dev.sh +7 -205
- package/lib/__templates__/nextjs/template.config.js +2 -4
- package/lib/__templates__/nuxt-vue/.coze +0 -5
- package/lib/__templates__/nuxt-vue/package.json +1 -1
- package/lib/__templates__/nuxt-vue/pnpm-lock.yaml +5 -5
- package/lib/__templates__/nuxt-vue/scripts/dev.sh +1 -82
- package/lib/__templates__/pi-agent/package.json +1 -1
- package/lib/__templates__/pi-agent/pnpm-lock.yaml +5 -5
- package/lib/__templates__/taro/.cozeproj/scripts/deploy_run.sh +1 -1
- package/lib/__templates__/taro/.cozeproj/scripts/dev_run.sh +68 -150
- package/lib/__templates__/taro/AGENTS.md +7 -11
- package/lib/__templates__/taro/README.md +4 -4
- package/lib/__templates__/taro/config/index.ts +2 -10
- package/lib/__templates__/taro/pnpm-lock.yaml +5 -5
- package/lib/__templates__/taro/server/package.json +1 -1
- package/lib/__templates__/taro/server/src/main.ts +2 -8
- package/lib/__templates__/templates.json +1 -51
- package/lib/__templates__/vite/package.json +1 -1
- package/lib/__templates__/vite/pnpm-lock.yaml +5 -5
- package/lib/__templates__/vite/scripts/build.ps1 +1 -1
- package/lib/__templates__/vite/scripts/dev.ps1 +65 -9
- package/lib/__templates__/vite/scripts/dev.sh +1 -82
- package/lib/__templates__/vite/scripts/start.ps1 +8 -2
- package/lib/__templates__/vite/template.config.js +2 -4
- package/lib/cli.js +204 -3590
- package/package.json +3 -5
- package/docs/deploy.md +0 -179
- package/lib/__templates__/native-static/scripts/serve.ps1 +0 -7
- package/lib/__templates__/nextjs/scripts/build.ps1 +0 -16
- package/lib/__templates__/nextjs/scripts/dev.ps1 +0 -63
- package/lib/__templates__/nextjs/scripts/prepare.ps1 +0 -18
- package/lib/__templates__/nextjs/scripts/start.ps1 +0 -11
- package/lib/__templates__/nextjs/scripts/validate.ps1 +0 -8
- package/lib/__templates__/nuxt-vue/scripts/build.ps1 +0 -12
- package/lib/__templates__/nuxt-vue/scripts/dev.ps1 +0 -63
- package/lib/__templates__/nuxt-vue/scripts/prepare.ps1 +0 -12
- package/lib/__templates__/nuxt-vue/scripts/start.ps1 +0 -11
- package/lib/__templates__/nuxt-vue/scripts/validate.ps1 +0 -8
- package/lib/__templates__/phaser/.coze +0 -18
- package/lib/__templates__/phaser/README.md +0 -45
- package/lib/__templates__/phaser/_gitignore +0 -23
- package/lib/__templates__/phaser/_npmrc +0 -14
- package/lib/__templates__/phaser/assets/image_sequence/coze-game-loading/frame_0001.png +0 -0
- package/lib/__templates__/phaser/assets/image_sequence/coze-game-loading/frame_0002.png +0 -0
- package/lib/__templates__/phaser/assets/image_sequence/coze-game-loading/frame_0003.png +0 -0
- package/lib/__templates__/phaser/assets/image_sequence/coze-game-loading/frame_0004.png +0 -0
- package/lib/__templates__/phaser/assets/image_sequence/coze-game-loading/frame_0005.png +0 -0
- package/lib/__templates__/phaser/assets/image_sequence/coze-game-loading/frame_0006.png +0 -0
- package/lib/__templates__/phaser/assets/image_sequence/coze-game-loading/frame_0007.png +0 -0
- package/lib/__templates__/phaser/assets/image_sequence/coze-game-loading/frame_0008.png +0 -0
- package/lib/__templates__/phaser/assets/image_sequence/coze-game-loading/frame_0009.png +0 -0
- package/lib/__templates__/phaser/assets/image_sequence/coze-game-loading/frame_0010.png +0 -0
- package/lib/__templates__/phaser/assets/image_sequence/coze-game-loading/frame_0011.png +0 -0
- package/lib/__templates__/phaser/assets/image_sequence/coze-game-loading/frame_0012.png +0 -0
- package/lib/__templates__/phaser/assets/image_sequence/coze-game-loading/frame_0013.png +0 -0
- package/lib/__templates__/phaser/assets/image_sequence/coze-game-loading/frame_0014.png +0 -0
- package/lib/__templates__/phaser/assets/image_sequence/coze-game-loading/frame_0015.png +0 -0
- package/lib/__templates__/phaser/assets/image_sequence/coze-game-loading/frame_0016.png +0 -0
- package/lib/__templates__/phaser/assets/image_sequence/coze-game-loading/frame_0017.png +0 -0
- package/lib/__templates__/phaser/assets/image_sequence/coze-game-loading/frame_0018.png +0 -0
- package/lib/__templates__/phaser/assets/image_sequence/coze-game-loading/frame_0019.png +0 -0
- package/lib/__templates__/phaser/assets/image_sequence/coze-game-loading/frame_0020.png +0 -0
- package/lib/__templates__/phaser/assets/image_sequence/coze-game-loading/frame_0021.png +0 -0
- package/lib/__templates__/phaser/assets/image_sequence/coze-game-loading/frame_0022.png +0 -0
- package/lib/__templates__/phaser/assets/image_sequence/coze-game-loading/frame_0023.png +0 -0
- package/lib/__templates__/phaser/assets/image_sequence/coze-game-loading/frame_0024.png +0 -0
- package/lib/__templates__/phaser/assets/image_sequence/coze-game-loading/manifest.json +0 -11
- package/lib/__templates__/phaser/debug-runtime/flow-graph.json +0 -20
- package/lib/__templates__/phaser/index.html +0 -12
- package/lib/__templates__/phaser/package.json +0 -31
- package/lib/__templates__/phaser/pnpm-lock.yaml +0 -661
- package/lib/__templates__/phaser/scripts/build.ps1 +0 -12
- package/lib/__templates__/phaser/scripts/build.sh +0 -8
- package/lib/__templates__/phaser/scripts/dev.ps1 +0 -49
- package/lib/__templates__/phaser/scripts/dev.sh +0 -82
- package/lib/__templates__/phaser/scripts/prepare.ps1 +0 -8
- package/lib/__templates__/phaser/scripts/prepare.sh +0 -7
- package/lib/__templates__/phaser/scripts/spawn-detached.cjs +0 -29
- package/lib/__templates__/phaser/scripts/start.ps1 +0 -49
- package/lib/__templates__/phaser/scripts/start.sh +0 -82
- package/lib/__templates__/phaser/scripts/validate.ps1 +0 -7
- package/lib/__templates__/phaser/scripts/validate.sh +0 -7
- package/lib/__templates__/phaser/src/assets.ts +0 -15
- package/lib/__templates__/phaser/src/global.d.ts +0 -39
- package/lib/__templates__/phaser/src/main.ts +0 -28
- package/lib/__templates__/phaser/src/scene/BootScene.ts +0 -213
- package/lib/__templates__/phaser/src/scene/DevLoadingScene.ts +0 -69
- package/lib/__templates__/phaser/src/style.css +0 -28
- package/lib/__templates__/phaser/src/types.ts +0 -32
- package/lib/__templates__/phaser/src/utils/asset-loader.ts +0 -319
- package/lib/__templates__/phaser/src/utils/index.ts +0 -2
- package/lib/__templates__/phaser/src/utils/mark-editable.ts +0 -13
- package/lib/__templates__/phaser/template.config.js +0 -43
- package/lib/__templates__/phaser/tsconfig.json +0 -23
- package/lib/__templates__/phaser/vite.config.ts +0 -96
- package/lib/__templates__/phaser-static/.coze +0 -15
- package/lib/__templates__/phaser-static/README.md +0 -40
- package/lib/__templates__/phaser-static/_gitignore +0 -6
- package/lib/__templates__/phaser-static/assets/image_sequence/coze-game-loading/frame_0001.png +0 -0
- package/lib/__templates__/phaser-static/assets/image_sequence/coze-game-loading/frame_0002.png +0 -0
- package/lib/__templates__/phaser-static/assets/image_sequence/coze-game-loading/frame_0003.png +0 -0
- package/lib/__templates__/phaser-static/assets/image_sequence/coze-game-loading/frame_0004.png +0 -0
- package/lib/__templates__/phaser-static/assets/image_sequence/coze-game-loading/frame_0005.png +0 -0
- package/lib/__templates__/phaser-static/assets/image_sequence/coze-game-loading/frame_0006.png +0 -0
- package/lib/__templates__/phaser-static/assets/image_sequence/coze-game-loading/frame_0007.png +0 -0
- package/lib/__templates__/phaser-static/assets/image_sequence/coze-game-loading/frame_0008.png +0 -0
- package/lib/__templates__/phaser-static/assets/image_sequence/coze-game-loading/frame_0009.png +0 -0
- package/lib/__templates__/phaser-static/assets/image_sequence/coze-game-loading/frame_0010.png +0 -0
- package/lib/__templates__/phaser-static/assets/image_sequence/coze-game-loading/frame_0011.png +0 -0
- package/lib/__templates__/phaser-static/assets/image_sequence/coze-game-loading/frame_0012.png +0 -0
- package/lib/__templates__/phaser-static/assets/image_sequence/coze-game-loading/frame_0013.png +0 -0
- package/lib/__templates__/phaser-static/assets/image_sequence/coze-game-loading/frame_0014.png +0 -0
- package/lib/__templates__/phaser-static/assets/image_sequence/coze-game-loading/frame_0015.png +0 -0
- package/lib/__templates__/phaser-static/assets/image_sequence/coze-game-loading/frame_0016.png +0 -0
- package/lib/__templates__/phaser-static/assets/image_sequence/coze-game-loading/frame_0017.png +0 -0
- package/lib/__templates__/phaser-static/assets/image_sequence/coze-game-loading/frame_0018.png +0 -0
- package/lib/__templates__/phaser-static/assets/image_sequence/coze-game-loading/frame_0019.png +0 -0
- package/lib/__templates__/phaser-static/assets/image_sequence/coze-game-loading/frame_0020.png +0 -0
- package/lib/__templates__/phaser-static/assets/image_sequence/coze-game-loading/frame_0021.png +0 -0
- package/lib/__templates__/phaser-static/assets/image_sequence/coze-game-loading/frame_0022.png +0 -0
- package/lib/__templates__/phaser-static/assets/image_sequence/coze-game-loading/frame_0023.png +0 -0
- package/lib/__templates__/phaser-static/assets/image_sequence/coze-game-loading/frame_0024.png +0 -0
- package/lib/__templates__/phaser-static/assets/image_sequence/coze-game-loading/manifest.json +0 -11
- package/lib/__templates__/phaser-static/debug-runtime/flow-graph.json +0 -20
- package/lib/__templates__/phaser-static/index.html +0 -17
- package/lib/__templates__/phaser-static/scripts/serve.ps1 +0 -7
- package/lib/__templates__/phaser-static/src/assets.js +0 -15
- package/lib/__templates__/phaser-static/src/main.js +0 -26
- package/lib/__templates__/phaser-static/src/phaser.js +0 -7
- package/lib/__templates__/phaser-static/src/scene/BootScene.js +0 -205
- package/lib/__templates__/phaser-static/src/scene/DevLoadingScene.js +0 -67
- package/lib/__templates__/phaser-static/src/style.css +0 -28
- package/lib/__templates__/phaser-static/src/utils/asset-loader.js +0 -267
- package/lib/__templates__/phaser-static/src/utils/index.js +0 -2
- package/lib/__templates__/phaser-static/src/utils/mark-editable.js +0 -3
- package/lib/__templates__/phaser-static/template.config.js +0 -35
- package/lib/deploy/package-project.js +0 -244
- package/lib/deploy/package-project.py +0 -183
package/lib/cli.js
CHANGED
|
@@ -14,7 +14,7 @@ var perf_hooks = require('perf_hooks');
|
|
|
14
14
|
var fs$1 = require('fs/promises');
|
|
15
15
|
var os = require('os');
|
|
16
16
|
var jsYaml = require('js-yaml');
|
|
17
|
-
var
|
|
17
|
+
var toml = require('@iarna/toml');
|
|
18
18
|
var crypto = require('crypto');
|
|
19
19
|
var fastGlob = require('fast-glob');
|
|
20
20
|
var child_process = require('child_process');
|
|
@@ -23,13 +23,6 @@ var Ajv = require('ajv');
|
|
|
23
23
|
var minimist = require('minimist');
|
|
24
24
|
var changeCase = require('change-case');
|
|
25
25
|
var ejs = require('ejs');
|
|
26
|
-
var node_os = require('node:os');
|
|
27
|
-
var promises = require('node:fs/promises');
|
|
28
|
-
var node_crypto = require('node:crypto');
|
|
29
|
-
var node_child_process = require('node:child_process');
|
|
30
|
-
var node_util = require('node:util');
|
|
31
|
-
var tar = require('tar');
|
|
32
|
-
var node_stream = require('node:stream');
|
|
33
26
|
|
|
34
27
|
/**
|
|
35
28
|
* 读取 templates.json 配置
|
|
@@ -1635,7 +1628,7 @@ function createNodeTransport() {
|
|
|
1635
1628
|
};
|
|
1636
1629
|
}
|
|
1637
1630
|
|
|
1638
|
-
function _nullishCoalesce$
|
|
1631
|
+
function _nullishCoalesce$a(lhs, rhsFn) { if (lhs != null) { return lhs; } else { return rhsFn(); } } function _optionalChain$t(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; }/**
|
|
1639
1632
|
* Slardar CLI Reporter 主类
|
|
1640
1633
|
* 封装 @slardar/base 的初始化和上报逻辑
|
|
1641
1634
|
*/
|
|
@@ -1692,7 +1685,7 @@ class SlardarCLIReporter {constructor() { SlardarCLIReporter.prototype.__init.ca
|
|
|
1692
1685
|
release: config.release,
|
|
1693
1686
|
env: config.env,
|
|
1694
1687
|
name: config.name,
|
|
1695
|
-
useLocalConfig: _nullishCoalesce$
|
|
1688
|
+
useLocalConfig: _nullishCoalesce$a(config.useLocalConfig, () => ( false)), // 默认使用服务端配置
|
|
1696
1689
|
domain: config.domain,
|
|
1697
1690
|
// 设置本地采样率为 100%,确保事件不被过滤
|
|
1698
1691
|
sample: {
|
|
@@ -1707,7 +1700,7 @@ class SlardarCLIReporter {constructor() { SlardarCLIReporter.prototype.__init.ca
|
|
|
1707
1700
|
this.client.on('send', (ev) => {
|
|
1708
1701
|
log$6(
|
|
1709
1702
|
'send hook called for event: %s',
|
|
1710
|
-
(_optionalChain$
|
|
1703
|
+
(_optionalChain$t([ev, 'optionalAccess', _ => _.ev_type]) ) || 'unknown',
|
|
1711
1704
|
);
|
|
1712
1705
|
});
|
|
1713
1706
|
|
|
@@ -1765,7 +1758,7 @@ class SlardarCLIReporter {constructor() { SlardarCLIReporter.prototype.__init.ca
|
|
|
1765
1758
|
)
|
|
1766
1759
|
: undefined;
|
|
1767
1760
|
|
|
1768
|
-
_optionalChain$
|
|
1761
|
+
_optionalChain$t([this, 'access', _2 => _2.client, 'access', _3 => _3.sendEvent, 'optionalCall', _4 => _4({
|
|
1769
1762
|
name,
|
|
1770
1763
|
metrics: cleanMetrics ,
|
|
1771
1764
|
categories: cleanCategories ,
|
|
@@ -1836,7 +1829,7 @@ class SlardarCLIReporter {constructor() { SlardarCLIReporter.prototype.__init.ca
|
|
|
1836
1829
|
log$6('Reporting JS error:', {
|
|
1837
1830
|
name: error.name,
|
|
1838
1831
|
message: error.message.slice(0, 100),
|
|
1839
|
-
stack: _optionalChain$
|
|
1832
|
+
stack: _optionalChain$t([error, 'access', _5 => _5.stack, 'optionalAccess', _6 => _6.slice, 'call', _7 => _7(0, 200)]),
|
|
1840
1833
|
extra,
|
|
1841
1834
|
source,
|
|
1842
1835
|
});
|
|
@@ -1856,7 +1849,7 @@ class SlardarCLIReporter {constructor() { SlardarCLIReporter.prototype.__init.ca
|
|
|
1856
1849
|
if (!this.ensureInitialized()) {
|
|
1857
1850
|
return;
|
|
1858
1851
|
}
|
|
1859
|
-
_optionalChain$
|
|
1852
|
+
_optionalChain$t([this, 'access', _8 => _8.client, 'access', _9 => _9.context, 'optionalAccess', _10 => _10.set, 'call', _11 => _11(key, value)]);
|
|
1860
1853
|
}
|
|
1861
1854
|
|
|
1862
1855
|
/**
|
|
@@ -1867,7 +1860,7 @@ class SlardarCLIReporter {constructor() { SlardarCLIReporter.prototype.__init.ca
|
|
|
1867
1860
|
return;
|
|
1868
1861
|
}
|
|
1869
1862
|
log$6('Merging context:', context);
|
|
1870
|
-
_optionalChain$
|
|
1863
|
+
_optionalChain$t([this, 'access', _12 => _12.client, 'access', _13 => _13.context, 'optionalAccess', _14 => _14.merge, 'call', _15 => _15(context)]);
|
|
1871
1864
|
}
|
|
1872
1865
|
|
|
1873
1866
|
/**
|
|
@@ -1877,7 +1870,7 @@ class SlardarCLIReporter {constructor() { SlardarCLIReporter.prototype.__init.ca
|
|
|
1877
1870
|
if (!this.ensureInitialized()) {
|
|
1878
1871
|
return;
|
|
1879
1872
|
}
|
|
1880
|
-
_optionalChain$
|
|
1873
|
+
_optionalChain$t([this, 'access', _16 => _16.client, 'access', _17 => _17.context, 'optionalAccess', _18 => _18.delete, 'call', _19 => _19(key)]);
|
|
1881
1874
|
}
|
|
1882
1875
|
|
|
1883
1876
|
/**
|
|
@@ -1887,7 +1880,7 @@ class SlardarCLIReporter {constructor() { SlardarCLIReporter.prototype.__init.ca
|
|
|
1887
1880
|
if (!this.ensureInitialized()) {
|
|
1888
1881
|
return;
|
|
1889
1882
|
}
|
|
1890
|
-
_optionalChain$
|
|
1883
|
+
_optionalChain$t([this, 'access', _20 => _20.client, 'access', _21 => _21.context, 'optionalAccess', _22 => _22.clear, 'call', _23 => _23()]);
|
|
1891
1884
|
}
|
|
1892
1885
|
|
|
1893
1886
|
/**
|
|
@@ -1924,7 +1917,7 @@ class SlardarCLIReporter {constructor() { SlardarCLIReporter.prototype.__init.ca
|
|
|
1924
1917
|
return;
|
|
1925
1918
|
}
|
|
1926
1919
|
log$6('Flushing Slardar data...');
|
|
1927
|
-
_optionalChain$
|
|
1920
|
+
_optionalChain$t([this, 'access', _24 => _24.client, 'access', _25 => _25.getSender, 'optionalCall', _26 => _26(), 'optionalAccess', _27 => _27.flush, 'call', _28 => _28()]);
|
|
1928
1921
|
log$6('Waiting %dms for events to be sent...', waitMs);
|
|
1929
1922
|
await new Promise(resolve => setTimeout(resolve, waitMs));
|
|
1930
1923
|
log$6('Slardar data flushed');
|
|
@@ -1943,7 +1936,7 @@ class SlardarCLIReporter {constructor() { SlardarCLIReporter.prototype.__init.ca
|
|
|
1943
1936
|
*/
|
|
1944
1937
|
const reporter = new SlardarCLIReporter();
|
|
1945
1938
|
|
|
1946
|
-
function _optionalChain$
|
|
1939
|
+
function _optionalChain$s(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; }
|
|
1947
1940
|
|
|
1948
1941
|
|
|
1949
1942
|
|
|
@@ -2003,11 +1996,11 @@ const EventBuilder = {
|
|
|
2003
1996
|
name: CLI_EVENTS.CLI_COMMAND,
|
|
2004
1997
|
categories: {
|
|
2005
1998
|
command,
|
|
2006
|
-
args: _optionalChain$
|
|
1999
|
+
args: _optionalChain$s([options, 'optionalAccess', _ => _.args]),
|
|
2007
2000
|
status: 'running' ,
|
|
2008
|
-
..._optionalChain$
|
|
2001
|
+
..._optionalChain$s([options, 'optionalAccess', _2 => _2.categories]),
|
|
2009
2002
|
},
|
|
2010
|
-
metrics: _optionalChain$
|
|
2003
|
+
metrics: _optionalChain$s([options, 'optionalAccess', _3 => _3.metrics]),
|
|
2011
2004
|
};
|
|
2012
2005
|
},
|
|
2013
2006
|
|
|
@@ -2028,13 +2021,13 @@ const EventBuilder = {
|
|
|
2028
2021
|
name: CLI_EVENTS.CLI_COMMAND_COMPLETE,
|
|
2029
2022
|
categories: {
|
|
2030
2023
|
command,
|
|
2031
|
-
args: _optionalChain$
|
|
2024
|
+
args: _optionalChain$s([options, 'optionalAccess', _4 => _4.args]),
|
|
2032
2025
|
status: success ? ('success' ) : ('fail' ),
|
|
2033
|
-
..._optionalChain$
|
|
2026
|
+
..._optionalChain$s([options, 'optionalAccess', _5 => _5.categories]),
|
|
2034
2027
|
},
|
|
2035
2028
|
metrics: {
|
|
2036
2029
|
duration,
|
|
2037
|
-
...(_optionalChain$
|
|
2030
|
+
...(_optionalChain$s([options, 'optionalAccess', _6 => _6.errorCode]) && { errorCode: options.errorCode }),
|
|
2038
2031
|
},
|
|
2039
2032
|
};
|
|
2040
2033
|
},
|
|
@@ -2055,12 +2048,12 @@ const EventBuilder = {
|
|
|
2055
2048
|
name: CLI_EVENTS.NETWORK_REQUEST,
|
|
2056
2049
|
categories: {
|
|
2057
2050
|
url,
|
|
2058
|
-
method: _optionalChain$
|
|
2059
|
-
statusCode: _optionalChain$
|
|
2060
|
-
status: _optionalChain$
|
|
2051
|
+
method: _optionalChain$s([options, 'optionalAccess', _7 => _7.method]) || 'GET',
|
|
2052
|
+
statusCode: _optionalChain$s([options, 'optionalAccess', _8 => _8.statusCode, 'optionalAccess', _9 => _9.toString, 'call', _10 => _10()]),
|
|
2053
|
+
status: _optionalChain$s([options, 'optionalAccess', _11 => _11.success]) ? ('success' ) : ('fail' ),
|
|
2061
2054
|
},
|
|
2062
2055
|
metrics: {
|
|
2063
|
-
duration: _optionalChain$
|
|
2056
|
+
duration: _optionalChain$s([options, 'optionalAccess', _12 => _12.duration]),
|
|
2064
2057
|
},
|
|
2065
2058
|
};
|
|
2066
2059
|
},
|
|
@@ -2082,11 +2075,11 @@ const EventBuilder = {
|
|
|
2082
2075
|
categories: {
|
|
2083
2076
|
operation,
|
|
2084
2077
|
filePath,
|
|
2085
|
-
status: _optionalChain$
|
|
2078
|
+
status: _optionalChain$s([options, 'optionalAccess', _13 => _13.success]) ? ('success' ) : ('fail' ),
|
|
2086
2079
|
},
|
|
2087
2080
|
metrics: {
|
|
2088
|
-
duration: _optionalChain$
|
|
2089
|
-
fileSize: _optionalChain$
|
|
2081
|
+
duration: _optionalChain$s([options, 'optionalAccess', _14 => _14.duration]),
|
|
2082
|
+
fileSize: _optionalChain$s([options, 'optionalAccess', _15 => _15.fileSize]),
|
|
2090
2083
|
},
|
|
2091
2084
|
};
|
|
2092
2085
|
},
|
|
@@ -2114,7 +2107,7 @@ const EventBuilder = {
|
|
|
2114
2107
|
};
|
|
2115
2108
|
|
|
2116
2109
|
var name = "@coze-arch/cli";
|
|
2117
|
-
var version = "0.0.36-alpha.
|
|
2110
|
+
var version = "0.0.36-alpha.4e6503";
|
|
2118
2111
|
var description = "coze coding devtools cli";
|
|
2119
2112
|
var license = "MIT";
|
|
2120
2113
|
var author = "fanwenjie.fe@bytedance.com";
|
|
@@ -2126,7 +2119,6 @@ var bin = {
|
|
|
2126
2119
|
var files = [
|
|
2127
2120
|
"lib",
|
|
2128
2121
|
"bin",
|
|
2129
|
-
"docs/deploy.md",
|
|
2130
2122
|
"lib/**/.npmrc",
|
|
2131
2123
|
"!**/*.tsbuildinfo",
|
|
2132
2124
|
"!**/*.map",
|
|
@@ -2163,9 +2155,7 @@ var dependencies = {
|
|
|
2163
2155
|
"fast-glob": "^3.3.3",
|
|
2164
2156
|
"js-yaml": "^4.2.0",
|
|
2165
2157
|
minimist: "^1.2.8",
|
|
2166
|
-
|
|
2167
|
-
shelljs: "^0.10.0",
|
|
2168
|
-
tar: "^7.5.22"
|
|
2158
|
+
shelljs: "^0.10.0"
|
|
2169
2159
|
};
|
|
2170
2160
|
var devDependencies = {
|
|
2171
2161
|
"@coze-arch/cli-logger": "workspace:*",
|
|
@@ -2177,6 +2167,7 @@ var devDependencies = {
|
|
|
2177
2167
|
"@coze-arch/ts-config": "workspace:*",
|
|
2178
2168
|
"@coze-arch/vitest-config": "workspace:*",
|
|
2179
2169
|
"@coze-coding/lambda": "workspace:*",
|
|
2170
|
+
"@emnapi/runtime": "^1.11.1",
|
|
2180
2171
|
"@inquirer/prompts": "^3.2.0",
|
|
2181
2172
|
"@rollup/plugin-commonjs": "^28.0.2",
|
|
2182
2173
|
"@rollup/plugin-json": "~6.1.0",
|
|
@@ -2224,7 +2215,7 @@ var packageJson = {
|
|
|
2224
2215
|
cozePublishConfig: cozePublishConfig
|
|
2225
2216
|
};
|
|
2226
2217
|
|
|
2227
|
-
function _optionalChain$
|
|
2218
|
+
function _optionalChain$r(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; }/**
|
|
2228
2219
|
* Slardar 监控初始化和上报
|
|
2229
2220
|
*/
|
|
2230
2221
|
|
|
@@ -2327,11 +2318,11 @@ const reportCommandComplete = safeRun(
|
|
|
2327
2318
|
,
|
|
2328
2319
|
) => {
|
|
2329
2320
|
const event = EventBuilder.cliCommandComplete(command, success, duration, {
|
|
2330
|
-
args: _optionalChain$
|
|
2331
|
-
errorCode: _optionalChain$
|
|
2321
|
+
args: _optionalChain$r([options, 'optionalAccess', _ => _.args]),
|
|
2322
|
+
errorCode: _optionalChain$r([options, 'optionalAccess', _2 => _2.errorCode]),
|
|
2332
2323
|
categories: {
|
|
2333
|
-
...(_optionalChain$
|
|
2334
|
-
..._optionalChain$
|
|
2324
|
+
...(_optionalChain$r([options, 'optionalAccess', _3 => _3.errorMessage]) && { errorMessage: options.errorMessage }),
|
|
2325
|
+
..._optionalChain$r([options, 'optionalAccess', _4 => _4.categories]),
|
|
2335
2326
|
},
|
|
2336
2327
|
});
|
|
2337
2328
|
reporter.sendEvent(event.name, event.metrics, event.categories);
|
|
@@ -2390,7 +2381,7 @@ const flushSlardar = safeRun('flushSlardar', async () => {
|
|
|
2390
2381
|
await reporter.flush();
|
|
2391
2382
|
});
|
|
2392
2383
|
|
|
2393
|
-
function _nullishCoalesce$
|
|
2384
|
+
function _nullishCoalesce$9(lhs, rhsFn) { if (lhs != null) { return lhs; } else { return rhsFn(); } } function _optionalChain$q(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) {
|
|
2394
2385
|
const ERROR = 0; LogLevel[LogLevel["ERROR"] = ERROR] = "ERROR";
|
|
2395
2386
|
const WARN = 1; LogLevel[LogLevel["WARN"] = WARN] = "WARN";
|
|
2396
2387
|
const SUCCESS = 2; LogLevel[LogLevel["SUCCESS"] = SUCCESS] = "SUCCESS";
|
|
@@ -2428,7 +2419,7 @@ class Logger {
|
|
|
2428
2419
|
|
|
2429
2420
|
constructor(options = {}) {
|
|
2430
2421
|
this.level = this.parseLogLevel(options.level);
|
|
2431
|
-
this.useColor = _nullishCoalesce$
|
|
2422
|
+
this.useColor = _nullishCoalesce$9(options.useColor, () => ( this.isColorSupported()));
|
|
2432
2423
|
this.prefix = options.prefix;
|
|
2433
2424
|
}
|
|
2434
2425
|
|
|
@@ -2437,7 +2428,7 @@ class Logger {
|
|
|
2437
2428
|
return level;
|
|
2438
2429
|
}
|
|
2439
2430
|
|
|
2440
|
-
const envLevel = _optionalChain$
|
|
2431
|
+
const envLevel = _optionalChain$q([process, 'access', _ => _.env, 'access', _2 => _2.LOG_LEVEL, 'optionalAccess', _3 => _3.toLowerCase, 'call', _4 => _4()]);
|
|
2441
2432
|
if (envLevel && envLevel in LOG_LEVEL_MAP) {
|
|
2442
2433
|
// envLevel 已通过 `in` 检查确认为 LOG_LEVEL_MAP 的键;
|
|
2443
2434
|
// 显式判空以满足 noUncheckedIndexedAccess,运行时行为不变
|
|
@@ -2454,7 +2445,7 @@ class Logger {
|
|
|
2454
2445
|
// 简单检测:Node.js 环境且支持 TTY
|
|
2455
2446
|
return (
|
|
2456
2447
|
typeof process !== 'undefined' &&
|
|
2457
|
-
_optionalChain$
|
|
2448
|
+
_optionalChain$q([process, 'access', _5 => _5.stdout, 'optionalAccess', _6 => _6.isTTY]) === true &&
|
|
2458
2449
|
process.env.NO_COLOR === undefined
|
|
2459
2450
|
);
|
|
2460
2451
|
}
|
|
@@ -2479,7 +2470,7 @@ class Logger {
|
|
|
2479
2470
|
|
|
2480
2471
|
const icon = this.colorize(options.icon, options.color);
|
|
2481
2472
|
const prefix = this.prefix ? `${icon} ${this.prefix}` : icon;
|
|
2482
|
-
console.log(prefix, options.message, ...(_nullishCoalesce$
|
|
2473
|
+
console.log(prefix, options.message, ...(_nullishCoalesce$9(options.args, () => ( []))));
|
|
2483
2474
|
}
|
|
2484
2475
|
|
|
2485
2476
|
error(message, ...args) {
|
|
@@ -2824,7 +2815,7 @@ const executeWarmup = async (options) => {
|
|
|
2824
2815
|
/**
|
|
2825
2816
|
* 注册 warmup 命令到 program
|
|
2826
2817
|
*/
|
|
2827
|
-
const registerCommand$
|
|
2818
|
+
const registerCommand$6 = program => {
|
|
2828
2819
|
program
|
|
2829
2820
|
.command('warmup')
|
|
2830
2821
|
.description('Pre-install dependencies for templates to speed up init')
|
|
@@ -2847,9 +2838,9 @@ const COZE_HOME_DIR = '.coze';
|
|
|
2847
2838
|
|
|
2848
2839
|
/**
|
|
2849
2840
|
* Logs directory name
|
|
2850
|
-
* Default:
|
|
2841
|
+
* Default: .coze-logs
|
|
2851
2842
|
*/
|
|
2852
|
-
const LOGS_DIR = 'logs';
|
|
2843
|
+
const LOGS_DIR = '.coze-logs';
|
|
2853
2844
|
|
|
2854
2845
|
/**
|
|
2855
2846
|
* Get the Coze home directory path
|
|
@@ -2864,10 +2855,10 @@ const getCozeHome = () =>
|
|
|
2864
2855
|
* Get the logs directory path
|
|
2865
2856
|
* Can be customized via COZE_LOG_DIR environment variable
|
|
2866
2857
|
*
|
|
2867
|
-
* @returns Absolute path to logs directory (default: ~/.coze
|
|
2858
|
+
* @returns Absolute path to logs directory (default: ~/.coze-logs)
|
|
2868
2859
|
*/
|
|
2869
2860
|
const getCozeLogsDir = () =>
|
|
2870
|
-
process.env.COZE_LOG_DIR || path.join(
|
|
2861
|
+
process.env.COZE_LOG_DIR || path.join(os.homedir(), LOGS_DIR);
|
|
2871
2862
|
|
|
2872
2863
|
/**
|
|
2873
2864
|
* Get path for a specific file/directory within Coze home
|
|
@@ -2898,7 +2889,7 @@ const getCozeFilePath = (relativePath) =>
|
|
|
2898
2889
|
* @example
|
|
2899
2890
|
* ```ts
|
|
2900
2891
|
* const devLog = getCozeLogPath('dev.log');
|
|
2901
|
-
* // Returns: ~/.coze
|
|
2892
|
+
* // Returns: ~/.coze-logs/dev.log
|
|
2902
2893
|
* ```
|
|
2903
2894
|
*/
|
|
2904
2895
|
const getCozeLogPath = (filename) =>
|
|
@@ -3236,7 +3227,7 @@ const executeUpdate = (
|
|
|
3236
3227
|
/**
|
|
3237
3228
|
* 注册 update 命令到 program
|
|
3238
3229
|
*/
|
|
3239
|
-
const registerCommand$
|
|
3230
|
+
const registerCommand$5 = program => {
|
|
3240
3231
|
program
|
|
3241
3232
|
.command('update <package>')
|
|
3242
3233
|
.description('Update a package dependency')
|
|
@@ -3262,7 +3253,7 @@ const registerCommand$6 = program => {
|
|
|
3262
3253
|
});
|
|
3263
3254
|
};
|
|
3264
3255
|
|
|
3265
|
-
function _optionalChain$
|
|
3256
|
+
function _optionalChain$p(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; }// Safe JSON parsing utilities with type safety and error handling
|
|
3266
3257
|
// Provides fallback values, validation, and error monitoring capabilities
|
|
3267
3258
|
|
|
3268
3259
|
/**
|
|
@@ -3362,12 +3353,12 @@ function safeJsonParse(
|
|
|
3362
3353
|
const parsed = JSON.parse(String(input));
|
|
3363
3354
|
|
|
3364
3355
|
// Optional validation
|
|
3365
|
-
if (_optionalChain$
|
|
3356
|
+
if (_optionalChain$p([options, 'optionalAccess', _ => _.validate])) {
|
|
3366
3357
|
if (options.validate(parsed)) {
|
|
3367
3358
|
return parsed;
|
|
3368
3359
|
} else {
|
|
3369
3360
|
const validationError = new Error('JSON validation failed');
|
|
3370
|
-
_optionalChain$
|
|
3361
|
+
_optionalChain$p([options, 'access', _2 => _2.onError, 'optionalCall', _3 => _3(validationError, input)]);
|
|
3371
3362
|
|
|
3372
3363
|
if (options.throwOnValidationError) {
|
|
3373
3364
|
throw validationError;
|
|
@@ -3379,10 +3370,10 @@ function safeJsonParse(
|
|
|
3379
3370
|
return parsed;
|
|
3380
3371
|
} catch (error) {
|
|
3381
3372
|
// Re-throw validation errors when throwOnValidationError is true
|
|
3382
|
-
if (error instanceof Error && error.message === 'JSON validation failed' && _optionalChain$
|
|
3373
|
+
if (error instanceof Error && error.message === 'JSON validation failed' && _optionalChain$p([options, 'optionalAccess', _4 => _4.throwOnValidationError])) {
|
|
3383
3374
|
throw error;
|
|
3384
3375
|
}
|
|
3385
|
-
_optionalChain$
|
|
3376
|
+
_optionalChain$p([options, 'optionalAccess', _5 => _5.onError, 'optionalCall', _6 => _6(error , input)]);
|
|
3386
3377
|
return defaultValue;
|
|
3387
3378
|
}
|
|
3388
3379
|
}
|
|
@@ -3422,7 +3413,7 @@ function isNode(node) {
|
|
|
3422
3413
|
}
|
|
3423
3414
|
const hasAnchor = (node) => (isScalar(node) || isCollection(node)) && !!node.anchor;
|
|
3424
3415
|
|
|
3425
|
-
function _optionalChain$
|
|
3416
|
+
function _optionalChain$o(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; }
|
|
3426
3417
|
const BREAK = Symbol('break visit');
|
|
3427
3418
|
const SKIP = Symbol('skip children');
|
|
3428
3419
|
const REMOVE = Symbol('remove node');
|
|
@@ -3535,15 +3526,15 @@ function callVisitor(key, node, visitor, path) {
|
|
|
3535
3526
|
if (typeof visitor === 'function')
|
|
3536
3527
|
return visitor(key, node, path);
|
|
3537
3528
|
if (isMap(node))
|
|
3538
|
-
return _optionalChain$
|
|
3529
|
+
return _optionalChain$o([visitor, 'access', _ => _.Map, 'optionalCall', _2 => _2(key, node, path)]);
|
|
3539
3530
|
if (isSeq(node))
|
|
3540
|
-
return _optionalChain$
|
|
3531
|
+
return _optionalChain$o([visitor, 'access', _3 => _3.Seq, 'optionalCall', _4 => _4(key, node, path)]);
|
|
3541
3532
|
if (isPair(node))
|
|
3542
|
-
return _optionalChain$
|
|
3533
|
+
return _optionalChain$o([visitor, 'access', _5 => _5.Pair, 'optionalCall', _6 => _6(key, node, path)]);
|
|
3543
3534
|
if (isScalar(node))
|
|
3544
|
-
return _optionalChain$
|
|
3535
|
+
return _optionalChain$o([visitor, 'access', _7 => _7.Scalar, 'optionalCall', _8 => _8(key, node, path)]);
|
|
3545
3536
|
if (isAlias(node))
|
|
3546
|
-
return _optionalChain$
|
|
3537
|
+
return _optionalChain$o([visitor, 'access', _9 => _9.Alias, 'optionalCall', _10 => _10(key, node, path)]);
|
|
3547
3538
|
return undefined;
|
|
3548
3539
|
}
|
|
3549
3540
|
function replaceNode(key, path, node) {
|
|
@@ -3634,7 +3625,7 @@ function applyReviver(reviver, obj, key, val) {
|
|
|
3634
3625
|
return reviver.call(obj, key, val);
|
|
3635
3626
|
}
|
|
3636
3627
|
|
|
3637
|
-
function _optionalChain$
|
|
3628
|
+
function _optionalChain$n(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; }
|
|
3638
3629
|
/**
|
|
3639
3630
|
* Recursively convert any node or its contents to native JavaScript
|
|
3640
3631
|
*
|
|
@@ -3664,7 +3655,7 @@ function toJS(value, arg, ctx) {
|
|
|
3664
3655
|
ctx.onCreate(res);
|
|
3665
3656
|
return res;
|
|
3666
3657
|
}
|
|
3667
|
-
if (typeof value === 'bigint' && !_optionalChain$
|
|
3658
|
+
if (typeof value === 'bigint' && !_optionalChain$n([ctx, 'optionalAccess', _ => _.keep]))
|
|
3668
3659
|
return Number(value);
|
|
3669
3660
|
return value;
|
|
3670
3661
|
}
|
|
@@ -3702,7 +3693,7 @@ class NodeBase {
|
|
|
3702
3693
|
}
|
|
3703
3694
|
}
|
|
3704
3695
|
|
|
3705
|
-
function _optionalChain$
|
|
3696
|
+
function _optionalChain$m(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; }
|
|
3706
3697
|
class Alias extends NodeBase {
|
|
3707
3698
|
constructor(source) {
|
|
3708
3699
|
super(ALIAS);
|
|
@@ -3718,10 +3709,10 @@ class Alias extends NodeBase {
|
|
|
3718
3709
|
* instance of the `source` anchor before this node.
|
|
3719
3710
|
*/
|
|
3720
3711
|
resolve(doc, ctx) {
|
|
3721
|
-
if (_optionalChain$
|
|
3712
|
+
if (_optionalChain$m([ctx, 'optionalAccess', _ => _.maxAliasCount]) === 0)
|
|
3722
3713
|
throw new ReferenceError('Alias resolution is disabled');
|
|
3723
3714
|
let nodes;
|
|
3724
|
-
if (_optionalChain$
|
|
3715
|
+
if (_optionalChain$m([ctx, 'optionalAccess', _2 => _2.aliasResolveCache])) {
|
|
3725
3716
|
nodes = ctx.aliasResolveCache;
|
|
3726
3717
|
}
|
|
3727
3718
|
else {
|
|
@@ -3760,7 +3751,7 @@ class Alias extends NodeBase {
|
|
|
3760
3751
|
data = anchors.get(source);
|
|
3761
3752
|
}
|
|
3762
3753
|
/* istanbul ignore if */
|
|
3763
|
-
if (_optionalChain$
|
|
3754
|
+
if (_optionalChain$m([data, 'optionalAccess', _3 => _3.res]) === undefined) {
|
|
3764
3755
|
const msg = 'This should not happen: Alias anchor was not resolved?';
|
|
3765
3756
|
throw new ReferenceError(msg);
|
|
3766
3757
|
}
|
|
@@ -3812,7 +3803,7 @@ function getAliasCount(doc, node, anchors) {
|
|
|
3812
3803
|
return 1;
|
|
3813
3804
|
}
|
|
3814
3805
|
|
|
3815
|
-
function _optionalChain$
|
|
3806
|
+
function _optionalChain$l(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; }
|
|
3816
3807
|
const isScalarValue = (value) => !value || (typeof value !== 'function' && typeof value !== 'object');
|
|
3817
3808
|
class Scalar extends NodeBase {
|
|
3818
3809
|
constructor(value) {
|
|
@@ -3820,7 +3811,7 @@ class Scalar extends NodeBase {
|
|
|
3820
3811
|
this.value = value;
|
|
3821
3812
|
}
|
|
3822
3813
|
toJSON(arg, ctx) {
|
|
3823
|
-
return _optionalChain$
|
|
3814
|
+
return _optionalChain$l([ctx, 'optionalAccess', _ => _.keep]) ? this.value : toJS(this.value, arg, ctx);
|
|
3824
3815
|
}
|
|
3825
3816
|
toString() {
|
|
3826
3817
|
return String(this.value);
|
|
@@ -3832,17 +3823,17 @@ Scalar.PLAIN = 'PLAIN';
|
|
|
3832
3823
|
Scalar.QUOTE_DOUBLE = 'QUOTE_DOUBLE';
|
|
3833
3824
|
Scalar.QUOTE_SINGLE = 'QUOTE_SINGLE';
|
|
3834
3825
|
|
|
3835
|
-
function _nullishCoalesce$
|
|
3826
|
+
function _nullishCoalesce$8(lhs, rhsFn) { if (lhs != null) { return lhs; } else { return rhsFn(); } } function _optionalChain$k(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; }
|
|
3836
3827
|
const defaultTagPrefix = 'tag:yaml.org,2002:';
|
|
3837
3828
|
function findTagObject(value, tagName, tags) {
|
|
3838
3829
|
if (tagName) {
|
|
3839
3830
|
const match = tags.filter(t => t.tag === tagName);
|
|
3840
|
-
const tagObj = _nullishCoalesce$
|
|
3831
|
+
const tagObj = _nullishCoalesce$8(match.find(t => !t.format), () => ( match[0]));
|
|
3841
3832
|
if (!tagObj)
|
|
3842
3833
|
throw new Error(`Tag ${tagName} not found`);
|
|
3843
3834
|
return tagObj;
|
|
3844
3835
|
}
|
|
3845
|
-
return tags.find(t => _optionalChain$
|
|
3836
|
+
return tags.find(t => _optionalChain$k([t, 'access', _ => _.identify, 'optionalCall', _2 => _2(value)]) && !t.format);
|
|
3846
3837
|
}
|
|
3847
3838
|
function createNode(value, tagName, ctx) {
|
|
3848
3839
|
if (isDocument(value))
|
|
@@ -3850,7 +3841,7 @@ function createNode(value, tagName, ctx) {
|
|
|
3850
3841
|
if (isNode(value))
|
|
3851
3842
|
return value;
|
|
3852
3843
|
if (isPair(value)) {
|
|
3853
|
-
const map = _optionalChain$
|
|
3844
|
+
const map = _optionalChain$k([ctx, 'access', _3 => _3.schema, 'access', _4 => _4[MAP], 'access', _5 => _5.createNode, 'optionalCall', _6 => _6(ctx.schema, null, ctx)]);
|
|
3854
3845
|
map.items.push(value);
|
|
3855
3846
|
return map;
|
|
3856
3847
|
}
|
|
@@ -3869,7 +3860,7 @@ function createNode(value, tagName, ctx) {
|
|
|
3869
3860
|
if (aliasDuplicateObjects && value && typeof value === 'object') {
|
|
3870
3861
|
ref = sourceObjects.get(value);
|
|
3871
3862
|
if (ref) {
|
|
3872
|
-
_nullishCoalesce$
|
|
3863
|
+
_nullishCoalesce$8(ref.anchor, () => ( (ref.anchor = onAnchor(value))));
|
|
3873
3864
|
return new Alias(ref.anchor);
|
|
3874
3865
|
}
|
|
3875
3866
|
else {
|
|
@@ -3877,7 +3868,7 @@ function createNode(value, tagName, ctx) {
|
|
|
3877
3868
|
sourceObjects.set(value, ref);
|
|
3878
3869
|
}
|
|
3879
3870
|
}
|
|
3880
|
-
if (_optionalChain$
|
|
3871
|
+
if (_optionalChain$k([tagName, 'optionalAccess', _7 => _7.startsWith, 'call', _8 => _8('!!')]))
|
|
3881
3872
|
tagName = defaultTagPrefix + tagName.slice(2);
|
|
3882
3873
|
let tagObj = findTagObject(value, tagName, schema.tags);
|
|
3883
3874
|
if (!tagObj) {
|
|
@@ -3902,9 +3893,9 @@ function createNode(value, tagName, ctx) {
|
|
|
3902
3893
|
onTagObj(tagObj);
|
|
3903
3894
|
delete ctx.onTagObj;
|
|
3904
3895
|
}
|
|
3905
|
-
const node = _optionalChain$
|
|
3896
|
+
const node = _optionalChain$k([tagObj, 'optionalAccess', _9 => _9.createNode])
|
|
3906
3897
|
? tagObj.createNode(ctx.schema, value, ctx)
|
|
3907
|
-
: typeof _optionalChain$
|
|
3898
|
+
: typeof _optionalChain$k([tagObj, 'optionalAccess', _10 => _10.nodeClass, 'optionalAccess', _11 => _11.from]) === 'function'
|
|
3908
3899
|
? tagObj.nodeClass.from(ctx.schema, value, ctx)
|
|
3909
3900
|
: new Scalar(value);
|
|
3910
3901
|
if (tagName)
|
|
@@ -4222,7 +4213,7 @@ function consumeMoreIndentedLines(text, i, indent) {
|
|
|
4222
4213
|
return end;
|
|
4223
4214
|
}
|
|
4224
4215
|
|
|
4225
|
-
function _optionalChain$
|
|
4216
|
+
function _optionalChain$j(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; }
|
|
4226
4217
|
const getFoldOptions = (ctx, isBlock) => ({
|
|
4227
4218
|
indentAtStart: isBlock ? ctx.indent.length : ctx.indentAtStart,
|
|
4228
4219
|
lineWidth: ctx.options.lineWidth,
|
|
@@ -4507,9 +4498,9 @@ function plainString(item, ctx, onComment, onChompKeep) {
|
|
|
4507
4498
|
// booleans get parsed with those types in v1.2 (e.g. '42', 'true' & '0.9e-3'),
|
|
4508
4499
|
// and others in v1.1.
|
|
4509
4500
|
if (actualString) {
|
|
4510
|
-
const test = (tag) => tag.default && tag.tag !== 'tag:yaml.org,2002:str' && _optionalChain$
|
|
4501
|
+
const test = (tag) => tag.default && tag.tag !== 'tag:yaml.org,2002:str' && _optionalChain$j([tag, 'access', _ => _.test, 'optionalAccess', _2 => _2.test, 'call', _3 => _3(str)]);
|
|
4511
4502
|
const { compat, tags } = ctx.doc.schema;
|
|
4512
|
-
if (tags.some(test) || _optionalChain$
|
|
4503
|
+
if (tags.some(test) || _optionalChain$j([compat, 'optionalAccess', _4 => _4.some, 'call', _5 => _5(test)]))
|
|
4513
4504
|
return quotedString(value, ctx);
|
|
4514
4505
|
}
|
|
4515
4506
|
return implicitKey
|
|
@@ -4555,7 +4546,7 @@ function stringifyString(item, ctx, onComment, onChompKeep) {
|
|
|
4555
4546
|
return res;
|
|
4556
4547
|
}
|
|
4557
4548
|
|
|
4558
|
-
function _nullishCoalesce$
|
|
4549
|
+
function _nullishCoalesce$7(lhs, rhsFn) { if (lhs != null) { return lhs; } else { return rhsFn(); } } function _optionalChain$i(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; }
|
|
4559
4550
|
function createStringifyContext(doc, options) {
|
|
4560
4551
|
const opt = Object.assign({
|
|
4561
4552
|
blockQuote: true,
|
|
@@ -4602,27 +4593,27 @@ function getTagObject(tags, item) {
|
|
|
4602
4593
|
if (item.tag) {
|
|
4603
4594
|
const match = tags.filter(t => t.tag === item.tag);
|
|
4604
4595
|
if (match.length > 0)
|
|
4605
|
-
return _nullishCoalesce$
|
|
4596
|
+
return _nullishCoalesce$7(match.find(t => t.format === item.format), () => ( match[0]));
|
|
4606
4597
|
}
|
|
4607
4598
|
let tagObj = undefined;
|
|
4608
4599
|
let obj;
|
|
4609
4600
|
if (isScalar(item)) {
|
|
4610
4601
|
obj = item.value;
|
|
4611
|
-
let match = tags.filter(t => _optionalChain$
|
|
4602
|
+
let match = tags.filter(t => _optionalChain$i([t, 'access', _ => _.identify, 'optionalCall', _2 => _2(obj)]));
|
|
4612
4603
|
if (match.length > 1) {
|
|
4613
4604
|
const testMatch = match.filter(t => t.test);
|
|
4614
4605
|
if (testMatch.length > 0)
|
|
4615
4606
|
match = testMatch;
|
|
4616
4607
|
}
|
|
4617
4608
|
tagObj =
|
|
4618
|
-
_nullishCoalesce$
|
|
4609
|
+
_nullishCoalesce$7(match.find(t => t.format === item.format), () => ( match.find(t => !t.format)));
|
|
4619
4610
|
}
|
|
4620
4611
|
else {
|
|
4621
4612
|
obj = item;
|
|
4622
4613
|
tagObj = tags.find(t => t.nodeClass && obj instanceof t.nodeClass);
|
|
4623
4614
|
}
|
|
4624
4615
|
if (!tagObj) {
|
|
4625
|
-
const name = _nullishCoalesce$
|
|
4616
|
+
const name = _nullishCoalesce$7(_optionalChain$i([obj, 'optionalAccess', _3 => _3.constructor, 'optionalAccess', _4 => _4.name]), () => ( (obj === null ? 'null' : typeof obj)));
|
|
4626
4617
|
throw new Error(`Tag not resolved for ${name} value`);
|
|
4627
4618
|
}
|
|
4628
4619
|
return tagObj;
|
|
@@ -4637,7 +4628,7 @@ function stringifyProps(node, tagObj, { anchors, doc }) {
|
|
|
4637
4628
|
anchors.add(anchor);
|
|
4638
4629
|
props.push(`&${anchor}`);
|
|
4639
4630
|
}
|
|
4640
|
-
const tag = _nullishCoalesce$
|
|
4631
|
+
const tag = _nullishCoalesce$7(node.tag, () => ( (tagObj.default ? null : tagObj.tag)));
|
|
4641
4632
|
if (tag)
|
|
4642
4633
|
props.push(doc.directives.tagString(tag));
|
|
4643
4634
|
return props.join(' ');
|
|
@@ -4648,7 +4639,7 @@ function stringify(item, ctx, onComment, onChompKeep) {
|
|
|
4648
4639
|
if (isAlias(item)) {
|
|
4649
4640
|
if (ctx.doc.directives)
|
|
4650
4641
|
return item.toString(ctx);
|
|
4651
|
-
if (_optionalChain$
|
|
4642
|
+
if (_optionalChain$i([ctx, 'access', _5 => _5.resolvedAliases, 'optionalAccess', _6 => _6.has, 'call', _7 => _7(item)])) {
|
|
4652
4643
|
throw new TypeError(`Cannot stringify circular structure without alias nodes`);
|
|
4653
4644
|
}
|
|
4654
4645
|
else {
|
|
@@ -4663,10 +4654,10 @@ function stringify(item, ctx, onComment, onChompKeep) {
|
|
|
4663
4654
|
const node = isNode(item)
|
|
4664
4655
|
? item
|
|
4665
4656
|
: ctx.doc.createNode(item, { onTagObj: o => (tagObj = o) });
|
|
4666
|
-
_nullishCoalesce$
|
|
4657
|
+
_nullishCoalesce$7(tagObj, () => ( (tagObj = getTagObject(ctx.doc.schema.tags, node))));
|
|
4667
4658
|
const props = stringifyProps(node, tagObj, ctx);
|
|
4668
4659
|
if (props.length > 0)
|
|
4669
|
-
ctx.indentAtStart = (_nullishCoalesce$
|
|
4660
|
+
ctx.indentAtStart = (_nullishCoalesce$7(ctx.indentAtStart, () => ( 0))) + props.length + 1;
|
|
4670
4661
|
const str = typeof tagObj.stringify === 'function'
|
|
4671
4662
|
? tagObj.stringify(node, ctx, onComment, onChompKeep)
|
|
4672
4663
|
: isScalar(node)
|
|
@@ -4679,7 +4670,7 @@ function stringify(item, ctx, onComment, onChompKeep) {
|
|
|
4679
4670
|
: `${props}\n${ctx.indent}${str}`;
|
|
4680
4671
|
}
|
|
4681
4672
|
|
|
4682
|
-
function _nullishCoalesce$
|
|
4673
|
+
function _nullishCoalesce$6(lhs, rhsFn) { if (lhs != null) { return lhs; } else { return rhsFn(); } }
|
|
4683
4674
|
function stringifyPair({ key, value }, ctx, onComment, onChompKeep) {
|
|
4684
4675
|
const { allNullValues, doc, indent, indentStep, options: { commentString, indentSeq, simpleKeys } } = ctx;
|
|
4685
4676
|
let keyComment = (isNode(key) && key.comment) || null;
|
|
@@ -4789,7 +4780,7 @@ function stringifyPair({ key, value }, ctx, onComment, onChompKeep) {
|
|
|
4789
4780
|
const vs0 = valueStr[0];
|
|
4790
4781
|
const nl0 = valueStr.indexOf('\n');
|
|
4791
4782
|
const hasNewline = nl0 !== -1;
|
|
4792
|
-
const flow = _nullishCoalesce$
|
|
4783
|
+
const flow = _nullishCoalesce$6(_nullishCoalesce$6(ctx.inFlow, () => ( value.flow)), () => ( value.items.length === 0));
|
|
4793
4784
|
if (hasNewline || !flow) {
|
|
4794
4785
|
let hasPropsLine = false;
|
|
4795
4786
|
if (hasNewline && (vs0 === '&' || vs0 === '!')) {
|
|
@@ -4830,7 +4821,7 @@ function warn(logLevel, warning) {
|
|
|
4830
4821
|
}
|
|
4831
4822
|
}
|
|
4832
4823
|
|
|
4833
|
-
function _optionalChain$
|
|
4824
|
+
function _optionalChain$h(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; }
|
|
4834
4825
|
// If the value associated with a merge key is a single mapping node, each of
|
|
4835
4826
|
// its key/value pairs is inserted into the current mapping, unless the key
|
|
4836
4827
|
// already exists in it. If the value associated with the merge key is a
|
|
@@ -4854,7 +4845,7 @@ const isMergeKey = (ctx, key) => (merge.identify(key) ||
|
|
|
4854
4845
|
(isScalar(key) &&
|
|
4855
4846
|
(!key.type || key.type === Scalar.PLAIN) &&
|
|
4856
4847
|
merge.identify(key.value))) &&
|
|
4857
|
-
_optionalChain$
|
|
4848
|
+
_optionalChain$h([ctx, 'optionalAccess', _ => _.doc, 'access', _2 => _2.schema, 'access', _3 => _3.tags, 'access', _4 => _4.some, 'call', _5 => _5(tag => tag.tag === merge.tag && tag.default)]);
|
|
4858
4849
|
function addMergeToJSMap(ctx, map, value) {
|
|
4859
4850
|
const source = resolveAliasValue(ctx, value);
|
|
4860
4851
|
if (isSeq(source))
|
|
@@ -4894,7 +4885,7 @@ function resolveAliasValue(ctx, value) {
|
|
|
4894
4885
|
return ctx && isAlias(value) ? value.resolve(ctx.doc, ctx) : value;
|
|
4895
4886
|
}
|
|
4896
4887
|
|
|
4897
|
-
function _optionalChain$
|
|
4888
|
+
function _optionalChain$g(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; }
|
|
4898
4889
|
function addPairToJSMap(ctx, map, { key, value }) {
|
|
4899
4890
|
if (isNode(key) && key.addToJSMap)
|
|
4900
4891
|
key.addToJSMap(ctx, map, value);
|
|
@@ -4931,7 +4922,7 @@ function stringifyKey(key, jsKey, ctx) {
|
|
|
4931
4922
|
// eslint-disable-next-line @typescript-eslint/no-base-to-string
|
|
4932
4923
|
if (typeof jsKey !== 'object')
|
|
4933
4924
|
return String(jsKey);
|
|
4934
|
-
if (isNode(key) && _optionalChain$
|
|
4925
|
+
if (isNode(key) && _optionalChain$g([ctx, 'optionalAccess', _ => _.doc])) {
|
|
4935
4926
|
const strCtx = createStringifyContext(ctx.doc, {});
|
|
4936
4927
|
strCtx.anchors = new Set();
|
|
4937
4928
|
for (const node of ctx.anchors.keys())
|
|
@@ -4951,7 +4942,7 @@ function stringifyKey(key, jsKey, ctx) {
|
|
|
4951
4942
|
return JSON.stringify(jsKey);
|
|
4952
4943
|
}
|
|
4953
4944
|
|
|
4954
|
-
function _optionalChain$
|
|
4945
|
+
function _optionalChain$f(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; }
|
|
4955
4946
|
function createPair(key, value, ctx) {
|
|
4956
4947
|
const k = createNode(key, undefined, ctx);
|
|
4957
4948
|
const v = createNode(value, undefined, ctx);
|
|
@@ -4972,19 +4963,19 @@ class Pair {
|
|
|
4972
4963
|
return new Pair(key, value);
|
|
4973
4964
|
}
|
|
4974
4965
|
toJSON(_, ctx) {
|
|
4975
|
-
const pair = _optionalChain$
|
|
4966
|
+
const pair = _optionalChain$f([ctx, 'optionalAccess', _2 => _2.mapAsMap]) ? new Map() : {};
|
|
4976
4967
|
return addPairToJSMap(ctx, pair, this);
|
|
4977
4968
|
}
|
|
4978
4969
|
toString(ctx, onComment, onChompKeep) {
|
|
4979
|
-
return _optionalChain$
|
|
4970
|
+
return _optionalChain$f([ctx, 'optionalAccess', _3 => _3.doc])
|
|
4980
4971
|
? stringifyPair(this, ctx, onComment, onChompKeep)
|
|
4981
4972
|
: JSON.stringify(this);
|
|
4982
4973
|
}
|
|
4983
4974
|
}
|
|
4984
4975
|
|
|
4985
|
-
function _nullishCoalesce$
|
|
4976
|
+
function _nullishCoalesce$5(lhs, rhsFn) { if (lhs != null) { return lhs; } else { return rhsFn(); } } function _optionalChain$e(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; }
|
|
4986
4977
|
function stringifyCollection(collection, ctx, options) {
|
|
4987
|
-
const flow = _nullishCoalesce$
|
|
4978
|
+
const flow = _nullishCoalesce$5(ctx.inFlow, () => ( collection.flow));
|
|
4988
4979
|
const stringify = flow ? stringifyFlowCollection : stringifyBlockCollection;
|
|
4989
4980
|
return stringify(collection, ctx, options);
|
|
4990
4981
|
}
|
|
@@ -5076,7 +5067,7 @@ function stringifyFlowCollection({ items }, ctx, { flowChars, itemIndent }) {
|
|
|
5076
5067
|
if (iv.commentBefore)
|
|
5077
5068
|
reqNewline = true;
|
|
5078
5069
|
}
|
|
5079
|
-
else if (item.value == null && _optionalChain$
|
|
5070
|
+
else if (item.value == null && _optionalChain$e([ik, 'optionalAccess', _ => _.comment])) {
|
|
5080
5071
|
comment = ik.comment;
|
|
5081
5072
|
}
|
|
5082
5073
|
}
|
|
@@ -5131,7 +5122,7 @@ function addCommentBefore({ indent, options: { commentString } }, lines, comment
|
|
|
5131
5122
|
}
|
|
5132
5123
|
}
|
|
5133
5124
|
|
|
5134
|
-
function _nullishCoalesce$
|
|
5125
|
+
function _nullishCoalesce$4(lhs, rhsFn) { if (lhs != null) { return lhs; } else { return rhsFn(); } } function _optionalChain$d(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; }
|
|
5135
5126
|
function findPair(items, key) {
|
|
5136
5127
|
const k = isScalar(key) ? key.value : key;
|
|
5137
5128
|
for (const it of items) {
|
|
@@ -5192,12 +5183,12 @@ class YAMLMap extends Collection {
|
|
|
5192
5183
|
_pair = pair;
|
|
5193
5184
|
else if (!pair || typeof pair !== 'object' || !('key' in pair)) {
|
|
5194
5185
|
// In TypeScript, this never happens.
|
|
5195
|
-
_pair = new Pair(pair, _optionalChain$
|
|
5186
|
+
_pair = new Pair(pair, _optionalChain$d([pair, 'optionalAccess', _2 => _2.value]));
|
|
5196
5187
|
}
|
|
5197
5188
|
else
|
|
5198
5189
|
_pair = new Pair(pair.key, pair.value);
|
|
5199
5190
|
const prev = findPair(this.items, _pair.key);
|
|
5200
|
-
const sortEntries = _optionalChain$
|
|
5191
|
+
const sortEntries = _optionalChain$d([this, 'access', _3 => _3.schema, 'optionalAccess', _4 => _4.sortMapEntries]);
|
|
5201
5192
|
if (prev) {
|
|
5202
5193
|
if (!overwrite)
|
|
5203
5194
|
throw new Error(`Key ${_pair.key} already set`);
|
|
@@ -5227,8 +5218,8 @@ class YAMLMap extends Collection {
|
|
|
5227
5218
|
}
|
|
5228
5219
|
get(key, keepScalar) {
|
|
5229
5220
|
const it = findPair(this.items, key);
|
|
5230
|
-
const node = _optionalChain$
|
|
5231
|
-
return _nullishCoalesce$
|
|
5221
|
+
const node = _optionalChain$d([it, 'optionalAccess', _5 => _5.value]);
|
|
5222
|
+
return _nullishCoalesce$4((!keepScalar && isScalar(node) ? node.value : node), () => ( undefined));
|
|
5232
5223
|
}
|
|
5233
5224
|
has(key) {
|
|
5234
5225
|
return !!findPair(this.items, key);
|
|
@@ -5242,8 +5233,8 @@ class YAMLMap extends Collection {
|
|
|
5242
5233
|
* @returns Instance of Type, Map, or Object
|
|
5243
5234
|
*/
|
|
5244
5235
|
toJSON(_, ctx, Type) {
|
|
5245
|
-
const map = Type ? new Type() : _optionalChain$
|
|
5246
|
-
if (_optionalChain$
|
|
5236
|
+
const map = Type ? new Type() : _optionalChain$d([ctx, 'optionalAccess', _6 => _6.mapAsMap]) ? new Map() : {};
|
|
5237
|
+
if (_optionalChain$d([ctx, 'optionalAccess', _7 => _7.onCreate]))
|
|
5247
5238
|
ctx.onCreate(map);
|
|
5248
5239
|
for (const item of this.items)
|
|
5249
5240
|
addPairToJSMap(ctx, map, item);
|
|
@@ -5268,7 +5259,7 @@ class YAMLMap extends Collection {
|
|
|
5268
5259
|
}
|
|
5269
5260
|
}
|
|
5270
5261
|
|
|
5271
|
-
function _optionalChain$
|
|
5262
|
+
function _optionalChain$c(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; }
|
|
5272
5263
|
class YAMLSeq extends Collection {
|
|
5273
5264
|
static get tagName() {
|
|
5274
5265
|
return 'tag:yaml.org,2002:seq';
|
|
@@ -5331,7 +5322,7 @@ class YAMLSeq extends Collection {
|
|
|
5331
5322
|
}
|
|
5332
5323
|
toJSON(_, ctx) {
|
|
5333
5324
|
const seq = [];
|
|
5334
|
-
if (_optionalChain$
|
|
5325
|
+
if (_optionalChain$c([ctx, 'optionalAccess', _2 => _2.onCreate]))
|
|
5335
5326
|
ctx.onCreate(seq);
|
|
5336
5327
|
let i = 0;
|
|
5337
5328
|
for (const item of this.items)
|
|
@@ -5410,7 +5401,7 @@ function createPairs(schema, iterable, ctx) {
|
|
|
5410
5401
|
return pairs;
|
|
5411
5402
|
}
|
|
5412
5403
|
|
|
5413
|
-
function _optionalChain$
|
|
5404
|
+
function _optionalChain$b(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; }
|
|
5414
5405
|
class YAMLOMap extends YAMLSeq {
|
|
5415
5406
|
constructor() {
|
|
5416
5407
|
super();
|
|
@@ -5429,7 +5420,7 @@ class YAMLOMap extends YAMLSeq {
|
|
|
5429
5420
|
if (!ctx)
|
|
5430
5421
|
return super.toJSON(_);
|
|
5431
5422
|
const map = new Map();
|
|
5432
|
-
if (_optionalChain$
|
|
5423
|
+
if (_optionalChain$b([ctx, 'optionalAccess', _2 => _2.onCreate]))
|
|
5433
5424
|
ctx.onCreate(map);
|
|
5434
5425
|
for (const pair of this.items) {
|
|
5435
5426
|
let key, value;
|
|
@@ -5547,7 +5538,7 @@ const isDirExists = async (file) => {
|
|
|
5547
5538
|
}
|
|
5548
5539
|
};
|
|
5549
5540
|
|
|
5550
|
-
function _optionalChain$
|
|
5541
|
+
function _optionalChain$a(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; }// ABOUTME: Project type detection utility
|
|
5551
5542
|
|
|
5552
5543
|
/**
|
|
5553
5544
|
* 支持的项目类型枚举
|
|
@@ -5649,7 +5640,7 @@ const collectProjectInfo = async (
|
|
|
5649
5640
|
}
|
|
5650
5641
|
|
|
5651
5642
|
const scripts = Object.entries(
|
|
5652
|
-
(_optionalChain$
|
|
5643
|
+
(_optionalChain$a([packageJson, 'optionalAccess', _ => _.scripts]) ) || {},
|
|
5653
5644
|
).reduce((acc, [name, script]) => {
|
|
5654
5645
|
if (typeof script === 'string') {
|
|
5655
5646
|
acc[name] = script;
|
|
@@ -5803,7 +5794,7 @@ const detectProjectType = async (
|
|
|
5803
5794
|
};
|
|
5804
5795
|
};
|
|
5805
5796
|
|
|
5806
|
-
function _optionalChain$
|
|
5797
|
+
function _optionalChain$9(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; }
|
|
5807
5798
|
|
|
5808
5799
|
|
|
5809
5800
|
/**
|
|
@@ -5815,7 +5806,7 @@ function _optionalChain$l(ops) { let lastAccessLHS = undefined; let value = ops[
|
|
|
5815
5806
|
const parseConfigContent = (content) => {
|
|
5816
5807
|
// 1. 尝试 TOML 格式 (默认)
|
|
5817
5808
|
try {
|
|
5818
|
-
const config =
|
|
5809
|
+
const config = toml.parse(content);
|
|
5819
5810
|
return config ;
|
|
5820
5811
|
} catch (error) {
|
|
5821
5812
|
// TOML 解析失败,继续尝试其他格式
|
|
@@ -5849,7 +5840,7 @@ const parseConfigContent = (content) => {
|
|
|
5849
5840
|
*/
|
|
5850
5841
|
const parseTomlConfigContent = (content) => {
|
|
5851
5842
|
try {
|
|
5852
|
-
return
|
|
5843
|
+
return toml.parse(content) ;
|
|
5853
5844
|
} catch (e) {
|
|
5854
5845
|
return null;
|
|
5855
5846
|
}
|
|
@@ -5930,7 +5921,7 @@ const saveTomlCozeConfig = async (
|
|
|
5930
5921
|
projectPath,
|
|
5931
5922
|
`.coze.tmp-${process.pid}-${Date.now()}`,
|
|
5932
5923
|
);
|
|
5933
|
-
const content =
|
|
5924
|
+
const content = toml.stringify(config );
|
|
5934
5925
|
|
|
5935
5926
|
try {
|
|
5936
5927
|
await fs$1.writeFile(tempCozeConfigPath, content, 'utf-8');
|
|
@@ -5970,13 +5961,13 @@ const getDefaultCommandConfig = (
|
|
|
5970
5961
|
) => {
|
|
5971
5962
|
switch (commandName) {
|
|
5972
5963
|
case 'dev':
|
|
5973
|
-
return _optionalChain$
|
|
5964
|
+
return _optionalChain$9([config, 'access', _ => _.dev, 'optionalAccess', _2 => _2.run]);
|
|
5974
5965
|
case 'build':
|
|
5975
|
-
return _optionalChain$
|
|
5966
|
+
return _optionalChain$9([config, 'access', _3 => _3.deploy, 'optionalAccess', _4 => _4.build]);
|
|
5976
5967
|
case 'start':
|
|
5977
|
-
return _optionalChain$
|
|
5968
|
+
return _optionalChain$9([config, 'access', _5 => _5.deploy, 'optionalAccess', _6 => _6.run]);
|
|
5978
5969
|
case 'validate':
|
|
5979
|
-
return _optionalChain$
|
|
5970
|
+
return _optionalChain$9([config, 'access', _7 => _7.dev, 'optionalAccess', _8 => _8.validate]);
|
|
5980
5971
|
default:
|
|
5981
5972
|
throw new Error(`Unknown command: ${commandName}`);
|
|
5982
5973
|
}
|
|
@@ -5988,13 +5979,13 @@ const getWindowsCommandConfig = (
|
|
|
5988
5979
|
) => {
|
|
5989
5980
|
switch (commandName) {
|
|
5990
5981
|
case 'dev':
|
|
5991
|
-
return _optionalChain$
|
|
5982
|
+
return _optionalChain$9([config, 'access', _9 => _9.dev, 'optionalAccess', _10 => _10.run_win]);
|
|
5992
5983
|
case 'build':
|
|
5993
|
-
return _optionalChain$
|
|
5984
|
+
return _optionalChain$9([config, 'access', _11 => _11.deploy, 'optionalAccess', _12 => _12.build_win]);
|
|
5994
5985
|
case 'start':
|
|
5995
|
-
return _optionalChain$
|
|
5986
|
+
return _optionalChain$9([config, 'access', _13 => _13.deploy, 'optionalAccess', _14 => _14.run_win]);
|
|
5996
5987
|
case 'validate':
|
|
5997
|
-
return _optionalChain$
|
|
5988
|
+
return _optionalChain$9([config, 'access', _15 => _15.dev, 'optionalAccess', _16 => _16.validate_win]);
|
|
5998
5989
|
default:
|
|
5999
5990
|
throw new Error(`Unknown command: ${commandName}`);
|
|
6000
5991
|
}
|
|
@@ -6019,7 +6010,7 @@ const getCommandConfig = (
|
|
|
6019
6010
|
platform === 'win32'
|
|
6020
6011
|
? getWindowsCommandConfig(config, commandName)
|
|
6021
6012
|
: undefined;
|
|
6022
|
-
const commandConfig = _optionalChain$
|
|
6013
|
+
const commandConfig = _optionalChain$9([windowsCommandConfig, 'optionalAccess', _17 => _17.length])
|
|
6023
6014
|
? windowsCommandConfig
|
|
6024
6015
|
: defaultCommandConfig;
|
|
6025
6016
|
|
|
@@ -6168,7 +6159,7 @@ const byFlag = (flag) => {
|
|
|
6168
6159
|
return predicate;
|
|
6169
6160
|
};
|
|
6170
6161
|
|
|
6171
|
-
function _optionalChain$
|
|
6162
|
+
function _optionalChain$8(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; }
|
|
6172
6163
|
|
|
6173
6164
|
|
|
6174
6165
|
|
|
@@ -6199,7 +6190,7 @@ echo "Validate passed!"
|
|
|
6199
6190
|
* @returns
|
|
6200
6191
|
*/
|
|
6201
6192
|
const isCozeValid$3 = (cozeConfig) => {
|
|
6202
|
-
if (_optionalChain$
|
|
6193
|
+
if (_optionalChain$8([cozeConfig, 'access', _ => _.dev, 'optionalAccess', _2 => _2.validate])) {
|
|
6203
6194
|
logger.info('[patch-expo-validate] NOT APPLY: dev.validate exists');
|
|
6204
6195
|
return false;
|
|
6205
6196
|
}
|
|
@@ -6344,7 +6335,7 @@ const patchExpoValidate = {
|
|
|
6344
6335
|
},
|
|
6345
6336
|
};
|
|
6346
6337
|
|
|
6347
|
-
function _optionalChain$
|
|
6338
|
+
function _optionalChain$7(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; }
|
|
6348
6339
|
|
|
6349
6340
|
|
|
6350
6341
|
|
|
@@ -6377,7 +6368,7 @@ echo "Validate passed!"
|
|
|
6377
6368
|
* @returns
|
|
6378
6369
|
*/
|
|
6379
6370
|
const isCozeValid$2 = (cozeConfig) => {
|
|
6380
|
-
if (_optionalChain$
|
|
6371
|
+
if (_optionalChain$7([cozeConfig, 'access', _ => _.dev, 'optionalAccess', _2 => _2.validate])) {
|
|
6381
6372
|
logger.info('[patch-nextjs-validate] NOT APPLY: dev.validate exists');
|
|
6382
6373
|
return false;
|
|
6383
6374
|
}
|
|
@@ -6525,7 +6516,7 @@ const patchNextjsValidate = {
|
|
|
6525
6516
|
},
|
|
6526
6517
|
};
|
|
6527
6518
|
|
|
6528
|
-
function _optionalChain$
|
|
6519
|
+
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; }
|
|
6529
6520
|
|
|
6530
6521
|
const PATCH_ID$5 = 'nextjs/validate-concurrently@0.0.30';
|
|
6531
6522
|
const PACKAGE_JSON_FILE$3 = 'package.json';
|
|
@@ -6558,7 +6549,7 @@ const readPackageJson = async (projectFolder) => {
|
|
|
6558
6549
|
};
|
|
6559
6550
|
|
|
6560
6551
|
const getTargetValidateScript = (packageJson) => {
|
|
6561
|
-
const validateScript = _optionalChain$
|
|
6552
|
+
const validateScript = _optionalChain$6([packageJson, 'access', _ => _.scripts, 'optionalAccess', _2 => _2.validate]);
|
|
6562
6553
|
if (typeof validateScript !== 'string') {
|
|
6563
6554
|
return null;
|
|
6564
6555
|
}
|
|
@@ -6575,7 +6566,7 @@ const getTargetValidateScript = (packageJson) => {
|
|
|
6575
6566
|
|
|
6576
6567
|
const canStackAfterNextjsValidatePatch = async (context, packageJson) => {
|
|
6577
6568
|
const scripts = packageJson.scripts || {};
|
|
6578
|
-
if (typeof scripts.validate !== 'undefined' || typeof scripts['ts-check'] !== 'string' || _optionalChain$
|
|
6569
|
+
if (typeof scripts.validate !== 'undefined' || typeof scripts['ts-check'] !== 'string' || _optionalChain$6([context, 'access', _3 => _3.cozeConfig, 'access', _4 => _4.dev, 'optionalAccess', _5 => _5.validate])) {
|
|
6579
6570
|
return false;
|
|
6580
6571
|
}
|
|
6581
6572
|
|
|
@@ -6644,7 +6635,7 @@ const patchNextjsValidateConcurrently = {
|
|
|
6644
6635
|
apply: patchPackageJson$2,
|
|
6645
6636
|
};
|
|
6646
6637
|
|
|
6647
|
-
function _optionalChain$
|
|
6638
|
+
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; }
|
|
6648
6639
|
|
|
6649
6640
|
|
|
6650
6641
|
|
|
@@ -6677,7 +6668,7 @@ echo "Validate passed!"
|
|
|
6677
6668
|
* @returns
|
|
6678
6669
|
*/
|
|
6679
6670
|
const isCozeValid$1 = (cozeConfig) => {
|
|
6680
|
-
if (_optionalChain$
|
|
6671
|
+
if (_optionalChain$5([cozeConfig, 'access', _ => _.dev, 'optionalAccess', _2 => _2.validate])) {
|
|
6681
6672
|
logger.info('[patch-vite-validate] NOT APPLY: dev.validate exists');
|
|
6682
6673
|
return false;
|
|
6683
6674
|
}
|
|
@@ -6822,7 +6813,7 @@ const patchViteValidate = {
|
|
|
6822
6813
|
},
|
|
6823
6814
|
};
|
|
6824
6815
|
|
|
6825
|
-
function _optionalChain$
|
|
6816
|
+
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; }
|
|
6826
6817
|
|
|
6827
6818
|
|
|
6828
6819
|
|
|
@@ -6859,7 +6850,7 @@ echo "Validate passed!"
|
|
|
6859
6850
|
* @returns
|
|
6860
6851
|
*/
|
|
6861
6852
|
const isCozeValid = (cozeConfig) => {
|
|
6862
|
-
if (_optionalChain$
|
|
6853
|
+
if (_optionalChain$4([cozeConfig, 'access', _ => _.dev, 'optionalAccess', _2 => _2.validate])) {
|
|
6863
6854
|
logger.info('[patch-taro-validate] NOT APPLY: dev.validate exists');
|
|
6864
6855
|
return false;
|
|
6865
6856
|
}
|
|
@@ -7008,7 +6999,7 @@ const patchTaroValidate = {
|
|
|
7008
6999
|
},
|
|
7009
7000
|
};
|
|
7010
7001
|
|
|
7011
|
-
function _optionalChain$
|
|
7002
|
+
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; }
|
|
7012
7003
|
const PATCH_ID$2 = 'taro/update-pack-script-for-tt-build@0.0.13';
|
|
7013
7004
|
const PACKAGE_JSON_FILE = 'package.json';
|
|
7014
7005
|
const PACK_SCRIPT_FILE = '.cozeproj/scripts/pack.sh';
|
|
@@ -7087,12 +7078,12 @@ const readPackageScripts = async (
|
|
|
7087
7078
|
const packageJsonContent = await fs$1.readFile(packageJsonPath, 'utf-8');
|
|
7088
7079
|
const packageJson = safeJsonParse(packageJsonContent, null);
|
|
7089
7080
|
|
|
7090
|
-
return _optionalChain$
|
|
7081
|
+
return _optionalChain$3([packageJson, 'optionalAccess', _ => _.scripts]) || null;
|
|
7091
7082
|
};
|
|
7092
7083
|
|
|
7093
7084
|
const hasBuildTtScript = async (projectFolder) => {
|
|
7094
7085
|
const scripts = await readPackageScripts(projectFolder);
|
|
7095
|
-
return typeof _optionalChain$
|
|
7086
|
+
return typeof _optionalChain$3([scripts, 'optionalAccess', _2 => _2['build:tt']]) === 'string';
|
|
7096
7087
|
};
|
|
7097
7088
|
|
|
7098
7089
|
const hasLegacyPackScript = async (projectFolder) => {
|
|
@@ -7446,7 +7437,7 @@ const getTemplatePatches = (
|
|
|
7446
7437
|
) =>
|
|
7447
7438
|
patches.filter(patch => patch.template === template);
|
|
7448
7439
|
|
|
7449
|
-
function _nullishCoalesce$
|
|
7440
|
+
function _nullishCoalesce$3(lhs, rhsFn) { if (lhs != null) { return lhs; } else { return rhsFn(); } } 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; }
|
|
7450
7441
|
const DEFAULT_LEGACY_VERSION = 'legacy';
|
|
7451
7442
|
|
|
7452
7443
|
const loadFlagsWithFallback = async () => {
|
|
@@ -7552,7 +7543,7 @@ const getNextPatchState = (
|
|
|
7552
7543
|
|
|
7553
7544
|
) => ({
|
|
7554
7545
|
template,
|
|
7555
|
-
version: _optionalChain$
|
|
7546
|
+
version: _optionalChain$2([config, 'access', _ => _.project, 'optionalAccess', _2 => _2.version]) || DEFAULT_LEGACY_VERSION,
|
|
7556
7547
|
appliedPatches: [...appliedPatches, patchId],
|
|
7557
7548
|
});
|
|
7558
7549
|
|
|
@@ -7576,15 +7567,15 @@ const executePatch = async (
|
|
|
7576
7567
|
}
|
|
7577
7568
|
|
|
7578
7569
|
const template =
|
|
7579
|
-
_optionalChain$
|
|
7570
|
+
_optionalChain$2([config, 'access', _3 => _3.project, 'optionalAccess', _4 => _4.template]) || (await detectTemplateKey(projectFolder));
|
|
7580
7571
|
|
|
7581
7572
|
if (!template) {
|
|
7582
7573
|
logger.info('Patch skipped: template not detected');
|
|
7583
7574
|
return;
|
|
7584
7575
|
}
|
|
7585
7576
|
|
|
7586
|
-
const appliedPatches = [...(_optionalChain$
|
|
7587
|
-
const projectVersion = _optionalChain$
|
|
7577
|
+
const appliedPatches = [...(_optionalChain$2([config, 'access', _5 => _5.project, 'optionalAccess', _6 => _6.appliedPatches]) || [])];
|
|
7578
|
+
const projectVersion = _optionalChain$2([config, 'access', _7 => _7.project, 'optionalAccess', _8 => _8.version]);
|
|
7588
7579
|
const flags = await loadFlagsWithFallback();
|
|
7589
7580
|
|
|
7590
7581
|
const context = {
|
|
@@ -7629,7 +7620,7 @@ const executePatch = async (
|
|
|
7629
7620
|
|
|
7630
7621
|
if (options.dryRun) {
|
|
7631
7622
|
logger.info(`Detected template: ${template}`);
|
|
7632
|
-
logger.info(`Current version: ${_nullishCoalesce$
|
|
7623
|
+
logger.info(`Current version: ${_nullishCoalesce$3(projectVersion, () => ( DEFAULT_LEGACY_VERSION))}`);
|
|
7633
7624
|
logger.info(`Applied patches: ${appliedPatches.join(', ') || '(none)'}`);
|
|
7634
7625
|
logger.info('Matched patches:');
|
|
7635
7626
|
matchedPatches.forEach(patch => {
|
|
@@ -7670,7 +7661,7 @@ const executePatch = async (
|
|
|
7670
7661
|
}
|
|
7671
7662
|
};
|
|
7672
7663
|
|
|
7673
|
-
const registerCommand$
|
|
7664
|
+
const registerCommand$4 = program => {
|
|
7674
7665
|
program
|
|
7675
7666
|
.command('patch')
|
|
7676
7667
|
.description('Apply template patches for existing projects')
|
|
@@ -7687,14 +7678,14 @@ const registerCommand$5 = program => {
|
|
|
7687
7678
|
) => {
|
|
7688
7679
|
await executePatch({
|
|
7689
7680
|
directory,
|
|
7690
|
-
dryRun: _optionalChain$
|
|
7691
|
-
showFlags: _optionalChain$
|
|
7681
|
+
dryRun: _optionalChain$2([command, 'optionalAccess', _9 => _9.dryRun]),
|
|
7682
|
+
showFlags: _optionalChain$2([command, 'optionalAccess', _10 => _10.showFlags]),
|
|
7692
7683
|
});
|
|
7693
7684
|
},
|
|
7694
7685
|
);
|
|
7695
7686
|
};
|
|
7696
7687
|
|
|
7697
|
-
function _nullishCoalesce$
|
|
7688
|
+
function _nullishCoalesce$2(lhs, rhsFn) { if (lhs != null) { return lhs; } else { return rhsFn(); } } 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; }
|
|
7698
7689
|
const d$1 = debug('coze-init-cli:run');
|
|
7699
7690
|
|
|
7700
7691
|
/**
|
|
@@ -7825,12 +7816,12 @@ const executeRun = async (commandName, options = {}) => {
|
|
|
7825
7816
|
}
|
|
7826
7817
|
|
|
7827
7818
|
// 将输出同时写入控制台和日志文件
|
|
7828
|
-
_optionalChain$
|
|
7819
|
+
_optionalChain$1([childProcess, 'access', _ => _.stdout, 'optionalAccess', _2 => _2.on, 'call', _3 => _3('data', (data) => {
|
|
7829
7820
|
process.stdout.write(data);
|
|
7830
7821
|
logStream.write(data);
|
|
7831
7822
|
})]);
|
|
7832
7823
|
|
|
7833
|
-
_optionalChain$
|
|
7824
|
+
_optionalChain$1([childProcess, 'access', _4 => _4.stderr, 'optionalAccess', _5 => _5.on, 'call', _6 => _6('data', (data) => {
|
|
7834
7825
|
process.stderr.write(data);
|
|
7835
7826
|
logStream.write(data);
|
|
7836
7827
|
})]);
|
|
@@ -7843,7 +7834,7 @@ const executeRun = async (commandName, options = {}) => {
|
|
|
7843
7834
|
const buildDuration = Date.now() - buildStartTime;
|
|
7844
7835
|
|
|
7845
7836
|
if (code !== 0) {
|
|
7846
|
-
const errorMessage = `Command exited with code ${_nullishCoalesce$
|
|
7837
|
+
const errorMessage = `Command exited with code ${_nullishCoalesce$2(code, () => ( 'unknown'))}${signal ? ` and signal ${signal}` : ''}`;
|
|
7847
7838
|
logger.error(errorMessage);
|
|
7848
7839
|
logger.error(`Check log file for details: ${logFilePath}`);
|
|
7849
7840
|
|
|
@@ -7855,12 +7846,12 @@ const executeRun = async (commandName, options = {}) => {
|
|
|
7855
7846
|
categories: {
|
|
7856
7847
|
fixDuration: String(fixDuration),
|
|
7857
7848
|
buildDuration: String(buildDuration),
|
|
7858
|
-
exitCode: String(_nullishCoalesce$
|
|
7849
|
+
exitCode: String(_nullishCoalesce$2(code, () => ( 'unknown'))),
|
|
7859
7850
|
projectType,
|
|
7860
7851
|
},
|
|
7861
7852
|
errorContext: {
|
|
7862
|
-
exitCode: String(_nullishCoalesce$
|
|
7863
|
-
signal: _nullishCoalesce$
|
|
7853
|
+
exitCode: String(_nullishCoalesce$2(code, () => ( 'unknown'))),
|
|
7854
|
+
signal: _nullishCoalesce$2(signal, () => ( 'none')),
|
|
7864
7855
|
logFile: logFilePath,
|
|
7865
7856
|
projectType,
|
|
7866
7857
|
},
|
|
@@ -7936,7 +7927,7 @@ const executeRun = async (commandName, options = {}) => {
|
|
|
7936
7927
|
/**
|
|
7937
7928
|
* 注册 dev/build/start 命令到 program
|
|
7938
7929
|
*/
|
|
7939
|
-
const registerCommand$
|
|
7930
|
+
const registerCommand$3 = program => {
|
|
7940
7931
|
// dev 命令
|
|
7941
7932
|
program
|
|
7942
7933
|
.command('dev')
|
|
@@ -8774,7 +8765,7 @@ const scanRoutesOnce = async (
|
|
|
8774
8765
|
}
|
|
8775
8766
|
};
|
|
8776
8767
|
|
|
8777
|
-
function _optionalChain
|
|
8768
|
+
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
|
|
8778
8769
|
|
|
8779
8770
|
|
|
8780
8771
|
const log = debug('coze:routes');
|
|
@@ -8862,7 +8853,7 @@ const executeRoutes = async (
|
|
|
8862
8853
|
/**
|
|
8863
8854
|
* Register routes command to program
|
|
8864
8855
|
*/
|
|
8865
|
-
const registerCommand$
|
|
8856
|
+
const registerCommand$2 = program => {
|
|
8866
8857
|
program
|
|
8867
8858
|
.command('routes')
|
|
8868
8859
|
.description('Generate routes manifest for the current project')
|
|
@@ -8875,11 +8866,11 @@ const registerCommand$3 = program => {
|
|
|
8875
8866
|
'Output file path (defaults to ~/.coze/routes.json)',
|
|
8876
8867
|
)
|
|
8877
8868
|
.action(async (directory, options) => {
|
|
8878
|
-
await executeRoutes({ directory, output: _optionalChain
|
|
8869
|
+
await executeRoutes({ directory, output: _optionalChain([options, 'optionalAccess', _ => _.output]) });
|
|
8879
8870
|
});
|
|
8880
8871
|
};
|
|
8881
8872
|
|
|
8882
|
-
function _nullishCoalesce$
|
|
8873
|
+
function _nullishCoalesce$1(lhs, rhsFn) { if (lhs != null) { return lhs; } else { return rhsFn(); } }
|
|
8883
8874
|
|
|
8884
8875
|
|
|
8885
8876
|
const d = debug('coze-init-cli:check-bins');
|
|
@@ -8936,7 +8927,7 @@ const checkBins = async (cwd, fix) => {
|
|
|
8936
8927
|
|
|
8937
8928
|
const bins =
|
|
8938
8929
|
typeof depPkg.bin === 'string'
|
|
8939
|
-
? { [_nullishCoalesce$
|
|
8930
|
+
? { [_nullishCoalesce$1(depName.split('/').pop(), () => ( depName))]: depPkg.bin }
|
|
8940
8931
|
: depPkg.bin;
|
|
8941
8932
|
|
|
8942
8933
|
d('%s declares bins: %o', depName, Object.keys(bins));
|
|
@@ -8986,7 +8977,7 @@ const checkBins = async (cwd, fix) => {
|
|
|
8986
8977
|
d('pnpm i --force completed');
|
|
8987
8978
|
};
|
|
8988
8979
|
|
|
8989
|
-
const registerCommand$
|
|
8980
|
+
const registerCommand$1 = program => {
|
|
8990
8981
|
program
|
|
8991
8982
|
.command('check-bins')
|
|
8992
8983
|
.description(
|
|
@@ -9178,6 +9169,7 @@ const shouldRenderFile = (filePath) => {
|
|
|
9178
9169
|
'.prettierrc',
|
|
9179
9170
|
'.babelrc',
|
|
9180
9171
|
'.sh',
|
|
9172
|
+
'.ps1',
|
|
9181
9173
|
]);
|
|
9182
9174
|
|
|
9183
9175
|
const ext = path.extname(filePath).toLowerCase();
|
|
@@ -9880,7 +9872,7 @@ const execute = async (
|
|
|
9880
9872
|
};
|
|
9881
9873
|
};
|
|
9882
9874
|
|
|
9883
|
-
function _nullishCoalesce
|
|
9875
|
+
function _nullishCoalesce(lhs, rhsFn) { if (lhs != null) { return lhs; } else { return rhsFn(); } }
|
|
9884
9876
|
/**
|
|
9885
9877
|
* 运行 pnpm install
|
|
9886
9878
|
*/
|
|
@@ -10001,8 +9993,8 @@ const runDev = (projectPath) => {
|
|
|
10001
9993
|
// 获取当前 CLI 的可执行文件路径
|
|
10002
9994
|
// process.argv[0] 是 node,process.argv[1] 是 CLI 入口文件
|
|
10003
9995
|
// 二者在 CLI 运行时必然存在,兜底空串仅为满足类型收窄,运行时不会命中
|
|
10004
|
-
const nodeBin = _nullishCoalesce
|
|
10005
|
-
const cliPath = _nullishCoalesce
|
|
9996
|
+
const nodeBin = _nullishCoalesce(process.argv[0], () => ( ''));
|
|
9997
|
+
const cliPath = _nullishCoalesce(process.argv[1], () => ( ''));
|
|
10006
9998
|
|
|
10007
9999
|
try {
|
|
10008
10000
|
// 使用通用的后台执行函数启动开发服务器
|
|
@@ -10072,7 +10064,7 @@ const executeTemplateEngineStep = async ctx => {
|
|
|
10072
10064
|
templateName: ctx.templateName,
|
|
10073
10065
|
outputPath: ctx.outputPath,
|
|
10074
10066
|
command: ctx.command,
|
|
10075
|
-
force: _nullishCoalesce
|
|
10067
|
+
force: _nullishCoalesce(ctx.options.force, () => ( false)),
|
|
10076
10068
|
});
|
|
10077
10069
|
|
|
10078
10070
|
// 保存结果到上下文
|
|
@@ -10331,7 +10323,7 @@ const executeInit = async (
|
|
|
10331
10323
|
/**
|
|
10332
10324
|
* 注册 init 命令到 program
|
|
10333
10325
|
*/
|
|
10334
|
-
const registerCommand
|
|
10326
|
+
const registerCommand = program => {
|
|
10335
10327
|
program
|
|
10336
10328
|
.command('init')
|
|
10337
10329
|
.description('Initialize a new project from a template')
|
|
@@ -10349,3442 +10341,64 @@ const registerCommand$1 = program => {
|
|
|
10349
10341
|
.allowUnknownOption() // 允许透传参数
|
|
10350
10342
|
.action(async (directory, options, command) => {
|
|
10351
10343
|
// 位置参数优先级高于 --output 选项
|
|
10352
|
-
const outputPath = _nullishCoalesce
|
|
10344
|
+
const outputPath = _nullishCoalesce(directory, () => ( options.output));
|
|
10353
10345
|
// Always use force mode - overwrite existing files without conflict check
|
|
10354
10346
|
const force = true;
|
|
10355
10347
|
await executeInit({ ...options, output: outputPath, force }, command);
|
|
10356
10348
|
});
|
|
10357
10349
|
};
|
|
10358
10350
|
|
|
10359
|
-
const
|
|
10360
|
-
|
|
10361
|
-
|
|
10362
|
-
|
|
10363
|
-
|
|
10364
|
-
|
|
10365
|
-
|
|
10366
|
-
|
|
10367
|
-
let current = command;
|
|
10368
|
-
while (current) {
|
|
10369
|
-
if (deployCommands.has(current)) {
|
|
10370
|
-
return current;
|
|
10371
|
-
}
|
|
10372
|
-
current = current.parent;
|
|
10373
|
-
}
|
|
10374
|
-
throw new Error('Unable to resolve the coze-dev deploy command context.');
|
|
10375
|
-
};
|
|
10376
|
-
|
|
10377
|
-
class CliError extends Error {
|
|
10378
|
-
constructor(
|
|
10379
|
-
message,
|
|
10380
|
-
code = 'DEPLOY_CLI_ERROR',
|
|
10381
|
-
details,
|
|
10382
|
-
) {
|
|
10383
|
-
super(message);this.code = code;this.details = details; this.name = 'CliError';
|
|
10384
|
-
}
|
|
10385
|
-
}
|
|
10386
|
-
|
|
10387
|
-
const toErrorPayload = (error) => {
|
|
10388
|
-
if (error instanceof CliError) {
|
|
10389
|
-
return { code: error.code, message: error.message, details: error.details };
|
|
10390
|
-
}
|
|
10391
|
-
return {
|
|
10392
|
-
code: 'INTERNAL_ERROR',
|
|
10393
|
-
message: error instanceof Error ? error.message : String(error),
|
|
10394
|
-
};
|
|
10395
|
-
};
|
|
10396
|
-
|
|
10397
|
-
const APPLICATION_TYPES = new Set([
|
|
10398
|
-
'service',
|
|
10399
|
-
'pages',
|
|
10400
|
-
'mini_program',
|
|
10401
|
-
]);
|
|
10402
|
-
|
|
10403
|
-
const PAGES_SERVICE_TYPE = 3;
|
|
10404
|
-
|
|
10405
|
-
const inferApplicationTypeFromProjectType = (
|
|
10406
|
-
projectType,
|
|
10407
|
-
) => {
|
|
10408
|
-
switch (projectType) {
|
|
10409
|
-
case 'miniapp':
|
|
10410
|
-
case 'miniprogram':
|
|
10411
|
-
return 'mini_program';
|
|
10412
|
-
case undefined:
|
|
10413
|
-
case '':
|
|
10414
|
-
return undefined;
|
|
10415
|
-
default:
|
|
10416
|
-
return 'service';
|
|
10417
|
-
}
|
|
10418
|
-
};
|
|
10419
|
-
|
|
10420
|
-
const parseApplicationType = (
|
|
10421
|
-
value,
|
|
10422
|
-
) => {
|
|
10423
|
-
if (!value) {
|
|
10424
|
-
return undefined;
|
|
10425
|
-
}
|
|
10426
|
-
if (!APPLICATION_TYPES.has(value )) {
|
|
10427
|
-
throw new CliError(
|
|
10428
|
-
`Unsupported application type ${value}; expected service, pages, or mini_program.`,
|
|
10429
|
-
'INVALID_APPLICATION_TYPE',
|
|
10430
|
-
);
|
|
10431
|
-
}
|
|
10432
|
-
return value ;
|
|
10433
|
-
};
|
|
10434
|
-
|
|
10435
|
-
const withRequestedApplicationType = (
|
|
10436
|
-
config,
|
|
10437
|
-
requestedType,
|
|
10438
|
-
hasApplication = false,
|
|
10439
|
-
) => {
|
|
10440
|
-
if (!requestedType) {
|
|
10441
|
-
return config;
|
|
10442
|
-
}
|
|
10443
|
-
if (hasApplication && config.application_type !== requestedType) {
|
|
10444
|
-
throw new CliError(
|
|
10445
|
-
`Application type mismatch: the application is ${config.application_type}, but ${requestedType} was requested.`,
|
|
10446
|
-
'APPLICATION_TYPE_MISMATCH',
|
|
10447
|
-
);
|
|
10448
|
-
}
|
|
10449
|
-
if (requestedType !== 'pages') {
|
|
10450
|
-
if (config.application_type !== requestedType) {
|
|
10451
|
-
throw new CliError(
|
|
10452
|
-
`Application type mismatch: server resolved ${config.application_type}, but ${requestedType} was requested.`,
|
|
10453
|
-
'APPLICATION_TYPE_MISMATCH',
|
|
10454
|
-
);
|
|
10455
|
-
}
|
|
10456
|
-
return config;
|
|
10457
|
-
}
|
|
10458
|
-
return {
|
|
10459
|
-
...config,
|
|
10460
|
-
application_type: 'pages',
|
|
10461
|
-
deploy_config: {
|
|
10462
|
-
...config.deploy_config,
|
|
10463
|
-
service_type: PAGES_SERVICE_TYPE,
|
|
10464
|
-
computer_id: undefined,
|
|
10465
|
-
},
|
|
10466
|
-
};
|
|
10467
|
-
};
|
|
10468
|
-
|
|
10469
|
-
function _optionalChain$b(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; }
|
|
10470
|
-
const DEFAULT_CONFIG = {
|
|
10471
|
-
apiBaseUrl: 'https://code.coze.cn/',
|
|
10472
|
-
openApiBaseUrl: 'https://api.coze.cn',
|
|
10473
|
-
clientId: '95438868623436343239609434490626.app.coze',
|
|
10474
|
-
};
|
|
10475
|
-
|
|
10476
|
-
const getSharedConfigPath = () =>
|
|
10477
|
-
node_path.join(node_os.homedir(), '.coze', 'cli', 'config.json');
|
|
10478
|
-
|
|
10479
|
-
const getLegacyConfigPath = () => node_path.join(node_os.homedir(), '.coze', 'config.json');
|
|
10480
|
-
|
|
10481
|
-
const getDesktopRuntimePaths = () => [
|
|
10482
|
-
node_path.join(node_os.homedir(), '.coze', 'desktop', 'runtime.beta.json'),
|
|
10483
|
-
node_path.join(node_os.homedir(), '.coze', 'desktop', 'runtime.json'),
|
|
10351
|
+
const commands = [
|
|
10352
|
+
registerCommand,
|
|
10353
|
+
registerCommand$3,
|
|
10354
|
+
registerCommand$6,
|
|
10355
|
+
registerCommand$4,
|
|
10356
|
+
registerCommand$5,
|
|
10357
|
+
registerCommand$2,
|
|
10358
|
+
registerCommand$1,
|
|
10484
10359
|
];
|
|
10485
10360
|
|
|
10486
|
-
const
|
|
10487
|
-
|
|
10488
|
-
|
|
10489
|
-
const readJson = async (path) => {
|
|
10490
|
-
try {
|
|
10491
|
-
const parsed = safeJsonParse(await promises.readFile(path, 'utf8'), undefined);
|
|
10492
|
-
return isRecord$3(parsed) ? parsed : undefined;
|
|
10493
|
-
} catch (error) {
|
|
10494
|
-
if ((error ).code === 'ENOENT') {
|
|
10495
|
-
return undefined;
|
|
10496
|
-
}
|
|
10497
|
-
throw new CliError(`Unable to read config ${path}: ${String(error)}`, 'CONFIG_INVALID');
|
|
10498
|
-
}
|
|
10499
|
-
};
|
|
10500
|
-
|
|
10501
|
-
const readDesktopAccessToken = async () => {
|
|
10502
|
-
for (const path of getDesktopRuntimePaths()) {
|
|
10503
|
-
try {
|
|
10504
|
-
const runtime = safeJsonParse(await promises.readFile(path, 'utf8'), undefined);
|
|
10505
|
-
if (!isRecord$3(runtime) || !isRecord$3(runtime.patToken)) {
|
|
10506
|
-
continue;
|
|
10507
|
-
}
|
|
10508
|
-
const {accessToken} = runtime.patToken;
|
|
10509
|
-
if (typeof accessToken === 'string' && accessToken.trim()) {
|
|
10510
|
-
return accessToken.trim();
|
|
10511
|
-
}
|
|
10512
|
-
} catch (error) {
|
|
10513
|
-
}
|
|
10514
|
-
}
|
|
10515
|
-
return undefined;
|
|
10516
|
-
};
|
|
10517
|
-
|
|
10518
|
-
const configuredPath = (options) =>
|
|
10519
|
-
_optionalChain$b([options, 'optionalAccess', _ => _.config]) || process.env.COZE_CONFIG_FILE;
|
|
10520
|
-
|
|
10521
|
-
const loadConfig = async (options = {}) => {
|
|
10522
|
-
const customPath = configuredPath(options);
|
|
10523
|
-
const globalConfig = customPath
|
|
10524
|
-
? await readJson(node_path.resolve(customPath))
|
|
10525
|
-
: (await readJson(getSharedConfigPath())) || (await readJson(getLegacyConfigPath()));
|
|
10526
|
-
const desktopAccessToken = await readDesktopAccessToken();
|
|
10527
|
-
const environmentAccessToken = process.env.COZE_API_TOKEN;
|
|
10528
|
-
const fixedAccessToken = desktopAccessToken || environmentAccessToken;
|
|
10529
|
-
const config = {
|
|
10530
|
-
...DEFAULT_CONFIG,
|
|
10531
|
-
...globalConfig,
|
|
10532
|
-
...(fixedAccessToken
|
|
10533
|
-
? {
|
|
10534
|
-
accessToken: fixedAccessToken,
|
|
10535
|
-
// Desktop PAT and COZE_API_TOKEN are fixed runtime credentials. Never
|
|
10536
|
-
// combine them with refresh metadata from an earlier OAuth login.
|
|
10537
|
-
refreshToken: undefined,
|
|
10538
|
-
tokenExpiresAt: undefined,
|
|
10539
|
-
}
|
|
10540
|
-
: {}),
|
|
10541
|
-
...(process.env.COZE_ORG_ID ? { organizationId: process.env.COZE_ORG_ID } : {}),
|
|
10542
|
-
...(process.env.COZE_ACCOUNT_ID ? { cozeAccountId: process.env.COZE_ACCOUNT_ID } : {}),
|
|
10543
|
-
...(process.env.COZE_SPACE_ID ? { spaceId: process.env.COZE_SPACE_ID } : {}),
|
|
10544
|
-
...(process.env.COZE_PROJECT_ID ? { projectId: process.env.COZE_PROJECT_ID } : {}),
|
|
10545
|
-
...(options.orgId ? { organizationId: options.orgId } : {}),
|
|
10546
|
-
...(options.spaceId ? { spaceId: options.spaceId } : {}),
|
|
10547
|
-
...(options.apiBaseUrl ? { apiBaseUrl: options.apiBaseUrl } : {}),
|
|
10548
|
-
// Runtime-only trust decision: a value persisted in config.json must never enable
|
|
10549
|
-
// project-secret injection for an OAuth access token.
|
|
10550
|
-
injectApiToken: Boolean(fixedAccessToken),
|
|
10551
|
-
};
|
|
10552
|
-
return config;
|
|
10553
|
-
};
|
|
10361
|
+
const main = async () => {
|
|
10362
|
+
// 初始化 Slardar 监控
|
|
10363
|
+
initSlardar();
|
|
10554
10364
|
|
|
10555
|
-
|
|
10556
|
-
|
|
10557
|
-
|
|
10558
|
-
|
|
10559
|
-
|
|
10560
|
-
const existing = (await readJson(target)) || {};
|
|
10561
|
-
const temp = node_path.join(node_path.dirname(target), `.config-${node_crypto.randomUUID()}.tmp`);
|
|
10562
|
-
await promises.mkdir(node_path.dirname(target), { recursive: true });
|
|
10563
|
-
try {
|
|
10564
|
-
await promises.writeFile(temp, `${JSON.stringify({ ...existing, ...patch }, null, 2)}\n`, {
|
|
10565
|
-
encoding: 'utf8',
|
|
10566
|
-
mode: 0o600,
|
|
10365
|
+
// 监听未捕获的异常
|
|
10366
|
+
process.on('uncaughtException', async (error) => {
|
|
10367
|
+
reportError(error, {
|
|
10368
|
+
type: 'uncaughtException',
|
|
10369
|
+
context: 'global',
|
|
10567
10370
|
});
|
|
10568
|
-
await
|
|
10569
|
-
|
|
10570
|
-
await promises.rm(temp, { force: true });
|
|
10571
|
-
}
|
|
10572
|
-
};
|
|
10573
|
-
|
|
10574
|
-
const FIVE_MINUTES = 5 * 60 * 1000;
|
|
10575
|
-
|
|
10576
|
-
|
|
10577
|
-
|
|
10578
|
-
|
|
10579
|
-
|
|
10580
|
-
|
|
10581
|
-
|
|
10582
|
-
const resolveExpiry = (expiresIn) =>
|
|
10583
|
-
expiresIn > 946684800 ? expiresIn * 1000 : Date.now() + expiresIn * 1000;
|
|
10584
|
-
|
|
10585
|
-
const parseJson = async (response) => {
|
|
10586
|
-
const text = await response.text();
|
|
10587
|
-
if (!text) {
|
|
10588
|
-
return {};
|
|
10589
|
-
}
|
|
10590
|
-
const parsed = safeJsonParse(text, {});
|
|
10591
|
-
return typeof parsed === 'object' && parsed !== null
|
|
10592
|
-
? (parsed )
|
|
10593
|
-
: {};
|
|
10594
|
-
};
|
|
10595
|
-
|
|
10596
|
-
const isRecord$2 = (value) =>
|
|
10597
|
-
typeof value === 'object' && value !== null && !Array.isArray(value);
|
|
10598
|
-
|
|
10599
|
-
const getCurrentUser = async (
|
|
10600
|
-
config,
|
|
10601
|
-
options,
|
|
10602
|
-
) => {
|
|
10603
|
-
const token = await getAccessToken(config, options);
|
|
10604
|
-
const response = await fetch(new URL('/v1/users/me', config.openApiBaseUrl), {
|
|
10605
|
-
headers: { authorization: `Bearer ${token}` },
|
|
10371
|
+
await flushSlardar();
|
|
10372
|
+
process.exit(1);
|
|
10606
10373
|
});
|
|
10607
|
-
const payload = await parseJson(response);
|
|
10608
|
-
if (!response.ok) {
|
|
10609
|
-
throw new CliError(
|
|
10610
|
-
typeof payload.msg === 'string'
|
|
10611
|
-
? payload.msg
|
|
10612
|
-
: 'Unable to validate the current login. Run `coze-dev deploy auth login` again.',
|
|
10613
|
-
response.status === 401 ? 'AUTH_REQUIRED' : 'AUTH_STATUS_FAILED',
|
|
10614
|
-
{ status: response.status },
|
|
10615
|
-
);
|
|
10616
|
-
}
|
|
10617
|
-
return isRecord$2(payload.data) ? payload.data : payload;
|
|
10618
|
-
};
|
|
10619
|
-
|
|
10620
|
-
const clearAuthPatch = {
|
|
10621
|
-
accessToken: undefined,
|
|
10622
|
-
refreshToken: undefined,
|
|
10623
|
-
tokenExpiresAt: undefined,
|
|
10624
|
-
organizationId: undefined,
|
|
10625
|
-
enterpriseId: undefined,
|
|
10626
|
-
spaceId: undefined,
|
|
10627
|
-
projectId: undefined,
|
|
10628
|
-
};
|
|
10629
|
-
|
|
10630
|
-
const getAccessToken = async (
|
|
10631
|
-
config,
|
|
10632
|
-
options,
|
|
10633
|
-
) => {
|
|
10634
|
-
if (!config.accessToken) {
|
|
10635
|
-
throw new CliError(
|
|
10636
|
-
'No shared login found. Run `coze-dev deploy auth login` first.',
|
|
10637
|
-
'AUTH_REQUIRED',
|
|
10638
|
-
);
|
|
10639
|
-
}
|
|
10640
|
-
if (!config.refreshToken || !config.tokenExpiresAt) {
|
|
10641
|
-
return config.accessToken;
|
|
10642
|
-
}
|
|
10643
|
-
if (Date.now() < config.tokenExpiresAt - FIVE_MINUTES) {
|
|
10644
|
-
return config.accessToken;
|
|
10645
|
-
}
|
|
10646
|
-
|
|
10647
|
-
const response = await fetch(
|
|
10648
|
-
new URL('/api/permission/oauth2/token', config.openApiBaseUrl),
|
|
10649
|
-
{
|
|
10650
|
-
method: 'POST',
|
|
10651
|
-
headers: { 'content-type': 'application/json' },
|
|
10652
|
-
body: JSON.stringify({
|
|
10653
|
-
grant_type: 'refresh_token',
|
|
10654
|
-
client_id: config.clientId,
|
|
10655
|
-
refresh_token: config.refreshToken,
|
|
10656
|
-
}),
|
|
10657
|
-
},
|
|
10658
|
-
);
|
|
10659
|
-
const payload = await parseJson(response);
|
|
10660
|
-
if (!response.ok || typeof payload.access_token !== 'string') {
|
|
10661
|
-
throw new CliError(
|
|
10662
|
-
typeof payload.error_description === 'string'
|
|
10663
|
-
? payload.error_description
|
|
10664
|
-
: 'Shared login has expired. Run `coze-dev deploy auth login` again.',
|
|
10665
|
-
'AUTH_REFRESH_FAILED',
|
|
10666
|
-
);
|
|
10667
|
-
}
|
|
10668
|
-
const token = payload ;
|
|
10669
|
-
const patch = {
|
|
10670
|
-
accessToken: token.access_token,
|
|
10671
|
-
refreshToken: token.refresh_token || config.refreshToken,
|
|
10672
|
-
tokenExpiresAt: resolveExpiry(token.expires_in),
|
|
10673
|
-
};
|
|
10674
|
-
Object.assign(config, patch);
|
|
10675
|
-
await saveSharedConfig(patch, options);
|
|
10676
|
-
return token.access_token;
|
|
10677
|
-
};
|
|
10678
|
-
|
|
10679
|
-
const saveOAuthToken = async (
|
|
10680
|
-
config,
|
|
10681
|
-
options,
|
|
10682
|
-
token,
|
|
10683
|
-
) => {
|
|
10684
|
-
const patch = {
|
|
10685
|
-
accessToken: token.access_token,
|
|
10686
|
-
refreshToken: token.refresh_token,
|
|
10687
|
-
tokenExpiresAt: resolveExpiry(token.expires_in),
|
|
10688
|
-
organizationId: undefined,
|
|
10689
|
-
enterpriseId: undefined,
|
|
10690
|
-
spaceId: undefined,
|
|
10691
|
-
projectId: undefined,
|
|
10692
|
-
};
|
|
10693
|
-
Object.assign(config, patch);
|
|
10694
|
-
await saveSharedConfig(patch, options);
|
|
10695
|
-
};
|
|
10696
|
-
|
|
10697
|
-
const logout = async (
|
|
10698
|
-
config,
|
|
10699
|
-
options,
|
|
10700
|
-
) => {
|
|
10701
|
-
Object.assign(config, clearAuthPatch);
|
|
10702
|
-
await saveSharedConfig(clearAuthPatch, options);
|
|
10703
|
-
};
|
|
10704
|
-
|
|
10705
|
-
const getAuthStatus = async (
|
|
10706
|
-
config,
|
|
10707
|
-
options,
|
|
10708
|
-
) => {
|
|
10709
|
-
if (!config.accessToken) {
|
|
10710
|
-
return { logged_in: false };
|
|
10711
|
-
}
|
|
10712
|
-
const user = await getCurrentUser(config, options);
|
|
10713
|
-
return {
|
|
10714
|
-
logged_in: true,
|
|
10715
|
-
user,
|
|
10716
|
-
token_expires_at: config.tokenExpiresAt
|
|
10717
|
-
? new Date(config.tokenExpiresAt).toISOString()
|
|
10718
|
-
: 'Never (PAT)',
|
|
10719
|
-
};
|
|
10720
|
-
};
|
|
10721
10374
|
|
|
10722
|
-
|
|
10723
|
-
|
|
10724
|
-
|
|
10725
|
-
|
|
10726
|
-
|
|
10727
|
-
|
|
10728
|
-
|
|
10729
|
-
|
|
10730
|
-
|
|
10731
|
-
return isRecord$1(payload) ? payload : {};
|
|
10732
|
-
};
|
|
10733
|
-
|
|
10734
|
-
const post = async (
|
|
10735
|
-
baseUrl,
|
|
10736
|
-
path,
|
|
10737
|
-
body,
|
|
10738
|
-
) => {
|
|
10739
|
-
const response = await fetch(new URL(path, baseUrl), {
|
|
10740
|
-
method: 'POST',
|
|
10741
|
-
headers: { 'content-type': 'application/json' },
|
|
10742
|
-
body: JSON.stringify(body),
|
|
10375
|
+
// 监听未处理的 Promise rejection
|
|
10376
|
+
process.on('unhandledRejection', async (reason) => {
|
|
10377
|
+
const error = reason instanceof Error ? reason : new Error(String(reason));
|
|
10378
|
+
reportError(error, {
|
|
10379
|
+
type: 'unhandledRejection',
|
|
10380
|
+
context: 'global',
|
|
10381
|
+
});
|
|
10382
|
+
await flushSlardar();
|
|
10383
|
+
process.exit(1);
|
|
10743
10384
|
});
|
|
10744
|
-
return { payload: await readPayload(response), response };
|
|
10745
|
-
};
|
|
10746
|
-
|
|
10747
|
-
const requireString = (
|
|
10748
|
-
payload,
|
|
10749
|
-
key,
|
|
10750
|
-
) => {
|
|
10751
|
-
const value = payload[key];
|
|
10752
|
-
if (typeof value !== 'string' || !value) {
|
|
10753
|
-
throw new CliError(`OAuth response returned no ${key}.`, 'INVALID_AUTH_RESPONSE');
|
|
10754
|
-
}
|
|
10755
|
-
return value;
|
|
10756
|
-
};
|
|
10757
|
-
|
|
10758
|
-
const requireNumber = (
|
|
10759
|
-
payload,
|
|
10760
|
-
key,
|
|
10761
|
-
) => {
|
|
10762
|
-
const value = Number(payload[key]);
|
|
10763
|
-
if (!Number.isFinite(value) || value <= 0) {
|
|
10764
|
-
throw new CliError(`OAuth response returned no ${key}.`, 'INVALID_AUTH_RESPONSE');
|
|
10765
|
-
}
|
|
10766
|
-
return value;
|
|
10767
|
-
};
|
|
10768
|
-
|
|
10769
|
-
const requestDeviceCode = async (config) => {
|
|
10770
|
-
const { payload, response } = await post(
|
|
10771
|
-
config.openApiBaseUrl,
|
|
10772
|
-
'/api/permission/oauth2/device/code',
|
|
10773
|
-
{ client_id: config.clientId },
|
|
10774
|
-
);
|
|
10775
|
-
if (!response.ok) {
|
|
10776
|
-
throw new CliError(
|
|
10777
|
-
typeof payload.error_description === 'string'
|
|
10778
|
-
? payload.error_description
|
|
10779
|
-
: 'Unable to start OAuth login.',
|
|
10780
|
-
'AUTH_LOGIN_FAILED',
|
|
10781
|
-
{ status: response.status },
|
|
10782
|
-
);
|
|
10783
|
-
}
|
|
10784
|
-
return {
|
|
10785
|
-
device_code: requireString(payload, 'device_code'),
|
|
10786
|
-
user_code: requireString(payload, 'user_code'),
|
|
10787
|
-
verification_uri: requireString(payload, 'verification_uri'),
|
|
10788
|
-
expires_in: requireNumber(payload, 'expires_in'),
|
|
10789
|
-
interval:
|
|
10790
|
-
typeof payload.interval === 'number' && payload.interval > 0
|
|
10791
|
-
? payload.interval
|
|
10792
|
-
: undefined,
|
|
10793
|
-
};
|
|
10794
|
-
};
|
|
10795
10385
|
|
|
10796
|
-
const
|
|
10797
|
-
const url = new URL(deviceCode.verification_uri);
|
|
10798
|
-
url.searchParams.set('user_code', deviceCode.user_code);
|
|
10799
|
-
return url.toString();
|
|
10800
|
-
};
|
|
10386
|
+
const program = new commander.Command();
|
|
10801
10387
|
|
|
10802
|
-
|
|
10803
|
-
|
|
10804
|
-
|
|
10805
|
-
|
|
10806
|
-
|
|
10807
|
-
|
|
10808
|
-
: 'xdg-open';
|
|
10809
|
-
const args = process.platform === 'win32' ? ['/c', 'start', '""', url] : [url];
|
|
10810
|
-
try {
|
|
10811
|
-
const child = node_child_process.spawn(command, args, { detached: true, stdio: 'ignore' });
|
|
10812
|
-
child.on('error', () => undefined);
|
|
10813
|
-
child.unref();
|
|
10814
|
-
} catch (error) {
|
|
10815
|
-
}
|
|
10816
|
-
};
|
|
10388
|
+
program
|
|
10389
|
+
.name('coze-dev')
|
|
10390
|
+
.description(
|
|
10391
|
+
'Coze Coding CLI - Project template engine for frontend stacks',
|
|
10392
|
+
)
|
|
10393
|
+
.version(packageJson.version);
|
|
10817
10394
|
|
|
10818
|
-
|
|
10819
|
-
new Promise(resolve => setTimeout(resolve, milliseconds));
|
|
10395
|
+
commands.forEach(initCmd => initCmd(program));
|
|
10820
10396
|
|
|
10821
|
-
|
|
10822
|
-
|
|
10823
|
-
deviceCode,
|
|
10824
|
-
) => {
|
|
10825
|
-
const expiresAt = Date.now() + deviceCode.expires_in * 1000;
|
|
10826
|
-
let interval = (deviceCode.interval || DEFAULT_POLL_INTERVAL_MS / 1000) * 1000;
|
|
10827
|
-
while (Date.now() < expiresAt) {
|
|
10828
|
-
const { payload, response } = await post(
|
|
10829
|
-
config.openApiBaseUrl,
|
|
10830
|
-
'/api/permission/oauth2/token',
|
|
10831
|
-
{
|
|
10832
|
-
grant_type: 'urn:ietf:params:oauth:grant-type:device_code',
|
|
10833
|
-
client_id: config.clientId,
|
|
10834
|
-
device_code: deviceCode.device_code,
|
|
10835
|
-
},
|
|
10836
|
-
);
|
|
10837
|
-
if (response.ok) {
|
|
10838
|
-
return {
|
|
10839
|
-
access_token: requireString(payload, 'access_token'),
|
|
10840
|
-
refresh_token: requireString(payload, 'refresh_token'),
|
|
10841
|
-
expires_in: requireNumber(payload, 'expires_in'),
|
|
10842
|
-
};
|
|
10843
|
-
}
|
|
10844
|
-
if (payload.error === 'authorization_pending') {
|
|
10845
|
-
await sleep(interval);
|
|
10846
|
-
continue;
|
|
10847
|
-
}
|
|
10848
|
-
if (payload.error === 'slow_down') {
|
|
10849
|
-
interval += SLOW_DOWN_INCREMENT_MS;
|
|
10850
|
-
await sleep(interval);
|
|
10851
|
-
continue;
|
|
10852
|
-
}
|
|
10853
|
-
throw new CliError(
|
|
10854
|
-
typeof payload.error_description === 'string'
|
|
10855
|
-
? payload.error_description
|
|
10856
|
-
: 'OAuth authorization failed.',
|
|
10857
|
-
'AUTH_LOGIN_FAILED',
|
|
10858
|
-
{ oauth_error: payload.error, status: response.status },
|
|
10859
|
-
);
|
|
10860
|
-
}
|
|
10861
|
-
throw new CliError('OAuth authorization expired. Please try again.', 'AUTH_LOGIN_EXPIRED');
|
|
10862
|
-
};
|
|
10863
|
-
|
|
10864
|
-
const loginWithOAuth = async (
|
|
10865
|
-
config,
|
|
10866
|
-
options,
|
|
10867
|
-
callbacks,
|
|
10868
|
-
) => {
|
|
10869
|
-
const deviceCode = await requestDeviceCode(config);
|
|
10870
|
-
const verificationUrl = buildVerificationUrl(deviceCode);
|
|
10871
|
-
callbacks.onVerification(verificationUrl);
|
|
10872
|
-
openBrowser(verificationUrl);
|
|
10873
|
-
await saveOAuthToken(config, options, await pollToken(config, deviceCode));
|
|
10874
|
-
};
|
|
10875
|
-
|
|
10876
|
-
function _optionalChain$a(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; }
|
|
10877
|
-
|
|
10878
|
-
|
|
10879
|
-
|
|
10880
|
-
|
|
10881
|
-
|
|
10882
|
-
|
|
10883
|
-
|
|
10884
|
-
|
|
10885
|
-
|
|
10886
|
-
|
|
10887
|
-
|
|
10888
|
-
|
|
10889
|
-
|
|
10890
|
-
|
|
10891
|
-
|
|
10892
|
-
|
|
10893
|
-
|
|
10894
|
-
|
|
10895
|
-
const API_PREFIX = '/api/coding/deployment/v2';
|
|
10896
|
-
const CREATE_PROJECT_PATH = '/api/ideserver_api/project/create_vibe_project';
|
|
10897
|
-
const LIST_SPACES_PATH = '/api/playground_api/space/list';
|
|
10898
|
-
const ENCRYPT_PROJECT_SECRET_PATH =
|
|
10899
|
-
'/api/permission_api/project_secret/encrypt_project_secret';
|
|
10900
|
-
const MAX_MESSAGE_LENGTH = 512;
|
|
10901
|
-
|
|
10902
|
-
const isRecord = (value) =>
|
|
10903
|
-
typeof value === 'object' && value !== null && !Array.isArray(value);
|
|
10904
|
-
|
|
10905
|
-
|
|
10906
|
-
|
|
10907
|
-
|
|
10908
|
-
|
|
10909
|
-
|
|
10910
|
-
|
|
10911
|
-
const parseResponse = async (response) => {
|
|
10912
|
-
const text = await response.text();
|
|
10913
|
-
if (!text) {
|
|
10914
|
-
return { payload: {}, text, validJson: true };
|
|
10915
|
-
}
|
|
10916
|
-
const invalid = Symbol('invalid-json');
|
|
10917
|
-
const parsed = safeJsonParse(text, invalid);
|
|
10918
|
-
return parsed === invalid
|
|
10919
|
-
? { payload: undefined, text, validJson: false }
|
|
10920
|
-
: { payload: parsed, text, validJson: true };
|
|
10921
|
-
};
|
|
10922
|
-
|
|
10923
|
-
|
|
10924
|
-
|
|
10925
|
-
|
|
10926
|
-
|
|
10927
|
-
|
|
10928
|
-
|
|
10929
|
-
|
|
10930
|
-
|
|
10931
|
-
const responseExcerpt = (text) => {
|
|
10932
|
-
const compact = text.replace(/\s+/gu, ' ').trim();
|
|
10933
|
-
return compact ? compact.slice(0, MAX_MESSAGE_LENGTH) : undefined;
|
|
10934
|
-
};
|
|
10935
|
-
|
|
10936
|
-
const unwrap = (
|
|
10937
|
-
payload,
|
|
10938
|
-
expectedKey,
|
|
10939
|
-
responseMetadata,
|
|
10940
|
-
) => {
|
|
10941
|
-
const root = isRecord(payload) ? payload : undefined;
|
|
10942
|
-
const first = isRecord(_optionalChain$a([root, 'optionalAccess', _ => _.data])) ? root.data : undefined;
|
|
10943
|
-
const second = isRecord(_optionalChain$a([first, 'optionalAccess', _2 => _2.data])) ? first.data : undefined;
|
|
10944
|
-
const envelope = [root, first].find(candidate => candidate && 'code' in candidate);
|
|
10945
|
-
if (_optionalChain$a([envelope, 'optionalAccess', _3 => _3.code]) !== undefined && Number(envelope.code) !== 0) {
|
|
10946
|
-
throw new CliError(
|
|
10947
|
-
typeof envelope.msg === 'string'
|
|
10948
|
-
? envelope.msg.slice(0, MAX_MESSAGE_LENGTH)
|
|
10949
|
-
: 'The deployment request was rejected.',
|
|
10950
|
-
'API_REJECTED',
|
|
10951
|
-
{ business_code: envelope.code, ...responseMetadata },
|
|
10952
|
-
);
|
|
10953
|
-
}
|
|
10954
|
-
if (!expectedKey) {
|
|
10955
|
-
return (second || first || root || {}) ;
|
|
10956
|
-
}
|
|
10957
|
-
const matched = [second, first, root].find(
|
|
10958
|
-
candidate => candidate && expectedKey in candidate,
|
|
10959
|
-
);
|
|
10960
|
-
if (!matched) {
|
|
10961
|
-
throw new CliError(
|
|
10962
|
-
`Deployment API returned no ${expectedKey}.`,
|
|
10963
|
-
'INVALID_RESPONSE',
|
|
10964
|
-
);
|
|
10965
|
-
}
|
|
10966
|
-
return matched ;
|
|
10967
|
-
};
|
|
10968
|
-
|
|
10969
|
-
class DeployApiClient {
|
|
10970
|
-
constructor(
|
|
10971
|
-
config,
|
|
10972
|
-
globalOptions,
|
|
10973
|
-
) {this.config = config;this.globalOptions = globalOptions;}
|
|
10974
|
-
|
|
10975
|
-
debug(message) {
|
|
10976
|
-
if (this.globalOptions.debug) {
|
|
10977
|
-
process.stderr.write(`[debug] [api] ${message}\n`);
|
|
10978
|
-
}
|
|
10979
|
-
}
|
|
10980
|
-
|
|
10981
|
-
async post(
|
|
10982
|
-
path,
|
|
10983
|
-
body,
|
|
10984
|
-
expectedKey,
|
|
10985
|
-
useApiPrefix = true,
|
|
10986
|
-
) {
|
|
10987
|
-
const token = await getAccessToken(this.config, this.globalOptions);
|
|
10988
|
-
const headers = {
|
|
10989
|
-
authorization: `Bearer ${token}`,
|
|
10990
|
-
'content-type': 'application/json',
|
|
10991
|
-
'agw-js-conv': 'str',
|
|
10992
|
-
'x-request-from-coze-cli': '1',
|
|
10993
|
-
};
|
|
10994
|
-
// Only an explicit environment credential may become a project runtime secret.
|
|
10995
|
-
// OAuth credentials loaded from config.json remain authentication-only.
|
|
10996
|
-
if (
|
|
10997
|
-
this.config.injectApiToken &&
|
|
10998
|
-
path === '/deploy_history/create' &&
|
|
10999
|
-
useApiPrefix
|
|
11000
|
-
) {
|
|
11001
|
-
headers['x-coze-deploy-inject-api-token'] = 'true';
|
|
11002
|
-
}
|
|
11003
|
-
// Coze account id: an explicit COZE_ACCOUNT_ID (config.cozeAccountId) always wins;
|
|
11004
|
-
// otherwise fall back to the organization id resolved from login/config.
|
|
11005
|
-
const cozeAccount = this.config.cozeAccountId || this.config.organizationId;
|
|
11006
|
-
if (cozeAccount) {
|
|
11007
|
-
headers['x-coze-account'] = cozeAccount;
|
|
11008
|
-
}
|
|
11009
|
-
const lane = _optionalChain$a([this, 'access', _4 => _4.globalOptions, 'access', _5 => _5.lane, 'optionalAccess', _6 => _6.trim, 'call', _7 => _7()]) || _optionalChain$a([this, 'access', _8 => _8.config, 'access', _9 => _9.xTTEnv, 'optionalAccess', _10 => _10.trim, 'call', _11 => _11()]);
|
|
11010
|
-
if (lane) {
|
|
11011
|
-
headers['x-use-ppe'] = '1';
|
|
11012
|
-
headers['x-tt-env'] = lane;
|
|
11013
|
-
}
|
|
11014
|
-
const requestUrl = new URL(
|
|
11015
|
-
`${useApiPrefix ? API_PREFIX : ''}${path}`,
|
|
11016
|
-
this.config.apiBaseUrl,
|
|
11017
|
-
);
|
|
11018
|
-
this.debug(
|
|
11019
|
-
`POST ${requestUrl.toString()}${lane ? ` lane=${lane}` : ''}`,
|
|
11020
|
-
);
|
|
11021
|
-
const response = await fetch(
|
|
11022
|
-
requestUrl,
|
|
11023
|
-
{ method: 'POST', headers, body: JSON.stringify(body) },
|
|
11024
|
-
);
|
|
11025
|
-
const responseMetadata = {
|
|
11026
|
-
status: response.status,
|
|
11027
|
-
status_text: response.statusText,
|
|
11028
|
-
log_id: response.headers.get('x-tt-logid') || undefined,
|
|
11029
|
-
request_path: requestUrl.pathname,
|
|
11030
|
-
content_type: response.headers.get('content-type') || undefined,
|
|
11031
|
-
};
|
|
11032
|
-
this.debug(
|
|
11033
|
-
`${response.status} ${response.statusText} ${requestUrl.pathname}` +
|
|
11034
|
-
`${responseMetadata.log_id ? ` log_id=${responseMetadata.log_id}` : ' log_id=unavailable'}`,
|
|
11035
|
-
);
|
|
11036
|
-
const { payload, text, validJson } = await parseResponse(response);
|
|
11037
|
-
if (!response.ok) {
|
|
11038
|
-
const root = isRecord(payload) ? payload : undefined;
|
|
11039
|
-
throw new CliError(
|
|
11040
|
-
typeof _optionalChain$a([root, 'optionalAccess', _12 => _12.msg]) === 'string'
|
|
11041
|
-
? root.msg.slice(0, MAX_MESSAGE_LENGTH)
|
|
11042
|
-
: `Deployment API failed: ${response.status} ${response.statusText}` +
|
|
11043
|
-
`${validJson ? '' : '; response was not JSON'}`,
|
|
11044
|
-
response.status === 401 ? 'AUTH_REQUIRED' : 'HTTP_ERROR',
|
|
11045
|
-
{
|
|
11046
|
-
...responseMetadata,
|
|
11047
|
-
response_excerpt: responseExcerpt(text),
|
|
11048
|
-
},
|
|
11049
|
-
);
|
|
11050
|
-
}
|
|
11051
|
-
if (!validJson) {
|
|
11052
|
-
throw new CliError(
|
|
11053
|
-
`Deployment API returned invalid JSON (${response.status}).`,
|
|
11054
|
-
'INVALID_RESPONSE',
|
|
11055
|
-
{
|
|
11056
|
-
...responseMetadata,
|
|
11057
|
-
response_excerpt: responseExcerpt(text),
|
|
11058
|
-
},
|
|
11059
|
-
);
|
|
11060
|
-
}
|
|
11061
|
-
return unwrap(payload, expectedKey, responseMetadata);
|
|
11062
|
-
}
|
|
11063
|
-
|
|
11064
|
-
createDeploymentProject(body) {
|
|
11065
|
-
return this.post(
|
|
11066
|
-
CREATE_PROJECT_PATH,
|
|
11067
|
-
body,
|
|
11068
|
-
'project_id',
|
|
11069
|
-
false,
|
|
11070
|
-
);
|
|
11071
|
-
}
|
|
11072
|
-
|
|
11073
|
-
// 回读当前登录态对应的 Coze 账号 id。无入参:账号由服务端从登录态解析(X-Coze-Account →
|
|
11074
|
-
// access token → 兜底登录用户),客户端传什么都只有「等于登录态」一种合法取值。
|
|
11075
|
-
// 只在建 Project 前用一次,用来定这个 Project 下应用的账号归属。
|
|
11076
|
-
getCozeAccount() {
|
|
11077
|
-
return this.post(
|
|
11078
|
-
'/account/get',
|
|
11079
|
-
{},
|
|
11080
|
-
'coze_account_id',
|
|
11081
|
-
);
|
|
11082
|
-
}
|
|
11083
|
-
|
|
11084
|
-
listSpaces(body
|
|
11085
|
-
|
|
11086
|
-
|
|
11087
|
-
|
|
11088
|
-
|
|
11089
|
-
) {
|
|
11090
|
-
return this.post(
|
|
11091
|
-
LIST_SPACES_PATH,
|
|
11092
|
-
body,
|
|
11093
|
-
'bot_space_list',
|
|
11094
|
-
false,
|
|
11095
|
-
);
|
|
11096
|
-
}
|
|
11097
|
-
|
|
11098
|
-
encryptProjectSecret(projectId, secrets) {
|
|
11099
|
-
return this.post(
|
|
11100
|
-
ENCRYPT_PROJECT_SECRET_PATH,
|
|
11101
|
-
{
|
|
11102
|
-
project_id: projectId,
|
|
11103
|
-
encrypt_secrets: {
|
|
11104
|
-
secrets,
|
|
11105
|
-
cred_providers: [],
|
|
11106
|
-
},
|
|
11107
|
-
},
|
|
11108
|
-
'sealed_secrets',
|
|
11109
|
-
false,
|
|
11110
|
-
);
|
|
11111
|
-
}
|
|
11112
|
-
|
|
11113
|
-
// 列当前登录用户名下的 Application,跨 Project。服务端从登录态取 user_id,
|
|
11114
|
-
// 请求体里只有分页参数(deploy_app/list 已去掉 project_id / user_id 两个寻址入参)。
|
|
11115
|
-
listApplications(body) {
|
|
11116
|
-
return this.post(
|
|
11117
|
-
'/deploy_app/list', body, 'items',
|
|
11118
|
-
);
|
|
11119
|
-
}
|
|
11120
|
-
|
|
11121
|
-
getApplication(appId) {
|
|
11122
|
-
return this.post('/deploy_app/get', { app_id: appId }, 'app_id');
|
|
11123
|
-
}
|
|
11124
|
-
|
|
11125
|
-
updateApplication(body) {
|
|
11126
|
-
return this.post('/deploy_app/update', body, 'app_id');
|
|
11127
|
-
}
|
|
11128
|
-
|
|
11129
|
-
// 删除 Application:服务端只接受 **Stopped** 状态,其余状态会带上当前状态报错(先 stop 再 delete)。
|
|
11130
|
-
// 已删除的再删一次是幂等成功。
|
|
11131
|
-
deleteApplication(appId) {
|
|
11132
|
-
return this.post('/deploy_app/delete', { app_id: appId });
|
|
11133
|
-
}
|
|
11134
|
-
|
|
11135
|
-
getDeployConfig(body
|
|
11136
|
-
|
|
11137
|
-
|
|
11138
|
-
|
|
11139
|
-
|
|
11140
|
-
|
|
11141
|
-
) {
|
|
11142
|
-
return this.post('/deploy_config/get', body, 'deploy_config');
|
|
11143
|
-
}
|
|
11144
|
-
|
|
11145
|
-
createDeployHistory(body) {
|
|
11146
|
-
return this.post('/deploy_history/create', body, 'app_id');
|
|
11147
|
-
}
|
|
11148
|
-
|
|
11149
|
-
preDeployUpload(body
|
|
11150
|
-
|
|
11151
|
-
|
|
11152
|
-
) {
|
|
11153
|
-
return this.post('/deploy_history/pre_upload', body, 'upload_url');
|
|
11154
|
-
}
|
|
11155
|
-
|
|
11156
|
-
getDeployHistory(body) {
|
|
11157
|
-
return this.post('/deploy_history/get', body, 'deploy_history_id');
|
|
11158
|
-
}
|
|
11159
|
-
|
|
11160
|
-
listDeployHistory(body) {
|
|
11161
|
-
return this.post
|
|
11162
|
-
|
|
11163
|
-
|
|
11164
|
-
|
|
11165
|
-
('/deploy_history/list', body, 'deploy_history_list');
|
|
11166
|
-
}
|
|
11167
|
-
|
|
11168
|
-
getOnlineDeployHistory(appId) {
|
|
11169
|
-
return this.post(
|
|
11170
|
-
'/deploy_history/get_online', { app_id: appId }, 'deploy_history_list',
|
|
11171
|
-
);
|
|
11172
|
-
}
|
|
11173
|
-
|
|
11174
|
-
getOnlineEnvironment(appId) {
|
|
11175
|
-
return this.post(
|
|
11176
|
-
'/environment/get_online', { app_id: appId }, 'app_id',
|
|
11177
|
-
);
|
|
11178
|
-
}
|
|
11179
|
-
|
|
11180
|
-
checkRollbackDatabase(body) {
|
|
11181
|
-
return this.post(
|
|
11182
|
-
'/deploy_history/check_rollback_database', body, 'is_rollback_possible',
|
|
11183
|
-
);
|
|
11184
|
-
}
|
|
11185
|
-
|
|
11186
|
-
cancelDeployHistory(body) {
|
|
11187
|
-
return this.post('/deploy_history/cancel', body);
|
|
11188
|
-
}
|
|
11189
|
-
|
|
11190
|
-
rollbackDeployHistory(body
|
|
11191
|
-
|
|
11192
|
-
|
|
11193
|
-
|
|
11194
|
-
) {
|
|
11195
|
-
return this.post(
|
|
11196
|
-
'/deploy_history/rollback', body, 'new_deploy_history_id',
|
|
11197
|
-
);
|
|
11198
|
-
}
|
|
11199
|
-
|
|
11200
|
-
stopApplication(appId) {
|
|
11201
|
-
return this.post('/application/stop', { app_id: appId });
|
|
11202
|
-
}
|
|
11203
|
-
|
|
11204
|
-
resumeApplication(appId) {
|
|
11205
|
-
return this.post('/application/resume', { app_id: appId });
|
|
11206
|
-
}
|
|
11207
|
-
|
|
11208
|
-
// 暂停是可逆的:只把线上 Unit 从 Ready 改成 Paused,函数留着,可被 resume 推回 Ready。
|
|
11209
|
-
// stop 会连函数一起删、落到 Stopped,只能靠重新部署恢复 —— resume 配对的是 pause,不是 stop。
|
|
11210
|
-
pauseApplication(appId) {
|
|
11211
|
-
return this.post('/application/pause', { app_id: appId });
|
|
11212
|
-
}
|
|
11213
|
-
|
|
11214
|
-
// PV / UV。入参是 app_id,但服务端反查 project_id 后按 **Project** 聚合 —— 埋点链路只有
|
|
11215
|
-
// project 维度,同一 Project 下多个 Application 拿到的是同一份数据。
|
|
11216
|
-
getUserAnalyticsMetrics(body) {
|
|
11217
|
-
return this.post(
|
|
11218
|
-
'/metrics/user_analytics/get', body, 'charts',
|
|
11219
|
-
);
|
|
11220
|
-
}
|
|
11221
|
-
|
|
11222
|
-
getBuildLog(body) {
|
|
11223
|
-
return this.post('/deploy_history/log', body, 'log');
|
|
11224
|
-
}
|
|
11225
|
-
|
|
11226
|
-
searchRuntimeLog(body) {
|
|
11227
|
-
return this.post(
|
|
11228
|
-
'/runtime_log/search', body, 'logs',
|
|
11229
|
-
);
|
|
11230
|
-
}
|
|
11231
|
-
|
|
11232
|
-
getRuntimeLogCount(appId) {
|
|
11233
|
-
return this.post(
|
|
11234
|
-
'/runtime_log/count', { app_id: appId }, 'limit',
|
|
11235
|
-
);
|
|
11236
|
-
}
|
|
11237
|
-
|
|
11238
|
-
getDeployCount(appId) {
|
|
11239
|
-
return this.post(
|
|
11240
|
-
'/deploy_history/get_count', { app_id: appId }, 'success_count',
|
|
11241
|
-
);
|
|
11242
|
-
}
|
|
11243
|
-
|
|
11244
|
-
getApplicationMetrics(body) {
|
|
11245
|
-
return this.post(
|
|
11246
|
-
'/metrics/get', body, 'charts',
|
|
11247
|
-
);
|
|
11248
|
-
}
|
|
11249
|
-
|
|
11250
|
-
getHostedUsageMonthly(body) {
|
|
11251
|
-
return this.post(
|
|
11252
|
-
'/hosted_usage/monthly', body, 'summary',
|
|
11253
|
-
);
|
|
11254
|
-
}
|
|
11255
|
-
|
|
11256
|
-
authorizeMiniProgram(body
|
|
11257
|
-
|
|
11258
|
-
|
|
11259
|
-
|
|
11260
|
-
|
|
11261
|
-
|
|
11262
|
-
|
|
11263
|
-
) {
|
|
11264
|
-
return this.post
|
|
11265
|
-
|
|
11266
|
-
|
|
11267
|
-
|
|
11268
|
-
('/mini_program/auth', body);
|
|
11269
|
-
}
|
|
11270
|
-
|
|
11271
|
-
createMiniProgramPreview(body
|
|
11272
|
-
|
|
11273
|
-
|
|
11274
|
-
|
|
11275
|
-
|
|
11276
|
-
|
|
11277
|
-
) {
|
|
11278
|
-
return this.post
|
|
11279
|
-
|
|
11280
|
-
|
|
11281
|
-
|
|
11282
|
-
|
|
11283
|
-
('/mini_program/preview', body);
|
|
11284
|
-
}
|
|
11285
|
-
|
|
11286
|
-
listDomains(appId, unitType) {
|
|
11287
|
-
return this.post(
|
|
11288
|
-
'/domain/list', {
|
|
11289
|
-
app_id: appId,
|
|
11290
|
-
...(unitType === undefined ? {} : { unit_type: unitType }),
|
|
11291
|
-
}, 'items',
|
|
11292
|
-
);
|
|
11293
|
-
}
|
|
11294
|
-
|
|
11295
|
-
createDomain(body) {
|
|
11296
|
-
return this.post('/domain/create', body, 'domain');
|
|
11297
|
-
}
|
|
11298
|
-
|
|
11299
|
-
// 改的是系统分配的 <prefix>.coze.site 里的 prefix,不是 createDomain 加进来的自定义域名 ——
|
|
11300
|
-
// 那类域名服务端只提供 create/delete,域名串本身不可改。
|
|
11301
|
-
updateDefaultDomainPrefix(body) {
|
|
11302
|
-
return this.post
|
|
11303
|
-
|
|
11304
|
-
|
|
11305
|
-
|
|
11306
|
-
|
|
11307
|
-
('/domain/update_default_prefix', body, 'new_domain_host_canonical');
|
|
11308
|
-
}
|
|
11309
|
-
|
|
11310
|
-
getMiniProgramAuthStatus(body) {
|
|
11311
|
-
return this.post
|
|
11312
|
-
|
|
11313
|
-
|
|
11314
|
-
|
|
11315
|
-
|
|
11316
|
-
('/api/coding/deployment/auth/status', body, 'is_authorized', false);
|
|
11317
|
-
}
|
|
11318
|
-
|
|
11319
|
-
bindMiniProgramAuth(body
|
|
11320
|
-
|
|
11321
|
-
|
|
11322
|
-
|
|
11323
|
-
|
|
11324
|
-
|
|
11325
|
-
) {
|
|
11326
|
-
return this.post
|
|
11327
|
-
|
|
11328
|
-
|
|
11329
|
-
|
|
11330
|
-
|
|
11331
|
-
|
|
11332
|
-
|
|
11333
|
-
('/api/coding/deployment/auth/bind', body, 'bind_status', false);
|
|
11334
|
-
}
|
|
11335
|
-
|
|
11336
|
-
submitMiniProgramAuthCode(body
|
|
11337
|
-
|
|
11338
|
-
|
|
11339
|
-
|
|
11340
|
-
|
|
11341
|
-
|
|
11342
|
-
) {
|
|
11343
|
-
return this.post(
|
|
11344
|
-
'/api/coding/deployment/auth/submit_code', body, undefined, false,
|
|
11345
|
-
);
|
|
11346
|
-
}
|
|
11347
|
-
|
|
11348
|
-
unbindMiniProgramAuth(body) {
|
|
11349
|
-
return this.post(
|
|
11350
|
-
'/api/coding/deployment/auth/unbind', body, undefined, false,
|
|
11351
|
-
);
|
|
11352
|
-
}
|
|
11353
|
-
}
|
|
11354
|
-
|
|
11355
|
-
const textValue = (value) => {
|
|
11356
|
-
if (typeof value === 'string') {
|
|
11357
|
-
return value;
|
|
11358
|
-
}
|
|
11359
|
-
return JSON.stringify(value, null, 2);
|
|
11360
|
-
};
|
|
11361
|
-
|
|
11362
|
-
class Output {
|
|
11363
|
-
constructor(
|
|
11364
|
-
format,
|
|
11365
|
-
debugEnabled = false,
|
|
11366
|
-
) {this.format = format;this.debugEnabled = debugEnabled;}
|
|
11367
|
-
|
|
11368
|
-
print(value) {
|
|
11369
|
-
process.stdout.write(
|
|
11370
|
-
this.format === 'json'
|
|
11371
|
-
? `${JSON.stringify(value, null, 2)}\n`
|
|
11372
|
-
: `${textValue(value)}\n`,
|
|
11373
|
-
);
|
|
11374
|
-
}
|
|
11375
|
-
|
|
11376
|
-
info(message) {
|
|
11377
|
-
if (this.format === 'text') {
|
|
11378
|
-
process.stderr.write(`${message}\n`);
|
|
11379
|
-
}
|
|
11380
|
-
}
|
|
11381
|
-
|
|
11382
|
-
notice(message) {
|
|
11383
|
-
process.stderr.write(`${message}\n`);
|
|
11384
|
-
}
|
|
11385
|
-
|
|
11386
|
-
warn(message) {
|
|
11387
|
-
process.stderr.write(`Warning: ${message}\n`);
|
|
11388
|
-
}
|
|
11389
|
-
|
|
11390
|
-
debug(message) {
|
|
11391
|
-
if (this.debugEnabled) {
|
|
11392
|
-
process.stderr.write(`[debug] ${message}\n`);
|
|
11393
|
-
}
|
|
11394
|
-
}
|
|
11395
|
-
}
|
|
11396
|
-
|
|
11397
|
-
const runtimes = new WeakMap();
|
|
11398
|
-
|
|
11399
|
-
const getRuntime = async (command) => {
|
|
11400
|
-
const deploy = findDeployCommand(command);
|
|
11401
|
-
let runtime = runtimes.get(deploy);
|
|
11402
|
-
if (!runtime) {
|
|
11403
|
-
runtime = (async () => {
|
|
11404
|
-
const options = deploy.opts();
|
|
11405
|
-
const config = await loadConfig(options);
|
|
11406
|
-
return {
|
|
11407
|
-
client: new DeployApiClient(config, options),
|
|
11408
|
-
config,
|
|
11409
|
-
cwd: process.cwd(),
|
|
11410
|
-
globalOptions: options,
|
|
11411
|
-
output: new Output(options.format || 'json', options.debug),
|
|
11412
|
-
};
|
|
11413
|
-
})();
|
|
11414
|
-
runtimes.set(deploy, runtime);
|
|
11415
|
-
}
|
|
11416
|
-
return runtime;
|
|
11417
|
-
};
|
|
11418
|
-
|
|
11419
|
-
const PRIVACY_POLICY_URL = 'https://docs.coze.cn/guides/privacy';
|
|
11420
|
-
const TERMS_OF_SERVICE_URL = 'https://docs.coze.cn/guides/terms-of-service';
|
|
11421
|
-
|
|
11422
|
-
const registerAuth = (program) => {
|
|
11423
|
-
const auth = program.command('auth').description('Manage deployment CLI authentication');
|
|
11424
|
-
|
|
11425
|
-
auth
|
|
11426
|
-
.command('login')
|
|
11427
|
-
.description('Login with Coze OAuth and save shared credentials')
|
|
11428
|
-
.action(async (_options, command) => {
|
|
11429
|
-
const runtime = await getRuntime(command);
|
|
11430
|
-
await loginWithOAuth(runtime.config, runtime.globalOptions, {
|
|
11431
|
-
onVerification: url => {
|
|
11432
|
-
runtime.output.notice(
|
|
11433
|
-
[
|
|
11434
|
-
'Open this URL to authorize coze-dev deploy:',
|
|
11435
|
-
url,
|
|
11436
|
-
`Privacy Policy: ${PRIVACY_POLICY_URL}`,
|
|
11437
|
-
`Terms of Service: ${TERMS_OF_SERVICE_URL}`,
|
|
11438
|
-
].join('\n'),
|
|
11439
|
-
);
|
|
11440
|
-
},
|
|
11441
|
-
});
|
|
11442
|
-
runtime.output.print({ success: true, logged_in: true, method: 'OAuth' });
|
|
11443
|
-
});
|
|
11444
|
-
|
|
11445
|
-
auth
|
|
11446
|
-
.command('status')
|
|
11447
|
-
.description('Check and refresh the current shared login')
|
|
11448
|
-
.action(async (_options, command) => {
|
|
11449
|
-
const runtime = await getRuntime(command);
|
|
11450
|
-
runtime.output.print(await getAuthStatus(runtime.config, runtime.globalOptions));
|
|
11451
|
-
});
|
|
11452
|
-
|
|
11453
|
-
auth
|
|
11454
|
-
.command('logout')
|
|
11455
|
-
.description('Clear shared credentials and account context')
|
|
11456
|
-
.action(async (_options, command) => {
|
|
11457
|
-
const runtime = await getRuntime(command);
|
|
11458
|
-
await logout(runtime.config, runtime.globalOptions);
|
|
11459
|
-
runtime.output.print({ success: true, logged_out: true });
|
|
11460
|
-
});
|
|
11461
|
-
};
|
|
11462
|
-
|
|
11463
|
-
const execFileAsync = node_util.promisify(node_child_process.execFile);
|
|
11464
|
-
|
|
11465
|
-
const registerContext = (program) => {
|
|
11466
|
-
const context = program.command('context').description('Show or update deployment context');
|
|
11467
|
-
context.command('show').action(async (_options, command) => {
|
|
11468
|
-
const runtime = await getRuntime(command);
|
|
11469
|
-
runtime.output.print({
|
|
11470
|
-
organization_id: runtime.config.organizationId,
|
|
11471
|
-
space_id: runtime.config.spaceId,
|
|
11472
|
-
project_id: runtime.config.projectId,
|
|
11473
|
-
lane: runtime.globalOptions.lane || runtime.config.xTTEnv,
|
|
11474
|
-
config_path: runtime.globalOptions.config || getSharedConfigPath(),
|
|
11475
|
-
});
|
|
11476
|
-
});
|
|
11477
|
-
context
|
|
11478
|
-
.command('use')
|
|
11479
|
-
.option('--space-id <spaceId>', 'Default Space ID')
|
|
11480
|
-
.option('--project-id <projectId>', 'Default Project ID')
|
|
11481
|
-
.action(async (options, command) => {
|
|
11482
|
-
const runtime = await getRuntime(command);
|
|
11483
|
-
await saveSharedConfig(
|
|
11484
|
-
{
|
|
11485
|
-
...(options.spaceId ? { spaceId: options.spaceId } : {}),
|
|
11486
|
-
...(options.projectId ? { projectId: options.projectId } : {}),
|
|
11487
|
-
},
|
|
11488
|
-
runtime.globalOptions,
|
|
11489
|
-
);
|
|
11490
|
-
runtime.output.print({
|
|
11491
|
-
space_id: options.spaceId || runtime.config.spaceId,
|
|
11492
|
-
project_id: options.projectId || runtime.config.projectId,
|
|
11493
|
-
});
|
|
11494
|
-
});
|
|
11495
|
-
};
|
|
11496
|
-
|
|
11497
|
-
const registerDoctor = (program) => {
|
|
11498
|
-
program
|
|
11499
|
-
.command('doctor')
|
|
11500
|
-
.description('Check deployment CLI prerequisites and shared login')
|
|
11501
|
-
.action(async (_options, command) => {
|
|
11502
|
-
const runtime = await getRuntime(command);
|
|
11503
|
-
let gitAvailable = true;
|
|
11504
|
-
try {
|
|
11505
|
-
await execFileAsync('git', ['--version']);
|
|
11506
|
-
} catch (e) {
|
|
11507
|
-
gitAvailable = false;
|
|
11508
|
-
}
|
|
11509
|
-
runtime.output.print({
|
|
11510
|
-
ok: gitAvailable && Boolean(runtime.config.accessToken),
|
|
11511
|
-
git: gitAvailable ? 'ok' : 'missing',
|
|
11512
|
-
login: runtime.config.accessToken ? 'reused' : 'missing',
|
|
11513
|
-
login_config: runtime.globalOptions.config || getSharedConfigPath(),
|
|
11514
|
-
project_id: runtime.config.projectId || 'not configured',
|
|
11515
|
-
});
|
|
11516
|
-
});
|
|
11517
|
-
};
|
|
11518
|
-
|
|
11519
|
-
function _optionalChain$9(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; }
|
|
11520
|
-
|
|
11521
|
-
|
|
11522
|
-
|
|
11523
|
-
|
|
11524
|
-
|
|
11525
|
-
|
|
11526
|
-
|
|
11527
|
-
|
|
11528
|
-
|
|
11529
|
-
|
|
11530
|
-
|
|
11531
|
-
|
|
11532
|
-
|
|
11533
|
-
|
|
11534
|
-
|
|
11535
|
-
|
|
11536
|
-
|
|
11537
|
-
|
|
11538
|
-
|
|
11539
|
-
|
|
11540
|
-
|
|
11541
|
-
|
|
11542
|
-
|
|
11543
|
-
|
|
11544
|
-
|
|
11545
|
-
|
|
11546
|
-
|
|
11547
|
-
|
|
11548
|
-
|
|
11549
|
-
const getDeployParentOptions = (command) =>
|
|
11550
|
-
_optionalChain$9([command, 'access', _ => _.parent, 'optionalAccess', _2 => _2.opts, 'call', _3 => _3()]) || {};
|
|
11551
|
-
|
|
11552
|
-
const getDeployAppIdOption = (
|
|
11553
|
-
options,
|
|
11554
|
-
command,
|
|
11555
|
-
) => options.appId || getDeployParentOptions(command).appId;
|
|
11556
|
-
|
|
11557
|
-
function _optionalChain$8(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; } async function _asyncOptionalChain$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 = await fn(value); } else if (op === 'call' || op === 'optionalCall') { value = await fn((...args) => value.call(lastAccessLHS, ...args)); lastAccessLHS = undefined; } } return value; }
|
|
11558
|
-
|
|
11559
|
-
const isAccountId = (value) => /^[1-9]\d*$/u.test(value);
|
|
11560
|
-
|
|
11561
|
-
/**
|
|
11562
|
-
* 定出这个 Project 下的应用该归属哪个 Coze 账号,写进 project_settings.extra.coze_account_id。
|
|
11563
|
-
*
|
|
11564
|
-
* 优先级(与 api-client 里 x-coze-account 的取值顺序一致,不另立一套口径):
|
|
11565
|
-
* 1. COZE_ACCOUNT_ID(config.cozeAccountId)—— 用户显式指定
|
|
11566
|
-
* 2. COZE_ORG_ID / --org-id(config.organizationId)—— 用户显式指定组织
|
|
11567
|
-
* 3. 登录态回读(deploy v2 account/get)
|
|
11568
|
-
*
|
|
11569
|
-
* ⚠️ 1、2 命中时**不打接口**:本地已经知道账号了,再问一次服务端只是多一个 RTT 和一个失败点。
|
|
11570
|
-
*
|
|
11571
|
-
* 拿不到就返回 undefined(不写 extra),部署照常继续:服务端在 deploy_history/create 里仍会
|
|
11572
|
-
* 按同一条阶梯解析账号,结果与不加这段逻辑时完全一致 —— 只是无登录态的预览初始化那条链路
|
|
11573
|
-
* 少了 Project 上这份归属记录。这是一个辅助接口,不该成为首次部署的单点。
|
|
11574
|
-
*/
|
|
11575
|
-
const resolveCozeAccountId = async (
|
|
11576
|
-
runtime,
|
|
11577
|
-
) => {
|
|
11578
|
-
const configured =
|
|
11579
|
-
_optionalChain$8([runtime, 'access', _ => _.config, 'access', _2 => _2.cozeAccountId, 'optionalAccess', _3 => _3.trim, 'call', _4 => _4()]) || _optionalChain$8([runtime, 'access', _5 => _5.config, 'access', _6 => _6.organizationId, 'optionalAccess', _7 => _7.trim, 'call', _8 => _8()]);
|
|
11580
|
-
if (configured) {
|
|
11581
|
-
if (!isAccountId(configured)) {
|
|
11582
|
-
// 不把非法值写进 Project —— 它会被服务端当成「明确但损坏的归属」直接报错。
|
|
11583
|
-
// 该值仍会作为 x-coze-account 发出去,由服务端给出明确的参数错误。
|
|
11584
|
-
runtime.output.debug(
|
|
11585
|
-
`[deploy] Ignoring malformed Coze account id for project settings: ${configured}`,
|
|
11586
|
-
);
|
|
11587
|
-
return undefined;
|
|
11588
|
-
}
|
|
11589
|
-
runtime.output.debug(`[deploy] Using configured Coze account ${configured}`);
|
|
11590
|
-
return configured;
|
|
11591
|
-
}
|
|
11592
|
-
try {
|
|
11593
|
-
const accountId = await _asyncOptionalChain$1([(await runtime.client.getCozeAccount()), 'access', async _9 => _9.coze_account_id, 'optionalAccess', async _10 => _10.trim, 'call', async _11 => _11()]);
|
|
11594
|
-
if (!accountId || !isAccountId(accountId)) {
|
|
11595
|
-
runtime.output.debug(
|
|
11596
|
-
`[deploy] Deployment API returned no usable Coze account id: ${String(accountId)}`,
|
|
11597
|
-
);
|
|
11598
|
-
return undefined;
|
|
11599
|
-
}
|
|
11600
|
-
runtime.output.debug(`[deploy] Resolved Coze account ${accountId} from the current login`);
|
|
11601
|
-
return accountId;
|
|
11602
|
-
} catch (error) {
|
|
11603
|
-
runtime.output.warn(
|
|
11604
|
-
`Unable to resolve the Coze account from the current login; the project will be created without an explicit account: ${String(error)}`,
|
|
11605
|
-
);
|
|
11606
|
-
return undefined;
|
|
11607
|
-
}
|
|
11608
|
-
};
|
|
11609
|
-
|
|
11610
|
-
const getCreateDeployConfig = (config) => ({
|
|
11611
|
-
deploy_config: {
|
|
11612
|
-
cpu: config.deploy_config.cpu,
|
|
11613
|
-
memory_mb: config.deploy_config.memory_mb,
|
|
11614
|
-
max_instance: config.deploy_config.max_instance,
|
|
11615
|
-
max_concurrency: config.deploy_config.max_concurrency,
|
|
11616
|
-
},
|
|
11617
|
-
service_type: config.deploy_config.service_type,
|
|
11618
|
-
...(config.deploy_config.computer_id
|
|
11619
|
-
? { computer_id: config.deploy_config.computer_id }
|
|
11620
|
-
: {}),
|
|
11621
|
-
});
|
|
11622
|
-
|
|
11623
|
-
const DEPLOY_STATUS = {
|
|
11624
|
-
pending: 1,
|
|
11625
|
-
running: 2,
|
|
11626
|
-
succeeded: 3,
|
|
11627
|
-
failed: 4,
|
|
11628
|
-
canceled: 5,
|
|
11629
|
-
interrupted: 6,
|
|
11630
|
-
preDeploy: 7,
|
|
11631
|
-
} ;
|
|
11632
|
-
|
|
11633
|
-
const STATUS_NAMES = {
|
|
11634
|
-
[DEPLOY_STATUS.pending]: 'Pending',
|
|
11635
|
-
[DEPLOY_STATUS.running]: 'Running',
|
|
11636
|
-
[DEPLOY_STATUS.succeeded]: 'Succeeded',
|
|
11637
|
-
[DEPLOY_STATUS.failed]: 'Failed',
|
|
11638
|
-
[DEPLOY_STATUS.canceled]: 'Canceled',
|
|
11639
|
-
[DEPLOY_STATUS.interrupted]: 'Interrupted',
|
|
11640
|
-
[DEPLOY_STATUS.preDeploy]: 'WaitingForUpload',
|
|
11641
|
-
};
|
|
11642
|
-
|
|
11643
|
-
/**
|
|
11644
|
-
* 终态 = 不会再变了。
|
|
11645
|
-
*
|
|
11646
|
-
* ⚠️ `interrupted(6)` **不是**终态,别再往这里加。它是过程态:服务端某条流水线自身轮询超时时,
|
|
11647
|
-
* 会把整次部署标成 Interrupted 并安排稍后重新触发(`base_pipe.NewInterruptedResult`),之后仍
|
|
11648
|
-
* 会推进到 Succeeded。安卓构建 10 分钟起步,几乎必然经过至少一次 Interrupted —— 把它当终态会
|
|
11649
|
-
* 让 `deploy --wait` 在构建中途就收工返回,此时 APK 还没产出,`mobile_artifact_list` 是空的。
|
|
11650
|
-
*/
|
|
11651
|
-
const TERMINAL_STATUSES = new Set([
|
|
11652
|
-
DEPLOY_STATUS.succeeded,
|
|
11653
|
-
DEPLOY_STATUS.failed,
|
|
11654
|
-
DEPLOY_STATUS.canceled,
|
|
11655
|
-
]);
|
|
11656
|
-
|
|
11657
|
-
const getDeployStatusText = (status) =>
|
|
11658
|
-
status ? STATUS_NAMES[status] || 'Unknown' : 'Unknown';
|
|
11659
|
-
|
|
11660
|
-
/** 这次部署的结果是否已经定下来了(到了终态就不会再变)。 */
|
|
11661
|
-
const isDeploymentSettled = (status) =>
|
|
11662
|
-
status !== undefined && TERMINAL_STATUSES.has(status);
|
|
11663
|
-
|
|
11664
|
-
function _optionalChain$7(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; }
|
|
11665
|
-
|
|
11666
|
-
const formatDeployDetails = (history) =>
|
|
11667
|
-
(_optionalChain$7([history, 'optionalAccess', _ => _.deploy_detail]) || []).map(detail => ({
|
|
11668
|
-
target: detail.target,
|
|
11669
|
-
status: getDeployStatusText(detail.status),
|
|
11670
|
-
deploy_log_key: detail.deploy_log_key,
|
|
11671
|
-
deploy_log_url: detail.deploy_log_url,
|
|
11672
|
-
}));
|
|
11673
|
-
|
|
11674
|
-
const getDeployLogKeys = (history) =>
|
|
11675
|
-
[...new Set(
|
|
11676
|
-
(history.deploy_detail || [])
|
|
11677
|
-
.map(detail => _optionalChain$7([detail, 'access', _2 => _2.deploy_log_key, 'optionalAccess', _3 => _3.trim, 'call', _4 => _4()]))
|
|
11678
|
-
.filter((key) => Boolean(key)),
|
|
11679
|
-
)];
|
|
11680
|
-
|
|
11681
|
-
const normalizePositiveId = (value) => {
|
|
11682
|
-
const normalized = value === undefined ? '' : String(value).trim();
|
|
11683
|
-
return /^[1-9]\d*$/.test(normalized) ? normalized : undefined;
|
|
11684
|
-
};
|
|
11685
|
-
|
|
11686
|
-
const resolveDeployHistoryId = (
|
|
11687
|
-
deployHistoryId,
|
|
11688
|
-
previousDeployHistoryId,
|
|
11689
|
-
) =>
|
|
11690
|
-
normalizePositiveId(deployHistoryId) || normalizePositiveId(previousDeployHistoryId);
|
|
11691
|
-
|
|
11692
|
-
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; }
|
|
11693
|
-
|
|
11694
|
-
const SOURCE_SNAPSHOT_BYTES = 20;
|
|
11695
|
-
const PROJECT_METADATA_FILE_MODE = 0o644;
|
|
11696
|
-
|
|
11697
|
-
const isId = (value) =>
|
|
11698
|
-
typeof value === 'string' && /^\d+$/u.test(value);
|
|
11699
|
-
|
|
11700
|
-
|
|
11701
|
-
const resolveAppId = async (cwd, appId) => {
|
|
11702
|
-
const explicit = _optionalChain$6([appId, 'optionalAccess', _ => _.trim, 'call', _2 => _2()]);
|
|
11703
|
-
if (explicit) {
|
|
11704
|
-
return explicit;
|
|
11705
|
-
}
|
|
11706
|
-
try {
|
|
11707
|
-
return (await readProjectMetadata(node_path.resolve(cwd))).appId;
|
|
11708
|
-
} catch (error) {
|
|
11709
|
-
if ((error ).code === 'COZE_FILE_NOT_FOUND') {
|
|
11710
|
-
return undefined;
|
|
11711
|
-
}
|
|
11712
|
-
throw error;
|
|
11713
|
-
}
|
|
11714
|
-
};
|
|
11715
|
-
|
|
11716
|
-
const requireAppId = async (cwd, appId) => {
|
|
11717
|
-
const resolved = await resolveAppId(cwd, appId);
|
|
11718
|
-
if (!resolved) {
|
|
11719
|
-
throw new CliError(
|
|
11720
|
-
'Application ID is required. Pass --app-id or use a directory whose .coze [project] contains app_id.',
|
|
11721
|
-
'APP_ID_REQUIRED',
|
|
11722
|
-
);
|
|
11723
|
-
}
|
|
11724
|
-
return resolved;
|
|
11725
|
-
};
|
|
11726
|
-
|
|
11727
|
-
const resolveSourceSnapshot = (sourceRootInput) => {
|
|
11728
|
-
const sourceRoot = node_path.resolve(sourceRootInput);
|
|
11729
|
-
const commitHash = node_crypto.randomBytes(SOURCE_SNAPSHOT_BYTES).toString('hex');
|
|
11730
|
-
return { commitHash, sourceRoot };
|
|
11731
|
-
};
|
|
11732
|
-
|
|
11733
|
-
const readProjectMetadata = async (
|
|
11734
|
-
sourceRoot,
|
|
11735
|
-
) => {
|
|
11736
|
-
let cozeFileContent = '';
|
|
11737
|
-
try {
|
|
11738
|
-
cozeFileContent = await promises.readFile(node_path.join(sourceRoot, '.coze'), 'utf8');
|
|
11739
|
-
} catch (error) {
|
|
11740
|
-
if ((error ).code === 'ENOENT') {
|
|
11741
|
-
throw new CliError(
|
|
11742
|
-
`No .coze file found in ${sourceRoot}.`,
|
|
11743
|
-
'COZE_FILE_NOT_FOUND',
|
|
11744
|
-
);
|
|
11745
|
-
}
|
|
11746
|
-
throw error;
|
|
11747
|
-
}
|
|
11748
|
-
const projectSection = _optionalChain$6([cozeFileContent, 'access', _3 => _3.match, 'call', _4 => _4(
|
|
11749
|
-
/^\s*\[project\]\s*(?:#.*)?$([\s\S]*?)(?=^\s*\[[^\]]+\]\s*(?:#.*)?$|(?![\s\S]))/mu,
|
|
11750
|
-
), 'optionalAccess', _5 => _5[1]]);
|
|
11751
|
-
const readProjectString = (key) =>
|
|
11752
|
-
_optionalChain$6([projectSection
|
|
11753
|
-
, 'optionalAccess', _6 => _6.match, 'call', _7 => _7(new RegExp(`^\\s*${key}\\s*=\\s*["']([^"']+)["']`, 'mu')), 'optionalAccess', _8 => _8[1]
|
|
11754
|
-
, 'optionalAccess', _9 => _9.trim, 'call', _10 => _10()]);
|
|
11755
|
-
const name = readProjectString('name');
|
|
11756
|
-
const projectType = readProjectString('project_type');
|
|
11757
|
-
const projectId = readProjectString('project_id');
|
|
11758
|
-
const appId = readProjectString('app_id');
|
|
11759
|
-
const hasUnquotedId = (key) =>
|
|
11760
|
-
Boolean(_optionalChain$6([projectSection, 'optionalAccess', _11 => _11.match, 'call', _12 => _12(new RegExp(`^\\s*${key}\\s*=\\s*(?!["'])\\S+`, 'mu'))]));
|
|
11761
|
-
if (hasUnquotedId('project_id') || hasUnquotedId('app_id')) {
|
|
11762
|
-
throw new CliError(
|
|
11763
|
-
'.coze [project].project_id and app_id must be quoted decimal strings.',
|
|
11764
|
-
'INVALID_COZE_FILE',
|
|
11765
|
-
);
|
|
11766
|
-
}
|
|
11767
|
-
if (projectId && !isId(projectId)) {
|
|
11768
|
-
throw new CliError('.coze [project].project_id must be a quoted decimal string.', 'INVALID_COZE_FILE');
|
|
11769
|
-
}
|
|
11770
|
-
if (appId && !isId(appId)) {
|
|
11771
|
-
throw new CliError('.coze [project].app_id must be a quoted decimal string.', 'INVALID_COZE_FILE');
|
|
11772
|
-
}
|
|
11773
|
-
return { name, projectType, projectId, appId, cozeFileContent };
|
|
11774
|
-
};
|
|
11775
|
-
|
|
11776
|
-
const updateProjectValue = (content, key, value) => {
|
|
11777
|
-
const sectionMatch = /^\s*\[project\]\s*(?:#.*)?$/mu.exec(content);
|
|
11778
|
-
if (!sectionMatch || sectionMatch.index === undefined) {
|
|
11779
|
-
const prefix = `[project]\n${key} = ${JSON.stringify(value)}\n\n`;
|
|
11780
|
-
return `${prefix}${content}`;
|
|
11781
|
-
}
|
|
11782
|
-
const sectionStart = sectionMatch.index + sectionMatch[0].length;
|
|
11783
|
-
const following = content.slice(sectionStart);
|
|
11784
|
-
const nextSection = /^\s*\[[^\]]+\]\s*(?:#.*)?$/mu.exec(following);
|
|
11785
|
-
const sectionEnd = _optionalChain$6([nextSection, 'optionalAccess', _13 => _13.index]) === undefined
|
|
11786
|
-
? content.length
|
|
11787
|
-
: sectionStart + nextSection.index;
|
|
11788
|
-
const before = content.slice(0, sectionStart);
|
|
11789
|
-
let body = content.slice(sectionStart, sectionEnd);
|
|
11790
|
-
const keyPattern = new RegExp(`^(\\s*)${key}\\s*=.*$`, 'mu');
|
|
11791
|
-
if (keyPattern.test(body)) {
|
|
11792
|
-
body = body.replace(keyPattern, `$1${key} = ${JSON.stringify(value)}`);
|
|
11793
|
-
} else {
|
|
11794
|
-
const separator = body.startsWith('\n') || body.startsWith('\r\n') ? '' : '\n';
|
|
11795
|
-
body = `${separator}${body}`;
|
|
11796
|
-
const trailingNewline = body.endsWith('\n') ? '' : '\n';
|
|
11797
|
-
body = `${body}${trailingNewline}${key} = ${JSON.stringify(value)}\n`;
|
|
11798
|
-
}
|
|
11799
|
-
return `${before}${body}${content.slice(sectionEnd)}`;
|
|
11800
|
-
};
|
|
11801
|
-
|
|
11802
|
-
const writeProjectBinding = async (
|
|
11803
|
-
sourceRoot,
|
|
11804
|
-
binding,
|
|
11805
|
-
) => {
|
|
11806
|
-
const path = node_path.join(sourceRoot, '.coze');
|
|
11807
|
-
let content = await promises.readFile(path, 'utf8');
|
|
11808
|
-
if (binding.projectId) {
|
|
11809
|
-
content = updateProjectValue(content, 'project_id', binding.projectId);
|
|
11810
|
-
}
|
|
11811
|
-
if (binding.appId) {
|
|
11812
|
-
content = updateProjectValue(content, 'app_id', binding.appId);
|
|
11813
|
-
}
|
|
11814
|
-
const tempPath = node_path.join(node_path.dirname(path), `.coze-${node_crypto.randomUUID()}.tmp`);
|
|
11815
|
-
try {
|
|
11816
|
-
await promises.writeFile(tempPath, content, {
|
|
11817
|
-
encoding: 'utf8',
|
|
11818
|
-
mode: PROJECT_METADATA_FILE_MODE,
|
|
11819
|
-
});
|
|
11820
|
-
await promises.chmod(tempPath, PROJECT_METADATA_FILE_MODE);
|
|
11821
|
-
await promises.rename(tempPath, path);
|
|
11822
|
-
} finally {
|
|
11823
|
-
await promises.rm(tempPath, { force: true });
|
|
11824
|
-
}
|
|
11825
|
-
return readProjectMetadata(sourceRoot);
|
|
11826
|
-
};
|
|
11827
|
-
|
|
11828
|
-
const ensureProjectMetadata = async (
|
|
11829
|
-
sourceRoot,
|
|
11830
|
-
options,
|
|
11831
|
-
) => {
|
|
11832
|
-
try {
|
|
11833
|
-
return await readProjectMetadata(sourceRoot);
|
|
11834
|
-
} catch (error) {
|
|
11835
|
-
if ((error ).code !== 'COZE_FILE_NOT_FOUND' || !options.allowCreate) {
|
|
11836
|
-
throw error;
|
|
11837
|
-
}
|
|
11838
|
-
}
|
|
11839
|
-
const name = _optionalChain$6([options, 'access', _14 => _14.name, 'optionalAccess', _15 => _15.trim, 'call', _16 => _16()]) || 'Pages application';
|
|
11840
|
-
const projectType = _optionalChain$6([options, 'access', _17 => _17.projectType, 'optionalAccess', _18 => _18.trim, 'call', _19 => _19()]) || 'web';
|
|
11841
|
-
await promises.writeFile(
|
|
11842
|
-
node_path.join(sourceRoot, '.coze'),
|
|
11843
|
-
`[project]\nname = ${JSON.stringify(name)}\nproject_type = ${JSON.stringify(projectType)}\n`,
|
|
11844
|
-
{ encoding: 'utf8', mode: PROJECT_METADATA_FILE_MODE },
|
|
11845
|
-
);
|
|
11846
|
-
await promises.chmod(node_path.join(sourceRoot, '.coze'), PROJECT_METADATA_FILE_MODE);
|
|
11847
|
-
return readProjectMetadata(sourceRoot);
|
|
11848
|
-
};
|
|
11849
|
-
|
|
11850
|
-
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; }
|
|
11851
|
-
const isFile = async (path) => {
|
|
11852
|
-
try {
|
|
11853
|
-
return (await promises.stat(path)).isFile();
|
|
11854
|
-
} catch (error) {
|
|
11855
|
-
if ((error ).code === 'ENOENT') {
|
|
11856
|
-
return false;
|
|
11857
|
-
}
|
|
11858
|
-
throw error;
|
|
11859
|
-
}
|
|
11860
|
-
};
|
|
11861
|
-
|
|
11862
|
-
const validatePagesSource = async (
|
|
11863
|
-
sourceRoot,
|
|
11864
|
-
cozeFileContent,
|
|
11865
|
-
) => {
|
|
11866
|
-
if (await isFile(node_path.join(sourceRoot, 'index.html'))) {
|
|
11867
|
-
return;
|
|
11868
|
-
}
|
|
11869
|
-
|
|
11870
|
-
let config;
|
|
11871
|
-
try {
|
|
11872
|
-
config = TOML.parse(cozeFileContent);
|
|
11873
|
-
} catch (error) {
|
|
11874
|
-
throw new CliError(
|
|
11875
|
-
`Unable to parse .coze: ${error instanceof Error ? error.message : String(error)}`,
|
|
11876
|
-
'INVALID_COZE_FILE',
|
|
11877
|
-
);
|
|
11878
|
-
}
|
|
11879
|
-
const project = config.project ;
|
|
11880
|
-
if (typeof _optionalChain$5([project, 'optionalAccess', _ => _.template]) !== 'string' || project.template.trim().toLowerCase() !== 'nextjs') {
|
|
11881
|
-
throw new CliError(
|
|
11882
|
-
'Pages source contains no index.html; .coze project.template must be "nextjs".',
|
|
11883
|
-
'PAGES_BUILD_CONFIG_REQUIRED',
|
|
11884
|
-
);
|
|
11885
|
-
}
|
|
11886
|
-
const deploy = config.deploy ;
|
|
11887
|
-
const build = _optionalChain$5([deploy, 'optionalAccess', _2 => _2.build]);
|
|
11888
|
-
if (!Array.isArray(build) || build.length === 0 || !build.every(part => typeof part === 'string' && part.length > 0)) {
|
|
11889
|
-
throw new CliError(
|
|
11890
|
-
'Pages source contains no index.html; .coze deploy.build must be a non-empty string array.',
|
|
11891
|
-
'PAGES_BUILD_CONFIG_REQUIRED',
|
|
11892
|
-
);
|
|
11893
|
-
}
|
|
11894
|
-
};
|
|
11895
|
-
|
|
11896
|
-
const readDeployLocalContext = async (
|
|
11897
|
-
sourceRoot,
|
|
11898
|
-
requestedApplicationType,
|
|
11899
|
-
appId,
|
|
11900
|
-
client,
|
|
11901
|
-
) => {
|
|
11902
|
-
const sourceSnapshot = resolveSourceSnapshot(sourceRoot);
|
|
11903
|
-
let applicationTypeHint = requestedApplicationType;
|
|
11904
|
-
let effectiveAppId = appId;
|
|
11905
|
-
if (!effectiveAppId) {
|
|
11906
|
-
try {
|
|
11907
|
-
effectiveAppId = (await ensureProjectMetadata(sourceRoot, { allowCreate: false })).appId;
|
|
11908
|
-
} catch (error) {
|
|
11909
|
-
if ((error ).code !== 'COZE_FILE_NOT_FOUND') {
|
|
11910
|
-
throw error;
|
|
11911
|
-
}
|
|
11912
|
-
}
|
|
11913
|
-
}
|
|
11914
|
-
if (!applicationTypeHint && effectiveAppId) {
|
|
11915
|
-
applicationTypeHint = (await client.getApplication(effectiveAppId)).application_type;
|
|
11916
|
-
}
|
|
11917
|
-
const isPagesDeployment = applicationTypeHint === 'pages';
|
|
11918
|
-
const metadata = await ensureProjectMetadata(sourceRoot, {
|
|
11919
|
-
allowCreate: isPagesDeployment,
|
|
11920
|
-
projectType: isPagesDeployment ? 'web' : undefined,
|
|
11921
|
-
});
|
|
11922
|
-
if (isPagesDeployment) {
|
|
11923
|
-
await validatePagesSource(sourceRoot, metadata.cozeFileContent);
|
|
11924
|
-
}
|
|
11925
|
-
return { ...sourceSnapshot, metadata, isPagesDeployment };
|
|
11926
|
-
};
|
|
11927
|
-
|
|
11928
|
-
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; }
|
|
11929
|
-
|
|
11930
|
-
/**
|
|
11931
|
-
* 把 `mobile_artifact_list` 连同「这个空数组到底什么意思」一起输出。
|
|
11932
|
-
*
|
|
11933
|
-
* 产物是部署过程中逐步落库的:APK 要等安卓构建跑完才写进去,比部署记录本身晚好几分钟。部署没到
|
|
11934
|
-
* 终态时,空的 `mobile_artifact_list` 只代表「还没产出来」,不代表「没有产物」—— 可这两种情况在
|
|
11935
|
-
* 输出里长得一模一样,调用方(尤其是 agent)会把前者读成后者,然后得出「部署成功但系统没返回
|
|
11936
|
-
* APK 下载地址」这种错误结论。线上真发生过。
|
|
11937
|
-
*
|
|
11938
|
-
* 所以未定终态时额外带一个 `artifacts_pending: true`;这个字段不出现,就表示这份列表已经是最终
|
|
11939
|
-
* 结果。`mobile_artifact_list` 本身保持恒存在,避免破坏已有脚本的读法。
|
|
11940
|
-
*/
|
|
11941
|
-
const mobileArtifactsOutput = (
|
|
11942
|
-
history,
|
|
11943
|
-
status = _optionalChain$4([history, 'optionalAccess', _ => _.status]),
|
|
11944
|
-
) => ({
|
|
11945
|
-
mobile_artifact_list: _optionalChain$4([history, 'optionalAccess', _2 => _2.mobile_artifact_list]) || [],
|
|
11946
|
-
...(isDeploymentSettled(status) ? {} : { artifacts_pending: true }),
|
|
11947
|
-
});
|
|
11948
|
-
|
|
11949
|
-
// 服务端 deploy_app/list 的 page_size 上限,超了会被判参数错误。
|
|
11950
|
-
// 客户端先拦一道,是为了把错误说在本地(带上上限值),而不是回一句服务端的通用参数错误。
|
|
11951
|
-
const APP_LIST_MAX_PAGE_SIZE = 100;
|
|
11952
|
-
|
|
11953
|
-
// page_token 是**页码的十进制字符串**(服务端口径,与 deploy_history/list 一致),不是不透明游标。
|
|
11954
|
-
// 所以这里能、也应该在本地校验:`--page-token abc` 早报错,比发出去再被拒强。
|
|
11955
|
-
const parsePositiveInt = (
|
|
11956
|
-
raw,
|
|
11957
|
-
option,
|
|
11958
|
-
code,
|
|
11959
|
-
max,
|
|
11960
|
-
) => {
|
|
11961
|
-
const value = Number(raw);
|
|
11962
|
-
if (!Number.isSafeInteger(value) || value <= 0) {
|
|
11963
|
-
throw new CliError(`${option} must be a positive integer.`, code, { [option]: raw });
|
|
11964
|
-
}
|
|
11965
|
-
if (max !== undefined && value > max) {
|
|
11966
|
-
throw new CliError(`${option} must not exceed ${String(max)}.`, code, { [option]: raw });
|
|
11967
|
-
}
|
|
11968
|
-
return value;
|
|
11969
|
-
};
|
|
11970
|
-
|
|
11971
|
-
// ⛔ 别再用 `Number(options.pageSize || 20)`:`--page-size abc` 会算出 NaN,
|
|
11972
|
-
// JSON.stringify 把它写成 null 发给服务端,最后表现为「参数没生效」而不是「参数写错了」。
|
|
11973
|
-
const parsePageSize = (
|
|
11974
|
-
raw,
|
|
11975
|
-
fallback,
|
|
11976
|
-
max,
|
|
11977
|
-
) => {
|
|
11978
|
-
if (raw === undefined || raw === '') {
|
|
11979
|
-
return fallback;
|
|
11980
|
-
}
|
|
11981
|
-
return parsePositiveInt(raw, '--page-size', 'INVALID_PAGE_SIZE', max);
|
|
11982
|
-
};
|
|
11983
|
-
|
|
11984
|
-
const parsePageToken = (raw) => {
|
|
11985
|
-
if (raw === undefined || raw === '') {
|
|
11986
|
-
return undefined;
|
|
11987
|
-
}
|
|
11988
|
-
parsePositiveInt(raw, '--page-token', 'INVALID_PAGE_TOKEN');
|
|
11989
|
-
return raw;
|
|
11990
|
-
};
|
|
11991
|
-
|
|
11992
|
-
|
|
11993
|
-
|
|
11994
|
-
|
|
11995
|
-
|
|
11996
|
-
|
|
11997
|
-
|
|
11998
|
-
// collectAllPages 顺着 next_page_token 把所有页取回来。
|
|
11999
|
-
//
|
|
12000
|
-
// 服务端从「全量单页」改成真分页之后,`app list` 一次只回一页;想要「我的全部应用」就得翻页。
|
|
12001
|
-
// 与其让每个调用方各写一遍循环,不如给一个 --all。
|
|
12002
|
-
//
|
|
12003
|
-
// ⚠️ 不设页数上限截断:静默截断正是这次要修掉的毛病。只防死循环——服务端如果一直回同一个
|
|
12004
|
-
// token(或说 has_more 却不给 token),直接报错,而不是无限翻。
|
|
12005
|
-
const collectAllPages = async (
|
|
12006
|
-
fetchPage,
|
|
12007
|
-
) => {
|
|
12008
|
-
const items = [];
|
|
12009
|
-
const seen = new Set();
|
|
12010
|
-
let pageToken;
|
|
12011
|
-
let pages = 0;
|
|
12012
|
-
for (;;) {
|
|
12013
|
-
const page = await fetchPage(pageToken);
|
|
12014
|
-
items.push(...(page.items || []));
|
|
12015
|
-
pages += 1;
|
|
12016
|
-
if (!page.has_more) {
|
|
12017
|
-
return { items, pages };
|
|
12018
|
-
}
|
|
12019
|
-
const next = page.next_page_token;
|
|
12020
|
-
if (!next || seen.has(next)) {
|
|
12021
|
-
throw new CliError(
|
|
12022
|
-
'The server reported more pages but returned no usable next_page_token.',
|
|
12023
|
-
'INVALID_PAGE_TOKEN',
|
|
12024
|
-
{ next_page_token: next, pages },
|
|
12025
|
-
);
|
|
12026
|
-
}
|
|
12027
|
-
seen.add(next);
|
|
12028
|
-
pageToken = next;
|
|
12029
|
-
}
|
|
12030
|
-
};
|
|
12031
|
-
|
|
12032
|
-
async function _asyncOptionalChain(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 = await fn(value); } else if (op === 'call' || op === 'optionalCall') { value = await fn((...args) => value.call(lastAccessLHS, ...args)); lastAccessLHS = undefined; } } return value; }
|
|
12033
|
-
|
|
12034
|
-
const registerDeployReadCommands = (deploy) => {
|
|
12035
|
-
deploy
|
|
12036
|
-
.command('status')
|
|
12037
|
-
.option('--app-id <appId>', 'Application ID')
|
|
12038
|
-
.option('--deploy-id <deployId>', 'Deployment history ID')
|
|
12039
|
-
.action(async (options, command) => {
|
|
12040
|
-
const runtime = await getRuntime(command);
|
|
12041
|
-
const appId = await requireAppId(runtime.cwd, getDeployAppIdOption(options, command));
|
|
12042
|
-
let deployHistoryId = options.deployId;
|
|
12043
|
-
if (!deployHistoryId) {
|
|
12044
|
-
deployHistoryId = await _asyncOptionalChain([(
|
|
12045
|
-
await runtime.client.listDeployHistory({ app_id: appId, page_size: 1 })
|
|
12046
|
-
), 'access', async _ => _.deploy_history_list, 'optionalAccess', async _2 => _2[0], 'optionalAccess', async _3 => _3.deploy_history_id]);
|
|
12047
|
-
}
|
|
12048
|
-
if (!deployHistoryId) {
|
|
12049
|
-
throw new CliError('No deployment history found.', 'DEPLOYMENT_NOT_FOUND');
|
|
12050
|
-
}
|
|
12051
|
-
const history = await runtime.client.getDeployHistory({
|
|
12052
|
-
app_id: appId,
|
|
12053
|
-
deploy_history_id: deployHistoryId,
|
|
12054
|
-
});
|
|
12055
|
-
runtime.output.print({
|
|
12056
|
-
app_id: appId,
|
|
12057
|
-
deploy_history_id: deployHistoryId,
|
|
12058
|
-
status: getDeployStatusText(history.status),
|
|
12059
|
-
commit_hash: history.commit_hash,
|
|
12060
|
-
commit_message: history.commit_message,
|
|
12061
|
-
domains: history.domain_list || [],
|
|
12062
|
-
error_analysis: history.error_analysis,
|
|
12063
|
-
deploy_detail: formatDeployDetails(history),
|
|
12064
|
-
connector_data_list: history.connector_data_list || [],
|
|
12065
|
-
...mobileArtifactsOutput(history),
|
|
12066
|
-
});
|
|
12067
|
-
});
|
|
12068
|
-
|
|
12069
|
-
deploy
|
|
12070
|
-
.command('list')
|
|
12071
|
-
.option('--app-id <appId>', 'Application ID')
|
|
12072
|
-
.option('--page-size <pageSize>', 'Page size', '10')
|
|
12073
|
-
.option('--page-token <pageToken>', 'Page token (page number)')
|
|
12074
|
-
.action(async (options, command) => {
|
|
12075
|
-
// 先在本地校验:`--page-size abc` 以前算出 NaN 发出去,表现成「参数没生效」。
|
|
12076
|
-
const pageSize = parsePageSize(options.pageSize, 10);
|
|
12077
|
-
const pageToken = parsePageToken(options.pageToken);
|
|
12078
|
-
const runtime = await getRuntime(command);
|
|
12079
|
-
const appId = await requireAppId(runtime.cwd, getDeployAppIdOption(options, command));
|
|
12080
|
-
const data = await runtime.client.listDeployHistory({
|
|
12081
|
-
app_id: appId,
|
|
12082
|
-
page_size: pageSize,
|
|
12083
|
-
page_token: pageToken,
|
|
12084
|
-
});
|
|
12085
|
-
runtime.output.print({
|
|
12086
|
-
items: (data.deploy_history_list || []).map(item => ({
|
|
12087
|
-
deploy_history_id: item.deploy_history_id,
|
|
12088
|
-
status: getDeployStatusText(item.status),
|
|
12089
|
-
commit_hash: item.commit_hash_short || item.commit_hash,
|
|
12090
|
-
commit_message: item.commit_message,
|
|
12091
|
-
created_at: item.created_at,
|
|
12092
|
-
can_rollback: item.can_rollback,
|
|
12093
|
-
deploy_detail: formatDeployDetails(item),
|
|
12094
|
-
connector_data_list: item.connector_data_list || [],
|
|
12095
|
-
...mobileArtifactsOutput(item),
|
|
12096
|
-
})),
|
|
12097
|
-
next_page_token: data.next_page_token,
|
|
12098
|
-
has_more: data.has_more,
|
|
12099
|
-
});
|
|
12100
|
-
});
|
|
12101
|
-
|
|
12102
|
-
deploy
|
|
12103
|
-
.command('online')
|
|
12104
|
-
.description('Show the current online deployment')
|
|
12105
|
-
.option('--app-id <appId>', 'Application ID')
|
|
12106
|
-
.action(async (options, command) => {
|
|
12107
|
-
const runtime = await getRuntime(command);
|
|
12108
|
-
const appId = await requireAppId(runtime.cwd, getDeployAppIdOption(options, command));
|
|
12109
|
-
const data = await runtime.client.getOnlineDeployHistory(appId);
|
|
12110
|
-
runtime.output.print({
|
|
12111
|
-
app_id: appId,
|
|
12112
|
-
items: (data.deploy_history_list || []).map(item => ({
|
|
12113
|
-
deploy_history_id: item.deploy_history_id,
|
|
12114
|
-
status: getDeployStatusText(item.status),
|
|
12115
|
-
commit_hash: item.commit_hash_short || item.commit_hash,
|
|
12116
|
-
commit_message: item.commit_message,
|
|
12117
|
-
created_at: item.created_at,
|
|
12118
|
-
deploy_detail: formatDeployDetails(item),
|
|
12119
|
-
domains: item.domain_list || [],
|
|
12120
|
-
...mobileArtifactsOutput(item),
|
|
12121
|
-
})),
|
|
12122
|
-
});
|
|
12123
|
-
});
|
|
12124
|
-
|
|
12125
|
-
deploy
|
|
12126
|
-
.command('rollback-check')
|
|
12127
|
-
.description('Check whether a deployment supports database rollback')
|
|
12128
|
-
.requiredOption('--deploy-id <deployId>', 'Target deployment history ID')
|
|
12129
|
-
.option('--app-id <appId>', 'Application ID')
|
|
12130
|
-
.action(async (options, command) => {
|
|
12131
|
-
const runtime = await getRuntime(command);
|
|
12132
|
-
const appId = await requireAppId(runtime.cwd, getDeployAppIdOption(options, command));
|
|
12133
|
-
const data = await runtime.client.checkRollbackDatabase({
|
|
12134
|
-
app_id: appId,
|
|
12135
|
-
deploy_history_id: options.deployId || '',
|
|
12136
|
-
});
|
|
12137
|
-
runtime.output.print({ app_id: appId, deploy_history_id: options.deployId, ...data });
|
|
12138
|
-
});
|
|
12139
|
-
|
|
12140
|
-
deploy
|
|
12141
|
-
.command('log-count')
|
|
12142
|
-
.description('Show runtime log count and limit')
|
|
12143
|
-
.option('--app-id <appId>', 'Application ID')
|
|
12144
|
-
.action(async (options, command) => {
|
|
12145
|
-
const runtime = await getRuntime(command);
|
|
12146
|
-
const appId = await requireAppId(runtime.cwd, getDeployAppIdOption(options, command));
|
|
12147
|
-
const data = await runtime.client.getRuntimeLogCount(appId);
|
|
12148
|
-
runtime.output.print({ app_id: appId, ...data });
|
|
12149
|
-
});
|
|
12150
|
-
|
|
12151
|
-
deploy
|
|
12152
|
-
.command('count')
|
|
12153
|
-
.description('Show successful deployment count')
|
|
12154
|
-
.option('--app-id <appId>', 'Application ID')
|
|
12155
|
-
.action(async (options, command) => {
|
|
12156
|
-
const runtime = await getRuntime(command);
|
|
12157
|
-
const appId = await requireAppId(runtime.cwd, getDeployAppIdOption(options, command));
|
|
12158
|
-
const data = await runtime.client.getDeployCount(appId);
|
|
12159
|
-
runtime.output.print({ app_id: appId, ...data });
|
|
12160
|
-
});
|
|
12161
|
-
};
|
|
12162
|
-
|
|
12163
|
-
const registerEnv = (code) => {
|
|
12164
|
-
const env = code
|
|
12165
|
-
.command('env')
|
|
12166
|
-
.description('Inspect the current online environment snapshot');
|
|
12167
|
-
|
|
12168
|
-
env
|
|
12169
|
-
.command('list')
|
|
12170
|
-
.description('List environment variables of the current online deployment')
|
|
12171
|
-
.option('--app-id <appId>', 'Application ID')
|
|
12172
|
-
.action(async (options, command) => {
|
|
12173
|
-
const runtime = await getRuntime(command);
|
|
12174
|
-
const appId = await requireAppId(
|
|
12175
|
-
runtime.cwd,
|
|
12176
|
-
getDeployAppIdOption(options, command),
|
|
12177
|
-
);
|
|
12178
|
-
runtime.output.print(await runtime.client.getOnlineEnvironment(appId));
|
|
12179
|
-
});
|
|
12180
|
-
};
|
|
12181
|
-
|
|
12182
|
-
/* eslint-disable security/detect-non-literal-fs-filename -- validated project-local build output paths */
|
|
12183
|
-
|
|
12184
|
-
const BUILD_OUTPUT_DIRS = new Set(['dist', 'dist-tt']);
|
|
12185
|
-
const EXCLUDED_PARTS = new Set([
|
|
12186
|
-
'.git',
|
|
12187
|
-
'.env',
|
|
12188
|
-
'node_modules',
|
|
12189
|
-
]);
|
|
12190
|
-
const REPRODUCIBLE_ARCHIVE_MTIME = new Date(0);
|
|
12191
|
-
|
|
12192
|
-
const validateBuildOutput = async (
|
|
12193
|
-
sourceRoot,
|
|
12194
|
-
buildOutputDir,
|
|
12195
|
-
) => {
|
|
12196
|
-
if (!BUILD_OUTPUT_DIRS.has(buildOutputDir)) {
|
|
12197
|
-
throw new CliError(
|
|
12198
|
-
`Unsupported Mini-program build output directory: ${buildOutputDir}.`,
|
|
12199
|
-
'SOURCE_PACKAGE_FAILED',
|
|
12200
|
-
);
|
|
12201
|
-
}
|
|
12202
|
-
const buildOutputRoot = node_path.resolve(sourceRoot, buildOutputDir);
|
|
12203
|
-
try {
|
|
12204
|
-
const info = await promises.lstat(buildOutputRoot);
|
|
12205
|
-
if (info.isSymbolicLink() || !info.isDirectory()) {
|
|
12206
|
-
throw new Error('build output must be a regular directory');
|
|
12207
|
-
}
|
|
12208
|
-
const realSourceRoot = await promises.realpath(sourceRoot);
|
|
12209
|
-
const realBuildOutputRoot = await promises.realpath(buildOutputRoot);
|
|
12210
|
-
const relativeOutput = node_path.relative(realSourceRoot, realBuildOutputRoot);
|
|
12211
|
-
if (!relativeOutput || relativeOutput.startsWith('..')) {
|
|
12212
|
-
throw new Error('build output must be inside the source root');
|
|
12213
|
-
}
|
|
12214
|
-
} catch (error) {
|
|
12215
|
-
throw new CliError(
|
|
12216
|
-
`Invalid Mini-program build output ${buildOutputRoot}: ${error instanceof Error ? error.message : String(error)}`,
|
|
12217
|
-
'SOURCE_PACKAGE_FAILED',
|
|
12218
|
-
);
|
|
12219
|
-
}
|
|
12220
|
-
};
|
|
12221
|
-
|
|
12222
|
-
const shouldInclude = (
|
|
12223
|
-
archivePath,
|
|
12224
|
-
entry,
|
|
12225
|
-
) => {
|
|
12226
|
-
if ('isSymbolicLink' in entry && entry.isSymbolicLink()) {
|
|
12227
|
-
return false;
|
|
12228
|
-
}
|
|
12229
|
-
return !archivePath.split(/[\\/]/u).some(part =>
|
|
12230
|
-
EXCLUDED_PARTS.has(part) || part.startsWith('.git'),
|
|
12231
|
-
);
|
|
12232
|
-
};
|
|
12233
|
-
|
|
12234
|
-
const createMiniProgramPackage = async (
|
|
12235
|
-
sourceRoot,
|
|
12236
|
-
buildOutputDir,
|
|
12237
|
-
) => {
|
|
12238
|
-
const resolvedSourceRoot = node_path.resolve(sourceRoot);
|
|
12239
|
-
await validateBuildOutput(resolvedSourceRoot, buildOutputDir);
|
|
12240
|
-
const tempDirectory = await promises.mkdtemp(node_path.join(node_os.tmpdir(), 'coze-mini-program-source-'));
|
|
12241
|
-
const outputPath = node_path.join(tempDirectory, 'source.tar.gz');
|
|
12242
|
-
try {
|
|
12243
|
-
await tar.create(
|
|
12244
|
-
{
|
|
12245
|
-
cwd: resolvedSourceRoot,
|
|
12246
|
-
file: outputPath,
|
|
12247
|
-
filter: shouldInclude,
|
|
12248
|
-
gzip: true,
|
|
12249
|
-
mtime: REPRODUCIBLE_ARCHIVE_MTIME,
|
|
12250
|
-
portable: true,
|
|
12251
|
-
},
|
|
12252
|
-
[buildOutputDir],
|
|
12253
|
-
);
|
|
12254
|
-
const info = await promises.stat(outputPath);
|
|
12255
|
-
if (info.size === 0) {
|
|
12256
|
-
throw new Error('source archive is empty');
|
|
12257
|
-
}
|
|
12258
|
-
return {
|
|
12259
|
-
path: outputPath,
|
|
12260
|
-
sizeBytes: info.size,
|
|
12261
|
-
cleanup: () => promises.rm(tempDirectory, { recursive: true, force: true }),
|
|
12262
|
-
};
|
|
12263
|
-
} catch (error) {
|
|
12264
|
-
await promises.rm(tempDirectory, { recursive: true, force: true });
|
|
12265
|
-
throw new CliError(
|
|
12266
|
-
`Unable to package Mini-program build output: ${error instanceof Error ? error.message : String(error)}`,
|
|
12267
|
-
'SOURCE_PACKAGE_FAILED',
|
|
12268
|
-
);
|
|
12269
|
-
}
|
|
12270
|
-
};
|
|
12271
|
-
|
|
12272
|
-
function _nullishCoalesce$1(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; }
|
|
12273
|
-
const CONNECTOR_IDS = {
|
|
12274
|
-
wechat: '10000127',
|
|
12275
|
-
douyin: '10000126',
|
|
12276
|
-
} ;
|
|
12277
|
-
|
|
12278
|
-
const MINI_PROGRAM_BUILD_OUTPUT_DIRS = {
|
|
12279
|
-
wechat: 'dist',
|
|
12280
|
-
douyin: 'dist-tt',
|
|
12281
|
-
} ;
|
|
12282
|
-
|
|
12283
|
-
|
|
12284
|
-
|
|
12285
|
-
|
|
12286
|
-
|
|
12287
|
-
|
|
12288
|
-
|
|
12289
|
-
|
|
12290
|
-
|
|
12291
|
-
|
|
12292
|
-
|
|
12293
|
-
|
|
12294
|
-
|
|
12295
|
-
|
|
12296
|
-
|
|
12297
|
-
const resolveConnectorId = (platform) => {
|
|
12298
|
-
const connectorId = CONNECTOR_IDS[platform ];
|
|
12299
|
-
if (!connectorId) {
|
|
12300
|
-
throw new CliError(
|
|
12301
|
-
`Unsupported Mini-program platform ${String(platform)}; expected wechat or douyin.`,
|
|
12302
|
-
'INVALID_MINIPROGRAM_PLATFORM',
|
|
12303
|
-
);
|
|
12304
|
-
}
|
|
12305
|
-
return connectorId;
|
|
12306
|
-
};
|
|
12307
|
-
|
|
12308
|
-
const resolveBuildOutputDir = (platform) => {
|
|
12309
|
-
const outputDir =
|
|
12310
|
-
MINI_PROGRAM_BUILD_OUTPUT_DIRS[platform ];
|
|
12311
|
-
if (!outputDir) {
|
|
12312
|
-
throw new CliError(
|
|
12313
|
-
`Unsupported Mini-program platform ${String(platform)}; expected wechat or douyin.`,
|
|
12314
|
-
'INVALID_MINIPROGRAM_PLATFORM',
|
|
12315
|
-
);
|
|
12316
|
-
}
|
|
12317
|
-
return outputDir;
|
|
12318
|
-
};
|
|
12319
|
-
|
|
12320
|
-
const resolveProjectId = async (
|
|
12321
|
-
command,
|
|
12322
|
-
options,
|
|
12323
|
-
) => {
|
|
12324
|
-
if (_optionalChain$3([options, 'access', _ => _.projectId, 'optionalAccess', _2 => _2.trim, 'call', _3 => _3()])) {
|
|
12325
|
-
return options.projectId.trim();
|
|
12326
|
-
}
|
|
12327
|
-
const runtime = await getRuntime(command);
|
|
12328
|
-
const sourceRoot = node_path.resolve(runtime.cwd, options.sourceRoot || '.');
|
|
12329
|
-
const metadata = await readProjectMetadata(sourceRoot);
|
|
12330
|
-
if (!metadata.projectId) {
|
|
12331
|
-
throw new CliError(
|
|
12332
|
-
'Project ID is required. Pass --project-id or use a source directory whose .coze [project] contains project_id.',
|
|
12333
|
-
'PROJECT_ID_REQUIRED',
|
|
12334
|
-
);
|
|
12335
|
-
}
|
|
12336
|
-
return metadata.projectId;
|
|
12337
|
-
};
|
|
12338
|
-
|
|
12339
|
-
const MINI_PROGRAM_AUTH_STATUS = {
|
|
12340
|
-
authorized: 1,
|
|
12341
|
-
needAuthorize: 2,
|
|
12342
|
-
boundToOtherUser: 3,
|
|
12343
|
-
} ;
|
|
12344
|
-
|
|
12345
|
-
const getBoundToOtherUserMessage = (platform) => {
|
|
12346
|
-
const platformName = platform === 'wechat' ? 'WeChat' : 'Douyin';
|
|
12347
|
-
const platformConsole =
|
|
12348
|
-
platform === 'wechat' ? 'WeChat Public Platform' : 'Douyin Open Platform';
|
|
12349
|
-
return [
|
|
12350
|
-
`This ${platformName} Mini-program AppID is authorized by another Coze user.`,
|
|
12351
|
-
`If this is an AppID you manage, revoke Coze's previous third-party platform authorization in the ${platformConsole}, then rerun this auth command. The CLI will recheck the AppID and authorize it for your current Coze account.`,
|
|
12352
|
-
'If this is not your AppID, change --mini-app-id to an AppID for which you have administrator permission, then rerun this auth command.',
|
|
12353
|
-
].join(' ');
|
|
12354
|
-
};
|
|
12355
|
-
|
|
12356
|
-
const getAuthRequiredMessage = () =>
|
|
12357
|
-
'This Mini-program AppID is not authorized for the current Coze user. Run `coze-dev deploy code mini-program auth` first.';
|
|
12358
|
-
|
|
12359
|
-
const getPreviewFailureMessage = (data
|
|
12360
|
-
|
|
12361
|
-
|
|
12362
|
-
) =>
|
|
12363
|
-
_optionalChain$3([data, 'access', _4 => _4.stderr, 'optionalAccess', _5 => _5.trim, 'call', _6 => _6()]) || _optionalChain$3([data, 'access', _7 => _7.stdout, 'optionalAccess', _8 => _8.trim, 'call', _9 => _9()]) || 'Mini-program preview failed.';
|
|
12364
|
-
|
|
12365
|
-
const registerAuthorizationCommand = (miniProgram) => {
|
|
12366
|
-
miniProgram
|
|
12367
|
-
.command('auth')
|
|
12368
|
-
.description('Authorize a Mini-program AppID for the current Coze user')
|
|
12369
|
-
.requiredOption('--platform <platform>', 'wechat or douyin')
|
|
12370
|
-
.requiredOption('--mini-app-id <miniAppId>', 'Mini-program AppID')
|
|
12371
|
-
.option('--project-id <projectId>', 'Deployment Project ID')
|
|
12372
|
-
.option('--source-root <sourceRoot>', 'Directory containing .coze', '.')
|
|
12373
|
-
.action(async (options, command) => {
|
|
12374
|
-
const runtime = await getRuntime(command);
|
|
12375
|
-
const projectId = await resolveProjectId(command, options);
|
|
12376
|
-
const authorization = await runtime.client.authorizeMiniProgram({
|
|
12377
|
-
project_id: projectId,
|
|
12378
|
-
app_id: options.miniAppId || '',
|
|
12379
|
-
connector_id: resolveConnectorId(options.platform),
|
|
12380
|
-
redirect_url: 'https://code.coze.cn/coding/auth/callback/miniprogram',
|
|
12381
|
-
});
|
|
12382
|
-
if (authorization.status === MINI_PROGRAM_AUTH_STATUS.needAuthorize) {
|
|
12383
|
-
runtime.output.print({
|
|
12384
|
-
project_id: projectId,
|
|
12385
|
-
mini_app_id: options.miniAppId,
|
|
12386
|
-
platform: options.platform,
|
|
12387
|
-
authorization_required: true,
|
|
12388
|
-
auth_url: authorization.auth_url,
|
|
12389
|
-
});
|
|
12390
|
-
return;
|
|
12391
|
-
}
|
|
12392
|
-
if (authorization.status === MINI_PROGRAM_AUTH_STATUS.boundToOtherUser) {
|
|
12393
|
-
throw new CliError(
|
|
12394
|
-
getBoundToOtherUserMessage(options.platform),
|
|
12395
|
-
'MINIPROGRAM_AUTHORIZED_BY_OTHER_USER',
|
|
12396
|
-
);
|
|
12397
|
-
}
|
|
12398
|
-
if (authorization.status !== MINI_PROGRAM_AUTH_STATUS.authorized) {
|
|
12399
|
-
throw new CliError(
|
|
12400
|
-
`Unexpected Mini-program authorization status: ${String(authorization.status)}.`,
|
|
12401
|
-
'INVALID_RESPONSE',
|
|
12402
|
-
);
|
|
12403
|
-
}
|
|
12404
|
-
runtime.output.print({
|
|
12405
|
-
project_id: projectId,
|
|
12406
|
-
mini_app_id: options.miniAppId,
|
|
12407
|
-
platform: options.platform,
|
|
12408
|
-
authorized: true,
|
|
12409
|
-
});
|
|
12410
|
-
});
|
|
12411
|
-
};
|
|
12412
|
-
|
|
12413
|
-
const registerPreviewCommand = (miniProgram) => {
|
|
12414
|
-
miniProgram
|
|
12415
|
-
.command('preview')
|
|
12416
|
-
.description('Create a Mini-program preview QR code from the local build artifact')
|
|
12417
|
-
.requiredOption('--platform <platform>', 'wechat or douyin')
|
|
12418
|
-
.requiredOption('--mini-app-id <miniAppId>', 'Mini-program AppID')
|
|
12419
|
-
.option('--project-id <projectId>', 'Deployment Project ID')
|
|
12420
|
-
.option('--source-root <sourceRoot>', 'Directory containing dist or dist-tt', '.')
|
|
12421
|
-
.option('--server-url <serverUrl>', 'Public HTTPS server URL to whitelist for this preview')
|
|
12422
|
-
.action(async (options, command) => {
|
|
12423
|
-
const runtime = await getRuntime(command);
|
|
12424
|
-
const projectId = await resolveProjectId(command, options);
|
|
12425
|
-
const authorization = await runtime.client.getMiniProgramAuthStatus({
|
|
12426
|
-
project_id: projectId,
|
|
12427
|
-
connector_id: resolveConnectorId(options.platform),
|
|
12428
|
-
});
|
|
12429
|
-
if (
|
|
12430
|
-
!authorization.is_authorized ||
|
|
12431
|
-
authorization.bound_related_id !== options.miniAppId
|
|
12432
|
-
) {
|
|
12433
|
-
throw new CliError(
|
|
12434
|
-
getAuthRequiredMessage(),
|
|
12435
|
-
'MINIPROGRAM_AUTH_REQUIRED',
|
|
12436
|
-
);
|
|
12437
|
-
}
|
|
12438
|
-
const sourceRoot = node_path.resolve(runtime.cwd, options.sourceRoot || '.');
|
|
12439
|
-
const buildOutputDir = resolveBuildOutputDir(options.platform);
|
|
12440
|
-
const sourcePackage = await createMiniProgramPackage(
|
|
12441
|
-
sourceRoot,
|
|
12442
|
-
buildOutputDir,
|
|
12443
|
-
);
|
|
12444
|
-
try {
|
|
12445
|
-
const content = await promises.readFile(sourcePackage.path);
|
|
12446
|
-
const data = await runtime.client.createMiniProgramPreview({
|
|
12447
|
-
project_id: projectId,
|
|
12448
|
-
app_id: options.miniAppId || '',
|
|
12449
|
-
connector_id: resolveConnectorId(options.platform),
|
|
12450
|
-
source_package_base64: content.toString('base64'),
|
|
12451
|
-
...(options.serverUrl ? { server_url: options.serverUrl } : {}),
|
|
12452
|
-
});
|
|
12453
|
-
if (data.failed) {
|
|
12454
|
-
throw new CliError(
|
|
12455
|
-
getPreviewFailureMessage(data),
|
|
12456
|
-
'MINIPROGRAM_PREVIEW_FAILED',
|
|
12457
|
-
);
|
|
12458
|
-
}
|
|
12459
|
-
runtime.output.print({
|
|
12460
|
-
project_id: projectId,
|
|
12461
|
-
mini_app_id: options.miniAppId,
|
|
12462
|
-
platform: options.platform,
|
|
12463
|
-
source_package_size_bytes: sourcePackage.sizeBytes,
|
|
12464
|
-
...data,
|
|
12465
|
-
});
|
|
12466
|
-
} finally {
|
|
12467
|
-
await sourcePackage.cleanup();
|
|
12468
|
-
}
|
|
12469
|
-
});
|
|
12470
|
-
};
|
|
12471
|
-
|
|
12472
|
-
const registerMiniProgram = (code) => {
|
|
12473
|
-
const miniProgram = code
|
|
12474
|
-
.command('mini-program')
|
|
12475
|
-
.alias('miniprogram')
|
|
12476
|
-
.description('Manage WeChat or Douyin Mini-program authorization');
|
|
12477
|
-
|
|
12478
|
-
miniProgram
|
|
12479
|
-
.command('status')
|
|
12480
|
-
.requiredOption('--platform <platform>', 'wechat or douyin')
|
|
12481
|
-
.option('--project-id <projectId>', 'Deployment Project ID')
|
|
12482
|
-
.option('--source-root <sourceRoot>', 'Directory containing .coze', '.')
|
|
12483
|
-
.action(async (options, command) => {
|
|
12484
|
-
const runtime = await getRuntime(command);
|
|
12485
|
-
const projectId = await resolveProjectId(command, options);
|
|
12486
|
-
const connectorId = resolveConnectorId(options.platform);
|
|
12487
|
-
const data = await runtime.client.getMiniProgramAuthStatus({
|
|
12488
|
-
project_id: projectId,
|
|
12489
|
-
connector_id: connectorId,
|
|
12490
|
-
});
|
|
12491
|
-
runtime.output.print({ project_id: projectId, platform: options.platform, ...data });
|
|
12492
|
-
});
|
|
12493
|
-
|
|
12494
|
-
miniProgram
|
|
12495
|
-
.command('bind')
|
|
12496
|
-
.requiredOption('--platform <platform>', 'wechat or douyin')
|
|
12497
|
-
.requiredOption('--mini-app-id <miniAppId>', 'Mini-program AppID')
|
|
12498
|
-
.requiredOption('--redirect-url <redirectUrl>', 'OAuth callback URL')
|
|
12499
|
-
.option('--project-id <projectId>', 'Deployment Project ID')
|
|
12500
|
-
.option('--source-root <sourceRoot>', 'Directory containing .coze', '.')
|
|
12501
|
-
.option('--override', 'Move an AppID already bound to another project owned by you')
|
|
12502
|
-
.action(async (options, command) => {
|
|
12503
|
-
const runtime = await getRuntime(command);
|
|
12504
|
-
const projectId = await resolveProjectId(command, options);
|
|
12505
|
-
const connectorId = resolveConnectorId(options.platform);
|
|
12506
|
-
const data = await runtime.client.bindMiniProgramAuth({
|
|
12507
|
-
project_id: projectId,
|
|
12508
|
-
connector_id: connectorId,
|
|
12509
|
-
redirect_url: options.redirectUrl || '',
|
|
12510
|
-
auth_params: { app_id: options.miniAppId || '' },
|
|
12511
|
-
override: _nullishCoalesce$1(options.override, () => ( false)),
|
|
12512
|
-
});
|
|
12513
|
-
runtime.output.print({
|
|
12514
|
-
project_id: projectId,
|
|
12515
|
-
platform: options.platform,
|
|
12516
|
-
mini_app_id: options.miniAppId,
|
|
12517
|
-
...data,
|
|
12518
|
-
});
|
|
12519
|
-
});
|
|
12520
|
-
|
|
12521
|
-
miniProgram
|
|
12522
|
-
.command('submit-code')
|
|
12523
|
-
.requiredOption('--platform <platform>', 'wechat or douyin')
|
|
12524
|
-
.requiredOption('--mini-app-id <miniAppId>', 'Mini-program AppID')
|
|
12525
|
-
.requiredOption('--code <code>', 'OAuth authorization code')
|
|
12526
|
-
.requiredOption('--verify-state <verifyState>', 'State returned by bind')
|
|
12527
|
-
.option('--project-id <projectId>', 'Deployment Project ID')
|
|
12528
|
-
.option('--source-root <sourceRoot>', 'Directory containing .coze', '.')
|
|
12529
|
-
.action(async (options, command) => {
|
|
12530
|
-
const runtime = await getRuntime(command);
|
|
12531
|
-
const projectId = await resolveProjectId(command, options);
|
|
12532
|
-
await runtime.client.submitMiniProgramAuthCode({
|
|
12533
|
-
project_id: projectId,
|
|
12534
|
-
connector_id: resolveConnectorId(options.platform),
|
|
12535
|
-
code: options.code || '',
|
|
12536
|
-
verify_state: options.verifyState || '',
|
|
12537
|
-
auth_params: { app_id: options.miniAppId || '' },
|
|
12538
|
-
});
|
|
12539
|
-
runtime.output.print({ project_id: projectId, platform: options.platform, bound: true });
|
|
12540
|
-
});
|
|
12541
|
-
|
|
12542
|
-
miniProgram
|
|
12543
|
-
.command('unbind')
|
|
12544
|
-
.requiredOption('--platform <platform>', 'wechat or douyin')
|
|
12545
|
-
.option('--project-id <projectId>', 'Deployment Project ID')
|
|
12546
|
-
.option('--source-root <sourceRoot>', 'Directory containing .coze', '.')
|
|
12547
|
-
.action(async (options, command) => {
|
|
12548
|
-
const runtime = await getRuntime(command);
|
|
12549
|
-
const projectId = await resolveProjectId(command, options);
|
|
12550
|
-
await runtime.client.unbindMiniProgramAuth({
|
|
12551
|
-
project_id: projectId,
|
|
12552
|
-
connector_id: resolveConnectorId(options.platform),
|
|
12553
|
-
});
|
|
12554
|
-
runtime.output.print({ project_id: projectId, platform: options.platform, unbound: true });
|
|
12555
|
-
});
|
|
12556
|
-
|
|
12557
|
-
registerAuthorizationCommand(miniProgram);
|
|
12558
|
-
registerPreviewCommand(miniProgram);
|
|
12559
|
-
};
|
|
12560
|
-
|
|
12561
|
-
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; }
|
|
12562
|
-
|
|
12563
|
-
const POLL_INTERVAL_MS = 3000;
|
|
12564
|
-
const MAX_CONSECUTIVE_RETRIES = 5;
|
|
12565
|
-
const TRANSIENT_RPC_ERROR_CODE = 230000001;
|
|
12566
|
-
/**
|
|
12567
|
-
* `--wait` 的总时长上限。
|
|
12568
|
-
*
|
|
12569
|
-
* Interrupted 不再算终态(见 status.ts),轮询只能靠这个兜底,否则一次卡住的部署会把 CLI
|
|
12570
|
-
* 永远挂在这里。取 60min 是照安卓构建定的:实测 10 分钟起步,中途还会经历若干次
|
|
12571
|
-
* Interrupted → 重新触发。
|
|
12572
|
-
*/
|
|
12573
|
-
const POLL_TIMEOUT_MS = 3600000; // 60min
|
|
12574
|
-
/** 心跳间隔:text 模式下每隔这么久报一次「还在跑」,免得长构建看起来像挂死。 */
|
|
12575
|
-
const HEARTBEAT_MS = 30000;
|
|
12576
|
-
|
|
12577
|
-
const wait = async () =>
|
|
12578
|
-
new Promise(resolve => setTimeout(resolve, POLL_INTERVAL_MS));
|
|
12579
|
-
|
|
12580
|
-
const isRetryablePollError = (error) =>
|
|
12581
|
-
error instanceof CliError &&
|
|
12582
|
-
error.code === 'API_REJECTED' &&
|
|
12583
|
-
Number(_optionalChain$2([error, 'access', _ => _.details, 'optionalAccess', _2 => _2.business_code])) === TRANSIENT_RPC_ERROR_CODE;
|
|
12584
|
-
|
|
12585
|
-
const pollHistory = async (
|
|
12586
|
-
command,
|
|
12587
|
-
appId,
|
|
12588
|
-
deployHistoryId,
|
|
12589
|
-
timeoutMs = POLL_TIMEOUT_MS,
|
|
12590
|
-
) => {
|
|
12591
|
-
const runtime = await getRuntime(command);
|
|
12592
|
-
const startedAt = Date.now();
|
|
12593
|
-
let consecutiveFailures = 0;
|
|
12594
|
-
let lastStatus;
|
|
12595
|
-
let lastBeatAt = startedAt;
|
|
12596
|
-
while (true) {
|
|
12597
|
-
const elapsed = () => Math.floor((Date.now() - startedAt) / 1000);
|
|
12598
|
-
try {
|
|
12599
|
-
const history = await runtime.client.getDeployHistory({
|
|
12600
|
-
app_id: appId,
|
|
12601
|
-
deploy_history_id: deployHistoryId,
|
|
12602
|
-
});
|
|
12603
|
-
consecutiveFailures = 0;
|
|
12604
|
-
const status = getDeployStatusText(history.status);
|
|
12605
|
-
runtime.output.debug(
|
|
12606
|
-
`[deploy] History ${deployHistoryId}: ${status} (${String(elapsed())}s elapsed)`,
|
|
12607
|
-
);
|
|
12608
|
-
if (history.status && TERMINAL_STATUSES.has(history.status)) {
|
|
12609
|
-
return history;
|
|
12610
|
-
}
|
|
12611
|
-
// 长构建(安卓十几分钟)期间给点动静:状态一变就报,否则每 30s 报一次还活着。
|
|
12612
|
-
// output.info 只在 text 模式写 stderr,json 模式是 no-op,不会污染机器可读输出。
|
|
12613
|
-
if (history.status !== lastStatus) {
|
|
12614
|
-
lastStatus = history.status;
|
|
12615
|
-
lastBeatAt = Date.now();
|
|
12616
|
-
runtime.output.info(`[deploy] ${status} (${String(elapsed())}s)`);
|
|
12617
|
-
} else if (Date.now() - lastBeatAt >= HEARTBEAT_MS) {
|
|
12618
|
-
lastBeatAt = Date.now();
|
|
12619
|
-
runtime.output.info(`[deploy] still ${status} (${String(elapsed())}s)`);
|
|
12620
|
-
}
|
|
12621
|
-
} catch (error) {
|
|
12622
|
-
if (!isRetryablePollError(error) || consecutiveFailures >= MAX_CONSECUTIVE_RETRIES) {
|
|
12623
|
-
throw error;
|
|
12624
|
-
}
|
|
12625
|
-
consecutiveFailures += 1;
|
|
12626
|
-
runtime.output.debug(
|
|
12627
|
-
`[deploy] Status check failed transiently; retrying (${String(consecutiveFailures)}/${String(MAX_CONSECUTIVE_RETRIES)}).`,
|
|
12628
|
-
);
|
|
12629
|
-
}
|
|
12630
|
-
if (Date.now() - startedAt >= timeoutMs) {
|
|
12631
|
-
throw new CliError(
|
|
12632
|
-
`Timed out after ${String(elapsed())}s waiting for deployment ${deployHistoryId}; ` +
|
|
12633
|
-
`last status: ${getDeployStatusText(lastStatus)}. The deployment may still be running — ` +
|
|
12634
|
-
'check it with `deploy code status`.',
|
|
12635
|
-
'DEPLOY_WAIT_TIMEOUT',
|
|
12636
|
-
{ app_id: appId, deploy_history_id: deployHistoryId, last_status: lastStatus },
|
|
12637
|
-
);
|
|
12638
|
-
}
|
|
12639
|
-
await wait();
|
|
12640
|
-
}
|
|
12641
|
-
};
|
|
12642
|
-
|
|
12643
|
-
const GENERAL_PROJECT_TYPE = 9;
|
|
12644
|
-
|
|
12645
|
-
/**
|
|
12646
|
-
* Map `.coze` `[project].project_type` to the VibeProjectType used when creating the
|
|
12647
|
-
* deployment project.
|
|
12648
|
-
*
|
|
12649
|
-
* The values on the left are the ones the deploy server understands (see `cozefileutil`
|
|
12650
|
-
* `ResolveDeployKindByProjectType` / `GeneralProjectTypeByCozeProjectType` in coze-coding);
|
|
12651
|
-
* the numbers on the right are `VibeProjectType` (idl/coze.coding.ide/project.thrift).
|
|
12652
|
-
*
|
|
12653
|
-
* Keeping the two in sync matters beyond project metadata: the created project type decides
|
|
12654
|
-
* the project-scoped `COZE_PROJECT_TYPE` secret injected into the runtime, whether a Postgres
|
|
12655
|
-
* database is provisioned for the project, and whether the traffic gateway enforces inbound
|
|
12656
|
-
* auth. Creating an `agent` project as General(9) therefore deploys successfully but leaves a
|
|
12657
|
-
* dead service: the agent template reads `COZE_PROJECT_TYPE` to pick its graph and needs
|
|
12658
|
-
* `PGDATABASE_URL` on startup.
|
|
12659
|
-
*
|
|
12660
|
-
* VibeProjectType WebApp(3) and AssistantAgent(8) are intentionally absent: no `.coze`
|
|
12661
|
-
* project_type maps to them.
|
|
12662
|
-
*/
|
|
12663
|
-
const resolveCreationProjectType = (
|
|
12664
|
-
projectType,
|
|
12665
|
-
) => {
|
|
12666
|
-
switch (projectType) {
|
|
12667
|
-
case 'agent':
|
|
12668
|
-
return 1;
|
|
12669
|
-
case 'workflow':
|
|
12670
|
-
case 'automation':
|
|
12671
|
-
return 2;
|
|
12672
|
-
case 'app':
|
|
12673
|
-
return 4;
|
|
12674
|
-
case 'skill':
|
|
12675
|
-
return 5;
|
|
12676
|
-
case 'web':
|
|
12677
|
-
case 'backend':
|
|
12678
|
-
return 6;
|
|
12679
|
-
case 'miniapp':
|
|
12680
|
-
case 'miniprogram':
|
|
12681
|
-
return 7;
|
|
12682
|
-
default:
|
|
12683
|
-
return GENERAL_PROJECT_TYPE;
|
|
12684
|
-
}
|
|
12685
|
-
};
|
|
12686
|
-
|
|
12687
|
-
const formatDeployment = (deployment) =>
|
|
12688
|
-
typeof deployment === 'object' && deployment
|
|
12689
|
-
? {
|
|
12690
|
-
...(deployment ),
|
|
12691
|
-
status: getDeployStatusText(
|
|
12692
|
-
Number((deployment ).status),
|
|
12693
|
-
),
|
|
12694
|
-
}
|
|
12695
|
-
: undefined;
|
|
12696
|
-
|
|
12697
|
-
const formatApplication = (application) => ({
|
|
12698
|
-
...application,
|
|
12699
|
-
online_deployment: formatDeployment(application.online_deployment),
|
|
12700
|
-
latest_deployment: formatDeployment(application.latest_deployment),
|
|
12701
|
-
});
|
|
12702
|
-
|
|
12703
|
-
// 对应 IDL 的 MetricTimeRange,数值与 V1 保持一致。
|
|
12704
|
-
const TIME_RANGES = {
|
|
12705
|
-
day: 1,
|
|
12706
|
-
week: 2,
|
|
12707
|
-
month: 3,
|
|
12708
|
-
yesterday: 4,
|
|
12709
|
-
'three-days': 5,
|
|
12710
|
-
};
|
|
12711
|
-
|
|
12712
|
-
const resolveTimeRange = (value) => {
|
|
12713
|
-
const timeRange = TIME_RANGES[value || 'day'];
|
|
12714
|
-
if (!timeRange) {
|
|
12715
|
-
throw new CliError(
|
|
12716
|
-
`Invalid time range; expected one of ${Object.keys(TIME_RANGES).join(', ')}.`,
|
|
12717
|
-
'INVALID_TIME_RANGE',
|
|
12718
|
-
{ time_range: value },
|
|
12719
|
-
);
|
|
12720
|
-
}
|
|
12721
|
-
return timeRange;
|
|
12722
|
-
};
|
|
12723
|
-
|
|
12724
|
-
const UNIT_TYPES = { dev: 1, prod: 2 };
|
|
12725
|
-
|
|
12726
|
-
// 改 Application 本身的两条写操作,都要显式 --yes 才生效。
|
|
12727
|
-
// 单独拎出来是因为它们和 registerApp 里其余只读命令性质不同(会改线上资产),
|
|
12728
|
-
// 顺带让 registerApp 保持在 max-line-per-function 之内。
|
|
12729
|
-
const registerAppMutations = (app) => {
|
|
12730
|
-
app
|
|
12731
|
-
.command('rename <name>')
|
|
12732
|
-
.description('Rename an application')
|
|
12733
|
-
.option('--app-id <appId>', 'Application ID')
|
|
12734
|
-
.option('--yes', 'Confirm rename')
|
|
12735
|
-
.action(async (name, options, command) => {
|
|
12736
|
-
if (!options.yes) {
|
|
12737
|
-
throw new CliError('Pass --yes to rename the application.', 'CONFIRMATION_REQUIRED');
|
|
12738
|
-
}
|
|
12739
|
-
const normalizedName = name.trim();
|
|
12740
|
-
if (!normalizedName || normalizedName.length > 255) {
|
|
12741
|
-
throw new CliError(
|
|
12742
|
-
'Application name must contain 1 to 255 characters.',
|
|
12743
|
-
'INVALID_APPLICATION_NAME',
|
|
12744
|
-
);
|
|
12745
|
-
}
|
|
12746
|
-
const runtime = await getRuntime(command);
|
|
12747
|
-
const appId = await requireAppId(runtime.cwd, options.appId);
|
|
12748
|
-
const application = await runtime.client.updateApplication({
|
|
12749
|
-
app_id: appId,
|
|
12750
|
-
name: normalizedName,
|
|
12751
|
-
});
|
|
12752
|
-
runtime.output.print(
|
|
12753
|
-
formatApplication(application ),
|
|
12754
|
-
);
|
|
12755
|
-
});
|
|
12756
|
-
app
|
|
12757
|
-
// 删除是终态、不可撤销,所以和 rename 一样必须显式 --yes。
|
|
12758
|
-
//
|
|
12759
|
-
// 服务端只接受 **Stopped** 的应用:还在服务的先 `code deploy stop --yes`,否则会拿到一条
|
|
12760
|
-
// 带当前状态的报错。这里刻意不替用户先停 —— 停服会真的把线上服务摘掉,那得是用户自己按的。
|
|
12761
|
-
.command('delete')
|
|
12762
|
-
.description('Delete a stopped application (irreversible)')
|
|
12763
|
-
.option('--app-id <appId>', 'Application ID')
|
|
12764
|
-
.option('--yes', 'Confirm delete')
|
|
12765
|
-
.action(async (options, command) => {
|
|
12766
|
-
if (!options.yes) {
|
|
12767
|
-
throw new CliError('Pass --yes to delete the application.', 'CONFIRMATION_REQUIRED');
|
|
12768
|
-
}
|
|
12769
|
-
const runtime = await getRuntime(command);
|
|
12770
|
-
const appId = await requireAppId(runtime.cwd, options.appId);
|
|
12771
|
-
await runtime.client.deleteApplication(appId);
|
|
12772
|
-
// 本地 .coze 里的 app_id 不动(这条命令可能是在别的目录带 --app-id 跑的),但要说清楚:
|
|
12773
|
-
// 不清掉它,同目录下一次 deploy 会打到一个已删除的应用上、被服务端拒。
|
|
12774
|
-
runtime.output.print({
|
|
12775
|
-
app_id: appId,
|
|
12776
|
-
deleted: true,
|
|
12777
|
-
note: 'Remove app_id from .coze [project] before deploying this directory again.',
|
|
12778
|
-
});
|
|
12779
|
-
});
|
|
12780
|
-
};
|
|
12781
|
-
|
|
12782
|
-
const registerApp = (code) => {
|
|
12783
|
-
const app = code.command('app').description('Manage deployment applications');
|
|
12784
|
-
registerAppMutations(app);
|
|
12785
|
-
app
|
|
12786
|
-
.command('list')
|
|
12787
|
-
// 列的是当前登录用户名下**跨 Project** 的全部 Application。没有 --project-id:
|
|
12788
|
-
// V2 的资产归属是 Owner 而不是 Project,同一个 Project 下的应用可以分属不同用户。
|
|
12789
|
-
// 也不传 user_id:服务端直接从登录态取,客户端传了也只能传自己。
|
|
12790
|
-
//
|
|
12791
|
-
// ⚠️ 服务端是真分页(一页最多 100 条),一次调用只回一页。要「我的全部应用」用 --all,
|
|
12792
|
-
// 它顺着 next_page_token 翻到底 —— 别再默认第一页就是全部。
|
|
12793
|
-
.option('--page-token <pageToken>', 'Pagination token (page number)')
|
|
12794
|
-
.option('--page-size <pageSize>', 'Page size', '20')
|
|
12795
|
-
.option('--all', 'Fetch every page by following next_page_token')
|
|
12796
|
-
.action(async (options, command) => {
|
|
12797
|
-
const pageSize = parsePageSize(options.pageSize, 20, APP_LIST_MAX_PAGE_SIZE);
|
|
12798
|
-
const pageToken = parsePageToken(options.pageToken);
|
|
12799
|
-
if (options.all && pageToken) {
|
|
12800
|
-
throw new CliError(
|
|
12801
|
-
'--all fetches every page and cannot be combined with --page-token.',
|
|
12802
|
-
'INVALID_PAGE_TOKEN',
|
|
12803
|
-
{ page_token: options.pageToken },
|
|
12804
|
-
);
|
|
12805
|
-
}
|
|
12806
|
-
const runtime = await getRuntime(command);
|
|
12807
|
-
const format = (items) =>
|
|
12808
|
-
items.map(item => formatApplication(item ));
|
|
12809
|
-
if (options.all) {
|
|
12810
|
-
const { items, pages } = await collectAllPages(next =>
|
|
12811
|
-
runtime.client.listApplications({ page_token: next, page_size: pageSize }),
|
|
12812
|
-
);
|
|
12813
|
-
runtime.output.print({ items: format(items), pages, has_more: false });
|
|
12814
|
-
return;
|
|
12815
|
-
}
|
|
12816
|
-
const data = await runtime.client.listApplications({
|
|
12817
|
-
page_token: pageToken,
|
|
12818
|
-
page_size: pageSize,
|
|
12819
|
-
});
|
|
12820
|
-
runtime.output.print({
|
|
12821
|
-
items: format(data.items),
|
|
12822
|
-
next_page_token: data.next_page_token,
|
|
12823
|
-
has_more: data.has_more,
|
|
12824
|
-
});
|
|
12825
|
-
});
|
|
12826
|
-
app
|
|
12827
|
-
.command('show')
|
|
12828
|
-
.requiredOption('--app-id <appId>', 'Application ID')
|
|
12829
|
-
.action(async (options, command) => {
|
|
12830
|
-
const runtime = await getRuntime(command);
|
|
12831
|
-
runtime.output.print(
|
|
12832
|
-
formatApplication(
|
|
12833
|
-
(await runtime.client.getApplication(options.appId))
|
|
12834
|
-
|
|
12835
|
-
|
|
12836
|
-
,
|
|
12837
|
-
),
|
|
12838
|
-
);
|
|
12839
|
-
});
|
|
12840
|
-
app
|
|
12841
|
-
.command('analytics')
|
|
12842
|
-
.description('Show PV / UV charts')
|
|
12843
|
-
.option('--app-id <appId>', 'Application ID')
|
|
12844
|
-
.option(
|
|
12845
|
-
'--time-range <timeRange>',
|
|
12846
|
-
`Time range: ${Object.keys(TIME_RANGES).join(', ')}`,
|
|
12847
|
-
'day',
|
|
12848
|
-
)
|
|
12849
|
-
.action(async (options, command) => {
|
|
12850
|
-
const timeRange = resolveTimeRange(options.timeRange);
|
|
12851
|
-
const runtime = await getRuntime(command);
|
|
12852
|
-
const appId = await requireAppId(runtime.cwd, options.appId);
|
|
12853
|
-
const data = await runtime.client.getUserAnalyticsMetrics({
|
|
12854
|
-
app_id: appId,
|
|
12855
|
-
time_range: timeRange,
|
|
12856
|
-
});
|
|
12857
|
-
runtime.output.print({ app_id: appId, charts: data.charts || [] });
|
|
12858
|
-
});
|
|
12859
|
-
app
|
|
12860
|
-
.command('metrics')
|
|
12861
|
-
.description('Show application runtime metrics')
|
|
12862
|
-
.option('--app-id <appId>', 'Application ID')
|
|
12863
|
-
.option(
|
|
12864
|
-
'--time-range <timeRange>',
|
|
12865
|
-
`Time range: ${Object.keys(TIME_RANGES).join(', ')}`,
|
|
12866
|
-
'day',
|
|
12867
|
-
)
|
|
12868
|
-
.action(async (options, command) => {
|
|
12869
|
-
const timeRange = resolveTimeRange(options.timeRange);
|
|
12870
|
-
const runtime = await getRuntime(command);
|
|
12871
|
-
const appId = await requireAppId(runtime.cwd, options.appId);
|
|
12872
|
-
const data = await runtime.client.getApplicationMetrics({
|
|
12873
|
-
app_id: appId,
|
|
12874
|
-
time_range: timeRange,
|
|
12875
|
-
});
|
|
12876
|
-
runtime.output.print({
|
|
12877
|
-
app_id: appId,
|
|
12878
|
-
charts: data.charts || [],
|
|
12879
|
-
stats: data.stats || [],
|
|
12880
|
-
});
|
|
12881
|
-
});
|
|
12882
|
-
app
|
|
12883
|
-
.command('usage')
|
|
12884
|
-
.description('Show monthly hosted usage')
|
|
12885
|
-
.option('--app-id <appId>', 'Application ID')
|
|
12886
|
-
.requiredOption('--bill-month <billMonth>', 'Billing month in YYYY-MM format')
|
|
12887
|
-
.action(async (options, command) => {
|
|
12888
|
-
const billMonth = options.billMonth || '';
|
|
12889
|
-
if (!/^\d{4}-(?:0[1-9]|1[0-2])$/u.test(billMonth)) {
|
|
12890
|
-
throw new CliError(
|
|
12891
|
-
'Invalid billing month; expected YYYY-MM.',
|
|
12892
|
-
'INVALID_BILL_MONTH',
|
|
12893
|
-
{ bill_month: billMonth },
|
|
12894
|
-
);
|
|
12895
|
-
}
|
|
12896
|
-
const runtime = await getRuntime(command);
|
|
12897
|
-
const appId = await requireAppId(runtime.cwd, options.appId);
|
|
12898
|
-
const data = await runtime.client.getHostedUsageMonthly({
|
|
12899
|
-
app_id: appId,
|
|
12900
|
-
bill_month: billMonth,
|
|
12901
|
-
});
|
|
12902
|
-
runtime.output.print({ app_id: appId, summary: data.summary });
|
|
12903
|
-
});
|
|
12904
|
-
};
|
|
12905
|
-
|
|
12906
|
-
const registerDomain = (code) => {
|
|
12907
|
-
const domain = code.command('domain').description('Manage application domains');
|
|
12908
|
-
domain
|
|
12909
|
-
.command('list')
|
|
12910
|
-
.option('--app-id <appId>', 'Application ID')
|
|
12911
|
-
.option('--unit-type <unitType>', 'Unit type: dev or prod', 'prod')
|
|
12912
|
-
.action(async (options, command) => {
|
|
12913
|
-
const unitType = UNIT_TYPES[options.unitType || 'prod'];
|
|
12914
|
-
if (!unitType) {
|
|
12915
|
-
throw new CliError(
|
|
12916
|
-
'Invalid unit type; expected dev or prod.',
|
|
12917
|
-
'INVALID_UNIT_TYPE',
|
|
12918
|
-
{ unit_type: options.unitType },
|
|
12919
|
-
);
|
|
12920
|
-
}
|
|
12921
|
-
const runtime = await getRuntime(command);
|
|
12922
|
-
const appId = await requireAppId(runtime.cwd, options.appId);
|
|
12923
|
-
const data = await runtime.client.listDomains(appId, unitType);
|
|
12924
|
-
runtime.output.print({
|
|
12925
|
-
app_id: appId,
|
|
12926
|
-
unit_type: options.unitType || 'prod',
|
|
12927
|
-
items: (data.items || []).map(item => ({
|
|
12928
|
-
id: item.id,
|
|
12929
|
-
domain_host: item.domain_host,
|
|
12930
|
-
})),
|
|
12931
|
-
});
|
|
12932
|
-
});
|
|
12933
|
-
domain
|
|
12934
|
-
// 改的是系统分配的 <prefix>.coze.site 的 prefix,不是 `domain add` 加进来的自定义域名 ——
|
|
12935
|
-
// 那类域名服务端只有 create/delete,域名串本身改不了。
|
|
12936
|
-
//
|
|
12937
|
-
// 和 rename 一样要 --yes:旧默认域名会立刻停止指向本应用,已经发出去的链接会失效。
|
|
12938
|
-
.command('set-prefix <prefix>')
|
|
12939
|
-
.description('Change the default domain prefix (<prefix>.coze.site)')
|
|
12940
|
-
.option('--app-id <appId>', 'Application ID')
|
|
12941
|
-
.option('--yes', 'Confirm prefix change')
|
|
12942
|
-
.action(async (prefix, options, command) => {
|
|
12943
|
-
if (!options.yes) {
|
|
12944
|
-
throw new CliError(
|
|
12945
|
-
'Pass --yes to change the default domain prefix.',
|
|
12946
|
-
'CONFIRMATION_REQUIRED',
|
|
12947
|
-
);
|
|
12948
|
-
}
|
|
12949
|
-
const normalizedPrefix = prefix.trim();
|
|
12950
|
-
// 只做形态校验:长度、保留词、占用与权益都由服务端判,客户端不复制第二套规则。
|
|
12951
|
-
if (!/^[a-z0-9](?:[a-z0-9-]*[a-z0-9])?$/u.test(normalizedPrefix)) {
|
|
12952
|
-
throw new CliError(
|
|
12953
|
-
'Invalid prefix; use lowercase letters, digits and hyphens, not starting or ending with a hyphen.',
|
|
12954
|
-
'INVALID_DOMAIN_PREFIX',
|
|
12955
|
-
{ prefix },
|
|
12956
|
-
);
|
|
12957
|
-
}
|
|
12958
|
-
const runtime = await getRuntime(command);
|
|
12959
|
-
const appId = await requireAppId(runtime.cwd, options.appId);
|
|
12960
|
-
const data = await runtime.client.updateDefaultDomainPrefix({
|
|
12961
|
-
app_id: appId,
|
|
12962
|
-
prefix: normalizedPrefix,
|
|
12963
|
-
});
|
|
12964
|
-
runtime.output.print({
|
|
12965
|
-
app_id: appId,
|
|
12966
|
-
prefix: normalizedPrefix,
|
|
12967
|
-
old_domain_host: data.old_domain_host_canonical,
|
|
12968
|
-
new_domain_host: data.new_domain_host_canonical,
|
|
12969
|
-
});
|
|
12970
|
-
});
|
|
12971
|
-
domain
|
|
12972
|
-
.command('add <domain>')
|
|
12973
|
-
.option('--app-id <appId>', 'Application ID')
|
|
12974
|
-
.action(async (domainHost, options, command) => {
|
|
12975
|
-
if (!/^[a-zA-Z0-9](?:[a-zA-Z0-9-]*\.)+[a-zA-Z0-9-]+$/u.test(domainHost)) {
|
|
12976
|
-
throw new CliError('Invalid domain.', 'INVALID_DOMAIN', { domain: domainHost });
|
|
12977
|
-
}
|
|
12978
|
-
const runtime = await getRuntime(command);
|
|
12979
|
-
const appId = await requireAppId(runtime.cwd, options.appId);
|
|
12980
|
-
await runtime.client.createDomain({ app_id: appId, domain: domainHost });
|
|
12981
|
-
runtime.output.print({ app_id: appId, domain: domainHost });
|
|
12982
|
-
});
|
|
12983
|
-
};
|
|
12984
|
-
|
|
12985
|
-
const PACKAGE_SCRIPT_CANDIDATES = [
|
|
12986
|
-
node_path.resolve(__dirname, 'deploy/package-project.js'),
|
|
12987
|
-
node_path.resolve(__dirname, '../../../scripts/deploy/package-project.js'),
|
|
12988
|
-
];
|
|
12989
|
-
|
|
12990
|
-
const packageCommand = (args) => {
|
|
12991
|
-
const packageScript = PACKAGE_SCRIPT_CANDIDATES.find(candidate =>
|
|
12992
|
-
node_fs.existsSync(candidate),
|
|
12993
|
-
);
|
|
12994
|
-
if (!packageScript) {
|
|
12995
|
-
throw new CliError(
|
|
12996
|
-
'The deployment packaging script is missing from this coze-dev installation.',
|
|
12997
|
-
'SOURCE_PACKAGE_FAILED',
|
|
12998
|
-
);
|
|
12999
|
-
}
|
|
13000
|
-
return [packageScript, ...args];
|
|
13001
|
-
};
|
|
13002
|
-
|
|
13003
|
-
const runPackageScript = async (args, debug = false) =>
|
|
13004
|
-
new Promise((resolvePromise, reject) => {
|
|
13005
|
-
const child = node_child_process.spawn(process.execPath, packageCommand(args), {
|
|
13006
|
-
stdio: ['ignore', 'pipe', 'pipe'],
|
|
13007
|
-
});
|
|
13008
|
-
let errorOutput = '';
|
|
13009
|
-
const forward = (chunk) => {
|
|
13010
|
-
const text = chunk.toString();
|
|
13011
|
-
if (debug) {
|
|
13012
|
-
process.stderr.write(text);
|
|
13013
|
-
}
|
|
13014
|
-
errorOutput = `${errorOutput}${text}`.slice(-65536);
|
|
13015
|
-
};
|
|
13016
|
-
child.stdout.on('data', forward);
|
|
13017
|
-
child.stderr.on('data', forward);
|
|
13018
|
-
child.once('error', reject);
|
|
13019
|
-
child.once('close', code => {
|
|
13020
|
-
if (code === 0) {
|
|
13021
|
-
resolvePromise();
|
|
13022
|
-
return;
|
|
13023
|
-
}
|
|
13024
|
-
reject(new Error(
|
|
13025
|
-
`Packaging process exited with code ${String(code)}${errorOutput ? `\n${errorOutput.trim()}` : ''}`,
|
|
13026
|
-
));
|
|
13027
|
-
});
|
|
13028
|
-
});
|
|
13029
|
-
|
|
13030
|
-
|
|
13031
|
-
|
|
13032
|
-
|
|
13033
|
-
|
|
13034
|
-
|
|
13035
|
-
|
|
13036
|
-
|
|
13037
|
-
|
|
13038
|
-
|
|
13039
|
-
|
|
13040
|
-
|
|
13041
|
-
const createSourcePackageArchive = async (
|
|
13042
|
-
sourceRoot,
|
|
13043
|
-
applicationType = 'service',
|
|
13044
|
-
debug = false,
|
|
13045
|
-
) => {
|
|
13046
|
-
const tempDirectory = await promises.mkdtemp(node_path.join(node_os.tmpdir(), 'coze-deploy-source-'));
|
|
13047
|
-
const outputPath = node_path.join(tempDirectory, 'source.tar.gz');
|
|
13048
|
-
try {
|
|
13049
|
-
await runPackageScript(
|
|
13050
|
-
[sourceRoot, outputPath, ...(applicationType === 'pages' ? ['--pages'] : [])],
|
|
13051
|
-
debug,
|
|
13052
|
-
);
|
|
13053
|
-
const info = await promises.stat(outputPath);
|
|
13054
|
-
if (info.size === 0) {
|
|
13055
|
-
throw new CliError('Source package is empty.', 'SOURCE_PACKAGE_FAILED');
|
|
13056
|
-
}
|
|
13057
|
-
return {
|
|
13058
|
-
path: outputPath,
|
|
13059
|
-
sizeBytes: info.size,
|
|
13060
|
-
cleanup: () => promises.rm(tempDirectory, { recursive: true, force: true }),
|
|
13061
|
-
};
|
|
13062
|
-
} catch (error) {
|
|
13063
|
-
await promises.rm(tempDirectory, { recursive: true, force: true });
|
|
13064
|
-
if (error instanceof CliError) {
|
|
13065
|
-
throw error;
|
|
13066
|
-
}
|
|
13067
|
-
throw new CliError(
|
|
13068
|
-
`Unable to package local source: ${error instanceof Error ? error.message : String(error)}`,
|
|
13069
|
-
'SOURCE_PACKAGE_FAILED',
|
|
13070
|
-
);
|
|
13071
|
-
}
|
|
13072
|
-
};
|
|
13073
|
-
|
|
13074
|
-
const UPLOAD_SESSION_FILENAME = '.coze-deploy-upload.json';
|
|
13075
|
-
|
|
13076
|
-
|
|
13077
|
-
|
|
13078
|
-
|
|
13079
|
-
|
|
13080
|
-
|
|
13081
|
-
|
|
13082
|
-
|
|
13083
|
-
|
|
13084
|
-
|
|
13085
|
-
|
|
13086
|
-
const isUploadSession = (value) => {
|
|
13087
|
-
if (!value || typeof value !== 'object') {
|
|
13088
|
-
return false;
|
|
13089
|
-
}
|
|
13090
|
-
const session = value ;
|
|
13091
|
-
return typeof session.idempotencyKey === 'string' &&
|
|
13092
|
-
typeof session.createdAt === 'number' &&
|
|
13093
|
-
typeof session.sourcePackageSizeBytes === 'number' &&
|
|
13094
|
-
Boolean(session.request && typeof session.request === 'object');
|
|
13095
|
-
};
|
|
13096
|
-
|
|
13097
|
-
const readUploadSession = async (sourceRoot) => {
|
|
13098
|
-
try {
|
|
13099
|
-
const parsed = safeJsonParse(
|
|
13100
|
-
await promises.readFile(node_path.join(sourceRoot, UPLOAD_SESSION_FILENAME), 'utf8'),
|
|
13101
|
-
undefined,
|
|
13102
|
-
);
|
|
13103
|
-
return isUploadSession(parsed) ? parsed : undefined;
|
|
13104
|
-
} catch (error) {
|
|
13105
|
-
if ((error ).code === 'ENOENT') {
|
|
13106
|
-
return undefined;
|
|
13107
|
-
}
|
|
13108
|
-
throw error;
|
|
13109
|
-
}
|
|
13110
|
-
};
|
|
13111
|
-
|
|
13112
|
-
const writeUploadSession = async (sourceRoot, session) => {
|
|
13113
|
-
const path = node_path.join(sourceRoot, UPLOAD_SESSION_FILENAME);
|
|
13114
|
-
const tempPath = node_path.join(node_path.dirname(path), `.coze-deploy-upload-${node_crypto.randomUUID()}.tmp`);
|
|
13115
|
-
await promises.mkdir(node_path.dirname(path), { recursive: true });
|
|
13116
|
-
try {
|
|
13117
|
-
await promises.writeFile(tempPath, `${JSON.stringify(session, null, 2)}\n`, { encoding: 'utf8', mode: 0o600 });
|
|
13118
|
-
await promises.rename(tempPath, path);
|
|
13119
|
-
} finally {
|
|
13120
|
-
await promises.rm(tempPath, { force: true });
|
|
13121
|
-
}
|
|
13122
|
-
};
|
|
13123
|
-
|
|
13124
|
-
const removeUploadSession = async (sourceRoot) => {
|
|
13125
|
-
await promises.rm(node_path.join(sourceRoot, UPLOAD_SESSION_FILENAME), { force: true });
|
|
13126
|
-
};
|
|
13127
|
-
|
|
13128
|
-
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; }
|
|
13129
|
-
const INLINE_SOURCE_PACKAGE_MAX_BYTES = 1024 * 1024;
|
|
13130
|
-
const PRE_DEPLOY_SESSION_TTL_MS = 2 * 60 * 60 * 1000;
|
|
13131
|
-
|
|
13132
|
-
const uploadFile = async (
|
|
13133
|
-
uploadUrl,
|
|
13134
|
-
requiredHeaders,
|
|
13135
|
-
archive,
|
|
13136
|
-
) => {
|
|
13137
|
-
const uploadRequest = {
|
|
13138
|
-
method: 'PUT',
|
|
13139
|
-
headers: requiredHeaders,
|
|
13140
|
-
body: node_stream.Readable.toWeb(node_fs.createReadStream(archive.path)) ,
|
|
13141
|
-
duplex: 'half',
|
|
13142
|
-
};
|
|
13143
|
-
const response = await fetch(uploadUrl, uploadRequest);
|
|
13144
|
-
if (!response.ok) {
|
|
13145
|
-
throw new CliError(`Direct artifact upload failed: ${response.status} ${response.statusText}`, 'ARTIFACT_UPLOAD_FAILED');
|
|
13146
|
-
}
|
|
13147
|
-
};
|
|
13148
|
-
|
|
13149
|
-
const createDeploymentWithSourcePackage = async (
|
|
13150
|
-
client,
|
|
13151
|
-
request,
|
|
13152
|
-
archive,
|
|
13153
|
-
sourceRoot,
|
|
13154
|
-
) => {
|
|
13155
|
-
if (archive.sizeBytes <= INLINE_SOURCE_PACKAGE_MAX_BYTES) {
|
|
13156
|
-
const content = await promises.readFile(archive.path);
|
|
13157
|
-
return {
|
|
13158
|
-
uploadMode: 'inline' ,
|
|
13159
|
-
result: await client.createDeployHistory({ ...request, source_package_base64: content.toString('base64') }),
|
|
13160
|
-
};
|
|
13161
|
-
}
|
|
13162
|
-
|
|
13163
|
-
const savedSession = await readUploadSession(sourceRoot);
|
|
13164
|
-
let retryRequest = request;
|
|
13165
|
-
let reconciledSession = savedSession;
|
|
13166
|
-
if (_optionalChain$1([savedSession, 'optionalAccess', _ => _.appId]) && savedSession.deployHistoryId) {
|
|
13167
|
-
const history = await client.getDeployHistory({
|
|
13168
|
-
app_id: savedSession.appId,
|
|
13169
|
-
deploy_history_id: savedSession.deployHistoryId,
|
|
13170
|
-
});
|
|
13171
|
-
switch (history.status) {
|
|
13172
|
-
case DEPLOY_STATUS.preDeploy:
|
|
13173
|
-
// The server is authoritative for the session lifetime. Reuse the
|
|
13174
|
-
// original key even if the local two-hour clock is close to expiry;
|
|
13175
|
-
// pre_upload will either refresh the URL or release an expired slot.
|
|
13176
|
-
break;
|
|
13177
|
-
case DEPLOY_STATUS.pending:
|
|
13178
|
-
case DEPLOY_STATUS.running:
|
|
13179
|
-
case DEPLOY_STATUS.interrupted:
|
|
13180
|
-
case DEPLOY_STATUS.succeeded:
|
|
13181
|
-
// The previous create request was accepted but its response may have
|
|
13182
|
-
// been lost. Do not upload or create another deployment.
|
|
13183
|
-
await removeUploadSession(sourceRoot);
|
|
13184
|
-
return {
|
|
13185
|
-
uploadMode: 'direct' ,
|
|
13186
|
-
result: {
|
|
13187
|
-
app_id: savedSession.appId,
|
|
13188
|
-
deploy_history_id: savedSession.deployHistoryId,
|
|
13189
|
-
status: history.status,
|
|
13190
|
-
version: typeof history.version === 'number' ? history.version : undefined,
|
|
13191
|
-
},
|
|
13192
|
-
};
|
|
13193
|
-
case DEPLOY_STATUS.failed:
|
|
13194
|
-
case DEPLOY_STATUS.canceled:
|
|
13195
|
-
// The reserved history can no longer be claimed. Start a new upload
|
|
13196
|
-
// against the Application that pre_upload already created.
|
|
13197
|
-
await removeUploadSession(sourceRoot);
|
|
13198
|
-
reconciledSession = undefined;
|
|
13199
|
-
retryRequest = {
|
|
13200
|
-
...request,
|
|
13201
|
-
project_id: undefined,
|
|
13202
|
-
app_id: savedSession.appId,
|
|
13203
|
-
};
|
|
13204
|
-
break;
|
|
13205
|
-
default:
|
|
13206
|
-
throw new CliError(
|
|
13207
|
-
`Unable to reconcile pre-deploy history ${savedSession.deployHistoryId}: unknown status ${String(history.status)}.`,
|
|
13208
|
-
'INVALID_RESPONSE',
|
|
13209
|
-
);
|
|
13210
|
-
}
|
|
13211
|
-
}
|
|
13212
|
-
const liveSavedSession = reconciledSession && (
|
|
13213
|
-
reconciledSession.appId && reconciledSession.deployHistoryId ||
|
|
13214
|
-
Date.now() - reconciledSession.createdAt < PRE_DEPLOY_SESSION_TTL_MS
|
|
13215
|
-
)
|
|
13216
|
-
? reconciledSession
|
|
13217
|
-
: undefined;
|
|
13218
|
-
if (liveSavedSession && liveSavedSession.sourcePackageSizeBytes !== archive.sizeBytes) {
|
|
13219
|
-
throw new CliError(
|
|
13220
|
-
'A different source package is waiting for upload. Cancel that deployment or wait for its two-hour session to expire.',
|
|
13221
|
-
'PRE_DEPLOY_SOURCE_CHANGED',
|
|
13222
|
-
);
|
|
13223
|
-
}
|
|
13224
|
-
if (reconciledSession && !liveSavedSession) {
|
|
13225
|
-
await removeUploadSession(sourceRoot);
|
|
13226
|
-
}
|
|
13227
|
-
const resumableSession = liveSavedSession;
|
|
13228
|
-
const session = resumableSession || {
|
|
13229
|
-
idempotencyKey: node_crypto.randomUUID(),
|
|
13230
|
-
createdAt: Date.now(),
|
|
13231
|
-
sourcePackageSizeBytes: archive.sizeBytes,
|
|
13232
|
-
request: retryRequest,
|
|
13233
|
-
};
|
|
13234
|
-
// Persist before preDeployUpload: if the server creates PreDeploy but the response is lost,
|
|
13235
|
-
// the next CLI run must reuse the same idempotency key.
|
|
13236
|
-
await writeUploadSession(sourceRoot, session);
|
|
13237
|
-
const preDeploy = await client.preDeployUpload({
|
|
13238
|
-
...session.request,
|
|
13239
|
-
source_package_size_bytes: String(archive.sizeBytes),
|
|
13240
|
-
idempotency_key: session.idempotencyKey,
|
|
13241
|
-
});
|
|
13242
|
-
await writeUploadSession(sourceRoot, {
|
|
13243
|
-
...session,
|
|
13244
|
-
appId: preDeploy.app_id,
|
|
13245
|
-
deployHistoryId: preDeploy.deploy_history_id,
|
|
13246
|
-
uploadReceipt: preDeploy.upload_receipt,
|
|
13247
|
-
});
|
|
13248
|
-
await uploadFile(preDeploy.upload_url, preDeploy.required_headers || {}, archive);
|
|
13249
|
-
const result = await client.createDeployHistory({
|
|
13250
|
-
...session.request,
|
|
13251
|
-
project_id: undefined,
|
|
13252
|
-
app_id: preDeploy.app_id,
|
|
13253
|
-
pre_deploy_history_id: preDeploy.deploy_history_id,
|
|
13254
|
-
upload_receipt: preDeploy.upload_receipt,
|
|
13255
|
-
source_package_size_bytes: String(archive.sizeBytes),
|
|
13256
|
-
});
|
|
13257
|
-
await removeUploadSession(sourceRoot);
|
|
13258
|
-
return { uploadMode: 'direct' , result };
|
|
13259
|
-
};
|
|
13260
|
-
|
|
13261
|
-
function _nullishCoalesce(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; }
|
|
13262
|
-
const SUPPORTED_MINIPROGRAM_CONNECTOR_IDS = new Set(['10000127', '10000126']);
|
|
13263
|
-
const collectConnectorId = (value, previous) => [
|
|
13264
|
-
...previous,
|
|
13265
|
-
value,
|
|
13266
|
-
];
|
|
13267
|
-
|
|
13268
|
-
const getConnectorConfigs = (connectorIds) =>
|
|
13269
|
-
(connectorIds || []).map(connectorId => {
|
|
13270
|
-
if (!SUPPORTED_MINIPROGRAM_CONNECTOR_IDS.has(connectorId)) {
|
|
13271
|
-
throw new CliError(
|
|
13272
|
-
`Unsupported connector ID ${connectorId}; expected 10000127 (WeChat) or 10000126 (Douyin).`,
|
|
13273
|
-
'INVALID_CONNECTOR_ID',
|
|
13274
|
-
);
|
|
13275
|
-
}
|
|
13276
|
-
return { connector_id: connectorId };
|
|
13277
|
-
});
|
|
13278
|
-
|
|
13279
|
-
// Keep deployment option and output contracts together for auditing against the V2 IDL.
|
|
13280
|
-
// eslint-disable-next-line @coze-arch/max-line-per-function -- keep V2 deployment contracts together
|
|
13281
|
-
const registerDeploy = (code) => {
|
|
13282
|
-
const deploy = code
|
|
13283
|
-
.command('deploy')
|
|
13284
|
-
.description('Deploy an application using deployment V2')
|
|
13285
|
-
.option('--source-root <sourceRoot>', 'Local source root', '.')
|
|
13286
|
-
.option('--project-id <projectId>', 'Project ID for the first deployment')
|
|
13287
|
-
.option('--app-id <appId>', 'Application ID')
|
|
13288
|
-
.option(
|
|
13289
|
-
'--application-type <type>',
|
|
13290
|
-
'Deployment application type: service, pages, or mini_program',
|
|
13291
|
-
)
|
|
13292
|
-
.option('-n, --name <name>', 'Application name for the first deployment')
|
|
13293
|
-
.option('--message <message>', 'Deployment message')
|
|
13294
|
-
.option(
|
|
13295
|
-
'--connector-id <connectorId>',
|
|
13296
|
-
'Mini-program channel: 10000127 (WeChat) or 10000126 (Douyin); repeatable',
|
|
13297
|
-
collectConnectorId,
|
|
13298
|
-
[],
|
|
13299
|
-
)
|
|
13300
|
-
.option('--wait', 'Wait for deployment completion')
|
|
13301
|
-
.option('--yes', 'Confirm deployment')
|
|
13302
|
-
// eslint-disable-next-line @coze-arch/max-line-per-function -- deployment orchestration is one auditable flow
|
|
13303
|
-
.action(async (options, command) => {
|
|
13304
|
-
const runtime = await getRuntime(command);
|
|
13305
|
-
const sourceRoot = node_path.resolve(runtime.cwd, options.sourceRoot || '.');
|
|
13306
|
-
const requestedApplicationType = parseApplicationType(options.applicationType);
|
|
13307
|
-
runtime.output.debug(`[deploy] Reading local project: ${sourceRoot}`);
|
|
13308
|
-
const localContext =
|
|
13309
|
-
await readDeployLocalContext(
|
|
13310
|
-
sourceRoot,
|
|
13311
|
-
requestedApplicationType,
|
|
13312
|
-
options.appId,
|
|
13313
|
-
runtime.client,
|
|
13314
|
-
);
|
|
13315
|
-
const { commitHash, isPagesDeployment } = localContext;
|
|
13316
|
-
let { metadata } = localContext;
|
|
13317
|
-
const deploymentName = _nullishCoalesce(options.name, () => ( metadata.name));
|
|
13318
|
-
let projectId = options.projectId || metadata.projectId;
|
|
13319
|
-
let appId = options.appId || metadata.appId;
|
|
13320
|
-
const appIdFromCoze = Boolean(metadata.appId && !options.appId);
|
|
13321
|
-
let projectCreated = false;
|
|
13322
|
-
let linkedApplicationType;
|
|
13323
|
-
if (appId) {
|
|
13324
|
-
const linkedApplication = await runtime.client.getApplication(appId);
|
|
13325
|
-
linkedApplicationType = linkedApplication.application_type;
|
|
13326
|
-
const linkedProjectId = linkedApplication.project_id;
|
|
13327
|
-
if (!options.appId && projectId && linkedProjectId && projectId !== linkedProjectId) {
|
|
13328
|
-
throw new CliError(
|
|
13329
|
-
`Project ${projectId} does not own application ${appId}; it belongs to project ${linkedProjectId}.`,
|
|
13330
|
-
'PROJECT_ID_CONFLICT',
|
|
13331
|
-
);
|
|
13332
|
-
}
|
|
13333
|
-
if (options.appId && linkedProjectId) {
|
|
13334
|
-
projectId = linkedProjectId;
|
|
13335
|
-
} else {
|
|
13336
|
-
projectId ||= linkedProjectId;
|
|
13337
|
-
}
|
|
13338
|
-
if (!projectId) {
|
|
13339
|
-
throw new CliError(
|
|
13340
|
-
`Application ${appId} did not return its associated project_id.`,
|
|
13341
|
-
'INVALID_RESPONSE',
|
|
13342
|
-
);
|
|
13343
|
-
}
|
|
13344
|
-
const inferredApplicationType = linkedApplicationType === 'pages'
|
|
13345
|
-
? 'pages'
|
|
13346
|
-
: inferApplicationTypeFromProjectType(metadata.projectType);
|
|
13347
|
-
const targetApplicationType = requestedApplicationType || inferredApplicationType;
|
|
13348
|
-
if (appIdFromCoze && targetApplicationType && linkedApplicationType !== targetApplicationType) {
|
|
13349
|
-
runtime.output.warn(
|
|
13350
|
-
`The linked application ${appId} is ${linkedApplicationType}, but ${targetApplicationType} is required. A new application will be created and written to .coze.`,
|
|
13351
|
-
);
|
|
13352
|
-
appId = undefined;
|
|
13353
|
-
}
|
|
13354
|
-
}
|
|
13355
|
-
if (!projectId) {
|
|
13356
|
-
runtime.output.debug(
|
|
13357
|
-
'[deploy] Creating a dedicated deployment project in personal space...',
|
|
13358
|
-
);
|
|
13359
|
-
// 账号归属只在建 Project 这一次定死:写进 project_settings.extra 之后,有登录态的首次
|
|
13360
|
-
// 部署和无登录态的预览初始化读到的是同一个账号。本地已经知道账号就不打这次接口。
|
|
13361
|
-
const cozeAccountId = await resolveCozeAccountId(runtime);
|
|
13362
|
-
const project = await runtime.client.createDeploymentProject({
|
|
13363
|
-
space_id: '0',
|
|
13364
|
-
user_query: deploymentName || 'CLI deployment project',
|
|
13365
|
-
project_type: resolveCreationProjectType(metadata.projectType),
|
|
13366
|
-
create_source: 'cli',
|
|
13367
|
-
project_settings: {
|
|
13368
|
-
project_symbol: 'v3.5',
|
|
13369
|
-
...(cozeAccountId ? { extra: { coze_account_id: cozeAccountId } } : {}),
|
|
13370
|
-
},
|
|
13371
|
-
});
|
|
13372
|
-
projectId = project.project_id;
|
|
13373
|
-
projectCreated = true;
|
|
13374
|
-
}
|
|
13375
|
-
if (metadata.projectId !== projectId) {
|
|
13376
|
-
metadata = await writeProjectBinding(sourceRoot, { projectId });
|
|
13377
|
-
}
|
|
13378
|
-
runtime.output.debug(`[deploy] Using project ${projectId} from ${projectCreated ? 'new project' : options.projectId ? '--project-id' : appId ? 'application binding' : '.coze'}`);
|
|
13379
|
-
const cozeFileContent = metadata.cozeFileContent;
|
|
13380
|
-
runtime.output.debug('[deploy] Loading deployment configuration...');
|
|
13381
|
-
const serverConfig = await runtime.client.getDeployConfig({
|
|
13382
|
-
...(appId ? { app_id: appId } : { project_id: projectId }),
|
|
13383
|
-
commit_hash: commitHash,
|
|
13384
|
-
...(isPagesDeployment ? { application_type: 'pages' } : {}),
|
|
13385
|
-
...(cozeFileContent ? { coze_file_content: cozeFileContent } : {}),
|
|
13386
|
-
});
|
|
13387
|
-
const config = withRequestedApplicationType(
|
|
13388
|
-
serverConfig,
|
|
13389
|
-
requestedApplicationType,
|
|
13390
|
-
Boolean(appId),
|
|
13391
|
-
);
|
|
13392
|
-
const applicationType = config.application_type;
|
|
13393
|
-
const connectorConfigs = getConnectorConfigs(options.connectorId);
|
|
13394
|
-
if (!options.yes) {
|
|
13395
|
-
runtime.output.debug('[deploy] Preflight complete; confirmation is required.');
|
|
13396
|
-
runtime.output.print({
|
|
13397
|
-
confirmation_required: true,
|
|
13398
|
-
app_id: appId,
|
|
13399
|
-
project_id: projectId,
|
|
13400
|
-
application_type: applicationType,
|
|
13401
|
-
commit_hash: commitHash,
|
|
13402
|
-
source_root: sourceRoot,
|
|
13403
|
-
deploy_config: config.deploy_config,
|
|
13404
|
-
current_version: config.current_version,
|
|
13405
|
-
next_version: config.next_version,
|
|
13406
|
-
risks: config.risk_list || [],
|
|
13407
|
-
...(!appId && deploymentName ? { name: deploymentName } : {}),
|
|
13408
|
-
message: options.message,
|
|
13409
|
-
lane: runtime.globalOptions.lane || runtime.config.xTTEnv,
|
|
13410
|
-
});
|
|
13411
|
-
return;
|
|
13412
|
-
}
|
|
13413
|
-
let encryptEnvVariable;
|
|
13414
|
-
if (applicationType !== 'pages') {
|
|
13415
|
-
runtime.output.debug('[deploy] Loading and encrypting online environment variables...');
|
|
13416
|
-
const onlineEnvironment = appId
|
|
13417
|
-
? await runtime.client.getOnlineEnvironment(appId)
|
|
13418
|
-
: undefined;
|
|
13419
|
-
if (onlineEnvironment && onlineEnvironment.snapshot_status >= 3) {
|
|
13420
|
-
throw new CliError(
|
|
13421
|
-
onlineEnvironment.status_message ||
|
|
13422
|
-
'The current online environment snapshot is unavailable.',
|
|
13423
|
-
'ONLINE_ENVIRONMENT_UNAVAILABLE',
|
|
13424
|
-
);
|
|
13425
|
-
}
|
|
13426
|
-
const envSecrets = (_optionalChain([onlineEnvironment, 'optionalAccess', _ => _.variables]) || [])
|
|
13427
|
-
.filter(variable => variable.source === 'user')
|
|
13428
|
-
.map(variable => ({
|
|
13429
|
-
secret_id: '',
|
|
13430
|
-
secret_key: variable.key,
|
|
13431
|
-
secret_val: variable.value,
|
|
13432
|
-
secret_type: 'user_custom' ,
|
|
13433
|
-
}));
|
|
13434
|
-
const encrypted = await runtime.client.encryptProjectSecret(projectId, envSecrets);
|
|
13435
|
-
encryptEnvVariable = encrypted.sealed_secrets;
|
|
13436
|
-
if (!encryptEnvVariable) {
|
|
13437
|
-
throw new CliError(
|
|
13438
|
-
'The project secret encryption API returned no sealed_secrets.',
|
|
13439
|
-
'INVALID_RESPONSE',
|
|
13440
|
-
);
|
|
13441
|
-
}
|
|
13442
|
-
}
|
|
13443
|
-
runtime.output.debug(
|
|
13444
|
-
`[deploy] Building and packaging ${applicationType} artifact...`,
|
|
13445
|
-
);
|
|
13446
|
-
const sourcePackage = await createSourcePackageArchive(
|
|
13447
|
-
sourceRoot,
|
|
13448
|
-
applicationType,
|
|
13449
|
-
runtime.globalOptions.debug,
|
|
13450
|
-
);
|
|
13451
|
-
runtime.output.debug(
|
|
13452
|
-
`[deploy] Package ready: ${String(sourcePackage.sizeBytes)} bytes`,
|
|
13453
|
-
);
|
|
13454
|
-
runtime.output.debug('[deploy] Uploading package and creating deployment...');
|
|
13455
|
-
const deploymentRequest = {
|
|
13456
|
-
...(appId ? { app_id: appId } : { project_id: projectId }),
|
|
13457
|
-
application_type: applicationType,
|
|
13458
|
-
commit_hash: commitHash,
|
|
13459
|
-
...(options.message ? { commit_message: options.message } : {}),
|
|
13460
|
-
...(!appId
|
|
13461
|
-
? { name: deploymentName, source_root: sourceRoot }
|
|
13462
|
-
: {}),
|
|
13463
|
-
is_sync_db_to_prod: false,
|
|
13464
|
-
table_sync_configs: [],
|
|
13465
|
-
connector_configs: connectorConfigs,
|
|
13466
|
-
...(cozeFileContent ? { coze_file_content: cozeFileContent } : {}),
|
|
13467
|
-
...(encryptEnvVariable
|
|
13468
|
-
? { encrypt_env_variable: encryptEnvVariable }
|
|
13469
|
-
: {}),
|
|
13470
|
-
...getCreateDeployConfig(config),
|
|
13471
|
-
};
|
|
13472
|
-
let deployment;
|
|
13473
|
-
try {
|
|
13474
|
-
deployment = await createDeploymentWithSourcePackage(runtime.client, deploymentRequest, sourcePackage, sourceRoot);
|
|
13475
|
-
} finally {
|
|
13476
|
-
await sourcePackage.cleanup();
|
|
13477
|
-
}
|
|
13478
|
-
const { result } = deployment;
|
|
13479
|
-
const deployHistoryId = resolveDeployHistoryId(
|
|
13480
|
-
result.deploy_history_id,
|
|
13481
|
-
result.prev_deploy_history_id,
|
|
13482
|
-
);
|
|
13483
|
-
if (!deployHistoryId) {
|
|
13484
|
-
throw new CliError('Deployment response returned no deploy_history_id.', 'INVALID_RESPONSE');
|
|
13485
|
-
}
|
|
13486
|
-
if (metadata.appId !== result.app_id || metadata.projectId !== projectId) {
|
|
13487
|
-
await writeProjectBinding(sourceRoot, {
|
|
13488
|
-
projectId,
|
|
13489
|
-
appId: result.app_id,
|
|
13490
|
-
});
|
|
13491
|
-
if (!appId) {
|
|
13492
|
-
runtime.output.warn(`Created application ${result.app_id} and saved it to .coze.`);
|
|
13493
|
-
}
|
|
13494
|
-
}
|
|
13495
|
-
if (options.wait) {
|
|
13496
|
-
runtime.output.debug('[deploy] Deployment accepted; waiting for completion...');
|
|
13497
|
-
} else {
|
|
13498
|
-
runtime.output.debug('[deploy] Deployment accepted.');
|
|
13499
|
-
}
|
|
13500
|
-
const history = options.wait
|
|
13501
|
-
? await pollHistory(command, result.app_id, deployHistoryId)
|
|
13502
|
-
: undefined;
|
|
13503
|
-
// 不带 --wait 时 history 是 undefined,产物必然还没落库:这里一定会带上
|
|
13504
|
-
// artifacts_pending,而不是甩一个看起来像「查过了,没有」的空数组出去。
|
|
13505
|
-
const effectiveStatus = _nullishCoalesce(_optionalChain([history, 'optionalAccess', _2 => _2.status]), () => ( result.status));
|
|
13506
|
-
runtime.output.print({
|
|
13507
|
-
app_id: result.app_id,
|
|
13508
|
-
deploy_history_id: deployHistoryId,
|
|
13509
|
-
version: result.version,
|
|
13510
|
-
commit_hash: commitHash,
|
|
13511
|
-
status: getDeployStatusText(effectiveStatus),
|
|
13512
|
-
source_package_size_bytes: sourcePackage.sizeBytes,
|
|
13513
|
-
upload_mode: deployment.uploadMode,
|
|
13514
|
-
local_link: appId && !projectCreated ? 'unchanged' : 'written',
|
|
13515
|
-
...mobileArtifactsOutput(history, effectiveStatus),
|
|
13516
|
-
});
|
|
13517
|
-
});
|
|
13518
|
-
|
|
13519
|
-
registerDeployReadCommands(deploy);
|
|
13520
|
-
|
|
13521
|
-
deploy
|
|
13522
|
-
.command('cancel')
|
|
13523
|
-
.requiredOption('--deploy-id <deployId>', 'Deployment history ID')
|
|
13524
|
-
.option('--app-id <appId>', 'Application ID')
|
|
13525
|
-
.option('--yes', 'Confirm cancellation')
|
|
13526
|
-
.action(async (options, command) => {
|
|
13527
|
-
const parentOptions = getDeployParentOptions(command);
|
|
13528
|
-
if (!options.yes && !parentOptions.yes) {
|
|
13529
|
-
throw new CliError('Pass --yes to cancel deployment.', 'CONFIRMATION_REQUIRED');
|
|
13530
|
-
}
|
|
13531
|
-
const runtime = await getRuntime(command);
|
|
13532
|
-
const appId = await requireAppId(runtime.cwd, getDeployAppIdOption(options, command));
|
|
13533
|
-
await runtime.client.cancelDeployHistory({
|
|
13534
|
-
app_id: appId,
|
|
13535
|
-
deploy_history_id: options.deployId || '',
|
|
13536
|
-
});
|
|
13537
|
-
runtime.output.print({ app_id: appId, canceled: true });
|
|
13538
|
-
});
|
|
13539
|
-
|
|
13540
|
-
deploy
|
|
13541
|
-
.command('rollback')
|
|
13542
|
-
.requiredOption('--deploy-id <deployId>', 'Target deployment history ID')
|
|
13543
|
-
.option('--app-id <appId>', 'Application ID')
|
|
13544
|
-
.option('--rollback-database', 'Rollback database')
|
|
13545
|
-
.option('--yes', 'Confirm rollback')
|
|
13546
|
-
.action(async (options, command) => {
|
|
13547
|
-
const parentOptions = getDeployParentOptions(command);
|
|
13548
|
-
if (!options.yes && !parentOptions.yes) {
|
|
13549
|
-
throw new CliError('Pass --yes to rollback.', 'CONFIRMATION_REQUIRED');
|
|
13550
|
-
}
|
|
13551
|
-
const runtime = await getRuntime(command);
|
|
13552
|
-
const appId = await requireAppId(runtime.cwd, getDeployAppIdOption(options, command));
|
|
13553
|
-
const data = await runtime.client.rollbackDeployHistory({
|
|
13554
|
-
app_id: appId,
|
|
13555
|
-
target_deploy_history_id: options.deployId || '',
|
|
13556
|
-
rollback_database: _nullishCoalesce(options.rollbackDatabase, () => ( false)),
|
|
13557
|
-
});
|
|
13558
|
-
runtime.output.print({ app_id: appId, ...data });
|
|
13559
|
-
});
|
|
13560
|
-
|
|
13561
|
-
// stop 不可逆(删函数 → Stopped,只能重新部署),pause 可逆(→ Paused,resume 能推回 Ready)。
|
|
13562
|
-
const applicationActions = {
|
|
13563
|
-
stop: (client, appId) => client.stopApplication(appId),
|
|
13564
|
-
resume: (client, appId) => client.resumeApplication(appId),
|
|
13565
|
-
pause: (client, appId) => client.pauseApplication(appId),
|
|
13566
|
-
} ;
|
|
13567
|
-
|
|
13568
|
-
for (const action of Object.keys(applicationActions) ) {
|
|
13569
|
-
deploy
|
|
13570
|
-
.command(action)
|
|
13571
|
-
.option('--app-id <appId>', 'Application ID')
|
|
13572
|
-
.option('--yes', `Confirm ${action}`)
|
|
13573
|
-
.action(async (options, command) => {
|
|
13574
|
-
const parentOptions = getDeployParentOptions(command);
|
|
13575
|
-
if (!options.yes && !parentOptions.yes) {
|
|
13576
|
-
throw new CliError(`Pass --yes to ${action}.`, 'CONFIRMATION_REQUIRED');
|
|
13577
|
-
}
|
|
13578
|
-
const runtime = await getRuntime(command);
|
|
13579
|
-
const appId = await requireAppId(runtime.cwd, getDeployAppIdOption(options, command));
|
|
13580
|
-
await applicationActions[action](runtime.client, appId);
|
|
13581
|
-
runtime.output.print({ app_id: appId, action, success: true });
|
|
13582
|
-
});
|
|
13583
|
-
}
|
|
13584
|
-
|
|
13585
|
-
deploy
|
|
13586
|
-
.command('logs')
|
|
13587
|
-
.option('--app-id <appId>', 'Application ID')
|
|
13588
|
-
.option('--start-time <startTime>', 'Start time in milliseconds')
|
|
13589
|
-
.option('--end-time <endTime>', 'End time in milliseconds')
|
|
13590
|
-
.option('--limit <limit>', 'Page size')
|
|
13591
|
-
.option('--cursor <cursor>', 'Pagination cursor')
|
|
13592
|
-
.option('--query <query>', 'Log keyword')
|
|
13593
|
-
.option('--level <level>', 'all, info, warn, or error')
|
|
13594
|
-
.action(async (options, command) => {
|
|
13595
|
-
const runtime = await getRuntime(command);
|
|
13596
|
-
const appId = await requireAppId(runtime.cwd, getDeployAppIdOption(options, command));
|
|
13597
|
-
runtime.output.print(
|
|
13598
|
-
await runtime.client.searchRuntimeLog({
|
|
13599
|
-
app_id: appId,
|
|
13600
|
-
start_time: options.startTime,
|
|
13601
|
-
end_time: options.endTime,
|
|
13602
|
-
limit: options.limit,
|
|
13603
|
-
cursor: options.cursor,
|
|
13604
|
-
query: options.query,
|
|
13605
|
-
level: options.level,
|
|
13606
|
-
}),
|
|
13607
|
-
);
|
|
13608
|
-
});
|
|
13609
|
-
|
|
13610
|
-
deploy
|
|
13611
|
-
.command('build-log')
|
|
13612
|
-
.requiredOption('--deploy-id <deployId>', 'Deployment history ID')
|
|
13613
|
-
.option('--key <key>', 'Deployment log key; inferred when the deployment has one log')
|
|
13614
|
-
.option('--app-id <appId>', 'Application ID')
|
|
13615
|
-
.action(async (options, command) => {
|
|
13616
|
-
const runtime = await getRuntime(command);
|
|
13617
|
-
const appId = await requireAppId(runtime.cwd, getDeployAppIdOption(options, command));
|
|
13618
|
-
let key = _optionalChain([options, 'access', _3 => _3.key, 'optionalAccess', _4 => _4.trim, 'call', _5 => _5()]);
|
|
13619
|
-
if (!key) {
|
|
13620
|
-
const history = await runtime.client.getDeployHistory({
|
|
13621
|
-
app_id: appId,
|
|
13622
|
-
deploy_history_id: options.deployId || '',
|
|
13623
|
-
});
|
|
13624
|
-
const keys = getDeployLogKeys(history);
|
|
13625
|
-
if (keys.length === 0) {
|
|
13626
|
-
throw new CliError(
|
|
13627
|
-
'The deployment has no build log key yet. Retry after deployment stages start.',
|
|
13628
|
-
'BUILD_LOG_NOT_READY',
|
|
13629
|
-
);
|
|
13630
|
-
}
|
|
13631
|
-
if (keys.length > 1) {
|
|
13632
|
-
throw new CliError(
|
|
13633
|
-
'The deployment has multiple build logs. Pass --key using deploy status output.',
|
|
13634
|
-
'BUILD_LOG_KEY_REQUIRED',
|
|
13635
|
-
{ available_keys: keys },
|
|
13636
|
-
);
|
|
13637
|
-
}
|
|
13638
|
-
key = keys[0];
|
|
13639
|
-
}
|
|
13640
|
-
if (!key) {
|
|
13641
|
-
throw new CliError('Deployment log key is empty.', 'BUILD_LOG_NOT_READY');
|
|
13642
|
-
}
|
|
13643
|
-
runtime.output.print(
|
|
13644
|
-
await runtime.client.getBuildLog({
|
|
13645
|
-
app_id: appId,
|
|
13646
|
-
deploy_history_id: options.deployId || '',
|
|
13647
|
-
key,
|
|
13648
|
-
}),
|
|
13649
|
-
);
|
|
13650
|
-
});
|
|
13651
|
-
|
|
13652
|
-
deploy
|
|
13653
|
-
.command('config')
|
|
13654
|
-
.option('--app-id <appId>', 'Application ID')
|
|
13655
|
-
.option('--commit-id <commitId>', 'Commit hash')
|
|
13656
|
-
.action(async (options, command) => {
|
|
13657
|
-
const runtime = await getRuntime(command);
|
|
13658
|
-
const appId = await requireAppId(runtime.cwd, getDeployAppIdOption(options, command));
|
|
13659
|
-
const application = await runtime.client.getApplication(appId);
|
|
13660
|
-
const commitHash = options.commitId || _optionalChain([application, 'access', _6 => _6.latest_deployment, 'optionalAccess', _7 => _7.commit_hash]);
|
|
13661
|
-
if (!commitHash) {
|
|
13662
|
-
throw new CliError('No deployment commit is available.', 'DEPLOYMENT_NOT_FOUND');
|
|
13663
|
-
}
|
|
13664
|
-
const applicationType = application.application_type;
|
|
13665
|
-
const cozeFileContent = applicationType === 'pages'
|
|
13666
|
-
? undefined
|
|
13667
|
-
: (await readProjectMetadata(node_path.resolve(runtime.cwd))).cozeFileContent;
|
|
13668
|
-
runtime.output.print(
|
|
13669
|
-
await runtime.client.getDeployConfig({
|
|
13670
|
-
app_id: appId,
|
|
13671
|
-
commit_hash: commitHash,
|
|
13672
|
-
...(applicationType === 'pages' ? { application_type: 'pages' } : {}),
|
|
13673
|
-
...(cozeFileContent ? { coze_file_content: cozeFileContent } : {}),
|
|
13674
|
-
}),
|
|
13675
|
-
);
|
|
13676
|
-
});
|
|
13677
|
-
};
|
|
13678
|
-
|
|
13679
|
-
const registerCommands = (program) => {
|
|
13680
|
-
registerAuth(program);
|
|
13681
|
-
registerContext(program);
|
|
13682
|
-
registerDoctor(program);
|
|
13683
|
-
const code = program.command('code').description('Deployment operations');
|
|
13684
|
-
registerApp(code);
|
|
13685
|
-
registerDeploy(code);
|
|
13686
|
-
registerDomain(code);
|
|
13687
|
-
registerEnv(code);
|
|
13688
|
-
registerMiniProgram(code);
|
|
13689
|
-
};
|
|
13690
|
-
|
|
13691
|
-
const configureDeployCommand = (command) => {
|
|
13692
|
-
markDeployCommand(command)
|
|
13693
|
-
.description('Deploy and manage Coze applications')
|
|
13694
|
-
.option('--format <format>', 'Output format: json or text', 'json')
|
|
13695
|
-
.option('--config <path>', 'Shared Coze CLI config path')
|
|
13696
|
-
.option('--org-id <id>', 'Override organization ID')
|
|
13697
|
-
.option('--space-id <id>', 'Override space ID')
|
|
13698
|
-
.option('--lane <name>', 'Route API requests to the specified PPE lane')
|
|
13699
|
-
.option('--api-base-url <url>', 'Override API base URL')
|
|
13700
|
-
.option('--debug', 'Print debug diagnostics')
|
|
13701
|
-
.showHelpAfterError()
|
|
13702
|
-
.exitOverride();
|
|
13703
|
-
registerCommands(command);
|
|
13704
|
-
return command;
|
|
13705
|
-
};
|
|
13706
|
-
|
|
13707
|
-
const registerCommand = (program) => {
|
|
13708
|
-
configureDeployCommand(program.command('deploy'));
|
|
13709
|
-
};
|
|
13710
|
-
|
|
13711
|
-
const readFormat = (argv) => {
|
|
13712
|
-
const index = argv.indexOf('--format');
|
|
13713
|
-
return index >= 0 && argv[index + 1] === 'text' ? 'text' : 'json';
|
|
13714
|
-
};
|
|
13715
|
-
|
|
13716
|
-
const handleDeployError = (error, argv = process.argv) => {
|
|
13717
|
-
if (
|
|
13718
|
-
error instanceof commander.CommanderError &&
|
|
13719
|
-
['commander.helpDisplayed', 'commander.version'].includes(error.code)
|
|
13720
|
-
) {
|
|
13721
|
-
return;
|
|
13722
|
-
}
|
|
13723
|
-
const output = new Output(readFormat(argv), argv.includes('--debug'));
|
|
13724
|
-
output.print({ error: toErrorPayload(error) });
|
|
13725
|
-
process.exitCode = error instanceof commander.CommanderError ? 4 : 1;
|
|
13726
|
-
};
|
|
13727
|
-
|
|
13728
|
-
const commands = [
|
|
13729
|
-
registerCommand$1,
|
|
13730
|
-
registerCommand$4,
|
|
13731
|
-
registerCommand$7,
|
|
13732
|
-
registerCommand$5,
|
|
13733
|
-
registerCommand$6,
|
|
13734
|
-
registerCommand$3,
|
|
13735
|
-
registerCommand$2,
|
|
13736
|
-
registerCommand,
|
|
13737
|
-
];
|
|
13738
|
-
|
|
13739
|
-
const main = async () => {
|
|
13740
|
-
// 初始化 Slardar 监控
|
|
13741
|
-
initSlardar();
|
|
13742
|
-
|
|
13743
|
-
// 监听未捕获的异常
|
|
13744
|
-
process.on('uncaughtException', async (error) => {
|
|
13745
|
-
reportError(error, {
|
|
13746
|
-
type: 'uncaughtException',
|
|
13747
|
-
context: 'global',
|
|
13748
|
-
});
|
|
13749
|
-
await flushSlardar();
|
|
13750
|
-
process.exit(1);
|
|
13751
|
-
});
|
|
13752
|
-
|
|
13753
|
-
// 监听未处理的 Promise rejection
|
|
13754
|
-
process.on('unhandledRejection', async (reason) => {
|
|
13755
|
-
const error = reason instanceof Error ? reason : new Error(String(reason));
|
|
13756
|
-
reportError(error, {
|
|
13757
|
-
type: 'unhandledRejection',
|
|
13758
|
-
context: 'global',
|
|
13759
|
-
});
|
|
13760
|
-
await flushSlardar();
|
|
13761
|
-
process.exit(1);
|
|
13762
|
-
});
|
|
13763
|
-
|
|
13764
|
-
const program = new commander.Command();
|
|
13765
|
-
|
|
13766
|
-
program
|
|
13767
|
-
.name('coze-dev')
|
|
13768
|
-
.description(
|
|
13769
|
-
'Coze Coding CLI - Project template engine for frontend stacks',
|
|
13770
|
-
)
|
|
13771
|
-
.version(packageJson.version);
|
|
13772
|
-
|
|
13773
|
-
commands.forEach(initCmd => initCmd(program));
|
|
13774
|
-
|
|
13775
|
-
// 在 help 输出中添加模板信息
|
|
13776
|
-
program.addHelpText('after', generateTemplatesHelpText());
|
|
10397
|
+
// 在 help 输出中添加模板信息
|
|
10398
|
+
program.addHelpText('after', generateTemplatesHelpText());
|
|
13777
10399
|
|
|
13778
10400
|
// 使用 parseAsync 等待命令执行完成
|
|
13779
|
-
|
|
13780
|
-
await program.parseAsync(process.argv);
|
|
13781
|
-
} catch (error) {
|
|
13782
|
-
if (process.argv[2] === 'deploy') {
|
|
13783
|
-
handleDeployError(error);
|
|
13784
|
-
} else {
|
|
13785
|
-
throw error;
|
|
13786
|
-
}
|
|
13787
|
-
}
|
|
10401
|
+
await program.parseAsync(process.argv);
|
|
13788
10402
|
|
|
13789
10403
|
// 统一在命令执行完成后 flush
|
|
13790
10404
|
// 注意:如果命令中调用了 process.exit(),不会执行到这里
|