@specific.dev/cli 0.1.66 → 0.1.67
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/admin/404/index.html +1 -1
- package/dist/admin/404.html +1 -1
- package/dist/admin/__next.!KGRlZmF1bHQp.__PAGE__.txt +1 -1
- package/dist/admin/__next.!KGRlZmF1bHQp.txt +1 -1
- package/dist/admin/__next._full.txt +1 -1
- package/dist/admin/__next._head.txt +1 -1
- package/dist/admin/__next._index.txt +1 -1
- package/dist/admin/__next._tree.txt +1 -1
- package/dist/admin/_not-found/__next._full.txt +1 -1
- package/dist/admin/_not-found/__next._head.txt +1 -1
- package/dist/admin/_not-found/__next._index.txt +1 -1
- package/dist/admin/_not-found/__next._not-found.__PAGE__.txt +1 -1
- package/dist/admin/_not-found/__next._not-found.txt +1 -1
- package/dist/admin/_not-found/__next._tree.txt +1 -1
- package/dist/admin/_not-found/index.html +1 -1
- package/dist/admin/_not-found/index.txt +1 -1
- package/dist/admin/databases/__next.!KGRlZmF1bHQp.databases.__PAGE__.txt +1 -1
- package/dist/admin/databases/__next.!KGRlZmF1bHQp.databases.txt +1 -1
- package/dist/admin/databases/__next.!KGRlZmF1bHQp.txt +1 -1
- package/dist/admin/databases/__next._full.txt +1 -1
- package/dist/admin/databases/__next._head.txt +1 -1
- package/dist/admin/databases/__next._index.txt +1 -1
- package/dist/admin/databases/__next._tree.txt +1 -1
- package/dist/admin/databases/index.html +1 -1
- package/dist/admin/databases/index.txt +1 -1
- package/dist/admin/fullscreen/__next._full.txt +1 -1
- package/dist/admin/fullscreen/__next._head.txt +1 -1
- package/dist/admin/fullscreen/__next._index.txt +1 -1
- package/dist/admin/fullscreen/__next._tree.txt +1 -1
- package/dist/admin/fullscreen/__next.fullscreen.__PAGE__.txt +1 -1
- package/dist/admin/fullscreen/__next.fullscreen.txt +1 -1
- package/dist/admin/fullscreen/databases/__next._full.txt +1 -1
- package/dist/admin/fullscreen/databases/__next._head.txt +1 -1
- package/dist/admin/fullscreen/databases/__next._index.txt +1 -1
- package/dist/admin/fullscreen/databases/__next._tree.txt +1 -1
- package/dist/admin/fullscreen/databases/__next.fullscreen.databases.__PAGE__.txt +1 -1
- package/dist/admin/fullscreen/databases/__next.fullscreen.databases.txt +1 -1
- package/dist/admin/fullscreen/databases/__next.fullscreen.txt +1 -1
- package/dist/admin/fullscreen/databases/index.html +1 -1
- package/dist/admin/fullscreen/databases/index.txt +1 -1
- package/dist/admin/fullscreen/index.html +1 -1
- package/dist/admin/fullscreen/index.txt +1 -1
- package/dist/admin/index.html +1 -1
- package/dist/admin/index.txt +1 -1
- package/dist/admin/workflows/__next.!KGRlZmF1bHQp.txt +1 -1
- package/dist/admin/workflows/__next.!KGRlZmF1bHQp.workflows.__PAGE__.txt +1 -1
- package/dist/admin/workflows/__next.!KGRlZmF1bHQp.workflows.txt +1 -1
- package/dist/admin/workflows/__next._full.txt +1 -1
- package/dist/admin/workflows/__next._head.txt +1 -1
- package/dist/admin/workflows/__next._index.txt +1 -1
- package/dist/admin/workflows/__next._tree.txt +1 -1
- package/dist/admin/workflows/index.html +1 -1
- package/dist/admin/workflows/index.txt +1 -1
- package/dist/cli.js +445 -169
- package/dist/postinstall.js +1 -1
- package/package.json +3 -2
- /package/dist/admin/_next/static/{Al0o3YauO07qHR3spSA9w → B_l0oWRS4jgPRx3kI3HDj}/_buildManifest.js +0 -0
- /package/dist/admin/_next/static/{Al0o3YauO07qHR3spSA9w → B_l0oWRS4jgPRx3kI3HDj}/_clientMiddlewareManifest.json +0 -0
- /package/dist/admin/_next/static/{Al0o3YauO07qHR3spSA9w → B_l0oWRS4jgPRx3kI3HDj}/_ssgManifest.js +0 -0
package/dist/cli.js
CHANGED
|
@@ -238,15 +238,15 @@ var init_wsl_utils = __esm({
|
|
|
238
238
|
const { stdout } = await executePowerShell(command, { powerShellPath: psPath });
|
|
239
239
|
return stdout.trim();
|
|
240
240
|
};
|
|
241
|
-
convertWslPathToWindows = async (
|
|
242
|
-
if (/^[a-z]+:\/\//i.test(
|
|
243
|
-
return
|
|
241
|
+
convertWslPathToWindows = async (path30) => {
|
|
242
|
+
if (/^[a-z]+:\/\//i.test(path30)) {
|
|
243
|
+
return path30;
|
|
244
244
|
}
|
|
245
245
|
try {
|
|
246
|
-
const { stdout } = await execFile2("wslpath", ["-aw",
|
|
246
|
+
const { stdout } = await execFile2("wslpath", ["-aw", path30], { encoding: "utf8" });
|
|
247
247
|
return stdout.trim();
|
|
248
248
|
} catch {
|
|
249
|
-
return
|
|
249
|
+
return path30;
|
|
250
250
|
}
|
|
251
251
|
};
|
|
252
252
|
}
|
|
@@ -754,8 +754,8 @@ var require_dist = __commonJS({
|
|
|
754
754
|
var $global, $module, $NaN = NaN;
|
|
755
755
|
if ("undefined" != typeof window ? $global = window : "undefined" != typeof self ? $global = self : "undefined" != typeof global ? ($global = global).require = __require : $global = this, void 0 === $global || void 0 === $global.Array) throw new Error("no global object found");
|
|
756
756
|
if ("undefined" != typeof module && ($module = module), !$global.fs && $global.require) try {
|
|
757
|
-
var
|
|
758
|
-
"object" == typeof
|
|
757
|
+
var fs32 = $global.require("fs");
|
|
758
|
+
"object" == typeof fs32 && null !== fs32 && 0 !== Object.keys(fs32).length && ($global.fs = fs32);
|
|
759
759
|
} catch (e) {
|
|
760
760
|
}
|
|
761
761
|
if (!$global.fs) {
|
|
@@ -183423,7 +183423,7 @@ ${frame}`;
|
|
|
183423
183423
|
}
|
|
183424
183424
|
});
|
|
183425
183425
|
|
|
183426
|
-
// src/cli.tsx
|
|
183426
|
+
// src/cli-program.tsx
|
|
183427
183427
|
import { Command } from "commander";
|
|
183428
183428
|
|
|
183429
183429
|
// src/commands/init.tsx
|
|
@@ -184496,7 +184496,7 @@ function trackEvent(event, properties) {
|
|
|
184496
184496
|
event,
|
|
184497
184497
|
properties: {
|
|
184498
184498
|
...properties,
|
|
184499
|
-
cli_version: "0.1.
|
|
184499
|
+
cli_version: "0.1.67",
|
|
184500
184500
|
platform: process.platform,
|
|
184501
184501
|
node_version: process.version,
|
|
184502
184502
|
project_id: getProjectId(),
|
|
@@ -184914,20 +184914,20 @@ function saveBetas(enabled, projectDir) {
|
|
|
184914
184914
|
// src/commands/docs.tsx
|
|
184915
184915
|
var __dirname2 = dirname2(fileURLToPath2(import.meta.url));
|
|
184916
184916
|
var docsDir = join8(__dirname2, "docs");
|
|
184917
|
-
|
|
184918
|
-
|
|
184919
|
-
|
|
184917
|
+
var _embeddedDocs = null;
|
|
184918
|
+
function docsCommand(path30) {
|
|
184919
|
+
const content = resolveDocContent(path30);
|
|
184920
|
+
if (!content) {
|
|
184920
184921
|
console.error(
|
|
184921
|
-
`Documentation not found: ${
|
|
184922
|
+
`Documentation not found: ${path30 || "index"}
|
|
184922
184923
|
|
|
184923
184924
|
Run 'specific docs' to see available topics.`
|
|
184924
184925
|
);
|
|
184925
184926
|
process.exit(1);
|
|
184926
184927
|
}
|
|
184927
184928
|
const enabledBetas = new Set(loadEnabledBetas());
|
|
184928
|
-
|
|
184929
|
-
|
|
184930
|
-
console.log(content);
|
|
184929
|
+
const filtered = filterBetaTags(content, enabledBetas);
|
|
184930
|
+
console.log(filtered);
|
|
184931
184931
|
}
|
|
184932
184932
|
function filterBetaTags(content, enabledBetas) {
|
|
184933
184933
|
return content.replace(
|
|
@@ -184937,18 +184937,32 @@ function filterBetaTags(content, enabledBetas) {
|
|
|
184937
184937
|
}
|
|
184938
184938
|
);
|
|
184939
184939
|
}
|
|
184940
|
-
function
|
|
184941
|
-
if (
|
|
184940
|
+
function resolveDocContent(path30) {
|
|
184941
|
+
if (_embeddedDocs) {
|
|
184942
|
+
return resolveEmbeddedDoc(path30);
|
|
184943
|
+
}
|
|
184944
|
+
return resolveFilesystemDoc(path30);
|
|
184945
|
+
}
|
|
184946
|
+
function resolveEmbeddedDoc(path30) {
|
|
184947
|
+
if (!path30) {
|
|
184948
|
+
return _embeddedDocs.get("index.md") ?? null;
|
|
184949
|
+
}
|
|
184950
|
+
const direct = _embeddedDocs.get(`${path30}.md`);
|
|
184951
|
+
if (direct) return direct;
|
|
184952
|
+
return _embeddedDocs.get(`${path30}/index.md`) ?? null;
|
|
184953
|
+
}
|
|
184954
|
+
function resolveFilesystemDoc(path30) {
|
|
184955
|
+
if (!path30) {
|
|
184942
184956
|
const indexPath2 = join8(docsDir, "index.md");
|
|
184943
|
-
return existsSync7(indexPath2) ? indexPath2 : null;
|
|
184957
|
+
return existsSync7(indexPath2) ? readFileSync6(indexPath2, "utf-8") : null;
|
|
184944
184958
|
}
|
|
184945
|
-
const directPath = join8(docsDir, `${
|
|
184959
|
+
const directPath = join8(docsDir, `${path30}.md`);
|
|
184946
184960
|
if (existsSync7(directPath)) {
|
|
184947
|
-
return directPath;
|
|
184961
|
+
return readFileSync6(directPath, "utf-8");
|
|
184948
184962
|
}
|
|
184949
|
-
const indexPath = join8(docsDir,
|
|
184963
|
+
const indexPath = join8(docsDir, path30, "index.md");
|
|
184950
184964
|
if (existsSync7(indexPath)) {
|
|
184951
|
-
return indexPath;
|
|
184965
|
+
return readFileSync6(indexPath, "utf-8");
|
|
184952
184966
|
}
|
|
184953
184967
|
return null;
|
|
184954
184968
|
}
|
|
@@ -186333,7 +186347,7 @@ var ReaddirpStream = class extends Readable {
|
|
|
186333
186347
|
this._directoryFilter = normalizeFilter(opts.directoryFilter);
|
|
186334
186348
|
const statMethod = opts.lstat ? lstat : stat;
|
|
186335
186349
|
if (wantBigintFsStats) {
|
|
186336
|
-
this._stat = (
|
|
186350
|
+
this._stat = (path30) => statMethod(path30, { bigint: true });
|
|
186337
186351
|
} else {
|
|
186338
186352
|
this._stat = statMethod;
|
|
186339
186353
|
}
|
|
@@ -186358,8 +186372,8 @@ var ReaddirpStream = class extends Readable {
|
|
|
186358
186372
|
const par = this.parent;
|
|
186359
186373
|
const fil = par && par.files;
|
|
186360
186374
|
if (fil && fil.length > 0) {
|
|
186361
|
-
const { path:
|
|
186362
|
-
const slice = fil.splice(0, batch).map((dirent) => this._formatEntry(dirent,
|
|
186375
|
+
const { path: path30, depth } = par;
|
|
186376
|
+
const slice = fil.splice(0, batch).map((dirent) => this._formatEntry(dirent, path30));
|
|
186363
186377
|
const awaited = await Promise.all(slice);
|
|
186364
186378
|
for (const entry of awaited) {
|
|
186365
186379
|
if (!entry)
|
|
@@ -186399,20 +186413,20 @@ var ReaddirpStream = class extends Readable {
|
|
|
186399
186413
|
this.reading = false;
|
|
186400
186414
|
}
|
|
186401
186415
|
}
|
|
186402
|
-
async _exploreDir(
|
|
186416
|
+
async _exploreDir(path30, depth) {
|
|
186403
186417
|
let files;
|
|
186404
186418
|
try {
|
|
186405
|
-
files = await readdir(
|
|
186419
|
+
files = await readdir(path30, this._rdOptions);
|
|
186406
186420
|
} catch (error) {
|
|
186407
186421
|
this._onError(error);
|
|
186408
186422
|
}
|
|
186409
|
-
return { files, depth, path:
|
|
186423
|
+
return { files, depth, path: path30 };
|
|
186410
186424
|
}
|
|
186411
|
-
async _formatEntry(dirent,
|
|
186425
|
+
async _formatEntry(dirent, path30) {
|
|
186412
186426
|
let entry;
|
|
186413
186427
|
const basename6 = this._isDirent ? dirent.name : dirent;
|
|
186414
186428
|
try {
|
|
186415
|
-
const fullPath = presolve(pjoin(
|
|
186429
|
+
const fullPath = presolve(pjoin(path30, basename6));
|
|
186416
186430
|
entry = { path: prelative(this._root, fullPath), fullPath, basename: basename6 };
|
|
186417
186431
|
entry[this._statsProp] = this._isDirent ? dirent : await this._stat(fullPath);
|
|
186418
186432
|
} catch (err) {
|
|
@@ -186812,16 +186826,16 @@ var delFromSet = (main, prop, item) => {
|
|
|
186812
186826
|
};
|
|
186813
186827
|
var isEmptySet = (val) => val instanceof Set ? val.size === 0 : !val;
|
|
186814
186828
|
var FsWatchInstances = /* @__PURE__ */ new Map();
|
|
186815
|
-
function createFsWatchInstance(
|
|
186829
|
+
function createFsWatchInstance(path30, options2, listener, errHandler, emitRaw) {
|
|
186816
186830
|
const handleEvent = (rawEvent, evPath) => {
|
|
186817
|
-
listener(
|
|
186818
|
-
emitRaw(rawEvent, evPath, { watchedPath:
|
|
186819
|
-
if (evPath &&
|
|
186820
|
-
fsWatchBroadcast(sp.resolve(
|
|
186831
|
+
listener(path30);
|
|
186832
|
+
emitRaw(rawEvent, evPath, { watchedPath: path30 });
|
|
186833
|
+
if (evPath && path30 !== evPath) {
|
|
186834
|
+
fsWatchBroadcast(sp.resolve(path30, evPath), KEY_LISTENERS, sp.join(path30, evPath));
|
|
186821
186835
|
}
|
|
186822
186836
|
};
|
|
186823
186837
|
try {
|
|
186824
|
-
return fs_watch(
|
|
186838
|
+
return fs_watch(path30, {
|
|
186825
186839
|
persistent: options2.persistent
|
|
186826
186840
|
}, handleEvent);
|
|
186827
186841
|
} catch (error) {
|
|
@@ -186837,12 +186851,12 @@ var fsWatchBroadcast = (fullPath, listenerType, val1, val2, val3) => {
|
|
|
186837
186851
|
listener(val1, val2, val3);
|
|
186838
186852
|
});
|
|
186839
186853
|
};
|
|
186840
|
-
var setFsWatchListener = (
|
|
186854
|
+
var setFsWatchListener = (path30, fullPath, options2, handlers) => {
|
|
186841
186855
|
const { listener, errHandler, rawEmitter } = handlers;
|
|
186842
186856
|
let cont = FsWatchInstances.get(fullPath);
|
|
186843
186857
|
let watcher;
|
|
186844
186858
|
if (!options2.persistent) {
|
|
186845
|
-
watcher = createFsWatchInstance(
|
|
186859
|
+
watcher = createFsWatchInstance(path30, options2, listener, errHandler, rawEmitter);
|
|
186846
186860
|
if (!watcher)
|
|
186847
186861
|
return;
|
|
186848
186862
|
return watcher.close.bind(watcher);
|
|
@@ -186853,7 +186867,7 @@ var setFsWatchListener = (path28, fullPath, options2, handlers) => {
|
|
|
186853
186867
|
addAndConvert(cont, KEY_RAW, rawEmitter);
|
|
186854
186868
|
} else {
|
|
186855
186869
|
watcher = createFsWatchInstance(
|
|
186856
|
-
|
|
186870
|
+
path30,
|
|
186857
186871
|
options2,
|
|
186858
186872
|
fsWatchBroadcast.bind(null, fullPath, KEY_LISTENERS),
|
|
186859
186873
|
errHandler,
|
|
@@ -186868,7 +186882,7 @@ var setFsWatchListener = (path28, fullPath, options2, handlers) => {
|
|
|
186868
186882
|
cont.watcherUnusable = true;
|
|
186869
186883
|
if (isWindows && error.code === "EPERM") {
|
|
186870
186884
|
try {
|
|
186871
|
-
const fd = await open2(
|
|
186885
|
+
const fd = await open2(path30, "r");
|
|
186872
186886
|
await fd.close();
|
|
186873
186887
|
broadcastErr(error);
|
|
186874
186888
|
} catch (err) {
|
|
@@ -186899,7 +186913,7 @@ var setFsWatchListener = (path28, fullPath, options2, handlers) => {
|
|
|
186899
186913
|
};
|
|
186900
186914
|
};
|
|
186901
186915
|
var FsWatchFileInstances = /* @__PURE__ */ new Map();
|
|
186902
|
-
var setFsWatchFileListener = (
|
|
186916
|
+
var setFsWatchFileListener = (path30, fullPath, options2, handlers) => {
|
|
186903
186917
|
const { listener, rawEmitter } = handlers;
|
|
186904
186918
|
let cont = FsWatchFileInstances.get(fullPath);
|
|
186905
186919
|
const copts = cont && cont.options;
|
|
@@ -186921,7 +186935,7 @@ var setFsWatchFileListener = (path28, fullPath, options2, handlers) => {
|
|
|
186921
186935
|
});
|
|
186922
186936
|
const currmtime = curr.mtimeMs;
|
|
186923
186937
|
if (curr.size !== prev.size || currmtime > prev.mtimeMs || currmtime === 0) {
|
|
186924
|
-
foreach(cont.listeners, (listener2) => listener2(
|
|
186938
|
+
foreach(cont.listeners, (listener2) => listener2(path30, curr));
|
|
186925
186939
|
}
|
|
186926
186940
|
})
|
|
186927
186941
|
};
|
|
@@ -186951,13 +186965,13 @@ var NodeFsHandler = class {
|
|
|
186951
186965
|
* @param listener on fs change
|
|
186952
186966
|
* @returns closer for the watcher instance
|
|
186953
186967
|
*/
|
|
186954
|
-
_watchWithNodeFs(
|
|
186968
|
+
_watchWithNodeFs(path30, listener) {
|
|
186955
186969
|
const opts = this.fsw.options;
|
|
186956
|
-
const directory = sp.dirname(
|
|
186957
|
-
const basename6 = sp.basename(
|
|
186970
|
+
const directory = sp.dirname(path30);
|
|
186971
|
+
const basename6 = sp.basename(path30);
|
|
186958
186972
|
const parent = this.fsw._getWatchedDir(directory);
|
|
186959
186973
|
parent.add(basename6);
|
|
186960
|
-
const absolutePath = sp.resolve(
|
|
186974
|
+
const absolutePath = sp.resolve(path30);
|
|
186961
186975
|
const options2 = {
|
|
186962
186976
|
persistent: opts.persistent
|
|
186963
186977
|
};
|
|
@@ -186967,12 +186981,12 @@ var NodeFsHandler = class {
|
|
|
186967
186981
|
if (opts.usePolling) {
|
|
186968
186982
|
const enableBin = opts.interval !== opts.binaryInterval;
|
|
186969
186983
|
options2.interval = enableBin && isBinaryPath(basename6) ? opts.binaryInterval : opts.interval;
|
|
186970
|
-
closer = setFsWatchFileListener(
|
|
186984
|
+
closer = setFsWatchFileListener(path30, absolutePath, options2, {
|
|
186971
186985
|
listener,
|
|
186972
186986
|
rawEmitter: this.fsw._emitRaw
|
|
186973
186987
|
});
|
|
186974
186988
|
} else {
|
|
186975
|
-
closer = setFsWatchListener(
|
|
186989
|
+
closer = setFsWatchListener(path30, absolutePath, options2, {
|
|
186976
186990
|
listener,
|
|
186977
186991
|
errHandler: this._boundHandleError,
|
|
186978
186992
|
rawEmitter: this.fsw._emitRaw
|
|
@@ -186988,13 +187002,13 @@ var NodeFsHandler = class {
|
|
|
186988
187002
|
if (this.fsw.closed) {
|
|
186989
187003
|
return;
|
|
186990
187004
|
}
|
|
186991
|
-
const
|
|
187005
|
+
const dirname10 = sp.dirname(file);
|
|
186992
187006
|
const basename6 = sp.basename(file);
|
|
186993
|
-
const parent = this.fsw._getWatchedDir(
|
|
187007
|
+
const parent = this.fsw._getWatchedDir(dirname10);
|
|
186994
187008
|
let prevStats = stats;
|
|
186995
187009
|
if (parent.has(basename6))
|
|
186996
187010
|
return;
|
|
186997
|
-
const listener = async (
|
|
187011
|
+
const listener = async (path30, newStats) => {
|
|
186998
187012
|
if (!this.fsw._throttle(THROTTLE_MODE_WATCH, file, 5))
|
|
186999
187013
|
return;
|
|
187000
187014
|
if (!newStats || newStats.mtimeMs === 0) {
|
|
@@ -187008,16 +187022,16 @@ var NodeFsHandler = class {
|
|
|
187008
187022
|
this.fsw._emit(EV.CHANGE, file, newStats2);
|
|
187009
187023
|
}
|
|
187010
187024
|
if ((isMacos || isLinux || isFreeBSD) && prevStats.ino !== newStats2.ino) {
|
|
187011
|
-
this.fsw._closeFile(
|
|
187025
|
+
this.fsw._closeFile(path30);
|
|
187012
187026
|
prevStats = newStats2;
|
|
187013
187027
|
const closer2 = this._watchWithNodeFs(file, listener);
|
|
187014
187028
|
if (closer2)
|
|
187015
|
-
this.fsw._addPathCloser(
|
|
187029
|
+
this.fsw._addPathCloser(path30, closer2);
|
|
187016
187030
|
} else {
|
|
187017
187031
|
prevStats = newStats2;
|
|
187018
187032
|
}
|
|
187019
187033
|
} catch (error) {
|
|
187020
|
-
this.fsw._remove(
|
|
187034
|
+
this.fsw._remove(dirname10, basename6);
|
|
187021
187035
|
}
|
|
187022
187036
|
} else if (parent.has(basename6)) {
|
|
187023
187037
|
const at = newStats.atimeMs;
|
|
@@ -187044,7 +187058,7 @@ var NodeFsHandler = class {
|
|
|
187044
187058
|
* @param item basename of this item
|
|
187045
187059
|
* @returns true if no more processing is needed for this entry.
|
|
187046
187060
|
*/
|
|
187047
|
-
async _handleSymlink(entry, directory,
|
|
187061
|
+
async _handleSymlink(entry, directory, path30, item) {
|
|
187048
187062
|
if (this.fsw.closed) {
|
|
187049
187063
|
return;
|
|
187050
187064
|
}
|
|
@@ -187054,7 +187068,7 @@ var NodeFsHandler = class {
|
|
|
187054
187068
|
this.fsw._incrReadyCount();
|
|
187055
187069
|
let linkPath;
|
|
187056
187070
|
try {
|
|
187057
|
-
linkPath = await fsrealpath(
|
|
187071
|
+
linkPath = await fsrealpath(path30);
|
|
187058
187072
|
} catch (e) {
|
|
187059
187073
|
this.fsw._emitReady();
|
|
187060
187074
|
return true;
|
|
@@ -187064,12 +187078,12 @@ var NodeFsHandler = class {
|
|
|
187064
187078
|
if (dir.has(item)) {
|
|
187065
187079
|
if (this.fsw._symlinkPaths.get(full) !== linkPath) {
|
|
187066
187080
|
this.fsw._symlinkPaths.set(full, linkPath);
|
|
187067
|
-
this.fsw._emit(EV.CHANGE,
|
|
187081
|
+
this.fsw._emit(EV.CHANGE, path30, entry.stats);
|
|
187068
187082
|
}
|
|
187069
187083
|
} else {
|
|
187070
187084
|
dir.add(item);
|
|
187071
187085
|
this.fsw._symlinkPaths.set(full, linkPath);
|
|
187072
|
-
this.fsw._emit(EV.ADD,
|
|
187086
|
+
this.fsw._emit(EV.ADD, path30, entry.stats);
|
|
187073
187087
|
}
|
|
187074
187088
|
this.fsw._emitReady();
|
|
187075
187089
|
return true;
|
|
@@ -187099,9 +187113,9 @@ var NodeFsHandler = class {
|
|
|
187099
187113
|
return;
|
|
187100
187114
|
}
|
|
187101
187115
|
const item = entry.path;
|
|
187102
|
-
let
|
|
187116
|
+
let path30 = sp.join(directory, item);
|
|
187103
187117
|
current.add(item);
|
|
187104
|
-
if (entry.stats.isSymbolicLink() && await this._handleSymlink(entry, directory,
|
|
187118
|
+
if (entry.stats.isSymbolicLink() && await this._handleSymlink(entry, directory, path30, item)) {
|
|
187105
187119
|
return;
|
|
187106
187120
|
}
|
|
187107
187121
|
if (this.fsw.closed) {
|
|
@@ -187110,8 +187124,8 @@ var NodeFsHandler = class {
|
|
|
187110
187124
|
}
|
|
187111
187125
|
if (item === target || !target && !previous.has(item)) {
|
|
187112
187126
|
this.fsw._incrReadyCount();
|
|
187113
|
-
|
|
187114
|
-
this._addToNodeFs(
|
|
187127
|
+
path30 = sp.join(dir, sp.relative(dir, path30));
|
|
187128
|
+
this._addToNodeFs(path30, initialAdd, wh, depth + 1);
|
|
187115
187129
|
}
|
|
187116
187130
|
}).on(EV.ERROR, this._boundHandleError);
|
|
187117
187131
|
return new Promise((resolve10, reject) => {
|
|
@@ -187180,13 +187194,13 @@ var NodeFsHandler = class {
|
|
|
187180
187194
|
* @param depth Child path actually targeted for watch
|
|
187181
187195
|
* @param target Child path actually targeted for watch
|
|
187182
187196
|
*/
|
|
187183
|
-
async _addToNodeFs(
|
|
187197
|
+
async _addToNodeFs(path30, initialAdd, priorWh, depth, target) {
|
|
187184
187198
|
const ready = this.fsw._emitReady;
|
|
187185
|
-
if (this.fsw._isIgnored(
|
|
187199
|
+
if (this.fsw._isIgnored(path30) || this.fsw.closed) {
|
|
187186
187200
|
ready();
|
|
187187
187201
|
return false;
|
|
187188
187202
|
}
|
|
187189
|
-
const wh = this.fsw._getWatchHelpers(
|
|
187203
|
+
const wh = this.fsw._getWatchHelpers(path30);
|
|
187190
187204
|
if (priorWh) {
|
|
187191
187205
|
wh.filterPath = (entry) => priorWh.filterPath(entry);
|
|
187192
187206
|
wh.filterDir = (entry) => priorWh.filterDir(entry);
|
|
@@ -187202,8 +187216,8 @@ var NodeFsHandler = class {
|
|
|
187202
187216
|
const follow = this.fsw.options.followSymlinks;
|
|
187203
187217
|
let closer;
|
|
187204
187218
|
if (stats.isDirectory()) {
|
|
187205
|
-
const absPath = sp.resolve(
|
|
187206
|
-
const targetPath = follow ? await fsrealpath(
|
|
187219
|
+
const absPath = sp.resolve(path30);
|
|
187220
|
+
const targetPath = follow ? await fsrealpath(path30) : path30;
|
|
187207
187221
|
if (this.fsw.closed)
|
|
187208
187222
|
return;
|
|
187209
187223
|
closer = await this._handleDir(wh.watchPath, stats, initialAdd, depth, target, wh, targetPath);
|
|
@@ -187213,29 +187227,29 @@ var NodeFsHandler = class {
|
|
|
187213
187227
|
this.fsw._symlinkPaths.set(absPath, targetPath);
|
|
187214
187228
|
}
|
|
187215
187229
|
} else if (stats.isSymbolicLink()) {
|
|
187216
|
-
const targetPath = follow ? await fsrealpath(
|
|
187230
|
+
const targetPath = follow ? await fsrealpath(path30) : path30;
|
|
187217
187231
|
if (this.fsw.closed)
|
|
187218
187232
|
return;
|
|
187219
187233
|
const parent = sp.dirname(wh.watchPath);
|
|
187220
187234
|
this.fsw._getWatchedDir(parent).add(wh.watchPath);
|
|
187221
187235
|
this.fsw._emit(EV.ADD, wh.watchPath, stats);
|
|
187222
|
-
closer = await this._handleDir(parent, stats, initialAdd, depth,
|
|
187236
|
+
closer = await this._handleDir(parent, stats, initialAdd, depth, path30, wh, targetPath);
|
|
187223
187237
|
if (this.fsw.closed)
|
|
187224
187238
|
return;
|
|
187225
187239
|
if (targetPath !== void 0) {
|
|
187226
|
-
this.fsw._symlinkPaths.set(sp.resolve(
|
|
187240
|
+
this.fsw._symlinkPaths.set(sp.resolve(path30), targetPath);
|
|
187227
187241
|
}
|
|
187228
187242
|
} else {
|
|
187229
187243
|
closer = this._handleFile(wh.watchPath, stats, initialAdd);
|
|
187230
187244
|
}
|
|
187231
187245
|
ready();
|
|
187232
187246
|
if (closer)
|
|
187233
|
-
this.fsw._addPathCloser(
|
|
187247
|
+
this.fsw._addPathCloser(path30, closer);
|
|
187234
187248
|
return false;
|
|
187235
187249
|
} catch (error) {
|
|
187236
187250
|
if (this.fsw._handleError(error)) {
|
|
187237
187251
|
ready();
|
|
187238
|
-
return
|
|
187252
|
+
return path30;
|
|
187239
187253
|
}
|
|
187240
187254
|
}
|
|
187241
187255
|
}
|
|
@@ -187278,24 +187292,24 @@ function createPattern(matcher) {
|
|
|
187278
187292
|
}
|
|
187279
187293
|
return () => false;
|
|
187280
187294
|
}
|
|
187281
|
-
function normalizePath(
|
|
187282
|
-
if (typeof
|
|
187295
|
+
function normalizePath(path30) {
|
|
187296
|
+
if (typeof path30 !== "string")
|
|
187283
187297
|
throw new Error("string expected");
|
|
187284
|
-
|
|
187285
|
-
|
|
187298
|
+
path30 = sp2.normalize(path30);
|
|
187299
|
+
path30 = path30.replace(/\\/g, "/");
|
|
187286
187300
|
let prepend = false;
|
|
187287
|
-
if (
|
|
187301
|
+
if (path30.startsWith("//"))
|
|
187288
187302
|
prepend = true;
|
|
187289
|
-
|
|
187303
|
+
path30 = path30.replace(DOUBLE_SLASH_RE, "/");
|
|
187290
187304
|
if (prepend)
|
|
187291
|
-
|
|
187292
|
-
return
|
|
187305
|
+
path30 = "/" + path30;
|
|
187306
|
+
return path30;
|
|
187293
187307
|
}
|
|
187294
187308
|
function matchPatterns(patterns, testString, stats) {
|
|
187295
|
-
const
|
|
187309
|
+
const path30 = normalizePath(testString);
|
|
187296
187310
|
for (let index = 0; index < patterns.length; index++) {
|
|
187297
187311
|
const pattern = patterns[index];
|
|
187298
|
-
if (pattern(
|
|
187312
|
+
if (pattern(path30, stats)) {
|
|
187299
187313
|
return true;
|
|
187300
187314
|
}
|
|
187301
187315
|
}
|
|
@@ -187333,19 +187347,19 @@ var toUnix = (string) => {
|
|
|
187333
187347
|
}
|
|
187334
187348
|
return str;
|
|
187335
187349
|
};
|
|
187336
|
-
var normalizePathToUnix = (
|
|
187337
|
-
var normalizeIgnored = (cwd = "") => (
|
|
187338
|
-
if (typeof
|
|
187339
|
-
return normalizePathToUnix(sp2.isAbsolute(
|
|
187350
|
+
var normalizePathToUnix = (path30) => toUnix(sp2.normalize(toUnix(path30)));
|
|
187351
|
+
var normalizeIgnored = (cwd = "") => (path30) => {
|
|
187352
|
+
if (typeof path30 === "string") {
|
|
187353
|
+
return normalizePathToUnix(sp2.isAbsolute(path30) ? path30 : sp2.join(cwd, path30));
|
|
187340
187354
|
} else {
|
|
187341
|
-
return
|
|
187355
|
+
return path30;
|
|
187342
187356
|
}
|
|
187343
187357
|
};
|
|
187344
|
-
var getAbsolutePath = (
|
|
187345
|
-
if (sp2.isAbsolute(
|
|
187346
|
-
return
|
|
187358
|
+
var getAbsolutePath = (path30, cwd) => {
|
|
187359
|
+
if (sp2.isAbsolute(path30)) {
|
|
187360
|
+
return path30;
|
|
187347
187361
|
}
|
|
187348
|
-
return sp2.join(cwd,
|
|
187362
|
+
return sp2.join(cwd, path30);
|
|
187349
187363
|
};
|
|
187350
187364
|
var EMPTY_SET = Object.freeze(/* @__PURE__ */ new Set());
|
|
187351
187365
|
var DirEntry = class {
|
|
@@ -187410,10 +187424,10 @@ var WatchHelper = class {
|
|
|
187410
187424
|
dirParts;
|
|
187411
187425
|
followSymlinks;
|
|
187412
187426
|
statMethod;
|
|
187413
|
-
constructor(
|
|
187427
|
+
constructor(path30, follow, fsw) {
|
|
187414
187428
|
this.fsw = fsw;
|
|
187415
|
-
const watchPath =
|
|
187416
|
-
this.path =
|
|
187429
|
+
const watchPath = path30;
|
|
187430
|
+
this.path = path30 = path30.replace(REPLACER_RE, "");
|
|
187417
187431
|
this.watchPath = watchPath;
|
|
187418
187432
|
this.fullWatchPath = sp2.resolve(watchPath);
|
|
187419
187433
|
this.dirParts = [];
|
|
@@ -187553,20 +187567,20 @@ var FSWatcher = class extends EventEmitter {
|
|
|
187553
187567
|
this._closePromise = void 0;
|
|
187554
187568
|
let paths = unifyPaths(paths_);
|
|
187555
187569
|
if (cwd) {
|
|
187556
|
-
paths = paths.map((
|
|
187557
|
-
const absPath = getAbsolutePath(
|
|
187570
|
+
paths = paths.map((path30) => {
|
|
187571
|
+
const absPath = getAbsolutePath(path30, cwd);
|
|
187558
187572
|
return absPath;
|
|
187559
187573
|
});
|
|
187560
187574
|
}
|
|
187561
|
-
paths.forEach((
|
|
187562
|
-
this._removeIgnoredPath(
|
|
187575
|
+
paths.forEach((path30) => {
|
|
187576
|
+
this._removeIgnoredPath(path30);
|
|
187563
187577
|
});
|
|
187564
187578
|
this._userIgnored = void 0;
|
|
187565
187579
|
if (!this._readyCount)
|
|
187566
187580
|
this._readyCount = 0;
|
|
187567
187581
|
this._readyCount += paths.length;
|
|
187568
|
-
Promise.all(paths.map(async (
|
|
187569
|
-
const res = await this._nodeFsHandler._addToNodeFs(
|
|
187582
|
+
Promise.all(paths.map(async (path30) => {
|
|
187583
|
+
const res = await this._nodeFsHandler._addToNodeFs(path30, !_internal, void 0, 0, _origAdd);
|
|
187570
187584
|
if (res)
|
|
187571
187585
|
this._emitReady();
|
|
187572
187586
|
return res;
|
|
@@ -187588,17 +187602,17 @@ var FSWatcher = class extends EventEmitter {
|
|
|
187588
187602
|
return this;
|
|
187589
187603
|
const paths = unifyPaths(paths_);
|
|
187590
187604
|
const { cwd } = this.options;
|
|
187591
|
-
paths.forEach((
|
|
187592
|
-
if (!sp2.isAbsolute(
|
|
187605
|
+
paths.forEach((path30) => {
|
|
187606
|
+
if (!sp2.isAbsolute(path30) && !this._closers.has(path30)) {
|
|
187593
187607
|
if (cwd)
|
|
187594
|
-
|
|
187595
|
-
|
|
187608
|
+
path30 = sp2.join(cwd, path30);
|
|
187609
|
+
path30 = sp2.resolve(path30);
|
|
187596
187610
|
}
|
|
187597
|
-
this._closePath(
|
|
187598
|
-
this._addIgnoredPath(
|
|
187599
|
-
if (this._watched.has(
|
|
187611
|
+
this._closePath(path30);
|
|
187612
|
+
this._addIgnoredPath(path30);
|
|
187613
|
+
if (this._watched.has(path30)) {
|
|
187600
187614
|
this._addIgnoredPath({
|
|
187601
|
-
path:
|
|
187615
|
+
path: path30,
|
|
187602
187616
|
recursive: true
|
|
187603
187617
|
});
|
|
187604
187618
|
}
|
|
@@ -187662,38 +187676,38 @@ var FSWatcher = class extends EventEmitter {
|
|
|
187662
187676
|
* @param stats arguments to be passed with event
|
|
187663
187677
|
* @returns the error if defined, otherwise the value of the FSWatcher instance's `closed` flag
|
|
187664
187678
|
*/
|
|
187665
|
-
async _emit(event,
|
|
187679
|
+
async _emit(event, path30, stats) {
|
|
187666
187680
|
if (this.closed)
|
|
187667
187681
|
return;
|
|
187668
187682
|
const opts = this.options;
|
|
187669
187683
|
if (isWindows)
|
|
187670
|
-
|
|
187684
|
+
path30 = sp2.normalize(path30);
|
|
187671
187685
|
if (opts.cwd)
|
|
187672
|
-
|
|
187673
|
-
const args = [
|
|
187686
|
+
path30 = sp2.relative(opts.cwd, path30);
|
|
187687
|
+
const args = [path30];
|
|
187674
187688
|
if (stats != null)
|
|
187675
187689
|
args.push(stats);
|
|
187676
187690
|
const awf = opts.awaitWriteFinish;
|
|
187677
187691
|
let pw;
|
|
187678
|
-
if (awf && (pw = this._pendingWrites.get(
|
|
187692
|
+
if (awf && (pw = this._pendingWrites.get(path30))) {
|
|
187679
187693
|
pw.lastChange = /* @__PURE__ */ new Date();
|
|
187680
187694
|
return this;
|
|
187681
187695
|
}
|
|
187682
187696
|
if (opts.atomic) {
|
|
187683
187697
|
if (event === EVENTS.UNLINK) {
|
|
187684
|
-
this._pendingUnlinks.set(
|
|
187698
|
+
this._pendingUnlinks.set(path30, [event, ...args]);
|
|
187685
187699
|
setTimeout(() => {
|
|
187686
|
-
this._pendingUnlinks.forEach((entry,
|
|
187700
|
+
this._pendingUnlinks.forEach((entry, path31) => {
|
|
187687
187701
|
this.emit(...entry);
|
|
187688
187702
|
this.emit(EVENTS.ALL, ...entry);
|
|
187689
|
-
this._pendingUnlinks.delete(
|
|
187703
|
+
this._pendingUnlinks.delete(path31);
|
|
187690
187704
|
});
|
|
187691
187705
|
}, typeof opts.atomic === "number" ? opts.atomic : 100);
|
|
187692
187706
|
return this;
|
|
187693
187707
|
}
|
|
187694
|
-
if (event === EVENTS.ADD && this._pendingUnlinks.has(
|
|
187708
|
+
if (event === EVENTS.ADD && this._pendingUnlinks.has(path30)) {
|
|
187695
187709
|
event = EVENTS.CHANGE;
|
|
187696
|
-
this._pendingUnlinks.delete(
|
|
187710
|
+
this._pendingUnlinks.delete(path30);
|
|
187697
187711
|
}
|
|
187698
187712
|
}
|
|
187699
187713
|
if (awf && (event === EVENTS.ADD || event === EVENTS.CHANGE) && this._readyEmitted) {
|
|
@@ -187711,16 +187725,16 @@ var FSWatcher = class extends EventEmitter {
|
|
|
187711
187725
|
this.emitWithAll(event, args);
|
|
187712
187726
|
}
|
|
187713
187727
|
};
|
|
187714
|
-
this._awaitWriteFinish(
|
|
187728
|
+
this._awaitWriteFinish(path30, awf.stabilityThreshold, event, awfEmit);
|
|
187715
187729
|
return this;
|
|
187716
187730
|
}
|
|
187717
187731
|
if (event === EVENTS.CHANGE) {
|
|
187718
|
-
const isThrottled = !this._throttle(EVENTS.CHANGE,
|
|
187732
|
+
const isThrottled = !this._throttle(EVENTS.CHANGE, path30, 50);
|
|
187719
187733
|
if (isThrottled)
|
|
187720
187734
|
return this;
|
|
187721
187735
|
}
|
|
187722
187736
|
if (opts.alwaysStat && stats === void 0 && (event === EVENTS.ADD || event === EVENTS.ADD_DIR || event === EVENTS.CHANGE)) {
|
|
187723
|
-
const fullPath = opts.cwd ? sp2.join(opts.cwd,
|
|
187737
|
+
const fullPath = opts.cwd ? sp2.join(opts.cwd, path30) : path30;
|
|
187724
187738
|
let stats2;
|
|
187725
187739
|
try {
|
|
187726
187740
|
stats2 = await stat3(fullPath);
|
|
@@ -187751,23 +187765,23 @@ var FSWatcher = class extends EventEmitter {
|
|
|
187751
187765
|
* @param timeout duration of time to suppress duplicate actions
|
|
187752
187766
|
* @returns tracking object or false if action should be suppressed
|
|
187753
187767
|
*/
|
|
187754
|
-
_throttle(actionType,
|
|
187768
|
+
_throttle(actionType, path30, timeout) {
|
|
187755
187769
|
if (!this._throttled.has(actionType)) {
|
|
187756
187770
|
this._throttled.set(actionType, /* @__PURE__ */ new Map());
|
|
187757
187771
|
}
|
|
187758
187772
|
const action = this._throttled.get(actionType);
|
|
187759
187773
|
if (!action)
|
|
187760
187774
|
throw new Error("invalid throttle");
|
|
187761
|
-
const actionPath = action.get(
|
|
187775
|
+
const actionPath = action.get(path30);
|
|
187762
187776
|
if (actionPath) {
|
|
187763
187777
|
actionPath.count++;
|
|
187764
187778
|
return false;
|
|
187765
187779
|
}
|
|
187766
187780
|
let timeoutObject;
|
|
187767
187781
|
const clear = () => {
|
|
187768
|
-
const item = action.get(
|
|
187782
|
+
const item = action.get(path30);
|
|
187769
187783
|
const count = item ? item.count : 0;
|
|
187770
|
-
action.delete(
|
|
187784
|
+
action.delete(path30);
|
|
187771
187785
|
clearTimeout(timeoutObject);
|
|
187772
187786
|
if (item)
|
|
187773
187787
|
clearTimeout(item.timeoutObject);
|
|
@@ -187775,7 +187789,7 @@ var FSWatcher = class extends EventEmitter {
|
|
|
187775
187789
|
};
|
|
187776
187790
|
timeoutObject = setTimeout(clear, timeout);
|
|
187777
187791
|
const thr = { timeoutObject, clear, count: 0 };
|
|
187778
|
-
action.set(
|
|
187792
|
+
action.set(path30, thr);
|
|
187779
187793
|
return thr;
|
|
187780
187794
|
}
|
|
187781
187795
|
_incrReadyCount() {
|
|
@@ -187789,44 +187803,44 @@ var FSWatcher = class extends EventEmitter {
|
|
|
187789
187803
|
* @param event
|
|
187790
187804
|
* @param awfEmit Callback to be called when ready for event to be emitted.
|
|
187791
187805
|
*/
|
|
187792
|
-
_awaitWriteFinish(
|
|
187806
|
+
_awaitWriteFinish(path30, threshold, event, awfEmit) {
|
|
187793
187807
|
const awf = this.options.awaitWriteFinish;
|
|
187794
187808
|
if (typeof awf !== "object")
|
|
187795
187809
|
return;
|
|
187796
187810
|
const pollInterval = awf.pollInterval;
|
|
187797
187811
|
let timeoutHandler;
|
|
187798
|
-
let fullPath =
|
|
187799
|
-
if (this.options.cwd && !sp2.isAbsolute(
|
|
187800
|
-
fullPath = sp2.join(this.options.cwd,
|
|
187812
|
+
let fullPath = path30;
|
|
187813
|
+
if (this.options.cwd && !sp2.isAbsolute(path30)) {
|
|
187814
|
+
fullPath = sp2.join(this.options.cwd, path30);
|
|
187801
187815
|
}
|
|
187802
187816
|
const now = /* @__PURE__ */ new Date();
|
|
187803
187817
|
const writes = this._pendingWrites;
|
|
187804
187818
|
function awaitWriteFinishFn(prevStat) {
|
|
187805
187819
|
statcb(fullPath, (err, curStat) => {
|
|
187806
|
-
if (err || !writes.has(
|
|
187820
|
+
if (err || !writes.has(path30)) {
|
|
187807
187821
|
if (err && err.code !== "ENOENT")
|
|
187808
187822
|
awfEmit(err);
|
|
187809
187823
|
return;
|
|
187810
187824
|
}
|
|
187811
187825
|
const now2 = Number(/* @__PURE__ */ new Date());
|
|
187812
187826
|
if (prevStat && curStat.size !== prevStat.size) {
|
|
187813
|
-
writes.get(
|
|
187827
|
+
writes.get(path30).lastChange = now2;
|
|
187814
187828
|
}
|
|
187815
|
-
const pw = writes.get(
|
|
187829
|
+
const pw = writes.get(path30);
|
|
187816
187830
|
const df = now2 - pw.lastChange;
|
|
187817
187831
|
if (df >= threshold) {
|
|
187818
|
-
writes.delete(
|
|
187832
|
+
writes.delete(path30);
|
|
187819
187833
|
awfEmit(void 0, curStat);
|
|
187820
187834
|
} else {
|
|
187821
187835
|
timeoutHandler = setTimeout(awaitWriteFinishFn, pollInterval, curStat);
|
|
187822
187836
|
}
|
|
187823
187837
|
});
|
|
187824
187838
|
}
|
|
187825
|
-
if (!writes.has(
|
|
187826
|
-
writes.set(
|
|
187839
|
+
if (!writes.has(path30)) {
|
|
187840
|
+
writes.set(path30, {
|
|
187827
187841
|
lastChange: now,
|
|
187828
187842
|
cancelWait: () => {
|
|
187829
|
-
writes.delete(
|
|
187843
|
+
writes.delete(path30);
|
|
187830
187844
|
clearTimeout(timeoutHandler);
|
|
187831
187845
|
return event;
|
|
187832
187846
|
}
|
|
@@ -187837,8 +187851,8 @@ var FSWatcher = class extends EventEmitter {
|
|
|
187837
187851
|
/**
|
|
187838
187852
|
* Determines whether user has asked to ignore this path.
|
|
187839
187853
|
*/
|
|
187840
|
-
_isIgnored(
|
|
187841
|
-
if (this.options.atomic && DOT_RE.test(
|
|
187854
|
+
_isIgnored(path30, stats) {
|
|
187855
|
+
if (this.options.atomic && DOT_RE.test(path30))
|
|
187842
187856
|
return true;
|
|
187843
187857
|
if (!this._userIgnored) {
|
|
187844
187858
|
const { cwd } = this.options;
|
|
@@ -187848,17 +187862,17 @@ var FSWatcher = class extends EventEmitter {
|
|
|
187848
187862
|
const list = [...ignoredPaths.map(normalizeIgnored(cwd)), ...ignored];
|
|
187849
187863
|
this._userIgnored = anymatch(list, void 0);
|
|
187850
187864
|
}
|
|
187851
|
-
return this._userIgnored(
|
|
187865
|
+
return this._userIgnored(path30, stats);
|
|
187852
187866
|
}
|
|
187853
|
-
_isntIgnored(
|
|
187854
|
-
return !this._isIgnored(
|
|
187867
|
+
_isntIgnored(path30, stat4) {
|
|
187868
|
+
return !this._isIgnored(path30, stat4);
|
|
187855
187869
|
}
|
|
187856
187870
|
/**
|
|
187857
187871
|
* Provides a set of common helpers and properties relating to symlink handling.
|
|
187858
187872
|
* @param path file or directory pattern being watched
|
|
187859
187873
|
*/
|
|
187860
|
-
_getWatchHelpers(
|
|
187861
|
-
return new WatchHelper(
|
|
187874
|
+
_getWatchHelpers(path30) {
|
|
187875
|
+
return new WatchHelper(path30, this.options.followSymlinks, this);
|
|
187862
187876
|
}
|
|
187863
187877
|
// Directory helpers
|
|
187864
187878
|
// -----------------
|
|
@@ -187890,63 +187904,63 @@ var FSWatcher = class extends EventEmitter {
|
|
|
187890
187904
|
* @param item base path of item/directory
|
|
187891
187905
|
*/
|
|
187892
187906
|
_remove(directory, item, isDirectory) {
|
|
187893
|
-
const
|
|
187894
|
-
const fullPath = sp2.resolve(
|
|
187895
|
-
isDirectory = isDirectory != null ? isDirectory : this._watched.has(
|
|
187896
|
-
if (!this._throttle("remove",
|
|
187907
|
+
const path30 = sp2.join(directory, item);
|
|
187908
|
+
const fullPath = sp2.resolve(path30);
|
|
187909
|
+
isDirectory = isDirectory != null ? isDirectory : this._watched.has(path30) || this._watched.has(fullPath);
|
|
187910
|
+
if (!this._throttle("remove", path30, 100))
|
|
187897
187911
|
return;
|
|
187898
187912
|
if (!isDirectory && this._watched.size === 1) {
|
|
187899
187913
|
this.add(directory, item, true);
|
|
187900
187914
|
}
|
|
187901
|
-
const wp = this._getWatchedDir(
|
|
187915
|
+
const wp = this._getWatchedDir(path30);
|
|
187902
187916
|
const nestedDirectoryChildren = wp.getChildren();
|
|
187903
|
-
nestedDirectoryChildren.forEach((nested) => this._remove(
|
|
187917
|
+
nestedDirectoryChildren.forEach((nested) => this._remove(path30, nested));
|
|
187904
187918
|
const parent = this._getWatchedDir(directory);
|
|
187905
187919
|
const wasTracked = parent.has(item);
|
|
187906
187920
|
parent.remove(item);
|
|
187907
187921
|
if (this._symlinkPaths.has(fullPath)) {
|
|
187908
187922
|
this._symlinkPaths.delete(fullPath);
|
|
187909
187923
|
}
|
|
187910
|
-
let relPath =
|
|
187924
|
+
let relPath = path30;
|
|
187911
187925
|
if (this.options.cwd)
|
|
187912
|
-
relPath = sp2.relative(this.options.cwd,
|
|
187926
|
+
relPath = sp2.relative(this.options.cwd, path30);
|
|
187913
187927
|
if (this.options.awaitWriteFinish && this._pendingWrites.has(relPath)) {
|
|
187914
187928
|
const event = this._pendingWrites.get(relPath).cancelWait();
|
|
187915
187929
|
if (event === EVENTS.ADD)
|
|
187916
187930
|
return;
|
|
187917
187931
|
}
|
|
187918
|
-
this._watched.delete(
|
|
187932
|
+
this._watched.delete(path30);
|
|
187919
187933
|
this._watched.delete(fullPath);
|
|
187920
187934
|
const eventName = isDirectory ? EVENTS.UNLINK_DIR : EVENTS.UNLINK;
|
|
187921
|
-
if (wasTracked && !this._isIgnored(
|
|
187922
|
-
this._emit(eventName,
|
|
187923
|
-
this._closePath(
|
|
187935
|
+
if (wasTracked && !this._isIgnored(path30))
|
|
187936
|
+
this._emit(eventName, path30);
|
|
187937
|
+
this._closePath(path30);
|
|
187924
187938
|
}
|
|
187925
187939
|
/**
|
|
187926
187940
|
* Closes all watchers for a path
|
|
187927
187941
|
*/
|
|
187928
|
-
_closePath(
|
|
187929
|
-
this._closeFile(
|
|
187930
|
-
const dir = sp2.dirname(
|
|
187931
|
-
this._getWatchedDir(dir).remove(sp2.basename(
|
|
187942
|
+
_closePath(path30) {
|
|
187943
|
+
this._closeFile(path30);
|
|
187944
|
+
const dir = sp2.dirname(path30);
|
|
187945
|
+
this._getWatchedDir(dir).remove(sp2.basename(path30));
|
|
187932
187946
|
}
|
|
187933
187947
|
/**
|
|
187934
187948
|
* Closes only file-specific watchers
|
|
187935
187949
|
*/
|
|
187936
|
-
_closeFile(
|
|
187937
|
-
const closers = this._closers.get(
|
|
187950
|
+
_closeFile(path30) {
|
|
187951
|
+
const closers = this._closers.get(path30);
|
|
187938
187952
|
if (!closers)
|
|
187939
187953
|
return;
|
|
187940
187954
|
closers.forEach((closer) => closer());
|
|
187941
|
-
this._closers.delete(
|
|
187955
|
+
this._closers.delete(path30);
|
|
187942
187956
|
}
|
|
187943
|
-
_addPathCloser(
|
|
187957
|
+
_addPathCloser(path30, closer) {
|
|
187944
187958
|
if (!closer)
|
|
187945
187959
|
return;
|
|
187946
|
-
let list = this._closers.get(
|
|
187960
|
+
let list = this._closers.get(path30);
|
|
187947
187961
|
if (!list) {
|
|
187948
187962
|
list = [];
|
|
187949
|
-
this._closers.set(
|
|
187963
|
+
this._closers.set(path30, list);
|
|
187950
187964
|
}
|
|
187951
187965
|
list.push(closer);
|
|
187952
187966
|
}
|
|
@@ -188995,6 +189009,7 @@ import { fileURLToPath as fileURLToPath3 } from "url";
|
|
|
188995
189009
|
import httpProxy from "http-proxy";
|
|
188996
189010
|
var __dirname3 = path13.dirname(fileURLToPath3(import.meta.url));
|
|
188997
189011
|
var adminDir = path13.join(__dirname3, "admin");
|
|
189012
|
+
var _embeddedAdmin = null;
|
|
188998
189013
|
var HTTP_PORT = 80;
|
|
188999
189014
|
var HTTPS_PORT = 443;
|
|
189000
189015
|
var DOMAIN_SUFFIX = ".local.spcf.app";
|
|
@@ -189341,6 +189356,48 @@ function sendNotFound(res, requestedService, serviceMap) {
|
|
|
189341
189356
|
</html>`);
|
|
189342
189357
|
}
|
|
189343
189358
|
function serveStaticFile(res, pathname) {
|
|
189359
|
+
if (_embeddedAdmin) {
|
|
189360
|
+
return serveEmbeddedFile(res, pathname);
|
|
189361
|
+
}
|
|
189362
|
+
return serveFilesystemFile(res, pathname);
|
|
189363
|
+
}
|
|
189364
|
+
function serveEmbeddedFile(res, pathname) {
|
|
189365
|
+
let filePath = pathname;
|
|
189366
|
+
if (filePath === "/" || filePath.endsWith("/")) {
|
|
189367
|
+
filePath = filePath + "index.html";
|
|
189368
|
+
}
|
|
189369
|
+
const relativePath = filePath.startsWith("/") ? filePath.slice(1) : filePath;
|
|
189370
|
+
let content = _embeddedAdmin.get(relativePath);
|
|
189371
|
+
if (content) {
|
|
189372
|
+
const ext = path13.extname(relativePath).toLowerCase();
|
|
189373
|
+
const contentType = MIME_TYPES[ext] || "application/octet-stream";
|
|
189374
|
+
res.writeHead(200, { "Content-Type": contentType });
|
|
189375
|
+
res.end(content);
|
|
189376
|
+
return;
|
|
189377
|
+
}
|
|
189378
|
+
content = _embeddedAdmin.get(relativePath + ".html");
|
|
189379
|
+
if (content) {
|
|
189380
|
+
res.writeHead(200, { "Content-Type": "text/html" });
|
|
189381
|
+
res.end(content);
|
|
189382
|
+
return;
|
|
189383
|
+
}
|
|
189384
|
+
const indexKey = relativePath.endsWith("/") ? relativePath + "index.html" : relativePath + "/index.html";
|
|
189385
|
+
content = _embeddedAdmin.get(indexKey);
|
|
189386
|
+
if (content) {
|
|
189387
|
+
res.writeHead(200, { "Content-Type": "text/html" });
|
|
189388
|
+
res.end(content);
|
|
189389
|
+
return;
|
|
189390
|
+
}
|
|
189391
|
+
const notFound = _embeddedAdmin.get("404.html");
|
|
189392
|
+
if (notFound) {
|
|
189393
|
+
res.writeHead(404, { "Content-Type": "text/html" });
|
|
189394
|
+
res.end(notFound);
|
|
189395
|
+
return;
|
|
189396
|
+
}
|
|
189397
|
+
res.writeHead(404, { "Content-Type": "text/html" });
|
|
189398
|
+
res.end("<h1>Not Found</h1>");
|
|
189399
|
+
}
|
|
189400
|
+
function serveFilesystemFile(res, pathname) {
|
|
189344
189401
|
let filePath = pathname;
|
|
189345
189402
|
if (filePath === "/" || filePath.endsWith("/")) {
|
|
189346
189403
|
filePath = filePath + "index.html";
|
|
@@ -194307,11 +194364,226 @@ function betaCommand() {
|
|
|
194307
194364
|
render8(/* @__PURE__ */ React10.createElement(BetaToggleUI, null));
|
|
194308
194365
|
}
|
|
194309
194366
|
|
|
194310
|
-
// src/
|
|
194367
|
+
// src/commands/update.tsx
|
|
194368
|
+
import React11, { useState as useState10, useEffect as useEffect8 } from "react";
|
|
194369
|
+
import { render as render9, Text as Text11, Box as Box10, useApp as useApp6 } from "ink";
|
|
194370
|
+
import Spinner7 from "ink-spinner";
|
|
194371
|
+
|
|
194372
|
+
// src/lib/update.ts
|
|
194373
|
+
import * as fs30 from "fs";
|
|
194374
|
+
import * as path28 from "path";
|
|
194375
|
+
var BINARIES_BASE_URL = "https://binaries.specific.dev/cli";
|
|
194376
|
+
function compareVersions(a, b) {
|
|
194377
|
+
const partsA = a.split(".").map(Number);
|
|
194378
|
+
const partsB = b.split(".").map(Number);
|
|
194379
|
+
const len = Math.max(partsA.length, partsB.length);
|
|
194380
|
+
for (let i = 0; i < len; i++) {
|
|
194381
|
+
const numA = partsA[i] ?? 0;
|
|
194382
|
+
const numB = partsB[i] ?? 0;
|
|
194383
|
+
if (numA !== numB) return numA - numB;
|
|
194384
|
+
}
|
|
194385
|
+
return 0;
|
|
194386
|
+
}
|
|
194387
|
+
async function checkForUpdate() {
|
|
194388
|
+
const currentVersion = "0.1.67";
|
|
194389
|
+
const response = await fetch(`${BINARIES_BASE_URL}/latest`);
|
|
194390
|
+
if (!response.ok) {
|
|
194391
|
+
throw new Error(`Failed to check for updates: HTTP ${response.status}`);
|
|
194392
|
+
}
|
|
194393
|
+
const latestVersion = (await response.text()).trim();
|
|
194394
|
+
const updateAvailable = compareVersions(latestVersion, currentVersion) > 0;
|
|
194395
|
+
return { currentVersion, latestVersion, updateAvailable };
|
|
194396
|
+
}
|
|
194397
|
+
function getCurrentBinaryPath() {
|
|
194398
|
+
return process.execPath;
|
|
194399
|
+
}
|
|
194400
|
+
function isBinaryWritable() {
|
|
194401
|
+
const binaryPath = getCurrentBinaryPath();
|
|
194402
|
+
const dir = path28.dirname(binaryPath);
|
|
194403
|
+
try {
|
|
194404
|
+
fs30.accessSync(dir, fs30.constants.W_OK);
|
|
194405
|
+
return true;
|
|
194406
|
+
} catch {
|
|
194407
|
+
return false;
|
|
194408
|
+
}
|
|
194409
|
+
}
|
|
194410
|
+
async function performUpdate(version, onProgress) {
|
|
194411
|
+
const binaryPath = getCurrentBinaryPath();
|
|
194412
|
+
const binaryDir = path28.dirname(binaryPath);
|
|
194413
|
+
const tempPath = path28.join(binaryDir, `.specific-update-${process.pid}`);
|
|
194414
|
+
try {
|
|
194415
|
+
const { platform: platform5, arch: arch3 } = getPlatformInfo();
|
|
194416
|
+
const url = `${BINARIES_BASE_URL}/${version}/specific-${platform5}-${arch3}`;
|
|
194417
|
+
await downloadFile(url, tempPath, onProgress);
|
|
194418
|
+
const stat4 = fs30.statSync(tempPath);
|
|
194419
|
+
if (stat4.size === 0) {
|
|
194420
|
+
throw new Error("Downloaded binary is empty");
|
|
194421
|
+
}
|
|
194422
|
+
fs30.chmodSync(tempPath, 493);
|
|
194423
|
+
onProgress?.({ phase: "finalizing" });
|
|
194424
|
+
fs30.unlinkSync(binaryPath);
|
|
194425
|
+
fs30.renameSync(tempPath, binaryPath);
|
|
194426
|
+
} catch (error) {
|
|
194427
|
+
try {
|
|
194428
|
+
if (fs30.existsSync(tempPath)) {
|
|
194429
|
+
fs30.unlinkSync(tempPath);
|
|
194430
|
+
}
|
|
194431
|
+
} catch {
|
|
194432
|
+
}
|
|
194433
|
+
throw error;
|
|
194434
|
+
}
|
|
194435
|
+
}
|
|
194436
|
+
|
|
194437
|
+
// src/lib/background-update.ts
|
|
194438
|
+
import { spawn as spawn10 } from "child_process";
|
|
194439
|
+
import * as fs31 from "fs";
|
|
194440
|
+
import * as path29 from "path";
|
|
194441
|
+
import * as os9 from "os";
|
|
194442
|
+
var SPECIFIC_DIR = path29.join(os9.homedir(), ".specific");
|
|
194443
|
+
var RATE_LIMIT_FILE = path29.join(SPECIFIC_DIR, "last-update-check");
|
|
194444
|
+
var LOCK_FILE = path29.join(SPECIFIC_DIR, "update.lock");
|
|
194445
|
+
var RATE_LIMIT_MS = 60 * 60 * 1e3;
|
|
194446
|
+
var STALE_LOCK_MS = 10 * 60 * 1e3;
|
|
194447
|
+
function writeCheckTimestamp() {
|
|
194448
|
+
fs31.mkdirSync(SPECIFIC_DIR, { recursive: true });
|
|
194449
|
+
fs31.writeFileSync(RATE_LIMIT_FILE, String(Date.now()), "utf-8");
|
|
194450
|
+
}
|
|
194451
|
+
function isRateLimited() {
|
|
194452
|
+
try {
|
|
194453
|
+
const content = fs31.readFileSync(RATE_LIMIT_FILE, "utf-8").trim();
|
|
194454
|
+
const lastCheck = parseInt(content, 10);
|
|
194455
|
+
if (isNaN(lastCheck)) return false;
|
|
194456
|
+
return Date.now() - lastCheck < RATE_LIMIT_MS;
|
|
194457
|
+
} catch {
|
|
194458
|
+
return false;
|
|
194459
|
+
}
|
|
194460
|
+
}
|
|
194461
|
+
function maybeStartBackgroundUpdate() {
|
|
194462
|
+
try {
|
|
194463
|
+
if (true) return;
|
|
194464
|
+
if (process.env.SPECIFIC_BACKGROUND_UPDATE === "1") return;
|
|
194465
|
+
if (isRateLimited()) return;
|
|
194466
|
+
if (!isBinaryWritable()) return;
|
|
194467
|
+
const child = spawn10(process.execPath, [], {
|
|
194468
|
+
detached: true,
|
|
194469
|
+
stdio: "ignore",
|
|
194470
|
+
env: {
|
|
194471
|
+
...process.env,
|
|
194472
|
+
SPECIFIC_BACKGROUND_UPDATE: "1"
|
|
194473
|
+
}
|
|
194474
|
+
});
|
|
194475
|
+
child.unref();
|
|
194476
|
+
} catch {
|
|
194477
|
+
}
|
|
194478
|
+
}
|
|
194479
|
+
|
|
194480
|
+
// src/commands/update.tsx
|
|
194481
|
+
function UpdateUI() {
|
|
194482
|
+
const { exit } = useApp6();
|
|
194483
|
+
const [state, setState] = useState10({ phase: "checking" });
|
|
194484
|
+
useEffect8(() => {
|
|
194485
|
+
if (state.phase !== "checking") return;
|
|
194486
|
+
let cancelled = false;
|
|
194487
|
+
async function check() {
|
|
194488
|
+
try {
|
|
194489
|
+
const result = await checkForUpdate();
|
|
194490
|
+
if (cancelled) return;
|
|
194491
|
+
if (!result.updateAvailable) {
|
|
194492
|
+
setState({ phase: "up-to-date", checkResult: result });
|
|
194493
|
+
return;
|
|
194494
|
+
}
|
|
194495
|
+
if (!isBinaryWritable()) {
|
|
194496
|
+
setState({ phase: "permission-error", checkResult: result });
|
|
194497
|
+
return;
|
|
194498
|
+
}
|
|
194499
|
+
setState({ phase: "downloading", checkResult: result });
|
|
194500
|
+
} catch (err) {
|
|
194501
|
+
if (cancelled) return;
|
|
194502
|
+
setState({
|
|
194503
|
+
phase: "error",
|
|
194504
|
+
error: err instanceof Error ? err.message : String(err)
|
|
194505
|
+
});
|
|
194506
|
+
}
|
|
194507
|
+
}
|
|
194508
|
+
check();
|
|
194509
|
+
return () => {
|
|
194510
|
+
cancelled = true;
|
|
194511
|
+
};
|
|
194512
|
+
}, [state.phase]);
|
|
194513
|
+
useEffect8(() => {
|
|
194514
|
+
if (state.phase !== "downloading" || !state.checkResult) return;
|
|
194515
|
+
let cancelled = false;
|
|
194516
|
+
async function download() {
|
|
194517
|
+
try {
|
|
194518
|
+
await performUpdate(state.checkResult.latestVersion, (progress) => {
|
|
194519
|
+
if (!cancelled) {
|
|
194520
|
+
setState((s) => ({ ...s, progress }));
|
|
194521
|
+
}
|
|
194522
|
+
});
|
|
194523
|
+
if (cancelled) return;
|
|
194524
|
+
trackEvent("cli_updated", {
|
|
194525
|
+
from_version: state.checkResult.currentVersion,
|
|
194526
|
+
to_version: state.checkResult.latestVersion
|
|
194527
|
+
});
|
|
194528
|
+
writeCheckTimestamp();
|
|
194529
|
+
setState((s) => ({ ...s, phase: "success" }));
|
|
194530
|
+
} catch (err) {
|
|
194531
|
+
if (cancelled) return;
|
|
194532
|
+
setState({
|
|
194533
|
+
phase: "error",
|
|
194534
|
+
checkResult: state.checkResult,
|
|
194535
|
+
error: err instanceof Error ? err.message : String(err)
|
|
194536
|
+
});
|
|
194537
|
+
}
|
|
194538
|
+
}
|
|
194539
|
+
download();
|
|
194540
|
+
return () => {
|
|
194541
|
+
cancelled = true;
|
|
194542
|
+
};
|
|
194543
|
+
}, [state.phase, state.checkResult]);
|
|
194544
|
+
useEffect8(() => {
|
|
194545
|
+
if (state.phase === "up-to-date" || state.phase === "success" || state.phase === "error" || state.phase === "permission-error") {
|
|
194546
|
+
const timer = setTimeout(() => exit(), 100);
|
|
194547
|
+
return () => clearTimeout(timer);
|
|
194548
|
+
}
|
|
194549
|
+
}, [state.phase, exit]);
|
|
194550
|
+
if (state.phase === "checking") {
|
|
194551
|
+
return /* @__PURE__ */ React11.createElement(Box10, null, /* @__PURE__ */ React11.createElement(Text11, { color: "blue" }, /* @__PURE__ */ React11.createElement(Spinner7, { type: "dots" })), /* @__PURE__ */ React11.createElement(Text11, null, " Checking for updates..."));
|
|
194552
|
+
}
|
|
194553
|
+
if (state.phase === "up-to-date") {
|
|
194554
|
+
return /* @__PURE__ */ React11.createElement(Text11, { color: "green" }, "Already up to date (v", state.checkResult.currentVersion, ")");
|
|
194555
|
+
}
|
|
194556
|
+
if (state.phase === "permission-error") {
|
|
194557
|
+
const { currentVersion, latestVersion } = state.checkResult;
|
|
194558
|
+
return /* @__PURE__ */ React11.createElement(Box10, { flexDirection: "column" }, /* @__PURE__ */ React11.createElement(Text11, null, "Update available: v", currentVersion, " \u2192 v", latestVersion), /* @__PURE__ */ React11.createElement(Text11, { color: "yellow" }, "Permission denied. Re-run with sudo:"), /* @__PURE__ */ React11.createElement(Text11, { color: "cyan" }, " sudo specific update"));
|
|
194559
|
+
}
|
|
194560
|
+
if (state.phase === "downloading") {
|
|
194561
|
+
const { currentVersion, latestVersion } = state.checkResult;
|
|
194562
|
+
const { progress } = state;
|
|
194563
|
+
const progressText = progress?.percent ? ` (${progress.percent}%)` : "";
|
|
194564
|
+
return /* @__PURE__ */ React11.createElement(Box10, { flexDirection: "column" }, /* @__PURE__ */ React11.createElement(Text11, null, "Updating: v", currentVersion, " \u2192 v", latestVersion), /* @__PURE__ */ React11.createElement(Box10, null, /* @__PURE__ */ React11.createElement(Text11, { color: "blue" }, /* @__PURE__ */ React11.createElement(Spinner7, { type: "dots" })), /* @__PURE__ */ React11.createElement(Text11, null, " ", progress?.phase === "finalizing" ? "Installing..." : `Downloading${progressText}`)));
|
|
194565
|
+
}
|
|
194566
|
+
if (state.phase === "success") {
|
|
194567
|
+
const { currentVersion, latestVersion } = state.checkResult;
|
|
194568
|
+
return /* @__PURE__ */ React11.createElement(Text11, { color: "green" }, "Updated successfully: v", currentVersion, " \u2192 v", latestVersion);
|
|
194569
|
+
}
|
|
194570
|
+
return /* @__PURE__ */ React11.createElement(Text11, { color: "red" }, "Update failed: ", state.error);
|
|
194571
|
+
}
|
|
194572
|
+
function updateCommand() {
|
|
194573
|
+
const distribution = "npm";
|
|
194574
|
+
if (distribution !== "binary") {
|
|
194575
|
+
console.log("This installation was installed via npm.");
|
|
194576
|
+
console.log("To update, run: npm update -g @specific.dev/cli");
|
|
194577
|
+
return;
|
|
194578
|
+
}
|
|
194579
|
+
render9(/* @__PURE__ */ React11.createElement(UpdateUI, null));
|
|
194580
|
+
}
|
|
194581
|
+
|
|
194582
|
+
// src/cli-program.tsx
|
|
194311
194583
|
var program = new Command();
|
|
194312
194584
|
var env = "production";
|
|
194313
194585
|
var envLabel = env !== "production" ? `[${env.toUpperCase()}] ` : "";
|
|
194314
|
-
program.name("specific").description(`${envLabel}Infrastructure-as-code for coding agents`).version("0.1.
|
|
194586
|
+
program.name("specific").description(`${envLabel}Infrastructure-as-code for coding agents`).version("0.1.67").enablePositionalOptions();
|
|
194315
194587
|
program.command("init").description("Initialize project for use with a coding agent").option("--agent <name...>", "Agents to configure (cursor, claude, codex, other)").action((options2) => initCommand(options2));
|
|
194316
194588
|
program.command("docs [topic]").description("Fetch LLM-optimized documentation").action(docsCommand);
|
|
194317
194589
|
program.command("check").description("Validate specific.hcl configuration").action(checkCommand);
|
|
@@ -194340,13 +194612,17 @@ program.command("clean").description("Remove .specific directory for a clean sla
|
|
|
194340
194612
|
cleanCommand(options2.key);
|
|
194341
194613
|
});
|
|
194342
194614
|
program.command("beta").description("Manage beta feature flags").action(betaCommand);
|
|
194615
|
+
program.command("update").description("Update Specific CLI to the latest version").action(updateCommand);
|
|
194343
194616
|
program.command("login").description("Log in to Specific").action(loginCommand);
|
|
194344
194617
|
program.command("logout").description("Log out of Specific").action(logoutCommand);
|
|
194345
194618
|
var commandName = process.argv[2] || "help";
|
|
194346
194619
|
trackEvent("cli_command_invoked", { command: commandName });
|
|
194620
|
+
maybeStartBackgroundUpdate();
|
|
194347
194621
|
process.on("beforeExit", async () => {
|
|
194348
194622
|
await shutdown();
|
|
194349
194623
|
});
|
|
194624
|
+
|
|
194625
|
+
// src/cli.tsx
|
|
194350
194626
|
program.parse();
|
|
194351
194627
|
/*! Bundled license information:
|
|
194352
194628
|
|