@ones-open/cli 0.0.12-21205.1 → 0.0.13

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.cjs CHANGED
@@ -24,6 +24,9 @@ const http = require("node:http");
24
24
  const open = require("open");
25
25
  const uuid = require("uuid");
26
26
  const PKCEChallenge = require("pkce-challenge");
27
+ const node_crypto = require("node:crypto");
28
+ const promises = require("node:stream/promises");
29
+ const node_os = require("node:os");
27
30
  var _documentCurrentScript = typeof document !== "undefined" ? document.currentScript : null;
28
31
  const en = {
29
32
  "desc.ones": "ONES CLI/{env}",
@@ -41,6 +44,13 @@ const en = {
41
44
  "desc.logout": "Log out of your ONES account",
42
45
  "desc.whoami": "Display the account information of the logged in user",
43
46
  "desc.app": "Manage app installations",
47
+ "desc.specs": "Manage ONES app specs resources to build your ONES App",
48
+ "desc.specs.fetch": "Fetch ONES app specs (download, checksum verify, and extract by default)",
49
+ "desc.specs.fetch.baseUrl": "Specify the base URL for specs resources",
50
+ "desc.specs.fetch.dir": "Specify the base directory (specs saved to <dir>/.ones/ones-app-specs)",
51
+ "desc.specs.fetch.noExtract": "Download only, do not extract archive automatically",
52
+ "desc.specs.fetch.json": "Output result in JSON format",
53
+ "desc.specs.fetch.force": "Force fetch even when local checksum is already up to date",
44
54
  "desc.install": "Install your ONES App",
45
55
  "desc.enable": "Enable your ONES App",
46
56
  "desc.disable": "Disable your ONES App",
@@ -66,7 +76,14 @@ const en = {
66
76
  "error.store.permission": 'Permission denied, please check the file permission with "{filePath}"',
67
77
  "error.hostedToken.requestFailed": "Failed to request hosted token",
68
78
  "error.hostedToken.empty": "Hosted token is empty",
69
- "error.legacy.create.missingProjectPath": "Project path is required"
79
+ "error.legacy.create.missingProjectPath": "Project path is required",
80
+ "error.specs.fetch.incorrectBaseURL": "Incorrect specs base URL",
81
+ "error.specs.fetch.fetchChecksumFailed": 'Failed to fetch checksum file from "{url}"',
82
+ "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}"',
83
+ "error.specs.fetch.downloadFailed": 'Failed to download specs archive from "{url}"',
84
+ "error.specs.fetch.extractFailed": 'Failed to extract archive "{file}": {reason}',
85
+ "error.specs.fetch.cleanupFailed": 'Failed to cleanup archive "{file}": {reason}',
86
+ "error.specs.fetch.verifyChecksumFailed": 'SHA256 verification failed, expected "{expected}" but got "{actual}"'
70
87
  };
71
88
  const map = {
72
89
  en
@@ -113,6 +130,10 @@ var ErrorCode = ((ErrorCode2) => {
113
130
  ErrorCode2["HOSTED_TOKEN_EMPTY"] = "E14";
114
131
  ErrorCode2["INCORRECT_DEV_COMMAND"] = "E15";
115
132
  ErrorCode2["INCORRECT_BUILD_COMMAND"] = "E16";
133
+ ErrorCode2["INCORRECT_SPECS_BASE_URL"] = "E17";
134
+ ErrorCode2["INCORRECT_SPECS_CHECKSUM"] = "E18";
135
+ ErrorCode2["SPECS_FETCH_FAILED"] = "E19";
136
+ ErrorCode2["SPECS_CHECKSUM_MISMATCH"] = "E20";
116
137
  return ErrorCode2;
117
138
  })(ErrorCode || {});
118
139
  const getPackageJSONPath = () => {
@@ -229,7 +250,7 @@ const getAppRcJSON = async () => {
229
250
  };
230
251
  const isOPKXFilename = /\.opkx$/;
231
252
  const defaultOutputPath = "";
232
- const normalize$b = async (options) => {
253
+ const normalize$c = async (options) => {
233
254
  var _options$output, _options$command;
234
255
  let output = node_path.resolve(process$1.cwd(), (_options$output = options.output) !== null && _options$output !== void 0 ? _options$output : defaultOutputPath);
235
256
  const command = (_options$command = options.command) !== null && _options$command !== void 0 ? _options$command : "";
@@ -248,7 +269,7 @@ const normalize$b = async (options) => {
248
269
  };
249
270
  const {
250
271
  existsSync,
251
- ensureDirSync
272
+ ensureDirSync: ensureDirSync$1
252
273
  } = fse;
253
274
  const build = async function() {
254
275
  var _appRcJSON$dev, _defaultAppRcJSON$dev, _appRcJSON$build$comm, _appRcJSON$build, _currentCommand$, _appRcJSON$build$comp, _appRcJSON$build2;
@@ -258,7 +279,7 @@ const build = async function() {
258
279
  const {
259
280
  options
260
281
  } = createOnesApp.getCommandOptions(args, buildCommandArguments);
261
- const normalizedOptions = await normalize$b(options);
282
+ const normalizedOptions = await normalize$c(options);
262
283
  const appManifestJSON = getAppManifestJSON();
263
284
  const appRcJSON = await getAppRcJSON();
264
285
  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]) || "";
@@ -306,7 +327,7 @@ const build = async function() {
306
327
  const outputPath = normalizedOptions.output;
307
328
  const outputDir = node_path.dirname(outputPath);
308
329
  const outputFilename = node_path.basename(outputPath);
309
- ensureDirSync(outputDir);
330
+ ensureDirSync$1(outputDir);
310
331
  const outputStream = node_fs.createWriteStream(outputPath);
311
332
  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 : [];
312
333
  const archive = archiver("zip", {
@@ -821,7 +842,7 @@ const resolveAppInfo = (input) => {
821
842
  process.exit(1);
822
843
  };
823
844
  const isPortNumber = /^[1-9]\d{0,4}$/;
824
- const normalize$a = async (options) => {
845
+ const normalize$b = async (options) => {
825
846
  var _options$clearStorage;
826
847
  const portInput = options.port;
827
848
  if (portInput)
@@ -1185,7 +1206,7 @@ const tunnel = async function() {
1185
1206
  const {
1186
1207
  options
1187
1208
  } = createOnesApp.getCommandOptions(args, tunnelCommandArguments);
1188
- const normalizedOptions = await normalize$a(options);
1209
+ const normalizedOptions = await normalize$b(options);
1189
1210
  const port = Number(normalizedOptions.port);
1190
1211
  const cancelWaiting = startWaiting();
1191
1212
  await invokeTunnel(port, {
@@ -1197,7 +1218,7 @@ const tunnel = async function() {
1197
1218
  const tunnelUrl = await buildTunnelUrl();
1198
1219
  console.log(`Relay endpoint: ${tunnelUrl}`);
1199
1220
  };
1200
- const normalize$9 = async (options) => {
1221
+ const normalize$a = async (options) => {
1201
1222
  var _options$appID;
1202
1223
  lodashEs.noop(options);
1203
1224
  return {
@@ -1280,7 +1301,7 @@ const install = async function() {
1280
1301
  const {
1281
1302
  options
1282
1303
  } = createOnesApp.getCommandOptions(args, installCommandArguments);
1283
- const normalizedOptions = await normalize$9(options);
1304
+ const normalizedOptions = await normalize$a(options);
1284
1305
  lodashEs.noop(normalizedOptions);
1285
1306
  const appInfo = resolveAppInfo({
1286
1307
  appID: options.appID
@@ -1307,7 +1328,7 @@ var DevCommandScripts = /* @__PURE__ */ ((DevCommandScripts2) => {
1307
1328
  return DevCommandScripts2;
1308
1329
  })(DevCommandScripts || {});
1309
1330
  const defaultInstall = InstallOptions.AUTO;
1310
- const normalize$8 = async (options) => {
1331
+ const normalize$9 = async (options) => {
1311
1332
  var _options$install, _options$command, _options$clearStorage;
1312
1333
  let install2 = (_options$install = options.install) !== null && _options$install !== void 0 ? _options$install : defaultInstall;
1313
1334
  const command = (_options$command = options.command) !== null && _options$command !== void 0 ? _options$command : "";
@@ -1378,7 +1399,7 @@ const dev = async function() {
1378
1399
  const {
1379
1400
  options
1380
1401
  } = createOnesApp.getCommandOptions(args, devCommandArguments);
1381
- const normalizedOptions = await normalize$8(options);
1402
+ const normalizedOptions = await normalize$9(options);
1382
1403
  const appRcJSON = await getAppRcJSON();
1383
1404
  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]) || "";
1384
1405
  if (!correctCommand) {
@@ -1604,7 +1625,7 @@ const sleep = (number) => {
1604
1625
  };
1605
1626
  const isURL = /^https?:\/\//;
1606
1627
  const HostBlackList = ["ones.cn", "www.ones.cn", "ones.com", "www.ones.com"];
1607
- const normalize$7 = async (options) => {
1628
+ const normalize$8 = async (options) => {
1608
1629
  const baseURLInput = options.baseURL;
1609
1630
  if (baseURLInput)
1610
1631
  ;
@@ -1642,7 +1663,7 @@ const login = async function() {
1642
1663
  const {
1643
1664
  options
1644
1665
  } = createOnesApp.getCommandOptions(args, loginCommandArguments);
1645
- const normalizedOptions = await normalize$7(options);
1666
+ const normalizedOptions = await normalize$8(options);
1646
1667
  const {
1647
1668
  code_verifier,
1648
1669
  code_challenge
@@ -1795,7 +1816,7 @@ const login = async function() {
1795
1816
  return createOnesApp.throwError(ErrorCode.INCORRECT_BASE_URL, i18n.t("error.login.incorrectBaseURL"));
1796
1817
  }
1797
1818
  };
1798
- const normalize$6 = async (options) => {
1819
+ const normalize$7 = async (options) => {
1799
1820
  lodashEs.noop(options);
1800
1821
  return {};
1801
1822
  };
@@ -1806,12 +1827,12 @@ const logout = async function() {
1806
1827
  const {
1807
1828
  options
1808
1829
  } = createOnesApp.getCommandOptions(args, logoutCommandArguments);
1809
- const normalizedOptions = await normalize$6(options);
1830
+ const normalizedOptions = await normalize$7(options);
1810
1831
  lodashEs.noop(normalizedOptions);
1811
1832
  await setStore({});
1812
1833
  console.log("Logged out successfully!");
1813
1834
  };
1814
- const normalize$5 = async (options) => {
1835
+ const normalize$6 = async (options) => {
1815
1836
  lodashEs.noop(options);
1816
1837
  return {};
1817
1838
  };
@@ -1823,7 +1844,7 @@ const whoami = async function() {
1823
1844
  const {
1824
1845
  options
1825
1846
  } = createOnesApp.getCommandOptions(args, whoamiCommandArguments);
1826
- const normalizedOptions = await normalize$5(options);
1847
+ const normalizedOptions = await normalize$6(options);
1827
1848
  lodashEs.noop(normalizedOptions);
1828
1849
  const baseURL = await getBaseURL();
1829
1850
  const cancelWaiting = startWaiting();
@@ -1839,7 +1860,7 @@ const whoami = async function() {
1839
1860
  consoleUnauthorizedMessage();
1840
1861
  }
1841
1862
  };
1842
- const normalize$4 = async (options) => {
1863
+ const normalize$5 = async (options) => {
1843
1864
  var _options$appID;
1844
1865
  lodashEs.noop(options);
1845
1866
  return {
@@ -1853,7 +1874,7 @@ const enable = async function() {
1853
1874
  const {
1854
1875
  options
1855
1876
  } = createOnesApp.getCommandOptions(args, enableCommandArguments);
1856
- const normalizedOptions = await normalize$4(options);
1877
+ const normalizedOptions = await normalize$5(options);
1857
1878
  lodashEs.noop(normalizedOptions);
1858
1879
  const appInfo = resolveAppInfo({
1859
1880
  appID: options.appID
@@ -1869,7 +1890,7 @@ const enable = async function() {
1869
1890
  console.error(JSON.stringify(result, null, 2));
1870
1891
  }
1871
1892
  };
1872
- const normalize$3 = async (options) => {
1893
+ const normalize$4 = async (options) => {
1873
1894
  var _options$appID;
1874
1895
  lodashEs.noop(options);
1875
1896
  return {
@@ -1883,7 +1904,7 @@ const disable = async function() {
1883
1904
  const {
1884
1905
  options
1885
1906
  } = createOnesApp.getCommandOptions(args, disableCommandArguments);
1886
- const normalizedOptions = await normalize$3(options);
1907
+ const normalizedOptions = await normalize$4(options);
1887
1908
  lodashEs.noop(normalizedOptions);
1888
1909
  const appInfo = resolveAppInfo({
1889
1910
  appID: options.appID
@@ -1899,7 +1920,7 @@ const disable = async function() {
1899
1920
  console.error(JSON.stringify(result, null, 2));
1900
1921
  }
1901
1922
  };
1902
- const normalize$2 = async (options) => {
1923
+ const normalize$3 = async (options) => {
1903
1924
  var _options$appID;
1904
1925
  lodashEs.noop(options);
1905
1926
  return {
@@ -1913,7 +1934,7 @@ const uninstall = async function() {
1913
1934
  const {
1914
1935
  options
1915
1936
  } = createOnesApp.getCommandOptions(args, uninstallCommandArguments);
1916
- const normalizedOptions = await normalize$2(options);
1937
+ const normalizedOptions = await normalize$3(options);
1917
1938
  lodashEs.noop(normalizedOptions);
1918
1939
  const appInfo = resolveAppInfo({
1919
1940
  appID: options.appID
@@ -1930,7 +1951,7 @@ const uninstall = async function() {
1930
1951
  }
1931
1952
  };
1932
1953
  const defaultTail = 100;
1933
- const normalize$1 = async (options) => {
1954
+ const normalize$2 = async (options) => {
1934
1955
  var _options$appID, _options$fromOpkxJson, _options$tail;
1935
1956
  const appID = (_options$appID = options.appID) !== null && _options$appID !== void 0 ? _options$appID : "";
1936
1957
  const fromOpkxJSON = (_options$fromOpkxJson = options.fromOpkxJson) !== null && _options$fromOpkxJson !== void 0 ? _options$fromOpkxJson : false;
@@ -1978,7 +1999,7 @@ const logs = async function() {
1978
1999
  const {
1979
2000
  options
1980
2001
  } = createOnesApp.getCommandOptions(args, logsCommandArguments);
1981
- const normalizedOptions = await normalize$1(options);
2002
+ const normalizedOptions = await normalize$2(options);
1982
2003
  const {
1983
2004
  appID,
1984
2005
  tail
@@ -2012,7 +2033,7 @@ const getTemplatePath = () => {
2012
2033
  const getTemplateLegacy = () => {
2013
2034
  return "legacy";
2014
2035
  };
2015
- const normalize = async (options) => {
2036
+ const normalize$1 = async (options) => {
2016
2037
  const projectPathInput = options.projectPath;
2017
2038
  if (projectPathInput)
2018
2039
  ;
@@ -2035,7 +2056,7 @@ const legacy = async function() {
2035
2056
  const {
2036
2057
  options
2037
2058
  } = createOnesApp.getCommandOptions(args, legacyCommandArguments);
2038
- const normalizedOptions = await normalize(options);
2059
+ const normalizedOptions = await normalize$1(options);
2039
2060
  const {
2040
2061
  projectPath
2041
2062
  } = normalizedOptions;
@@ -2050,6 +2071,274 @@ const legacy = async function() {
2050
2071
  });
2051
2072
  console.log("Plugin created successfully!");
2052
2073
  };
2074
+ const defaultBaseURL = "https://open.ones.cn/";
2075
+ const defaultDir = "~/.ones/ones-app-specs";
2076
+ const expandHomeDirectory = (dir) => {
2077
+ if (dir === "~") {
2078
+ return node_os.homedir();
2079
+ }
2080
+ if (dir.startsWith("~/")) {
2081
+ return node_path.resolve(node_os.homedir(), dir.slice(2));
2082
+ }
2083
+ return dir;
2084
+ };
2085
+ const normalizeBaseURL = (baseURLInput) => {
2086
+ let url;
2087
+ try {
2088
+ url = new URL(baseURLInput);
2089
+ } catch (error) {
2090
+ return createOnesApp.throwError(ErrorCode.INCORRECT_SPECS_BASE_URL, i18n.t("error.specs.fetch.incorrectBaseURL"));
2091
+ }
2092
+ if (url.protocol === "http:" || url.protocol === "https:")
2093
+ ;
2094
+ else {
2095
+ return createOnesApp.throwError(ErrorCode.INCORRECT_SPECS_BASE_URL, i18n.t("error.specs.fetch.incorrectBaseURL"));
2096
+ }
2097
+ url.search = "";
2098
+ url.hash = "";
2099
+ if (!url.pathname.endsWith("/")) {
2100
+ url.pathname = `${url.pathname}/`;
2101
+ }
2102
+ return url.toString();
2103
+ };
2104
+ const normalize = async (options) => {
2105
+ var _options$baseUrl, _options$extract, _context, _options$json, _options$force;
2106
+ const baseUrl = normalizeBaseURL((_options$baseUrl = options.baseUrl) !== null && _options$baseUrl !== void 0 ? _options$baseUrl : defaultBaseURL);
2107
+ const dir = options.dir ? node_path.resolve(process$1.cwd(), expandHomeDirectory(options.dir), ".ones", "ones-app-specs") : node_path.resolve(process$1.cwd(), expandHomeDirectory(defaultDir));
2108
+ const extractString = `${(_options$extract = options.extract) !== null && _options$extract !== void 0 ? _options$extract : "true"}`.toLowerCase();
2109
+ const extract = _includesInstanceProperty(_context = ["false", "0", "no"]).call(_context, extractString) ? false : true;
2110
+ const json = (_options$json = options.json) !== null && _options$json !== void 0 ? _options$json : false;
2111
+ const force = (_options$force = options.force) !== null && _options$force !== void 0 ? _options$force : false;
2112
+ return {
2113
+ baseUrl,
2114
+ dir,
2115
+ extract,
2116
+ json,
2117
+ force
2118
+ };
2119
+ };
2120
+ const {
2121
+ ensureDirSync,
2122
+ writeFile,
2123
+ remove,
2124
+ pathExists,
2125
+ readFile
2126
+ } = fse;
2127
+ const CHECKSUM_FILENAME = "ones-app-specs.sha256";
2128
+ const DEFAULT_ARCHIVE_FILENAME = "ones-app-specs.zip";
2129
+ const DOWNLOAD_TIMEOUT = 6e4;
2130
+ const getShellSafePath = (value) => {
2131
+ return `'${value.replace(/'/g, `'\\''`)}'`;
2132
+ };
2133
+ const getExtractErrorOutput = (result) => {
2134
+ var _result$error;
2135
+ const output = [result.stderr, result.stdout].map((item) => typeof item === "string" ? item.trim() : "").filter(Boolean).join("\n");
2136
+ if ((_result$error = result.error) !== null && _result$error !== void 0 && _result$error.message) {
2137
+ return result.error.message;
2138
+ }
2139
+ return output || "unknown error";
2140
+ };
2141
+ const extractArchive = (archivePath, dir) => {
2142
+ if (process.platform === "win32") {
2143
+ const powershellEscape = (value) => value.replace(/'/g, "''");
2144
+ const command = `Expand-Archive -LiteralPath '${powershellEscape(archivePath)}' -DestinationPath '${powershellEscape(dir)}' -Force`;
2145
+ const result2 = node_child_process.spawnSync("powershell", ["-NoProfile", "-NonInteractive", "-Command", command], {
2146
+ encoding: "utf8"
2147
+ });
2148
+ if (result2.status === 0 && !result2.error) {
2149
+ return;
2150
+ }
2151
+ return createOnesApp.throwError(ErrorCode.SPECS_FETCH_FAILED, i18n.t("error.specs.fetch.extractFailed", {
2152
+ file: archivePath,
2153
+ reason: getExtractErrorOutput(result2)
2154
+ }));
2155
+ }
2156
+ const result = node_child_process.spawnSync("unzip", ["-oq", archivePath, "-d", dir], {
2157
+ encoding: "utf8"
2158
+ });
2159
+ if (result.status === 0 && !result.error) {
2160
+ return;
2161
+ }
2162
+ return createOnesApp.throwError(ErrorCode.SPECS_FETCH_FAILED, i18n.t("error.specs.fetch.extractFailed", {
2163
+ file: archivePath,
2164
+ reason: getExtractErrorOutput(result)
2165
+ }));
2166
+ };
2167
+ const parseChecksumValue = (text) => {
2168
+ var _match$;
2169
+ const firstLine = text.split(/\r?\n/).map((line) => line.trim()).find(Boolean);
2170
+ if (!firstLine) {
2171
+ return null;
2172
+ }
2173
+ const match = firstLine.match(/^([a-fA-F0-9]{64})(?:\s+\*?(.+))?$/);
2174
+ if (!match) {
2175
+ return null;
2176
+ }
2177
+ const checksum = match[1].toLowerCase();
2178
+ const archiveFilenameInput = ((_match$ = match[2]) !== null && _match$ !== void 0 ? _match$ : DEFAULT_ARCHIVE_FILENAME).trim();
2179
+ const archiveFilename = node_path.basename(archiveFilenameInput);
2180
+ if (!archiveFilename || archiveFilename !== archiveFilenameInput) {
2181
+ return null;
2182
+ }
2183
+ return {
2184
+ checksum,
2185
+ archiveFilename
2186
+ };
2187
+ };
2188
+ const parseChecksum = (text) => {
2189
+ var _text$split$find$trim, _text$split$find;
2190
+ const parsed = parseChecksumValue(text);
2191
+ if (parsed) {
2192
+ return parsed;
2193
+ }
2194
+ 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 : "";
2195
+ const preview = firstLine.slice(0, 120) || "<empty>";
2196
+ return createOnesApp.throwError(ErrorCode.INCORRECT_SPECS_CHECKSUM, i18n.t("error.specs.fetch.incorrectChecksum", {
2197
+ preview
2198
+ }));
2199
+ };
2200
+ const getSHA256 = async (filePath) => {
2201
+ const hash = node_crypto.createHash("sha256");
2202
+ const stream = node_fs.createReadStream(filePath);
2203
+ for await (const chunk of stream) {
2204
+ hash.update(chunk);
2205
+ }
2206
+ return hash.digest("hex");
2207
+ };
2208
+ const specsFetch = async function() {
2209
+ for (var _len = arguments.length, args = new Array(_len), _key = 0; _key < _len; _key++) {
2210
+ args[_key] = arguments[_key];
2211
+ }
2212
+ const {
2213
+ options
2214
+ } = createOnesApp.getCommandOptions(args, specsFetchCommandArguments);
2215
+ const normalizedOptions = await normalize(options);
2216
+ const baseURL = normalizedOptions.baseUrl;
2217
+ const dir = normalizedOptions.dir;
2218
+ const onesDir = node_path.dirname(dir);
2219
+ const shouldExtract = normalizedOptions.extract;
2220
+ const useJSONOutput = normalizedOptions.json;
2221
+ const forceFetch = normalizedOptions.force;
2222
+ ensureDirSync(dir);
2223
+ const checksumURL = new URL(CHECKSUM_FILENAME, baseURL).toString();
2224
+ const checksumText = await axios.get(checksumURL, {
2225
+ responseType: "text",
2226
+ timeout: REQUEST_TIMEOUT
2227
+ }).then((response2) => {
2228
+ var _response2$data;
2229
+ return `${(_response2$data = response2.data) !== null && _response2$data !== void 0 ? _response2$data : ""}`;
2230
+ }).catch(() => {
2231
+ return createOnesApp.throwError(ErrorCode.SPECS_FETCH_FAILED, i18n.t("error.specs.fetch.fetchChecksumFailed", {
2232
+ url: checksumURL
2233
+ }));
2234
+ });
2235
+ const parsedChecksum = parseChecksum(checksumText);
2236
+ const archiveURL = new URL(parsedChecksum.archiveFilename, baseURL).toString();
2237
+ const archivePath = node_path.join(dir, parsedChecksum.archiveFilename);
2238
+ const checksumPath = node_path.join(dir, CHECKSUM_FILENAME);
2239
+ const localChecksum = await pathExists(checksumPath).then(async (exists) => {
2240
+ if (!exists) {
2241
+ return null;
2242
+ }
2243
+ const content = await readFile(checksumPath, "utf8");
2244
+ return parseChecksumValue(content);
2245
+ }).catch(() => null);
2246
+ if (!forceFetch && (localChecksum === null || localChecksum === void 0 ? void 0 : localChecksum.checksum) === parsedChecksum.checksum) {
2247
+ if (useJSONOutput) {
2248
+ console.log(JSON.stringify({
2249
+ status: "up_to_date",
2250
+ base_url: baseURL,
2251
+ download_dir: dir,
2252
+ specs_dir: dir,
2253
+ checksum_url: checksumURL,
2254
+ sha256: parsedChecksum.checksum,
2255
+ force: false,
2256
+ message: "Local ones-app-specs is already up to date."
2257
+ }, null, 2));
2258
+ return;
2259
+ }
2260
+ console.log("Local ones-app-specs is already up to date.");
2261
+ console.log(`SHA256: ${parsedChecksum.checksum}`);
2262
+ console.log(`Specs directory: ${dir}`);
2263
+ return;
2264
+ }
2265
+ const response = await axios({
2266
+ url: archiveURL,
2267
+ method: "GET",
2268
+ responseType: "stream",
2269
+ timeout: DOWNLOAD_TIMEOUT
2270
+ }).catch(() => {
2271
+ return createOnesApp.throwError(ErrorCode.SPECS_FETCH_FAILED, i18n.t("error.specs.fetch.downloadFailed", {
2272
+ url: archiveURL
2273
+ }));
2274
+ });
2275
+ await promises.pipeline(response.data, node_fs.createWriteStream(archivePath)).catch(async () => {
2276
+ await remove(archivePath).catch(() => void 0);
2277
+ return createOnesApp.throwError(ErrorCode.SPECS_FETCH_FAILED, i18n.t("error.specs.fetch.downloadFailed", {
2278
+ url: archiveURL
2279
+ }));
2280
+ });
2281
+ const actualChecksum = await getSHA256(archivePath);
2282
+ if (actualChecksum === parsedChecksum.checksum)
2283
+ ;
2284
+ else {
2285
+ await remove(archivePath).catch(() => void 0);
2286
+ return createOnesApp.throwError(ErrorCode.SPECS_CHECKSUM_MISMATCH, i18n.t("error.specs.fetch.verifyChecksumFailed", {
2287
+ expected: parsedChecksum.checksum,
2288
+ actual: actualChecksum
2289
+ }));
2290
+ }
2291
+ const verifyCommand = `sha256sum -c ${getShellSafePath(checksumPath)}`;
2292
+ if (shouldExtract) {
2293
+ try {
2294
+ ensureDirSync(onesDir);
2295
+ extractArchive(archivePath, onesDir);
2296
+ await writeFile(checksumPath, `${parsedChecksum.checksum} ${parsedChecksum.archiveFilename}
2297
+ `, "utf8");
2298
+ await remove(archivePath).catch(() => void 0);
2299
+ } catch (error) {
2300
+ return createOnesApp.throwError(ErrorCode.SPECS_FETCH_FAILED, i18n.t("error.specs.fetch.cleanupFailed", {
2301
+ file: archivePath,
2302
+ reason: `${error}`
2303
+ }));
2304
+ }
2305
+ } else {
2306
+ await writeFile(checksumPath, `${parsedChecksum.checksum} ${parsedChecksum.archiveFilename}
2307
+ `, "utf8");
2308
+ }
2309
+ if (useJSONOutput) {
2310
+ console.log(JSON.stringify({
2311
+ status: "success",
2312
+ base_url: baseURL,
2313
+ download_dir: dir,
2314
+ specs_dir: dir,
2315
+ checksum_url: checksumURL,
2316
+ archive_url: archiveURL,
2317
+ archive_path: archivePath,
2318
+ checksum_path: checksumPath,
2319
+ sha256: actualChecksum,
2320
+ force: forceFetch,
2321
+ extract: shouldExtract,
2322
+ archive_removed: shouldExtract,
2323
+ verify_command: shouldExtract ? null : verifyCommand
2324
+ }, null, 2));
2325
+ return;
2326
+ }
2327
+ console.log("ONES specs fetched successfully!");
2328
+ console.log(`SHA256: ${actualChecksum}`);
2329
+ console.log(`Specs directory: ${dir}`);
2330
+ console.log(`Base URL: ${baseURL}`);
2331
+ console.log(`Checksum URL: ${checksumURL}`);
2332
+ console.log(`Archive URL: ${archiveURL}`);
2333
+ console.log(`Archive path: ${archivePath}`);
2334
+ if (shouldExtract) {
2335
+ console.log("Archive extracted successfully!");
2336
+ console.log("Archive cleanup: enabled (source zip removed)");
2337
+ } else {
2338
+ console.log("Archive extraction: skipped");
2339
+ console.log(`Verify command: ${verifyCommand}`);
2340
+ }
2341
+ };
2053
2342
  const buildCommandArguments = [];
2054
2343
  const $build = new commander.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);
2055
2344
  createOnesApp.addCommandUsage($build);
@@ -2098,6 +2387,16 @@ const $app = new commander.Command("app").description(i18n.t("desc.app"));
2098
2387
  $app.addCommand($install).addCommand($enable).addCommand($disable).addCommand($uninstall).addCommand($logs);
2099
2388
  createOnesApp.addCommandUsage($app);
2100
2389
  createOnesApp.addCommandOutput($app);
2390
+ const specsFetchCommandArguments = [];
2391
+ const $fetch = new commander.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);
2392
+ $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"));
2393
+ createOnesApp.addCommandUsage($fetch);
2394
+ createOnesApp.addCommandOutput($fetch);
2395
+ const $specs = new commander.Command("specs").description(i18n.t("desc.specs"));
2396
+ $specs.addCommand($fetch);
2397
+ $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"));
2398
+ createOnesApp.addCommandUsage($specs);
2399
+ createOnesApp.addCommandOutput($specs);
2101
2400
  const legacyCommandArguments = ["projectPath"];
2102
2401
  const $create = new commander.Command("create").description(i18n.t("desc.legacy.create")).argument("<project-path>", i18n.t("desc.legacy.create.projectPath")).action(legacy);
2103
2402
  createOnesApp.addCommandUsage($create);
@@ -2111,7 +2410,7 @@ const version = `${getPackageJSON().version}`;
2111
2410
  const env = `${version} Node/${process.version}`;
2112
2411
  ones.description(i18n.t("desc.ones", {
2113
2412
  env
2114
- })).addCommand(createOnesApp.$create).addCommand($build).addCommand($dev).addCommand($tunnel).addCommand($app).addCommand($login).addCommand($logout).addCommand($whoami).addCommand($legacy).configureHelp({
2413
+ })).addCommand(createOnesApp.$create).addCommand($build).addCommand($dev).addCommand($tunnel).addCommand($app).addCommand($login).addCommand($logout).addCommand($whoami).addCommand($specs).addCommand($legacy).configureHelp({
2115
2414
  visibleCommands: (cmd) => {
2116
2415
  const blackList = ["legacy"];
2117
2416
  return cmd.commands.filter((command) => !_includesInstanceProperty(blackList).call(blackList, command.name()));