@ones-open/cli 0.0.12-21205.1 → 0.0.12

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.js CHANGED
@@ -3,7 +3,7 @@ import { Command } from "commander";
3
3
  import { ErrorCode as ErrorCode$1, AppPackageJSONSchema, throwError, AppManifestJSONSchema, getPublicPath, PUBLIC_FILENAME, AppRcJSONSchema, AppManifestStrictJSONSchema, getCommandOptions, HostedTokenScope, addCommandUsage, addCommandOutput, $create as $create$1, setContext } from "create-ones-app";
4
4
  import { dirname, join, resolve, basename } from "node:path";
5
5
  import { spawnSync, spawn } from "node:child_process";
6
- import { readFileSync, createWriteStream } from "node:fs";
6
+ import { readFileSync, createWriteStream, createReadStream } from "node:fs";
7
7
  import fse from "fs-extra";
8
8
  import archiver from "archiver";
9
9
  import { get, merge, random, noop } from "lodash-es";
@@ -22,6 +22,9 @@ import http from "node:http";
22
22
  import open from "open";
23
23
  import { v4 } from "uuid";
24
24
  import PKCEChallenge from "pkce-challenge";
25
+ import { createHash } from "node:crypto";
26
+ import { pipeline } from "node:stream/promises";
27
+ import { homedir } from "node:os";
25
28
  const en = {
26
29
  "desc.ones": "ONES CLI/{env}",
27
30
  "desc.build": "Build your ONES App",
@@ -38,6 +41,13 @@ const en = {
38
41
  "desc.logout": "Log out of your ONES account",
39
42
  "desc.whoami": "Display the account information of the logged in user",
40
43
  "desc.app": "Manage app installations",
44
+ "desc.specs": "Manage ONES app specs resources to build your ONES App",
45
+ "desc.specs.fetch": "Fetch ONES app specs (download, checksum verify, and extract by default)",
46
+ "desc.specs.fetch.baseUrl": "Specify the base URL for specs resources",
47
+ "desc.specs.fetch.dir": "Specify the base directory (specs saved to <dir>/.ones/ones-app-specs)",
48
+ "desc.specs.fetch.noExtract": "Download only, do not extract archive automatically",
49
+ "desc.specs.fetch.json": "Output result in JSON format",
50
+ "desc.specs.fetch.force": "Force fetch even when local checksum is already up to date",
41
51
  "desc.install": "Install your ONES App",
42
52
  "desc.enable": "Enable your ONES App",
43
53
  "desc.disable": "Disable your ONES App",
@@ -63,7 +73,14 @@ const en = {
63
73
  "error.store.permission": 'Permission denied, please check the file permission with "{filePath}"',
64
74
  "error.hostedToken.requestFailed": "Failed to request hosted token",
65
75
  "error.hostedToken.empty": "Hosted token is empty",
66
- "error.legacy.create.missingProjectPath": "Project path is required"
76
+ "error.legacy.create.missingProjectPath": "Project path is required",
77
+ "error.specs.fetch.incorrectBaseURL": "Incorrect specs base URL",
78
+ "error.specs.fetch.fetchChecksumFailed": 'Failed to fetch checksum file from "{url}"',
79
+ "error.specs.fetch.incorrectChecksum": 'Invalid checksum content. Please provide a correct base URL that serves "ones-app-specs.sha256" in format "<sha256> <zip-file>". Received: "{preview}"',
80
+ "error.specs.fetch.downloadFailed": 'Failed to download specs archive from "{url}"',
81
+ "error.specs.fetch.extractFailed": 'Failed to extract archive "{file}": {reason}',
82
+ "error.specs.fetch.cleanupFailed": 'Failed to cleanup archive "{file}": {reason}',
83
+ "error.specs.fetch.verifyChecksumFailed": 'SHA256 verification failed, expected "{expected}" but got "{actual}"'
67
84
  };
68
85
  const map = {
69
86
  en
@@ -110,6 +127,10 @@ var ErrorCode = ((ErrorCode2) => {
110
127
  ErrorCode2["HOSTED_TOKEN_EMPTY"] = "E14";
111
128
  ErrorCode2["INCORRECT_DEV_COMMAND"] = "E15";
112
129
  ErrorCode2["INCORRECT_BUILD_COMMAND"] = "E16";
130
+ ErrorCode2["INCORRECT_SPECS_BASE_URL"] = "E17";
131
+ ErrorCode2["INCORRECT_SPECS_CHECKSUM"] = "E18";
132
+ ErrorCode2["SPECS_FETCH_FAILED"] = "E19";
133
+ ErrorCode2["SPECS_CHECKSUM_MISMATCH"] = "E20";
113
134
  return ErrorCode2;
114
135
  })(ErrorCode || {});
115
136
  const getPackageJSONPath = () => {
@@ -226,7 +247,7 @@ const getAppRcJSON = async () => {
226
247
  };
227
248
  const isOPKXFilename = /\.opkx$/;
228
249
  const defaultOutputPath = "";
229
- const normalize$b = async (options) => {
250
+ const normalize$c = async (options) => {
230
251
  var _options$output, _options$command;
231
252
  let output = resolve(cwd(), (_options$output = options.output) !== null && _options$output !== void 0 ? _options$output : defaultOutputPath);
232
253
  const command = (_options$command = options.command) !== null && _options$command !== void 0 ? _options$command : "";
@@ -245,7 +266,7 @@ const normalize$b = async (options) => {
245
266
  };
246
267
  const {
247
268
  existsSync,
248
- ensureDirSync
269
+ ensureDirSync: ensureDirSync$1
249
270
  } = fse;
250
271
  const build = async function() {
251
272
  var _appRcJSON$dev, _defaultAppRcJSON$dev, _appRcJSON$build$comm, _appRcJSON$build, _currentCommand$, _appRcJSON$build$comp, _appRcJSON$build2;
@@ -255,7 +276,7 @@ const build = async function() {
255
276
  const {
256
277
  options
257
278
  } = getCommandOptions(args, buildCommandArguments);
258
- const normalizedOptions = await normalize$b(options);
279
+ const normalizedOptions = await normalize$c(options);
259
280
  const appManifestJSON = getAppManifestJSON();
260
281
  const appRcJSON = await getAppRcJSON();
261
282
  const correctCommand = normalizedOptions.command || ((_appRcJSON$dev = appRcJSON.dev) === null || _appRcJSON$dev === void 0 || (_appRcJSON$dev = _appRcJSON$dev.command) === null || _appRcJSON$dev === void 0 ? void 0 : _appRcJSON$dev[0]) || ((_defaultAppRcJSON$dev = defaultAppRcJSON.dev) === null || _defaultAppRcJSON$dev === void 0 || (_defaultAppRcJSON$dev = _defaultAppRcJSON$dev.command) === null || _defaultAppRcJSON$dev === void 0 ? void 0 : _defaultAppRcJSON$dev[0]) || "";
@@ -303,7 +324,7 @@ const build = async function() {
303
324
  const outputPath = normalizedOptions.output;
304
325
  const outputDir = dirname(outputPath);
305
326
  const outputFilename = basename(outputPath);
306
- ensureDirSync(outputDir);
327
+ ensureDirSync$1(outputDir);
307
328
  const outputStream = createWriteStream(outputPath);
308
329
  const files = (_appRcJSON$build$comp = (_appRcJSON$build2 = appRcJSON.build) === null || _appRcJSON$build2 === void 0 || (_appRcJSON$build2 = _appRcJSON$build2.compress) === null || _appRcJSON$build2 === void 0 ? void 0 : _appRcJSON$build2.files) !== null && _appRcJSON$build$comp !== void 0 ? _appRcJSON$build$comp : [];
309
330
  const archive = archiver("zip", {
@@ -818,7 +839,7 @@ const resolveAppInfo = (input) => {
818
839
  process.exit(1);
819
840
  };
820
841
  const isPortNumber = /^[1-9]\d{0,4}$/;
821
- const normalize$a = async (options) => {
842
+ const normalize$b = async (options) => {
822
843
  var _options$clearStorage;
823
844
  const portInput = options.port;
824
845
  if (portInput)
@@ -1182,7 +1203,7 @@ const tunnel = async function() {
1182
1203
  const {
1183
1204
  options
1184
1205
  } = getCommandOptions(args, tunnelCommandArguments);
1185
- const normalizedOptions = await normalize$a(options);
1206
+ const normalizedOptions = await normalize$b(options);
1186
1207
  const port = Number(normalizedOptions.port);
1187
1208
  const cancelWaiting = startWaiting();
1188
1209
  await invokeTunnel(port, {
@@ -1194,7 +1215,7 @@ const tunnel = async function() {
1194
1215
  const tunnelUrl = await buildTunnelUrl();
1195
1216
  console.log(`Relay endpoint: ${tunnelUrl}`);
1196
1217
  };
1197
- const normalize$9 = async (options) => {
1218
+ const normalize$a = async (options) => {
1198
1219
  var _options$appID;
1199
1220
  noop(options);
1200
1221
  return {
@@ -1277,7 +1298,7 @@ const install = async function() {
1277
1298
  const {
1278
1299
  options
1279
1300
  } = getCommandOptions(args, installCommandArguments);
1280
- const normalizedOptions = await normalize$9(options);
1301
+ const normalizedOptions = await normalize$a(options);
1281
1302
  noop(normalizedOptions);
1282
1303
  const appInfo = resolveAppInfo({
1283
1304
  appID: options.appID
@@ -1304,7 +1325,7 @@ var DevCommandScripts = /* @__PURE__ */ ((DevCommandScripts2) => {
1304
1325
  return DevCommandScripts2;
1305
1326
  })(DevCommandScripts || {});
1306
1327
  const defaultInstall = InstallOptions.AUTO;
1307
- const normalize$8 = async (options) => {
1328
+ const normalize$9 = async (options) => {
1308
1329
  var _options$install, _options$command, _options$clearStorage;
1309
1330
  let install2 = (_options$install = options.install) !== null && _options$install !== void 0 ? _options$install : defaultInstall;
1310
1331
  const command = (_options$command = options.command) !== null && _options$command !== void 0 ? _options$command : "";
@@ -1375,7 +1396,7 @@ const dev = async function() {
1375
1396
  const {
1376
1397
  options
1377
1398
  } = getCommandOptions(args, devCommandArguments);
1378
- const normalizedOptions = await normalize$8(options);
1399
+ const normalizedOptions = await normalize$9(options);
1379
1400
  const appRcJSON = await getAppRcJSON();
1380
1401
  const correctCommand = normalizedOptions.command || ((_appRcJSON$dev = appRcJSON.dev) === null || _appRcJSON$dev === void 0 || (_appRcJSON$dev = _appRcJSON$dev.command) === null || _appRcJSON$dev === void 0 ? void 0 : _appRcJSON$dev[0]) || ((_defaultAppRcJSON$dev = defaultAppRcJSON.dev) === null || _defaultAppRcJSON$dev === void 0 || (_defaultAppRcJSON$dev = _defaultAppRcJSON$dev.command) === null || _defaultAppRcJSON$dev === void 0 ? void 0 : _defaultAppRcJSON$dev[0]) || "";
1381
1402
  if (!correctCommand) {
@@ -1601,7 +1622,7 @@ const sleep = (number) => {
1601
1622
  };
1602
1623
  const isURL = /^https?:\/\//;
1603
1624
  const HostBlackList = ["ones.cn", "www.ones.cn", "ones.com", "www.ones.com"];
1604
- const normalize$7 = async (options) => {
1625
+ const normalize$8 = async (options) => {
1605
1626
  const baseURLInput = options.baseURL;
1606
1627
  if (baseURLInput)
1607
1628
  ;
@@ -1639,7 +1660,7 @@ const login = async function() {
1639
1660
  const {
1640
1661
  options
1641
1662
  } = getCommandOptions(args, loginCommandArguments);
1642
- const normalizedOptions = await normalize$7(options);
1663
+ const normalizedOptions = await normalize$8(options);
1643
1664
  const {
1644
1665
  code_verifier,
1645
1666
  code_challenge
@@ -1792,7 +1813,7 @@ const login = async function() {
1792
1813
  return throwError(ErrorCode.INCORRECT_BASE_URL, i18n.t("error.login.incorrectBaseURL"));
1793
1814
  }
1794
1815
  };
1795
- const normalize$6 = async (options) => {
1816
+ const normalize$7 = async (options) => {
1796
1817
  noop(options);
1797
1818
  return {};
1798
1819
  };
@@ -1803,12 +1824,12 @@ const logout = async function() {
1803
1824
  const {
1804
1825
  options
1805
1826
  } = getCommandOptions(args, logoutCommandArguments);
1806
- const normalizedOptions = await normalize$6(options);
1827
+ const normalizedOptions = await normalize$7(options);
1807
1828
  noop(normalizedOptions);
1808
1829
  await setStore({});
1809
1830
  console.log("Logged out successfully!");
1810
1831
  };
1811
- const normalize$5 = async (options) => {
1832
+ const normalize$6 = async (options) => {
1812
1833
  noop(options);
1813
1834
  return {};
1814
1835
  };
@@ -1820,7 +1841,7 @@ const whoami = async function() {
1820
1841
  const {
1821
1842
  options
1822
1843
  } = getCommandOptions(args, whoamiCommandArguments);
1823
- const normalizedOptions = await normalize$5(options);
1844
+ const normalizedOptions = await normalize$6(options);
1824
1845
  noop(normalizedOptions);
1825
1846
  const baseURL = await getBaseURL();
1826
1847
  const cancelWaiting = startWaiting();
@@ -1836,7 +1857,7 @@ const whoami = async function() {
1836
1857
  consoleUnauthorizedMessage();
1837
1858
  }
1838
1859
  };
1839
- const normalize$4 = async (options) => {
1860
+ const normalize$5 = async (options) => {
1840
1861
  var _options$appID;
1841
1862
  noop(options);
1842
1863
  return {
@@ -1850,7 +1871,7 @@ const enable = async function() {
1850
1871
  const {
1851
1872
  options
1852
1873
  } = getCommandOptions(args, enableCommandArguments);
1853
- const normalizedOptions = await normalize$4(options);
1874
+ const normalizedOptions = await normalize$5(options);
1854
1875
  noop(normalizedOptions);
1855
1876
  const appInfo = resolveAppInfo({
1856
1877
  appID: options.appID
@@ -1866,7 +1887,7 @@ const enable = async function() {
1866
1887
  console.error(JSON.stringify(result, null, 2));
1867
1888
  }
1868
1889
  };
1869
- const normalize$3 = async (options) => {
1890
+ const normalize$4 = async (options) => {
1870
1891
  var _options$appID;
1871
1892
  noop(options);
1872
1893
  return {
@@ -1880,7 +1901,7 @@ const disable = async function() {
1880
1901
  const {
1881
1902
  options
1882
1903
  } = getCommandOptions(args, disableCommandArguments);
1883
- const normalizedOptions = await normalize$3(options);
1904
+ const normalizedOptions = await normalize$4(options);
1884
1905
  noop(normalizedOptions);
1885
1906
  const appInfo = resolveAppInfo({
1886
1907
  appID: options.appID
@@ -1896,7 +1917,7 @@ const disable = async function() {
1896
1917
  console.error(JSON.stringify(result, null, 2));
1897
1918
  }
1898
1919
  };
1899
- const normalize$2 = async (options) => {
1920
+ const normalize$3 = async (options) => {
1900
1921
  var _options$appID;
1901
1922
  noop(options);
1902
1923
  return {
@@ -1910,7 +1931,7 @@ const uninstall = async function() {
1910
1931
  const {
1911
1932
  options
1912
1933
  } = getCommandOptions(args, uninstallCommandArguments);
1913
- const normalizedOptions = await normalize$2(options);
1934
+ const normalizedOptions = await normalize$3(options);
1914
1935
  noop(normalizedOptions);
1915
1936
  const appInfo = resolveAppInfo({
1916
1937
  appID: options.appID
@@ -1927,7 +1948,7 @@ const uninstall = async function() {
1927
1948
  }
1928
1949
  };
1929
1950
  const defaultTail = 100;
1930
- const normalize$1 = async (options) => {
1951
+ const normalize$2 = async (options) => {
1931
1952
  var _options$appID, _options$fromOpkxJson, _options$tail;
1932
1953
  const appID = (_options$appID = options.appID) !== null && _options$appID !== void 0 ? _options$appID : "";
1933
1954
  const fromOpkxJSON = (_options$fromOpkxJson = options.fromOpkxJson) !== null && _options$fromOpkxJson !== void 0 ? _options$fromOpkxJson : false;
@@ -1975,7 +1996,7 @@ const logs = async function() {
1975
1996
  const {
1976
1997
  options
1977
1998
  } = getCommandOptions(args, logsCommandArguments);
1978
- const normalizedOptions = await normalize$1(options);
1999
+ const normalizedOptions = await normalize$2(options);
1979
2000
  const {
1980
2001
  appID,
1981
2002
  tail
@@ -2009,7 +2030,7 @@ const getTemplatePath = () => {
2009
2030
  const getTemplateLegacy = () => {
2010
2031
  return "legacy";
2011
2032
  };
2012
- const normalize = async (options) => {
2033
+ const normalize$1 = async (options) => {
2013
2034
  const projectPathInput = options.projectPath;
2014
2035
  if (projectPathInput)
2015
2036
  ;
@@ -2032,7 +2053,7 @@ const legacy = async function() {
2032
2053
  const {
2033
2054
  options
2034
2055
  } = getCommandOptions(args, legacyCommandArguments);
2035
- const normalizedOptions = await normalize(options);
2056
+ const normalizedOptions = await normalize$1(options);
2036
2057
  const {
2037
2058
  projectPath
2038
2059
  } = normalizedOptions;
@@ -2047,6 +2068,274 @@ const legacy = async function() {
2047
2068
  });
2048
2069
  console.log("Plugin created successfully!");
2049
2070
  };
2071
+ const defaultBaseURL = "https://open.ones.cn/";
2072
+ const defaultDir = "~/.ones/ones-app-specs";
2073
+ const expandHomeDirectory = (dir) => {
2074
+ if (dir === "~") {
2075
+ return homedir();
2076
+ }
2077
+ if (dir.startsWith("~/")) {
2078
+ return resolve(homedir(), dir.slice(2));
2079
+ }
2080
+ return dir;
2081
+ };
2082
+ const normalizeBaseURL = (baseURLInput) => {
2083
+ let url;
2084
+ try {
2085
+ url = new URL(baseURLInput);
2086
+ } catch (error) {
2087
+ return throwError(ErrorCode.INCORRECT_SPECS_BASE_URL, i18n.t("error.specs.fetch.incorrectBaseURL"));
2088
+ }
2089
+ if (url.protocol === "http:" || url.protocol === "https:")
2090
+ ;
2091
+ else {
2092
+ return throwError(ErrorCode.INCORRECT_SPECS_BASE_URL, i18n.t("error.specs.fetch.incorrectBaseURL"));
2093
+ }
2094
+ url.search = "";
2095
+ url.hash = "";
2096
+ if (!url.pathname.endsWith("/")) {
2097
+ url.pathname = `${url.pathname}/`;
2098
+ }
2099
+ return url.toString();
2100
+ };
2101
+ const normalize = async (options) => {
2102
+ var _options$baseUrl, _options$extract, _context, _options$json, _options$force;
2103
+ const baseUrl = normalizeBaseURL((_options$baseUrl = options.baseUrl) !== null && _options$baseUrl !== void 0 ? _options$baseUrl : defaultBaseURL);
2104
+ const dir = options.dir ? resolve(cwd(), expandHomeDirectory(options.dir), ".ones", "ones-app-specs") : resolve(cwd(), expandHomeDirectory(defaultDir));
2105
+ const extractString = `${(_options$extract = options.extract) !== null && _options$extract !== void 0 ? _options$extract : "true"}`.toLowerCase();
2106
+ const extract = _includesInstanceProperty(_context = ["false", "0", "no"]).call(_context, extractString) ? false : true;
2107
+ const json = (_options$json = options.json) !== null && _options$json !== void 0 ? _options$json : false;
2108
+ const force = (_options$force = options.force) !== null && _options$force !== void 0 ? _options$force : false;
2109
+ return {
2110
+ baseUrl,
2111
+ dir,
2112
+ extract,
2113
+ json,
2114
+ force
2115
+ };
2116
+ };
2117
+ const {
2118
+ ensureDirSync,
2119
+ writeFile,
2120
+ remove,
2121
+ pathExists,
2122
+ readFile
2123
+ } = fse;
2124
+ const CHECKSUM_FILENAME = "ones-app-specs.sha256";
2125
+ const DEFAULT_ARCHIVE_FILENAME = "ones-app-specs.zip";
2126
+ const DOWNLOAD_TIMEOUT = 6e4;
2127
+ const getShellSafePath = (value) => {
2128
+ return `'${value.replace(/'/g, `'\\''`)}'`;
2129
+ };
2130
+ const getExtractErrorOutput = (result) => {
2131
+ var _result$error;
2132
+ const output = [result.stderr, result.stdout].map((item) => typeof item === "string" ? item.trim() : "").filter(Boolean).join("\n");
2133
+ if ((_result$error = result.error) !== null && _result$error !== void 0 && _result$error.message) {
2134
+ return result.error.message;
2135
+ }
2136
+ return output || "unknown error";
2137
+ };
2138
+ const extractArchive = (archivePath, dir) => {
2139
+ if (process.platform === "win32") {
2140
+ const powershellEscape = (value) => value.replace(/'/g, "''");
2141
+ const command = `Expand-Archive -LiteralPath '${powershellEscape(archivePath)}' -DestinationPath '${powershellEscape(dir)}' -Force`;
2142
+ const result2 = spawnSync("powershell", ["-NoProfile", "-NonInteractive", "-Command", command], {
2143
+ encoding: "utf8"
2144
+ });
2145
+ if (result2.status === 0 && !result2.error) {
2146
+ return;
2147
+ }
2148
+ return throwError(ErrorCode.SPECS_FETCH_FAILED, i18n.t("error.specs.fetch.extractFailed", {
2149
+ file: archivePath,
2150
+ reason: getExtractErrorOutput(result2)
2151
+ }));
2152
+ }
2153
+ const result = spawnSync("unzip", ["-oq", archivePath, "-d", dir], {
2154
+ encoding: "utf8"
2155
+ });
2156
+ if (result.status === 0 && !result.error) {
2157
+ return;
2158
+ }
2159
+ return throwError(ErrorCode.SPECS_FETCH_FAILED, i18n.t("error.specs.fetch.extractFailed", {
2160
+ file: archivePath,
2161
+ reason: getExtractErrorOutput(result)
2162
+ }));
2163
+ };
2164
+ const parseChecksumValue = (text) => {
2165
+ var _match$;
2166
+ const firstLine = text.split(/\r?\n/).map((line) => line.trim()).find(Boolean);
2167
+ if (!firstLine) {
2168
+ return null;
2169
+ }
2170
+ const match = firstLine.match(/^([a-fA-F0-9]{64})(?:\s+\*?(.+))?$/);
2171
+ if (!match) {
2172
+ return null;
2173
+ }
2174
+ const checksum = match[1].toLowerCase();
2175
+ const archiveFilenameInput = ((_match$ = match[2]) !== null && _match$ !== void 0 ? _match$ : DEFAULT_ARCHIVE_FILENAME).trim();
2176
+ const archiveFilename = basename(archiveFilenameInput);
2177
+ if (!archiveFilename || archiveFilename !== archiveFilenameInput) {
2178
+ return null;
2179
+ }
2180
+ return {
2181
+ checksum,
2182
+ archiveFilename
2183
+ };
2184
+ };
2185
+ const parseChecksum = (text) => {
2186
+ var _text$split$find$trim, _text$split$find;
2187
+ const parsed = parseChecksumValue(text);
2188
+ if (parsed) {
2189
+ return parsed;
2190
+ }
2191
+ const firstLine = (_text$split$find$trim = (_text$split$find = text.split(/\r?\n/).find(Boolean)) === null || _text$split$find === void 0 ? void 0 : _text$split$find.trim()) !== null && _text$split$find$trim !== void 0 ? _text$split$find$trim : "";
2192
+ const preview = firstLine.slice(0, 120) || "<empty>";
2193
+ return throwError(ErrorCode.INCORRECT_SPECS_CHECKSUM, i18n.t("error.specs.fetch.incorrectChecksum", {
2194
+ preview
2195
+ }));
2196
+ };
2197
+ const getSHA256 = async (filePath) => {
2198
+ const hash = createHash("sha256");
2199
+ const stream = createReadStream(filePath);
2200
+ for await (const chunk of stream) {
2201
+ hash.update(chunk);
2202
+ }
2203
+ return hash.digest("hex");
2204
+ };
2205
+ const specsFetch = async function() {
2206
+ for (var _len = arguments.length, args = new Array(_len), _key = 0; _key < _len; _key++) {
2207
+ args[_key] = arguments[_key];
2208
+ }
2209
+ const {
2210
+ options
2211
+ } = getCommandOptions(args, specsFetchCommandArguments);
2212
+ const normalizedOptions = await normalize(options);
2213
+ const baseURL = normalizedOptions.baseUrl;
2214
+ const dir = normalizedOptions.dir;
2215
+ const onesDir = dirname(dir);
2216
+ const shouldExtract = normalizedOptions.extract;
2217
+ const useJSONOutput = normalizedOptions.json;
2218
+ const forceFetch = normalizedOptions.force;
2219
+ ensureDirSync(dir);
2220
+ const checksumURL = new URL(CHECKSUM_FILENAME, baseURL).toString();
2221
+ const checksumText = await axios.get(checksumURL, {
2222
+ responseType: "text",
2223
+ timeout: REQUEST_TIMEOUT
2224
+ }).then((response2) => {
2225
+ var _response2$data;
2226
+ return `${(_response2$data = response2.data) !== null && _response2$data !== void 0 ? _response2$data : ""}`;
2227
+ }).catch(() => {
2228
+ return throwError(ErrorCode.SPECS_FETCH_FAILED, i18n.t("error.specs.fetch.fetchChecksumFailed", {
2229
+ url: checksumURL
2230
+ }));
2231
+ });
2232
+ const parsedChecksum = parseChecksum(checksumText);
2233
+ const archiveURL = new URL(parsedChecksum.archiveFilename, baseURL).toString();
2234
+ const archivePath = join(dir, parsedChecksum.archiveFilename);
2235
+ const checksumPath = join(dir, CHECKSUM_FILENAME);
2236
+ const localChecksum = await pathExists(checksumPath).then(async (exists) => {
2237
+ if (!exists) {
2238
+ return null;
2239
+ }
2240
+ const content = await readFile(checksumPath, "utf8");
2241
+ return parseChecksumValue(content);
2242
+ }).catch(() => null);
2243
+ if (!forceFetch && (localChecksum === null || localChecksum === void 0 ? void 0 : localChecksum.checksum) === parsedChecksum.checksum) {
2244
+ if (useJSONOutput) {
2245
+ console.log(JSON.stringify({
2246
+ status: "up_to_date",
2247
+ base_url: baseURL,
2248
+ download_dir: dir,
2249
+ specs_dir: dir,
2250
+ checksum_url: checksumURL,
2251
+ sha256: parsedChecksum.checksum,
2252
+ force: false,
2253
+ message: "Local ones-app-specs is already up to date."
2254
+ }, null, 2));
2255
+ return;
2256
+ }
2257
+ console.log("Local ones-app-specs is already up to date.");
2258
+ console.log(`SHA256: ${parsedChecksum.checksum}`);
2259
+ console.log(`Specs directory: ${dir}`);
2260
+ return;
2261
+ }
2262
+ const response = await axios({
2263
+ url: archiveURL,
2264
+ method: "GET",
2265
+ responseType: "stream",
2266
+ timeout: DOWNLOAD_TIMEOUT
2267
+ }).catch(() => {
2268
+ return throwError(ErrorCode.SPECS_FETCH_FAILED, i18n.t("error.specs.fetch.downloadFailed", {
2269
+ url: archiveURL
2270
+ }));
2271
+ });
2272
+ await pipeline(response.data, createWriteStream(archivePath)).catch(async () => {
2273
+ await remove(archivePath).catch(() => void 0);
2274
+ return throwError(ErrorCode.SPECS_FETCH_FAILED, i18n.t("error.specs.fetch.downloadFailed", {
2275
+ url: archiveURL
2276
+ }));
2277
+ });
2278
+ const actualChecksum = await getSHA256(archivePath);
2279
+ if (actualChecksum === parsedChecksum.checksum)
2280
+ ;
2281
+ else {
2282
+ await remove(archivePath).catch(() => void 0);
2283
+ return throwError(ErrorCode.SPECS_CHECKSUM_MISMATCH, i18n.t("error.specs.fetch.verifyChecksumFailed", {
2284
+ expected: parsedChecksum.checksum,
2285
+ actual: actualChecksum
2286
+ }));
2287
+ }
2288
+ const verifyCommand = `sha256sum -c ${getShellSafePath(checksumPath)}`;
2289
+ if (shouldExtract) {
2290
+ try {
2291
+ ensureDirSync(onesDir);
2292
+ extractArchive(archivePath, onesDir);
2293
+ await writeFile(checksumPath, `${parsedChecksum.checksum} ${parsedChecksum.archiveFilename}
2294
+ `, "utf8");
2295
+ await remove(archivePath).catch(() => void 0);
2296
+ } catch (error) {
2297
+ return throwError(ErrorCode.SPECS_FETCH_FAILED, i18n.t("error.specs.fetch.cleanupFailed", {
2298
+ file: archivePath,
2299
+ reason: `${error}`
2300
+ }));
2301
+ }
2302
+ } else {
2303
+ await writeFile(checksumPath, `${parsedChecksum.checksum} ${parsedChecksum.archiveFilename}
2304
+ `, "utf8");
2305
+ }
2306
+ if (useJSONOutput) {
2307
+ console.log(JSON.stringify({
2308
+ status: "success",
2309
+ base_url: baseURL,
2310
+ download_dir: dir,
2311
+ specs_dir: dir,
2312
+ checksum_url: checksumURL,
2313
+ archive_url: archiveURL,
2314
+ archive_path: archivePath,
2315
+ checksum_path: checksumPath,
2316
+ sha256: actualChecksum,
2317
+ force: forceFetch,
2318
+ extract: shouldExtract,
2319
+ archive_removed: shouldExtract,
2320
+ verify_command: shouldExtract ? null : verifyCommand
2321
+ }, null, 2));
2322
+ return;
2323
+ }
2324
+ console.log("ONES specs fetched successfully!");
2325
+ console.log(`SHA256: ${actualChecksum}`);
2326
+ console.log(`Specs directory: ${dir}`);
2327
+ console.log(`Base URL: ${baseURL}`);
2328
+ console.log(`Checksum URL: ${checksumURL}`);
2329
+ console.log(`Archive URL: ${archiveURL}`);
2330
+ console.log(`Archive path: ${archivePath}`);
2331
+ if (shouldExtract) {
2332
+ console.log("Archive extracted successfully!");
2333
+ console.log("Archive cleanup: enabled (source zip removed)");
2334
+ } else {
2335
+ console.log("Archive extraction: skipped");
2336
+ console.log(`Verify command: ${verifyCommand}`);
2337
+ }
2338
+ };
2050
2339
  const buildCommandArguments = [];
2051
2340
  const $build = new Command("build").description(i18n.t("desc.build")).option("-o, --output [file-path]", i18n.t("desc.build.output")).option("-c, --command [string]", i18n.t("desc.build.command")).action(build);
2052
2341
  addCommandUsage($build);
@@ -2095,6 +2384,16 @@ const $app = new Command("app").description(i18n.t("desc.app"));
2095
2384
  $app.addCommand($install).addCommand($enable).addCommand($disable).addCommand($uninstall).addCommand($logs);
2096
2385
  addCommandUsage($app);
2097
2386
  addCommandOutput($app);
2387
+ const specsFetchCommandArguments = [];
2388
+ const $fetch = new Command("fetch").description(i18n.t("desc.specs.fetch")).option("-u, --base-url <url>", i18n.t("desc.specs.fetch.baseUrl")).option("-d, --dir <directory>", i18n.t("desc.specs.fetch.dir")).option("--no-extract", i18n.t("desc.specs.fetch.noExtract")).option("--json", i18n.t("desc.specs.fetch.json")).option("--force", i18n.t("desc.specs.fetch.force")).action(specsFetch);
2389
+ $fetch.addHelpText("after", ["", "Examples:", " ones specs fetch", " ones specs fetch --json", " ones specs fetch --no-extract", " ones specs fetch --force", " ones specs fetch --base-url http://open-preview.myones.net/ --dir /path/to/project"].join("\n"));
2390
+ addCommandUsage($fetch);
2391
+ addCommandOutput($fetch);
2392
+ const $specs = new Command("specs").description(i18n.t("desc.specs"));
2393
+ $specs.addCommand($fetch);
2394
+ $specs.addHelpText("after", ["", "Examples:", " ones specs fetch", " ones specs fetch --json", " ones specs fetch --no-extract", " ones specs fetch --force", " ones specs fetch --base-url https://docs.ones.com/developer/ --dir /path/to/project"].join("\n"));
2395
+ addCommandUsage($specs);
2396
+ addCommandOutput($specs);
2098
2397
  const legacyCommandArguments = ["projectPath"];
2099
2398
  const $create = new Command("create").description(i18n.t("desc.legacy.create")).argument("<project-path>", i18n.t("desc.legacy.create.projectPath")).action(legacy);
2100
2399
  addCommandUsage($create);
@@ -2108,7 +2407,7 @@ const version = `${getPackageJSON().version}`;
2108
2407
  const env = `${version} Node/${process.version}`;
2109
2408
  ones.description(i18n.t("desc.ones", {
2110
2409
  env
2111
- })).addCommand($create$1).addCommand($build).addCommand($dev).addCommand($tunnel).addCommand($app).addCommand($login).addCommand($logout).addCommand($whoami).addCommand($legacy).configureHelp({
2410
+ })).addCommand($create$1).addCommand($build).addCommand($dev).addCommand($tunnel).addCommand($app).addCommand($login).addCommand($logout).addCommand($whoami).addCommand($specs).addCommand($legacy).configureHelp({
2112
2411
  visibleCommands: (cmd) => {
2113
2412
  const blackList = ["legacy"];
2114
2413
  return cmd.commands.filter((command) => !_includesInstanceProperty(blackList).call(blackList, command.name()));
@@ -13,4 +13,5 @@ export * from './disable';
13
13
  export * from './uninstall';
14
14
  export * from './logs';
15
15
  export * from './legacy';
16
+ export * from './specs-fetch';
16
17
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/actions/index.ts"],"names":[],"mappings":"AAAA;;GAEG;AACH,cAAc,SAAS,CAAA;AACvB,cAAc,OAAO,CAAA;AACrB,cAAc,UAAU,CAAA;AACxB,cAAc,SAAS,CAAA;AACvB,cAAc,UAAU,CAAA;AACxB,cAAc,UAAU,CAAA;AACxB,cAAc,WAAW,CAAA;AACzB,cAAc,UAAU,CAAA;AACxB,cAAc,WAAW,CAAA;AACzB,cAAc,aAAa,CAAA;AAC3B,cAAc,QAAQ,CAAA;AACtB,cAAc,UAAU,CAAA"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/actions/index.ts"],"names":[],"mappings":"AAAA;;GAEG;AACH,cAAc,SAAS,CAAA;AACvB,cAAc,OAAO,CAAA;AACrB,cAAc,UAAU,CAAA;AACxB,cAAc,SAAS,CAAA;AACvB,cAAc,UAAU,CAAA;AACxB,cAAc,UAAU,CAAA;AACxB,cAAc,WAAW,CAAA;AACzB,cAAc,UAAU,CAAA;AACxB,cAAc,WAAW,CAAA;AACzB,cAAc,aAAa,CAAA;AAC3B,cAAc,QAAQ,CAAA;AACtB,cAAc,UAAU,CAAA;AACxB,cAAc,eAAe,CAAA"}
@@ -0,0 +1,4 @@
1
+ import type { CommandArguments } from '../../common/command';
2
+ import type { SpecsFetchCommandOptions } from '../../command';
3
+ export declare const specsFetch: (...args: CommandArguments<SpecsFetchCommandOptions>) => Promise<undefined>;
4
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../src/actions/specs-fetch/index.ts"],"names":[],"mappings":"AAaA,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,kBAAkB,CAAA;AACxD,OAAO,KAAK,EAA8B,wBAAwB,EAAE,MAAM,WAAW,CAAA;AA6GrF,eAAO,MAAM,UAAU,GAAU,GAAG,MAAM,gBAAgB,CAAC,wBAAwB,CAAC,uBA6KnF,CAAA"}
@@ -0,0 +1,6 @@
1
+ import type { CommandOptions } from '../../common/command';
2
+ import type { SpecsFetchCommandArguments, SpecsFetchCommandOptions } from '../../command';
3
+ type NormalizeOptions = CommandOptions<SpecsFetchCommandArguments, SpecsFetchCommandOptions>['options'];
4
+ export declare const normalize: (options: NormalizeOptions) => Promise<Required<NormalizeOptions>>;
5
+ export {};
6
+ //# sourceMappingURL=normalize.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"normalize.d.ts","sourceRoot":"","sources":["../../../../src/actions/specs-fetch/normalize.ts"],"names":[],"mappings":"AAKA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,kBAAkB,CAAA;AACtD,OAAO,KAAK,EAAE,0BAA0B,EAAE,wBAAwB,EAAE,MAAM,WAAW,CAAA;AAErF,KAAK,gBAAgB,GAAG,cAAc,CACpC,0BAA0B,EAC1B,wBAAwB,CACzB,CAAC,SAAS,CAAC,CAAA;AA4CZ,eAAO,MAAM,SAAS,GAAU,SAAS,gBAAgB,KAAG,OAAO,CAAC,QAAQ,CAAC,gBAAgB,CAAC,CAiB7F,CAAA"}
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/cli/index.ts"],"names":[],"mappings":"AAsCA,eAAO,MAAM,cAAc,qBAM1B,CAAA"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/cli/index.ts"],"names":[],"mappings":"AAuCA,eAAO,MAAM,cAAc,qBAM1B,CAAA"}
@@ -8,10 +8,12 @@ export * from './login';
8
8
  export * from './logout';
9
9
  export * from './whoami';
10
10
  export * from './app';
11
+ export * from './specs';
11
12
  export * from './install';
12
13
  export * from './enable';
13
14
  export * from './disable';
14
15
  export * from './uninstall';
15
16
  export * from './logs';
16
17
  export * from './legacy';
18
+ export * from './specs-fetch';
17
19
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/command/index.ts"],"names":[],"mappings":"AAAA;;GAEG;AACH,cAAc,SAAS,CAAA;AACvB,cAAc,OAAO,CAAA;AACrB,cAAc,UAAU,CAAA;AACxB,cAAc,SAAS,CAAA;AACvB,cAAc,UAAU,CAAA;AACxB,cAAc,UAAU,CAAA;AACxB,cAAc,OAAO,CAAA;AACrB,cAAc,WAAW,CAAA;AACzB,cAAc,UAAU,CAAA;AACxB,cAAc,WAAW,CAAA;AACzB,cAAc,aAAa,CAAA;AAC3B,cAAc,QAAQ,CAAA;AACtB,cAAc,UAAU,CAAA"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/command/index.ts"],"names":[],"mappings":"AAAA;;GAEG;AACH,cAAc,SAAS,CAAA;AACvB,cAAc,OAAO,CAAA;AACrB,cAAc,UAAU,CAAA;AACxB,cAAc,SAAS,CAAA;AACvB,cAAc,UAAU,CAAA;AACxB,cAAc,UAAU,CAAA;AACxB,cAAc,OAAO,CAAA;AACrB,cAAc,SAAS,CAAA;AACvB,cAAc,WAAW,CAAA;AACzB,cAAc,UAAU,CAAA;AACxB,cAAc,WAAW,CAAA;AACzB,cAAc,aAAa,CAAA;AAC3B,cAAc,QAAQ,CAAA;AACtB,cAAc,UAAU,CAAA;AACxB,cAAc,eAAe,CAAA"}
@@ -0,0 +1,4 @@
1
+ import { Command } from 'commander';
2
+ declare const $specs: Command;
3
+ export { $specs };
4
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../src/command/specs/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAA;AAKnC,QAAA,MAAM,MAAM,SAAyD,CAAA;AAmBrE,OAAO,EAAE,MAAM,EAAE,CAAA"}
@@ -0,0 +1,13 @@
1
+ import { Command } from 'commander';
2
+ export declare const specsFetchCommandArguments: readonly [];
3
+ export type SpecsFetchCommandArguments = typeof specsFetchCommandArguments;
4
+ export interface SpecsFetchCommandOptions {
5
+ baseUrl?: string;
6
+ dir?: string;
7
+ extract?: boolean;
8
+ json?: boolean;
9
+ force?: boolean;
10
+ }
11
+ declare const $fetch: Command;
12
+ export { $fetch };
13
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../src/command/specs-fetch/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAA;AAKnC,eAAO,MAAM,0BAA0B,aAAc,CAAA;AAErD,MAAM,MAAM,0BAA0B,GAAG,OAAO,0BAA0B,CAAA;AAE1E,MAAM,WAAW,wBAAwB;IACvC,OAAO,CAAC,EAAE,MAAM,CAAA;IAChB,GAAG,CAAC,EAAE,MAAM,CAAA;IACZ,OAAO,CAAC,EAAE,OAAO,CAAA;IACjB,IAAI,CAAC,EAAE,OAAO,CAAA;IACd,KAAK,CAAC,EAAE,OAAO,CAAA;CAChB;AAED,QAAA,MAAM,MAAM,SAOS,CAAA;AAiBrB,OAAO,EAAE,MAAM,EAAE,CAAA"}