@adbayb/stack 2.40.0-next-f8ad939 → 2.40.0-next-6049a9b
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/bin/index.js +1 -3
- package/configs/oxlint/index.ts +90 -12
- package/dist/index.js +99 -61
- package/package.json +1 -1
package/bin/index.js
CHANGED
|
@@ -1,7 +1,5 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
|
|
3
|
-
import
|
|
4
|
-
|
|
5
|
-
const pkg = createRequire(import.meta.url)("../package.json");
|
|
3
|
+
import pkg from "../package.json" with { type: "json" };
|
|
6
4
|
|
|
7
5
|
void import(new URL(`../${pkg.exports["."].default}`, import.meta.url));
|
package/configs/oxlint/index.ts
CHANGED
|
@@ -1,6 +1,64 @@
|
|
|
1
1
|
import { defineConfig } from "oxlint";
|
|
2
2
|
|
|
3
|
+
const JAVASCRIPT_EXTENSIONS = ["js", "jsx", "cjs", "mjs", "mjsx"];
|
|
4
|
+
const TYPESCRIPT_EXTENSIONS = ["ts", "tsx", "cts", "mts", "mtsx"];
|
|
5
|
+
const JAVASCRIPT_LIKE_EXTENSIONS = [...JAVASCRIPT_EXTENSIONS, ...TYPESCRIPT_EXTENSIONS];
|
|
6
|
+
const JAVASCRIPT_LIKE_EXTENSIONS_AS_STRING = JAVASCRIPT_LIKE_EXTENSIONS.join(",");
|
|
7
|
+
|
|
8
|
+
const TEST_LIKE_FILES = [
|
|
9
|
+
`**/{test,test-d}.{${JAVASCRIPT_LIKE_EXTENSIONS_AS_STRING}}`,
|
|
10
|
+
`**/*.{test,test-d}.{${JAVASCRIPT_LIKE_EXTENSIONS_AS_STRING}}`,
|
|
11
|
+
];
|
|
12
|
+
|
|
13
|
+
const RELAXED_LIKE_FILES = [
|
|
14
|
+
...TEST_LIKE_FILES,
|
|
15
|
+
"**/.config/**",
|
|
16
|
+
"**/.configs/**",
|
|
17
|
+
"**/config/**",
|
|
18
|
+
"**/configs/**",
|
|
19
|
+
"**/examples/**",
|
|
20
|
+
"**/scripts/**",
|
|
21
|
+
"**/tools/**",
|
|
22
|
+
`**/config.{${JAVASCRIPT_LIKE_EXTENSIONS_AS_STRING}}`,
|
|
23
|
+
`**/configs.{${JAVASCRIPT_LIKE_EXTENSIONS_AS_STRING}}`,
|
|
24
|
+
`**/*.config.{${JAVASCRIPT_LIKE_EXTENSIONS_AS_STRING}}`,
|
|
25
|
+
`**/*.configs.{${JAVASCRIPT_LIKE_EXTENSIONS_AS_STRING}}`,
|
|
26
|
+
`**/stories.{${JAVASCRIPT_LIKE_EXTENSIONS_AS_STRING}}`,
|
|
27
|
+
`**/*.stories.{${JAVASCRIPT_LIKE_EXTENSIONS_AS_STRING}}`,
|
|
28
|
+
];
|
|
29
|
+
|
|
3
30
|
export default defineConfig({
|
|
31
|
+
categories: {
|
|
32
|
+
correctness: "error",
|
|
33
|
+
nursery: "error",
|
|
34
|
+
pedantic: "error",
|
|
35
|
+
perf: "error",
|
|
36
|
+
style: "error",
|
|
37
|
+
suspicious: "error",
|
|
38
|
+
},
|
|
39
|
+
options: {
|
|
40
|
+
denyWarnings: true,
|
|
41
|
+
reportUnusedDisableDirectives: "error",
|
|
42
|
+
respectEslintDisableDirectives: false,
|
|
43
|
+
typeAware: true,
|
|
44
|
+
typeCheck: true,
|
|
45
|
+
},
|
|
46
|
+
overrides: [
|
|
47
|
+
{
|
|
48
|
+
files: TEST_LIKE_FILES,
|
|
49
|
+
plugins: ["vitest"],
|
|
50
|
+
},
|
|
51
|
+
{
|
|
52
|
+
files: [
|
|
53
|
+
...RELAXED_LIKE_FILES,
|
|
54
|
+
`*.config(s)?.{${JAVASCRIPT_LIKE_EXTENSIONS_AS_STRING}}`,
|
|
55
|
+
],
|
|
56
|
+
rules: {
|
|
57
|
+
"import/no-anonymous-default-export": "off",
|
|
58
|
+
},
|
|
59
|
+
},
|
|
60
|
+
],
|
|
61
|
+
// TODO: add jsPlugins for perfectionist and padding-line-between-statements + add React rules (such as set-state-in-effect) from React X https://github.com/oxc-project/oxc/issues/1022 + potentially https://github.com/es-tooling/eslint-plugin-depend/blob/main/docs/rules/ban-dependencies.md
|
|
4
62
|
plugins: [
|
|
5
63
|
"eslint",
|
|
6
64
|
"import",
|
|
@@ -13,18 +71,38 @@ export default defineConfig({
|
|
|
13
71
|
"react-perf",
|
|
14
72
|
"typescript",
|
|
15
73
|
"unicorn",
|
|
16
|
-
"vitest",
|
|
17
74
|
],
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
75
|
+
rules: {
|
|
76
|
+
"array-callback-return": ["error", { allowImplicit: true }],
|
|
77
|
+
"arrow-body-style": ["error", "always"],
|
|
78
|
+
"id-length": "off",
|
|
79
|
+
"import/exports-last": "off",
|
|
80
|
+
"import/group-exports": "off",
|
|
81
|
+
"import/max-dependencies": "off",
|
|
82
|
+
"import/no-named-export": "off",
|
|
83
|
+
"import/no-nodejs-modules": "off",
|
|
84
|
+
"import/prefer-default-export": "off",
|
|
85
|
+
"jsdoc/require-param-type": "off",
|
|
86
|
+
"jsdoc/require-property-type": "off",
|
|
87
|
+
"jsdoc/require-returns-type": "off",
|
|
88
|
+
"max-classes-per-file": "off",
|
|
89
|
+
"max-lines": "off",
|
|
90
|
+
"max-lines-per-function": "off",
|
|
91
|
+
"max-statements": "off",
|
|
92
|
+
"no-continue": "off",
|
|
93
|
+
"no-magic-numbers": "off",
|
|
94
|
+
"no-ternary": "off",
|
|
95
|
+
"no-undef": "off",
|
|
96
|
+
"no-warning-comments": "off",
|
|
97
|
+
"node/no-sync": "off",
|
|
98
|
+
"prefer-named-capture-group": "off",
|
|
99
|
+
"prefer-readonly-parameter-types": "off",
|
|
100
|
+
"react/jsx-max-depth": "off",
|
|
101
|
+
"sort-imports": ["error", { ignoreDeclarationSort: true }],
|
|
102
|
+
"strict-boolean-expressions": "off",
|
|
103
|
+
"typescript/consistent-return": "off",
|
|
104
|
+
"typescript/consistent-type-definitions": ["error", "type"],
|
|
105
|
+
"typescript/no-unsafe-type-assertion": "off",
|
|
106
|
+
"unicorn/filename-case": "off",
|
|
29
107
|
},
|
|
30
108
|
});
|
package/dist/index.js
CHANGED
|
@@ -6,9 +6,9 @@ import { chmod, cp, mkdir, readFile, readdir, rename, rm, symlink, writeFile } f
|
|
|
6
6
|
|
|
7
7
|
//#region src/helpers.ts
|
|
8
8
|
const require = createRequire(import.meta.url);
|
|
9
|
-
|
|
9
|
+
const assert = (expectedCondition, createError) => {
|
|
10
10
|
if (!expectedCondition) throw createError();
|
|
11
|
-
}
|
|
11
|
+
};
|
|
12
12
|
/**
|
|
13
13
|
* Helper to format log messages with a welcoming bot.
|
|
14
14
|
*
|
|
@@ -91,7 +91,7 @@ const setPackageManager = async () => {
|
|
|
91
91
|
*
|
|
92
92
|
* @see {@link https://github.com/nodejs/corepack/issues/613}
|
|
93
93
|
*/
|
|
94
|
-
|
|
94
|
+
await helpers.exec("pnx corepack enable");
|
|
95
95
|
};
|
|
96
96
|
async function getRequest(url, responseType) {
|
|
97
97
|
const response = await fetch(url);
|
|
@@ -103,31 +103,35 @@ async function getRequest(url, responseType) {
|
|
|
103
103
|
return response.json();
|
|
104
104
|
}
|
|
105
105
|
const request = { get: getRequest };
|
|
106
|
-
const oxlint = (options) =>
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
106
|
+
const oxlint = (options) => {
|
|
107
|
+
return async (files = []) => {
|
|
108
|
+
const args = [
|
|
109
|
+
...files,
|
|
110
|
+
"--disable-nested-config",
|
|
111
|
+
"--no-error-on-unmatched-pattern"
|
|
112
|
+
];
|
|
113
|
+
if (options.isFixMode) args.push("--fix");
|
|
114
|
+
try {
|
|
115
|
+
return await helpers.exec(`oxlint ${args.join(" ")}`);
|
|
116
|
+
} catch (error) {
|
|
117
|
+
throw createError("oxlint", error instanceof Error ? error : new Error(String(error)));
|
|
118
|
+
}
|
|
119
|
+
};
|
|
118
120
|
};
|
|
119
|
-
const oxfmt = (options) =>
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
121
|
+
const oxfmt = (options) => {
|
|
122
|
+
return async (files = []) => {
|
|
123
|
+
const args = [
|
|
124
|
+
...files,
|
|
125
|
+
"--disable-nested-config",
|
|
126
|
+
"--no-error-on-unmatched-pattern",
|
|
127
|
+
options.isFixMode ? "--write" : "--check"
|
|
128
|
+
];
|
|
129
|
+
try {
|
|
130
|
+
return await helpers.exec(`oxfmt ${args.join(" ")}`);
|
|
131
|
+
} catch (error) {
|
|
132
|
+
throw createError("oxfmt", error instanceof Error ? error : new Error(String(error)));
|
|
133
|
+
}
|
|
134
|
+
};
|
|
131
135
|
};
|
|
132
136
|
const turbo = async (command, options = {}) => {
|
|
133
137
|
try {
|
|
@@ -199,7 +203,9 @@ const checkDependency = async () => {
|
|
|
199
203
|
const checkDependencyVersionMismatch = createPackagesVersionMismatchChecker();
|
|
200
204
|
const packages = JSON.parse(stdout).map((pkg) => {
|
|
201
205
|
const packagePath = join(pkg.path, "package.json");
|
|
202
|
-
assert(pkg.name, () =>
|
|
206
|
+
assert(pkg.name, () => {
|
|
207
|
+
return createPackageError(`\`${packagePath}\` must have a name field.`);
|
|
208
|
+
});
|
|
203
209
|
const packageContent = require(packagePath);
|
|
204
210
|
const peerDependencies = packageContent.peerDependencies ?? {};
|
|
205
211
|
const devDependencies = packageContent.devDependencies ?? {};
|
|
@@ -221,7 +227,7 @@ const checkDependencyVersionRange = ({ dependencies, devDependencies, name, peer
|
|
|
221
227
|
consumedBy: name,
|
|
222
228
|
name: dependencyName
|
|
223
229
|
});
|
|
224
|
-
if (version !== "workspace:*" && !isExcluded(version) && !/^\d
|
|
230
|
+
if (version !== "workspace:*" && !isExcluded(version) && !/^\d/u.test(version)) throw createPackageError(`As a dev dependency, \`${dependencyName}\` version must be fixed (or set as "workspace:*" for local packages) to reduce accidental breaking change risks due to an implicit semver upgrade.`, {
|
|
225
231
|
consumedBy: name,
|
|
226
232
|
name: dependencyName
|
|
227
233
|
});
|
|
@@ -276,17 +282,21 @@ const createPackagesVersionMismatchChecker = () => {
|
|
|
276
282
|
const createPackageError = (message, context) => {
|
|
277
283
|
return createError("stack check", context ? `\`${context.name}\` consumed by \`${context.consumedBy}\` doesn't conform to package guidelines.\n${message}` : message);
|
|
278
284
|
};
|
|
279
|
-
|
|
280
|
-
assert(version, () =>
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
}
|
|
285
|
+
const assertVersion = (version, { consumedBy, name }) => {
|
|
286
|
+
assert(version, () => {
|
|
287
|
+
return createPackageError(`\`${name}\` must have a valid version specified (current version equals to \`${String(version)}\`).`, {
|
|
288
|
+
consumedBy,
|
|
289
|
+
name
|
|
290
|
+
});
|
|
291
|
+
});
|
|
292
|
+
};
|
|
285
293
|
const isExcluded = (version) => {
|
|
286
|
-
const isPreReleaseVersion = /\d+\.\d+\.\d+-(alpha|beta|experimental|next|rc)
|
|
294
|
+
const isPreReleaseVersion = /\d+\.\d+\.\d+-(alpha|beta|experimental|next|rc).*/u.exec(version);
|
|
287
295
|
return version.startsWith("npm:") || isPreReleaseVersion;
|
|
288
296
|
};
|
|
289
|
-
const hasCaret = (version) =>
|
|
297
|
+
const hasCaret = (version) => {
|
|
298
|
+
return version.startsWith("^");
|
|
299
|
+
};
|
|
290
300
|
|
|
291
301
|
//#endregion
|
|
292
302
|
//#region src/commands/check/checkFormatting.ts
|
|
@@ -355,9 +365,13 @@ const createCheckCommand = (program) => {
|
|
|
355
365
|
}
|
|
356
366
|
});
|
|
357
367
|
};
|
|
358
|
-
const label$4 = (message) =>
|
|
359
|
-
|
|
360
|
-
|
|
368
|
+
const label$4 = (message) => {
|
|
369
|
+
return `${message} 🧐`;
|
|
370
|
+
};
|
|
371
|
+
const ifFilterDefinedAndNotEqualTo = (filter) => {
|
|
372
|
+
return (context) => {
|
|
373
|
+
return context.filter !== void 0 && context.filter !== filter;
|
|
374
|
+
};
|
|
361
375
|
};
|
|
362
376
|
|
|
363
377
|
//#endregion
|
|
@@ -399,24 +413,34 @@ const createCleanCommand = (program) => {
|
|
|
399
413
|
}
|
|
400
414
|
});
|
|
401
415
|
};
|
|
402
|
-
const label$3 = (message) =>
|
|
416
|
+
const label$3 = (message) => {
|
|
417
|
+
return `${message} 🧹`;
|
|
418
|
+
};
|
|
403
419
|
const cleanFiles = async (files) => {
|
|
404
|
-
|
|
405
|
-
|
|
406
|
-
|
|
407
|
-
|
|
420
|
+
await Promise.all(files.map(async (file) => {
|
|
421
|
+
await rm(file, {
|
|
422
|
+
force: true,
|
|
423
|
+
recursive: true
|
|
424
|
+
});
|
|
425
|
+
}));
|
|
408
426
|
};
|
|
409
427
|
const isDirectoryExistAndNotEmpty = (path) => {
|
|
410
428
|
return existsSync(path) && readdirSync(path).length > 0;
|
|
411
429
|
};
|
|
412
430
|
const retrieveIgnoredFiles = async () => {
|
|
413
|
-
return (await helpers.exec("git clean -fdXn")).split(/\n|\r\n/).filter((cleanOutput) =>
|
|
431
|
+
return (await helpers.exec("git clean -fdXn")).split(/\n|\r\n/u).filter((cleanOutput) => {
|
|
432
|
+
return PRESERVE_FILES.every((excludedFile) => {
|
|
433
|
+
return !cleanOutput.includes(excludedFile);
|
|
434
|
+
});
|
|
435
|
+
}).map((cleanOutput) => {
|
|
436
|
+
return cleanOutput.split(" ").at(-1) ?? "";
|
|
437
|
+
}).filter(Boolean);
|
|
414
438
|
};
|
|
415
439
|
const PRESERVE_FILES = ["node_modules"];
|
|
416
440
|
|
|
417
441
|
//#endregion
|
|
418
442
|
//#region package.json
|
|
419
|
-
var version = "2.40.0-next-
|
|
443
|
+
var version = "2.40.0-next-6049a9b";
|
|
420
444
|
|
|
421
445
|
//#endregion
|
|
422
446
|
//#region src/commands/create.ts
|
|
@@ -457,7 +481,7 @@ const createCreateCommand = (program) => {
|
|
|
457
481
|
}).task({
|
|
458
482
|
async handler({ inputDescription, inputName, inputTemplate, inputUrl }) {
|
|
459
483
|
if (!inputName) throw createError("stack create", "The project name is not optional. Make sure to provide a valid value (non-empty string).");
|
|
460
|
-
const { repoName, repoOwner } = (inputUrl.startsWith("git") ? /^git@.*:(?<repoOwner>.*)\/(?<repoName>.*)\.git$/ : /^https?:\/\/.*\/(?<repoOwner>.*)\/(?<repoName>.*)\.git$/).exec(inputUrl)?.groups ?? {};
|
|
484
|
+
const { repoName, repoOwner } = (inputUrl.startsWith("git") ? /^git@.*:(?<repoOwner>.*)\/(?<repoName>.*)\.git$/u : /^https?:\/\/.*\/(?<repoOwner>.*)\/(?<repoName>.*)\.git$/u).exec(inputUrl)?.groups ?? {};
|
|
461
485
|
if (!repoOwner || !repoName) throw createError("git", "The owner and repository name can not be extracted. Please make sure to follow either `/^git@.*:(?<repoOwner>.*)/(?<repoName>.*).git$/` or `/^https?://.*/(?<repoOwner>.*)/(?<repoName>.*).git$/` pattern.");
|
|
462
486
|
const nodeVersion = await request.get("https://resolve-node.vercel.app/lts", "text");
|
|
463
487
|
const { version: pnpmVersion } = await request.get("https://registry.npmjs.org/pnpm/latest", "json");
|
|
@@ -487,7 +511,7 @@ const createCreateCommand = (program) => {
|
|
|
487
511
|
},
|
|
488
512
|
type: "confirm",
|
|
489
513
|
validate({ canRemoveExistingDirectoryInput, data: { projectName } }) {
|
|
490
|
-
if (canRemoveExistingDirectoryInput) return
|
|
514
|
+
if (canRemoveExistingDirectoryInput) return;
|
|
491
515
|
return createError("mkdir", `Remove or rename the \`${projectName}\` existing directory to apply the template from a clean state.`);
|
|
492
516
|
}
|
|
493
517
|
}).task({
|
|
@@ -566,9 +590,11 @@ const createCreateCommand = (program) => {
|
|
|
566
590
|
});
|
|
567
591
|
} });
|
|
568
592
|
};
|
|
569
|
-
const label$2 = (message) =>
|
|
593
|
+
const label$2 = (message) => {
|
|
594
|
+
return `${message} 🔨`;
|
|
595
|
+
};
|
|
570
596
|
const slugify = (input) => {
|
|
571
|
-
return input.toLowerCase().replaceAll(/[^a-z0-9\s-]/
|
|
597
|
+
return input.toLowerCase().replaceAll(/[^a-z0-9\s-]/gu, "").trim().replaceAll(/\s+/gu, "-").replaceAll(/-+/gu, "-");
|
|
572
598
|
};
|
|
573
599
|
const toCapitalLetter = (input) => {
|
|
574
600
|
return input.charAt(0).toUpperCase() + input.slice(1);
|
|
@@ -587,15 +613,19 @@ const createTemplateEngine = async (workingPath, { projectName, templateModel, t
|
|
|
587
613
|
process.chdir(workingPath);
|
|
588
614
|
return {
|
|
589
615
|
async processContents() {
|
|
590
|
-
await Promise.all(templateEntries.filter(({ type }) =>
|
|
591
|
-
return
|
|
616
|
+
await Promise.all(templateEntries.filter(({ type }) => {
|
|
617
|
+
return type === "content";
|
|
618
|
+
}).map(async (entry) => {
|
|
619
|
+
await writeFile(entry.path, setTemplateVariables(entry, templateModel));
|
|
592
620
|
}));
|
|
593
621
|
},
|
|
594
622
|
async processPaths() {
|
|
595
623
|
const sortedDirectoryEntries = templateEntries.filter(({ content, type }) => {
|
|
596
624
|
if (type === "path.directory" || type === "path.file") return hasTemplateVariable(basename(content));
|
|
597
625
|
return false;
|
|
598
|
-
}).toSorted(({ path: pathA }, { path: pathB }) =>
|
|
626
|
+
}).toSorted(({ path: pathA }, { path: pathB }) => {
|
|
627
|
+
return pathB.length - pathA.length;
|
|
628
|
+
});
|
|
599
629
|
for (const entry of sortedDirectoryEntries) {
|
|
600
630
|
const newPath = setTemplateVariables(entry, templateModel);
|
|
601
631
|
await rename(entry.path, newPath);
|
|
@@ -623,13 +653,15 @@ const getTemplateEntries = async (path) => {
|
|
|
623
653
|
content: await readFile(entryPath, "utf8"),
|
|
624
654
|
type: "content"
|
|
625
655
|
}]).map(({ content, type }) => {
|
|
626
|
-
if (!hasTemplateVariable(content)) return
|
|
656
|
+
if (!hasTemplateVariable(content)) return;
|
|
627
657
|
return {
|
|
628
658
|
content,
|
|
629
659
|
path: entryPath,
|
|
630
660
|
type
|
|
631
661
|
};
|
|
632
|
-
}).filter((input) =>
|
|
662
|
+
}).filter((input) => {
|
|
663
|
+
return Boolean(input);
|
|
664
|
+
});
|
|
633
665
|
}))).flat();
|
|
634
666
|
};
|
|
635
667
|
const setTemplateVariables = (entry, model) => {
|
|
@@ -637,7 +669,7 @@ const setTemplateVariables = (entry, model) => {
|
|
|
637
669
|
return model[dataModelKey] ?? match;
|
|
638
670
|
});
|
|
639
671
|
};
|
|
640
|
-
const TEMPLATE_VARIABLE_MATCHER =
|
|
672
|
+
const TEMPLATE_VARIABLE_MATCHER = /\{\{(.*?)\}\}/giu;
|
|
641
673
|
const hasTemplateVariable = (input) => {
|
|
642
674
|
/**
|
|
643
675
|
* TemplateVariableMatcher.test() is not used since the `RegExp` is stateful when the global is
|
|
@@ -685,7 +717,9 @@ const createFixCommand = (program) => {
|
|
|
685
717
|
label: label$1("Fix code issues")
|
|
686
718
|
});
|
|
687
719
|
};
|
|
688
|
-
const label$1 = (message) =>
|
|
720
|
+
const label$1 = (message) => {
|
|
721
|
+
return `${message} 🚑`;
|
|
722
|
+
};
|
|
689
723
|
|
|
690
724
|
//#endregion
|
|
691
725
|
//#region src/commands/install.ts
|
|
@@ -705,7 +739,9 @@ const createInstallCommand = (program) => {
|
|
|
705
739
|
label: label("Install `git.commit-msg` hook")
|
|
706
740
|
});
|
|
707
741
|
};
|
|
708
|
-
const label = (message) =>
|
|
742
|
+
const label = (message) => {
|
|
743
|
+
return `${message} 📲`;
|
|
744
|
+
};
|
|
709
745
|
const installGitHook = async (hook, content) => {
|
|
710
746
|
const filename = resolveFromWorkingDirectory(`.git/hooks/${hook}`);
|
|
711
747
|
await writeFile(filename, content);
|
|
@@ -760,8 +796,10 @@ const createReleaseCommand = (program) => {
|
|
|
760
796
|
skip: ifNotEqualTo("publish")
|
|
761
797
|
});
|
|
762
798
|
};
|
|
763
|
-
const ifNotEqualTo = (validOption) =>
|
|
764
|
-
return
|
|
799
|
+
const ifNotEqualTo = (validOption) => {
|
|
800
|
+
return (context) => {
|
|
801
|
+
return !context[validOption];
|
|
802
|
+
};
|
|
765
803
|
};
|
|
766
804
|
|
|
767
805
|
//#endregion
|