@shopify/create-app 4.9.1 → 4.9.3
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/{analytics-IECFN4JQ.js → analytics-TTLHU7RJ.js} +14 -14
- package/dist/{analytics-LBB7P36D.js → analytics-XMJCXJPW.js} +14 -14
- package/dist/{chunk-3YGXE2AP.js → chunk-3FNBF3J4.js} +3 -3
- package/dist/{chunk-XIVTHG4G.js → chunk-5H43E2UF.js} +14 -14
- package/dist/{chunk-U5GH53OY.js → chunk-7U2D7OQY.js} +16 -16
- package/dist/{chunk-IGYLFVSH.js → chunk-CJUEOAXA.js} +4 -4
- package/dist/{chunk-EJPPP2UR.js → chunk-GI3EXDGY.js} +4 -4
- package/dist/{chunk-27YRBZHB.js → chunk-GXR6N3MP.js} +2 -2
- package/dist/{chunk-AIZTGQJR.js → chunk-HAZKL7NQ.js} +6 -6
- package/dist/{chunk-DC6ZFOVX.js → chunk-HT6VPO56.js} +3 -3
- package/dist/{chunk-37A2FHUG.js → chunk-KFK6UTCG.js} +2 -2
- package/dist/{chunk-6OYK2NCF.js → chunk-MA5EMKMH.js} +2 -2
- package/dist/{chunk-WXRXVG7I.js → chunk-N46TBZG5.js} +2 -2
- package/dist/{chunk-XTW7GZNX.js → chunk-N5WBV6WX.js} +5 -5
- package/dist/{chunk-GXCPTCSE.js → chunk-QIGNQLSJ.js} +2 -2
- package/dist/{chunk-QWRYHKCI.js → chunk-R6VAFEZ5.js} +3 -3
- package/dist/{chunk-7NOX742S.js → chunk-T2OHLRUY.js} +4 -4
- package/dist/{chunk-63WOEPSQ.js → chunk-U53ZNKER.js} +80 -27
- package/dist/{chunk-XE2VSA7J.js → chunk-YGIFL56H.js} +9 -9
- package/dist/{chunk-7RUPPYI4.js → chunk-ZWNY6NQH.js} +7 -7
- package/dist/{command-json-schema-NKZVCRA4.js → command-json-schema-RCC6ZVRF.js} +7 -7
- package/dist/{conf-store-OXRRZ7GJ.js → conf-store-STBXZZZR.js} +5 -5
- package/dist/{custom-oclif-loader-GXZPW6CV.js → custom-oclif-loader-Q7GRLCIZ.js} +5 -5
- package/dist/{deprecations-DRF2EUF3.js → deprecations-T466QS35.js} +10 -10
- package/dist/{environments-4D4TK7F7.js → environments-L53AHQLZ.js} +11 -11
- package/dist/{error-handler-LQ3ZDIBZ.js → error-handler-DRCELNRR.js} +14 -14
- package/dist/{fs-PMEOY2EH.js → fs-VUYIAOSY.js} +3 -3
- package/dist/hooks/postrun.js +4 -4
- package/dist/hooks/prerun.js +6 -6
- package/dist/index.js +212 -130
- package/dist/{is-global-LYFZG4LV.js → is-global-C4ZYYOO2.js} +3 -3
- package/dist/{json-error-4FQODRLE.js → json-error-YAPVM6KF.js} +6 -6
- package/dist/{local-EVID5OFN.js → local-YQI64EPC.js} +2 -2
- package/dist/{metadata-WETP27SP.js → metadata-NABA27NK.js} +3 -3
- package/dist/{node-package-manager-BLIC3IFC.js → node-package-manager-GY7LMT5D.js} +12 -12
- package/dist/{notifications-system-45UW7RPJ.js → notifications-system-244NM3IW.js} +15 -15
- package/dist/{os-VO35CUIL.js → os-34M2RBVM.js} +4 -4
- package/dist/{output-7GWEONQ7.js → output-GT6WTA4L.js} +3 -3
- package/dist/{system-F25CZRFX.js → system-Q623ZJ6Z.js} +10 -10
- package/dist/{ui-KEWWVBIJ.js → ui-DVZCQR62.js} +10 -10
- package/dist/{upgrade-RSDWMQIO.js → upgrade-3FR3Z3QX.js} +16 -16
- package/dist/{version-XXESWBZG.js → version-GRDUIVHB.js} +11 -11
- package/dist/{version-MTILA6OW.js → version-GZMTMHG3.js} +2 -2
- package/oclif.manifest.json +1 -1
- package/package.json +3 -3
package/dist/index.js
CHANGED
|
@@ -4,7 +4,7 @@ import {
|
|
|
4
4
|
decodeToml,
|
|
5
5
|
loadEnvironment,
|
|
6
6
|
require_toml_patch
|
|
7
|
-
} from "./chunk-
|
|
7
|
+
} from "./chunk-N5WBV6WX.js";
|
|
8
8
|
import {
|
|
9
9
|
require_normalize_path
|
|
10
10
|
} from "./chunk-RIQNGBMO.js";
|
|
@@ -15,7 +15,7 @@ import {
|
|
|
15
15
|
import {
|
|
16
16
|
setCurrentCommandId,
|
|
17
17
|
showNotificationsIfNeeded
|
|
18
|
-
} from "./chunk-
|
|
18
|
+
} from "./chunk-YGIFL56H.js";
|
|
19
19
|
import {
|
|
20
20
|
ClientError,
|
|
21
21
|
DevServerCore,
|
|
@@ -81,7 +81,7 @@ import {
|
|
|
81
81
|
setPathValue,
|
|
82
82
|
shopifyFetch,
|
|
83
83
|
storeAdminUrl
|
|
84
|
-
} from "./chunk-
|
|
84
|
+
} from "./chunk-5H43E2UF.js";
|
|
85
85
|
import {
|
|
86
86
|
setNextDeprecationDate
|
|
87
87
|
} from "./chunk-MSED5ZFM.js";
|
|
@@ -103,26 +103,26 @@ import {
|
|
|
103
103
|
usesWorkspaces,
|
|
104
104
|
versionSatisfies,
|
|
105
105
|
writePackageJSON
|
|
106
|
-
} from "./chunk-
|
|
106
|
+
} from "./chunk-HAZKL7NQ.js";
|
|
107
107
|
import {
|
|
108
108
|
import_websocket_server
|
|
109
109
|
} from "./chunk-LDYT4FTV.js";
|
|
110
110
|
import "./chunk-FKZ3NFHZ.js";
|
|
111
111
|
import {
|
|
112
112
|
CLI_KIT_VERSION
|
|
113
|
-
} from "./chunk-
|
|
113
|
+
} from "./chunk-MA5EMKMH.js";
|
|
114
114
|
import "./chunk-G53O4PDO.js";
|
|
115
115
|
import {
|
|
116
116
|
LocalStorage,
|
|
117
117
|
require_ajv,
|
|
118
118
|
runAtMinimumInterval,
|
|
119
119
|
serviceEnvironment
|
|
120
|
-
} from "./chunk-
|
|
120
|
+
} from "./chunk-CJUEOAXA.js";
|
|
121
121
|
import {
|
|
122
122
|
globalCLIVersion,
|
|
123
123
|
isPreReleaseVersion,
|
|
124
124
|
localCLIVersion
|
|
125
|
-
} from "./chunk-
|
|
125
|
+
} from "./chunk-QIGNQLSJ.js";
|
|
126
126
|
import {
|
|
127
127
|
AbortController as AbortController2,
|
|
128
128
|
Alert,
|
|
@@ -170,10 +170,10 @@ import {
|
|
|
170
170
|
use_input_default,
|
|
171
171
|
use_stdin_default,
|
|
172
172
|
use_stdout_default
|
|
173
|
-
} from "./chunk-
|
|
173
|
+
} from "./chunk-U53ZNKER.js";
|
|
174
174
|
import {
|
|
175
175
|
runWithCommandEventsForCommand
|
|
176
|
-
} from "./chunk-
|
|
176
|
+
} from "./chunk-T2OHLRUY.js";
|
|
177
177
|
import {
|
|
178
178
|
execa,
|
|
179
179
|
isStream,
|
|
@@ -186,14 +186,14 @@ import {
|
|
|
186
186
|
require_signal_exit,
|
|
187
187
|
stripFinalNewline,
|
|
188
188
|
username
|
|
189
|
-
} from "./chunk-
|
|
189
|
+
} from "./chunk-GXR6N3MP.js";
|
|
190
190
|
import "./chunk-JGGOQOPO.js";
|
|
191
191
|
import {
|
|
192
192
|
addPublicMetadata,
|
|
193
193
|
addSensitiveMetadata,
|
|
194
194
|
createRuntimeMetadataContainer,
|
|
195
195
|
runWithTimer
|
|
196
|
-
} from "./chunk-
|
|
196
|
+
} from "./chunk-HT6VPO56.js";
|
|
197
197
|
import {
|
|
198
198
|
fileHash,
|
|
199
199
|
getAppAutomationToken,
|
|
@@ -206,20 +206,20 @@ import {
|
|
|
206
206
|
} from "./chunk-SHCNJ47P.js";
|
|
207
207
|
import {
|
|
208
208
|
defineJsonOutputSchema
|
|
209
|
-
} from "./chunk-
|
|
209
|
+
} from "./chunk-N46TBZG5.js";
|
|
210
210
|
import "./chunk-CM6ALOD7.js";
|
|
211
211
|
import {
|
|
212
212
|
AbortError,
|
|
213
213
|
AbortSilentError,
|
|
214
214
|
BugError,
|
|
215
215
|
CancelExecution
|
|
216
|
-
} from "./chunk-
|
|
216
|
+
} from "./chunk-GI3EXDGY.js";
|
|
217
217
|
import {
|
|
218
218
|
waitForPostRunHookAndExit
|
|
219
|
-
} from "./chunk-
|
|
219
|
+
} from "./chunk-7U2D7OQY.js";
|
|
220
220
|
import {
|
|
221
221
|
treeKill
|
|
222
|
-
} from "./chunk-
|
|
222
|
+
} from "./chunk-KFK6UTCG.js";
|
|
223
223
|
import {
|
|
224
224
|
appendFile,
|
|
225
225
|
asHumanFriendlyArray,
|
|
@@ -316,7 +316,7 @@ import {
|
|
|
316
316
|
unstyled,
|
|
317
317
|
writeFile,
|
|
318
318
|
writeFileSync
|
|
319
|
-
} from "./chunk-
|
|
319
|
+
} from "./chunk-ZWNY6NQH.js";
|
|
320
320
|
import {
|
|
321
321
|
codespacePortForwardingDomain,
|
|
322
322
|
codespaceURL,
|
|
@@ -330,7 +330,7 @@ import {
|
|
|
330
330
|
isUnitTest,
|
|
331
331
|
isVerbose,
|
|
332
332
|
noInputFlag
|
|
333
|
-
} from "./chunk-
|
|
333
|
+
} from "./chunk-R6VAFEZ5.js";
|
|
334
334
|
import {
|
|
335
335
|
environmentVariables,
|
|
336
336
|
themeKitAccessDomain
|
|
@@ -203943,7 +203943,7 @@ var import_core2 = __toESM(require_lib()), BaseCommand = class extends import_co
|
|
|
203943
203943
|
}
|
|
203944
203944
|
async catch(error) {
|
|
203945
203945
|
error.skipOclifErrorHandling = !0;
|
|
203946
|
-
let { errorHandler } = await import("./error-handler-
|
|
203946
|
+
let { errorHandler } = await import("./error-handler-DRCELNRR.js");
|
|
203947
203947
|
return await errorHandler(error, this.config), import_core2.Errors.handle(error);
|
|
203948
203948
|
}
|
|
203949
203949
|
async _run() {
|
|
@@ -203951,11 +203951,11 @@ var import_core2 = __toESM(require_lib()), BaseCommand = class extends import_co
|
|
|
203951
203951
|
}
|
|
203952
203952
|
async init() {
|
|
203953
203953
|
if (this.exitWithTimestampWhenEnvVariablePresent(), setCurrentCommandId(this.id ?? ""), !isDevelopment()) {
|
|
203954
|
-
let { registerCleanBugsnagErrorsFromWithinPlugins } = await import("./error-handler-
|
|
203954
|
+
let { registerCleanBugsnagErrorsFromWithinPlugins } = await import("./error-handler-DRCELNRR.js");
|
|
203955
203955
|
await registerCleanBugsnagErrorsFromWithinPlugins(this.config);
|
|
203956
203956
|
}
|
|
203957
203957
|
await removeDuplicatedPlugins(this.config), this.showNpmFlagWarning();
|
|
203958
|
-
let { showNotificationsIfNeeded: showNotificationsIfNeeded2 } = await import("./notifications-system-
|
|
203958
|
+
let { showNotificationsIfNeeded: showNotificationsIfNeeded2 } = await import("./notifications-system-244NM3IW.js");
|
|
203959
203959
|
return await showNotificationsIfNeeded2(), super.init();
|
|
203960
203960
|
}
|
|
203961
203961
|
// NPM creates an environment variable for every flag passed to a script.
|
|
@@ -203963,7 +203963,7 @@ var import_core2 = __toESM(require_lib()), BaseCommand = class extends import_co
|
|
|
203963
203963
|
// and warns the user to use the `--` separator.
|
|
203964
203964
|
showNpmFlagWarning() {
|
|
203965
203965
|
let commandVariables = this.constructor;
|
|
203966
|
-
Object.keys(commandVariables.flags || {}).map((key) => `npm_config_${underscore(key).replace(/^no_/, "")}`).some((flag) => process.env[flag] !== void 0) && import("./ui-
|
|
203966
|
+
Object.keys(commandVariables.flags || {}).map((key) => `npm_config_${underscore(key).replace(/^no_/, "")}`).some((flag) => process.env[flag] !== void 0) && import("./ui-DVZCQR62.js").then(({ renderWarning: renderWarning2 }) => {
|
|
203967
203967
|
renderWarning2({
|
|
203968
203968
|
body: [
|
|
203969
203969
|
"NPM scripts require an extra",
|
|
@@ -204012,7 +204012,7 @@ ${explanation} in non-interactive terminal environments, such as a CI environmen
|
|
|
204012
204012
|
let flags = originalResult.flags, environmentsFileName = this.environmentsFilename();
|
|
204013
204013
|
if (!environmentsFileName)
|
|
204014
204014
|
return originalResult;
|
|
204015
|
-
let { environmentFilePath } = await import("./environments-
|
|
204015
|
+
let { environmentFilePath } = await import("./environments-L53AHQLZ.js"), environmentFileExists = await environmentFilePath(environmentsFileName, { from: flags.path }), environments = [];
|
|
204016
204016
|
flags.environment && (environments = Array.isArray(flags.environment) ? flags.environment : [flags.environment]);
|
|
204017
204017
|
let environmentSpecified = environments.length > 0;
|
|
204018
204018
|
if (!environmentFileExists && !environmentSpecified || environmentSpecified && environments.length > 1)
|
|
@@ -204033,7 +204033,7 @@ ${explanation} in non-interactive terminal environments, such as a CI environmen
|
|
|
204033
204033
|
* is specified it will try to load a default environment.
|
|
204034
204034
|
*/
|
|
204035
204035
|
async loadEnvironmentForCommand(path4, environmentsFileName, specifiedEnvironment) {
|
|
204036
|
-
let { loadEnvironment: loadEnvironment2 } = await import("./environments-
|
|
204036
|
+
let { loadEnvironment: loadEnvironment2 } = await import("./environments-L53AHQLZ.js");
|
|
204037
204037
|
return specifiedEnvironment ? { environment: await loadEnvironment2(specifiedEnvironment, environmentsFileName, { from: path4 }), isDefaultEnvironment: !1 } : { environment: await loadEnvironment2("default", environmentsFileName, { from: path4, silent: !0 }), isDefaultEnvironment: !0 };
|
|
204038
204038
|
}
|
|
204039
204039
|
};
|
|
@@ -204056,7 +204056,7 @@ function reportEnvironmentApplication(noDefaultsFlags, flagsWithEnvironments, en
|
|
|
204056
204056
|
if (Object.keys(changes).length === 0)
|
|
204057
204057
|
return;
|
|
204058
204058
|
let items = Object.entries(changes).map(([name, value]) => `${name}: ${value}`);
|
|
204059
|
-
import("./ui-
|
|
204059
|
+
import("./ui-DVZCQR62.js").then(({ renderInfo: renderInfo2 }) => {
|
|
204060
204060
|
renderInfo2({
|
|
204061
204061
|
headline: ["Using applicable flags from", { userInput: environmentName }, "environment:"],
|
|
204062
204062
|
body: [{ list: { items } }]
|
|
@@ -204107,7 +204107,7 @@ async function removeDuplicatedPlugins(config2) {
|
|
|
204107
204107
|
let plugins = Array.from(config2.plugins.values()), bundlePlugins = ["@shopify/app", "@shopify/plugin-cloudflare"], pluginsToRemove = plugins.filter((plugin) => bundlePlugins.includes(plugin.name));
|
|
204108
204108
|
if (pluginsToRemove.length > 0) {
|
|
204109
204109
|
let commandsToRun = pluginsToRemove.map((plugin) => ` - shopify plugins remove ${plugin.name}`).join(`
|
|
204110
|
-
`), { renderWarning: renderWarning2 } = await import("./ui-
|
|
204110
|
+
`), { renderWarning: renderWarning2 } = await import("./ui-DVZCQR62.js");
|
|
204111
204111
|
renderWarning2({
|
|
204112
204112
|
headline: `Unsupported plugins detected: ${pluginsToRemove.map((plugin) => plugin.name).join(", ")}`,
|
|
204113
204113
|
body: [
|
|
@@ -204129,20 +204129,20 @@ init_cjs_shims();
|
|
|
204129
204129
|
init_cjs_shims();
|
|
204130
204130
|
import { fileURLToPath as fileURLToPath2 } from "node:url";
|
|
204131
204131
|
async function launchCLI(options) {
|
|
204132
|
-
let { isDevelopment: isDevelopment2 } = await import("./local-
|
|
204132
|
+
let { isDevelopment: isDevelopment2 } = await import("./local-YQI64EPC.js"), { ShopifyConfig } = await import("./custom-oclif-loader-Q7GRLCIZ.js"), oclifModule = await import("./lib-NYDMHWZM.js"), { run, flush, Errors: Errors2, settings } = oclifModule.default ?? oclifModule;
|
|
204133
204133
|
isDevelopment2() && (settings.debug = !0);
|
|
204134
204134
|
try {
|
|
204135
204135
|
let config2 = new ShopifyConfig({ root: fileURLToPath2(options.moduleURL) });
|
|
204136
204136
|
await config2.load(), options.lazyCommandLoader && config2.setLazyCommandLoader(options.lazyCommandLoader);
|
|
204137
204137
|
let argv = options.argv ?? process.argv.slice(2), passthroughIndex = argv.indexOf("--");
|
|
204138
204138
|
if ((passthroughIndex === -1 ? argv : argv.slice(0, passthroughIndex)).includes("--json-schema") || isTruthy(process.env.SHOPIFY_FLAG_JSON_SCHEMA)) {
|
|
204139
|
-
let { printCommandJsonSchema } = await import("./command-json-schema-
|
|
204139
|
+
let { printCommandJsonSchema } = await import("./command-json-schema-RCC6ZVRF.js");
|
|
204140
204140
|
await printCommandJsonSchema(config2, argv, options.lazyCommandLoader);
|
|
204141
204141
|
return;
|
|
204142
204142
|
}
|
|
204143
204143
|
await run(argv, config2), await flush();
|
|
204144
204144
|
} catch (error) {
|
|
204145
|
-
let { errorHandler } = await import("./error-handler-
|
|
204145
|
+
let { errorHandler } = await import("./error-handler-DRCELNRR.js");
|
|
204146
204146
|
await errorHandler(error);
|
|
204147
204147
|
let handledError = error;
|
|
204148
204148
|
return Errors2.handle({
|
|
@@ -204160,7 +204160,7 @@ var import_core3 = __toESM(require_lib());
|
|
|
204160
204160
|
async function exitIfOldNodeVersion(versions2 = process.versions) {
|
|
204161
204161
|
let nodeVersion = versions2.node, nodeMajorVersion = Number(nodeVersion.split(".")[0]);
|
|
204162
204162
|
if (nodeMajorVersion < 22) {
|
|
204163
|
-
let { renderError: renderError2 } = await import("./ui-
|
|
204163
|
+
let { renderError: renderError2 } = await import("./ui-DVZCQR62.js");
|
|
204164
204164
|
renderError2({
|
|
204165
204165
|
headline: "Upgrade to a supported Node version now.",
|
|
204166
204166
|
body: [
|
|
@@ -204187,7 +204187,7 @@ async function runCLI(options, launchCLI2 = launchCLI, argv = process.argv, env2
|
|
|
204187
204187
|
return setupEnvironmentVariables(options, argv, env2), options.runInCreateMode && await addInitToArgvWhenRunningCreateCLI(options, argv), forceNoColor(argv, env2), await exitIfOldNodeVersion(versions2), launchCLI2({ moduleURL: options.moduleURL, lazyCommandLoader: options.lazyCommandLoader });
|
|
204188
204188
|
}
|
|
204189
204189
|
async function addInitToArgvWhenRunningCreateCLI(options, argv = process.argv) {
|
|
204190
|
-
let { findUpAndReadPackageJson: findUpAndReadPackageJson2 } = await import("./node-package-manager-
|
|
204190
|
+
let { findUpAndReadPackageJson: findUpAndReadPackageJson2 } = await import("./node-package-manager-GY7LMT5D.js"), { moduleDirectory: moduleDirectory2 } = await import("./path-2KZ7FSGN.js"), name = (await findUpAndReadPackageJson2(moduleDirectory2(options.moduleURL))).content.name.replace("@shopify/create-", "");
|
|
204191
204191
|
if (argv.findIndex((arg) => arg.includes("init")) === -1) {
|
|
204192
204192
|
let initIndex2 = argv.findIndex((arg) => arg.match(new RegExp(`bin(\\/|\\\\)+(create-${name}|dev|run)`))) + 1;
|
|
204193
204193
|
argv.splice(initIndex2, 0, "init");
|
|
@@ -217373,7 +217373,7 @@ init_cjs_shims();
|
|
|
217373
217373
|
|
|
217374
217374
|
// ../cli-kit/dist/public/node/liquid.js
|
|
217375
217375
|
init_cjs_shims();
|
|
217376
|
-
var import_liquidjs = __toESM(require_liquid_node()
|
|
217376
|
+
var import_liquidjs = __toESM(require_liquid_node());
|
|
217377
217377
|
function renderLiquidTemplate(templateContent, data) {
|
|
217378
217378
|
let engine = new import_liquidjs.Liquid();
|
|
217379
217379
|
return engine.render(engine.parse(templateContent), data);
|
|
@@ -220472,7 +220472,7 @@ init_cjs_shims();
|
|
|
220472
220472
|
init_cjs_shims();
|
|
220473
220473
|
var import_core29 = __toESM(require_lib(), 1), blockingLevels = ["high", "medium", "low", "none"], appSecurityBlockingFlag = {
|
|
220474
220474
|
blocking: import_core29.Flags.custom({
|
|
220475
|
-
description: "The minimum finding severity that causes a non-zero exit code.",
|
|
220475
|
+
description: "The minimum finding severity that causes a non-zero exit code: high, medium, or low. Defaults to none, which never fails on findings.",
|
|
220476
220476
|
options: blockingLevels,
|
|
220477
220477
|
default: "none",
|
|
220478
220478
|
env: "SHOPIFY_FLAG_APP_SECURITY_BLOCKING"
|
|
@@ -220595,7 +220595,7 @@ Do not report:
|
|
|
220595
220595
|
`,
|
|
220596
220596
|
`---
|
|
220597
220597
|
id: APP_PROXY_LIQUID_INJECTION
|
|
220598
|
-
version:
|
|
220598
|
+
version: 3
|
|
220599
220599
|
severity: high
|
|
220600
220600
|
precedence: prefer-agent
|
|
220601
220601
|
---
|
|
@@ -220700,10 +220700,10 @@ Do not report:
|
|
|
220700
220700
|
- Protocol-only canonicalization concerns with no demonstrated app-local exploit path
|
|
220701
220701
|
- Test handlers
|
|
220702
220702
|
`,
|
|
220703
|
-
"---\nid: COMMITTED_SECRET\nversion:
|
|
220703
|
+
"---\nid: COMMITTED_SECRET\nversion: 4\nseverity: high\nprecedence: union\n---\n\n# Committed Secret\n\nInspect files skipped by deterministic secret scanning for committed credentials. Never quote or reproduce a secret; cite only the file and redacted credential kind, and recommend rotation.\n\nDo not report placeholders, public client identifiers (`SHOPIFY_API_KEY`, Stripe `pk_`), or files git confirms are untracked and ignored. Template env files (`.env.example`, `.sample`, `.template`, `.dist`) are findings only when they contain a known credential format.\n",
|
|
220704
220704
|
`---
|
|
220705
220705
|
id: CREDENTIAL_BROWSER_LEAKAGE
|
|
220706
|
-
version:
|
|
220706
|
+
version: 2
|
|
220707
220707
|
severity: high
|
|
220708
220708
|
precedence: prefer-agent
|
|
220709
220709
|
---
|
|
@@ -220714,7 +220714,7 @@ Trace credentials, access tokens, session tokens, and client secrets into loader
|
|
|
220714
220714
|
`,
|
|
220715
220715
|
`---
|
|
220716
220716
|
id: CREDENTIAL_LOG_LEAKAGE
|
|
220717
|
-
version:
|
|
220717
|
+
version: 2
|
|
220718
220718
|
severity: high
|
|
220719
220719
|
precedence: prefer-agent
|
|
220720
220720
|
---
|
|
@@ -221025,7 +221025,7 @@ Do not report:
|
|
|
221025
221025
|
`,
|
|
221026
221026
|
`---
|
|
221027
221027
|
id: DEPRECATED_SCRIPT_TAG_SCOPE
|
|
221028
|
-
version:
|
|
221028
|
+
version: 2
|
|
221029
221029
|
severity: medium
|
|
221030
221030
|
precedence: prefer-agent
|
|
221031
221031
|
---
|
|
@@ -221036,7 +221036,7 @@ Inspect parsed app scopes and JavaScript/TypeScript Admin API operations for dep
|
|
|
221036
221036
|
`,
|
|
221037
221037
|
`---
|
|
221038
221038
|
id: EOL_API_VERSION
|
|
221039
|
-
version:
|
|
221039
|
+
version: 2
|
|
221040
221040
|
severity: low
|
|
221041
221041
|
precedence: prefer-agent
|
|
221042
221042
|
---
|
|
@@ -221045,7 +221045,7 @@ precedence: prefer-agent
|
|
|
221045
221045
|
|
|
221046
221046
|
Inspect the selected \`shopify.app*.toml\` plus React Router \`app/shopify.server.*\` declarations. Shopify publishes quarterly versions in January, April, July, and October and supports each stable version for 12 months; the app security check allows a documented 30-day extension grace period before reporting it as end-of-life. Cite the exact declaration. For malformed config, computed \`ApiVersion\` values, or a Shopify-announced exceptional extension, inspect the source and current lifecycle policy rather than inferring from unrelated constants.
|
|
221047
221047
|
`,
|
|
221048
|
-
"---\nid: EXPIRING_OFFLINE_TOKEN\nversion:
|
|
221048
|
+
"---\nid: EXPIRING_OFFLINE_TOKEN\nversion: 2\nseverity: medium\nprecedence: prefer-agent\n---\n\n# Expiring Offline Token\n\nFor supported React Router apps, verify `expiringOfflineAccessTokens` is enabled and the selected session storage persists `expires`, `refreshToken`, and `refreshTokenExpires` metadata needed for refresh and rotation. `isOnline: false` selects an offline session; it does not disable token expiry and is not a finding. Report an explicit `expiringOfflineAccessTokens: false`. Treat absent or computed flags, custom storage, and ambiguous Prisma schemas as unresolved investigation: inspect storage adapters, migrations, and serialization before returning a clean result. Config-only and unsupported frameworks are handled by the runtime applicability boundary.\n",
|
|
221049
221049
|
`---
|
|
221050
221050
|
id: INSECURE_WEBHOOK_URL
|
|
221051
221051
|
version: 2
|
|
@@ -221060,17 +221060,24 @@ Inspect webhook destinations and OAuth redirect URLs in the selected Shopify app
|
|
|
221060
221060
|
"---\nid: LIQUID_UNSAFE_RENDER\nversion: 1\nseverity: medium\nprecedence: union\n---\n\n# Liquid Unsafe Render\n\nInspect only theme-extension Liquid/HTML files the parser could not analyze. Liquid output is not automatically HTML-escaped. Check the destination: use `escape`/`escape_once` for HTML text and ordinary attributes, `json` when embedding a value as JavaScript data, and `metafield_tag` only for supported rich metafield rendering in HTML content. HTML escaping is not sufficient for event handlers, `srcdoc`, or a `<script src>` URL; avoid merchant-controlled output there and validate any dynamic URL. An ordinary non-script `src` attribute is not itself an executable sink. `{% raw %}` suppresses Liquid parsing, so apparent output inside it is literal text. Follow rendered snippets and inspect ambiguous filters or parser failures before reporting.\n",
|
|
221061
221061
|
`---
|
|
221062
221062
|
id: METAFIELD_OFFLINE_TOKEN
|
|
221063
|
-
version:
|
|
221063
|
+
version: 2
|
|
221064
221064
|
severity: high
|
|
221065
221065
|
---
|
|
221066
221066
|
|
|
221067
221067
|
# Metafield Offline Token
|
|
221068
221068
|
|
|
221069
|
-
Trace metafield writes and determine
|
|
221069
|
+
Trace metafield and metaobject writes and determine their token provenance. Report a write that runs in an offline Admin API context that no verified request for the same shop authorizes: for example \`unauthenticated.admin(shop)\` or a stored offline session reached from an unauthenticated route, an unverified webhook or app proxy request, or a job whose shop or values come from request-controlled input.
|
|
221070
|
+
|
|
221071
|
+
An offline session returned by \`authenticate.admin(request)\` (the React Router SDK default when \`useOnlineTokens\` isn't set) is a verified, shop-bound context: Shopify verified the session token and the staff member's access to the app. Don't report a write only because its token is offline or because an online token would add user attribution or expiry. Report it when:
|
|
221072
|
+
|
|
221073
|
+
- the app defines its own per-user permission, for example an app-level role or allowlist check, and this write bypasses it. Name that permission.
|
|
221074
|
+
- request-controlled values reach an app-reserved (\`$app\`) metafield or metaobject that the app treats as trusted state and merchants can't edit themselves, for example a definition with \`access.admin = "merchant_read"\` or no merchant access, or billing, entitlement or feature-flag data. Writing to the \`$app\` namespace isn't safe by itself.
|
|
221075
|
+
|
|
221076
|
+
Confirm token provenance and compensating authorization before reporting.
|
|
221070
221077
|
`,
|
|
221071
221078
|
`---
|
|
221072
221079
|
id: MISSING_AUTHORIZATION_CHECK
|
|
221073
|
-
version:
|
|
221080
|
+
version: 3
|
|
221074
221081
|
severity: high
|
|
221075
221082
|
---
|
|
221076
221083
|
|
|
@@ -221127,6 +221134,16 @@ actions.
|
|
|
221127
221134
|
changes, direct URLs that survive permission downgrades, and backend actions
|
|
221128
221135
|
that remain callable after a feature is hidden or disabled in the UI.
|
|
221129
221136
|
|
|
221137
|
+
## Shopify embedded apps (React Router)
|
|
221138
|
+
|
|
221139
|
+
\`authenticate.admin(request)\` verifies the Shopify session token, so the caller is a staff member of that shop whom Shopify has granted access to this app. With offline tokens (the SDK default), Admin API calls use the app's granted scopes rather than the staff member's own permissions. That is Shopify's standard embedded app model, not a finding by itself. Report a handler only when it skips a concrete authorization boundary inside the app:
|
|
221140
|
+
|
|
221141
|
+
- The app defines its own roles, owners, or allowlists (for example a check on \`sessionToken.sub\`, \`onlineAccessInfo.associated_user\`, \`account_owner\`, or an app database role), and a handler that performs the same or a more privileged operation doesn't apply it. Compare each route's loader and action, and sibling routes.
|
|
221142
|
+
- A request-supplied identifier selects an app-owned record that belongs to another user of the app.
|
|
221143
|
+
- The app uses online tokens to respect staff permissions on some paths, but a privileged path falls back to an offline session.
|
|
221144
|
+
|
|
221145
|
+
If none of these applies, record the check as executed with no finding.
|
|
221146
|
+
|
|
221130
221147
|
## What to report
|
|
221131
221148
|
|
|
221132
221149
|
For each action that exposes a concrete unauthorized operation beyond authentication:
|
|
@@ -221530,7 +221547,7 @@ Do not report:
|
|
|
221530
221547
|
`,
|
|
221531
221548
|
`---
|
|
221532
221549
|
id: REQUEST_CONTROLLED_ADMIN_CONTEXT
|
|
221533
|
-
version:
|
|
221550
|
+
version: 4
|
|
221534
221551
|
severity: high
|
|
221535
221552
|
precedence: prefer-agent
|
|
221536
221553
|
---
|
|
@@ -222129,17 +222146,7 @@ Do not report:
|
|
|
222129
222146
|
- \`exec()\` with literal strings (no user input)
|
|
222130
222147
|
- Shell calls with properly escaped arguments
|
|
222131
222148
|
`,
|
|
222132
|
-
|
|
222133
|
-
id: STATIC_FRAME_ANCESTORS
|
|
222134
|
-
version: 1
|
|
222135
|
-
severity: high
|
|
222136
|
-
precedence: prefer-agent
|
|
222137
|
-
---
|
|
222138
|
-
|
|
222139
|
-
# Static Frame Ancestors
|
|
222140
|
-
|
|
222141
|
-
Inspect embedded-app Content-Security-Policy construction. Report wildcard or static cross-shop frame-ancestors policies; accept a policy derived safely for the authenticated shop plus Shopify Admin.
|
|
222142
|
-
`,
|
|
222149
|
+
"---\nid: STATIC_FRAME_ANCESTORS\nversion: 2\nseverity: high\nprecedence: prefer-agent\n---\n\n# Static Frame Ancestors\n\nInspect embedded-app Content-Security-Policy construction, including headers that app code sets after or instead of the SDK's. Report wildcard or static cross-shop frame-ancestors policies, such as `*`, `https:`, `*.myshopify.com`, or a fixed list of shop domains, whether the value is written literally or built from variables. Accept a policy derived safely for the shop plus Shopify Admin.\n\nThe React Router SDK's `addDocumentResponseHeaders` (from `shopifyApp()`, usually called in `entry.server`) is the accepted pattern: it sets `frame-ancestors` to the sanitized request shop plus Shopify Admin origins, including Shopify-operated development admin origins. Don't report it unless app code overrides or extends its header.\n",
|
|
222143
222150
|
`---
|
|
222144
222151
|
id: TEXT_SETTING_HTML_SMUGGLING
|
|
222145
222152
|
version: 2
|
|
@@ -222334,7 +222341,7 @@ Do not report:
|
|
|
222334
222341
|
`,
|
|
222335
222342
|
`---
|
|
222336
222343
|
id: UNAUTHENTICATED_ENDPOINT
|
|
222337
|
-
version:
|
|
222344
|
+
version: 3
|
|
222338
222345
|
severity: high
|
|
222339
222346
|
precedence: union
|
|
222340
222347
|
---
|
|
@@ -222471,7 +222478,7 @@ pack instructions.
|
|
|
222471
222478
|
`,
|
|
222472
222479
|
`---
|
|
222473
222480
|
id: UNSAFE_INNERHTML
|
|
222474
|
-
version:
|
|
222481
|
+
version: 3
|
|
222475
222482
|
severity: high
|
|
222476
222483
|
precedence: union
|
|
222477
222484
|
---
|
|
@@ -222745,7 +222752,10 @@ For each check:
|
|
|
222745
222752
|
5. Keep the check \`id\` and \`version\` exactly as they appear in {{AGENT_CHECKS_PATH}}.
|
|
222746
222753
|
6. Include concise evidence citations. Never include a detected secret value or unnecessary personal data.
|
|
222747
222754
|
|
|
222748
|
-
A check with no verified issue must not produce a fabricated finding.
|
|
222755
|
+
A check with no verified issue must not produce a fabricated finding. Choose the status from what you were able to investigate, not from whether you can prove a negative:
|
|
222756
|
+
|
|
222757
|
+
- \`executed\`: you traced the paths the check directs you to and found no concrete issue. This includes code that follows the safe pattern the check or its \`docs_url\` describes. A candidate is ruled out when the code establishes the boundary the check asks about, even if you can't rule out hypothetical policies or requirements that the repository doesn't define.
|
|
222758
|
+
- \`unresolved\`: you couldn't complete the investigation, for example because required code was unreadable, out of scope, or outside the repository and you couldn't inspect it, or you found a specific candidate whose boundary you could neither establish nor show to be missing. Name the candidate's file and line, or the missing input, in the reason.
|
|
222749
222759
|
|
|
222750
222760
|
### 4. Write one findings document
|
|
222751
222761
|
|
|
@@ -222789,7 +222799,7 @@ Write a single JSON document that covers every check you ran:
|
|
|
222789
222799
|
- \`status\` is one of:
|
|
222790
222800
|
- \`executed\`: you investigated the check, whether or not it produced findings.
|
|
222791
222801
|
- \`not_applicable\`: the capability the check covers is absent. It can't have findings.
|
|
222792
|
-
- \`unresolved\`: you couldn't
|
|
222802
|
+
- \`unresolved\`: you couldn't complete the investigation, or you named a specific candidate whose boundary is still unclear. An unresolved check didn't pass; never describe it as passing.
|
|
222793
222803
|
- \`not_applicable\` and \`unresolved\` require a \`reason\` with a short \`code\` and a \`message\`.
|
|
222794
222804
|
- Each finding needs \`file\`, \`line\` (1 or greater), \`message\`, and at least one \`evidence\` item with \`file\`, \`line\`, and \`quote\`.
|
|
222795
222805
|
- Optional finding fields: \`snippet\`, \`confidence\` (\`high\`, \`medium\`, or \`low\`), \`reasoning\`, and \`suppression\` (\`{"justification": "..."}\`).
|
|
@@ -222860,6 +222870,36 @@ init_cjs_shims();
|
|
|
222860
222870
|
|
|
222861
222871
|
// ../app/dist/cli/services/app-security-engine/rules/secret-rules.js
|
|
222862
222872
|
init_cjs_shims();
|
|
222873
|
+
|
|
222874
|
+
// ../app/dist/cli/services/app-security-engine/scanners/git.js
|
|
222875
|
+
init_cjs_shims();
|
|
222876
|
+
var UNTRUSTED_REPOSITORY_PROTECTIONS = {
|
|
222877
|
+
// Reading the index runs the file-system monitor program. The empty value turns it off on every Git version;
|
|
222878
|
+
// older versions take `false` as the program's name.
|
|
222879
|
+
fileSystemMonitor: { args: ["-c", "core.fsmonitor="] },
|
|
222880
|
+
// Refuses a bare repository Git would otherwise find in the working directory, such as one committed as files.
|
|
222881
|
+
bareRepository: { args: ["-c", "safe.bareRepository=explicit"] },
|
|
222882
|
+
// A partial clone fetches a missing object on demand, running the repository's transport commands.
|
|
222883
|
+
lazyFetch: { env: { GIT_NO_LAZY_FETCH: "1" } },
|
|
222884
|
+
// An empty allow-list refuses every transport, for Git versions that predate GIT_NO_LAZY_FETCH.
|
|
222885
|
+
transports: { env: { GIT_ALLOW_PROTOCOL: "" } }
|
|
222886
|
+
}, protections = Object.values(UNTRUSTED_REPOSITORY_PROTECTIONS), protectionArguments = protections.flatMap((protection) => protection.args ?? []);
|
|
222887
|
+
function protectionEnvironment() {
|
|
222888
|
+
return Object.fromEntries(protections.flatMap((protection) => Object.entries(protection.env ?? {})));
|
|
222889
|
+
}
|
|
222890
|
+
async function runGit(directory, args) {
|
|
222891
|
+
try {
|
|
222892
|
+
let result = await captureOutputWithExitCode("git", [...protectionArguments, ...args], {
|
|
222893
|
+
cwd: directory,
|
|
222894
|
+
env: protectionEnvironment()
|
|
222895
|
+
});
|
|
222896
|
+
return { exitCode: result.exitCode, stdout: result.stdout };
|
|
222897
|
+
} catch {
|
|
222898
|
+
return;
|
|
222899
|
+
}
|
|
222900
|
+
}
|
|
222901
|
+
|
|
222902
|
+
// ../app/dist/cli/services/app-security-engine/rules/secret-rules.js
|
|
222863
222903
|
var SHOPIFY_TOKEN_PATTERN = {
|
|
222864
222904
|
regex: /shp(?:(?:at|ca|pa|ss)_[a-fA-F0-9]{16,}|(?:rt|sb|tka|ua)_[a-zA-Z0-9]{16,})/,
|
|
222865
222905
|
name: "Shopify token",
|
|
@@ -222950,7 +222990,7 @@ function isEnvFile(path4) {
|
|
|
222950
222990
|
return envFileBasename(path4) !== void 0;
|
|
222951
222991
|
}
|
|
222952
222992
|
async function gitTopLevel(cwd2) {
|
|
222953
|
-
let result = await
|
|
222993
|
+
let result = await gitProbe(cwd2, ["rev-parse", "--show-toplevel"]);
|
|
222954
222994
|
return result.exitCode === 0 && result.out !== "" ? result.out : void 0;
|
|
222955
222995
|
}
|
|
222956
222996
|
async function ignoredFileScanReason(file, gitIgnoreListing, appTopLevel) {
|
|
@@ -223031,16 +223071,12 @@ async function scanCommittedSecrets(secretEvidenceFiles, appRoot, gitIgnoreListi
|
|
|
223031
223071
|
}
|
|
223032
223072
|
return issues;
|
|
223033
223073
|
}
|
|
223034
|
-
async function
|
|
223035
|
-
|
|
223036
|
-
|
|
223037
|
-
return { exitCode: result.exitCode, out: result.stdout.trim() };
|
|
223038
|
-
} catch {
|
|
223039
|
-
return { exitCode: void 0, out: "" };
|
|
223040
|
-
}
|
|
223074
|
+
async function gitProbe(cwd2, args) {
|
|
223075
|
+
let result = await runGit(cwd2, args);
|
|
223076
|
+
return { exitCode: result?.exitCode, out: result?.stdout.trim() ?? "" };
|
|
223041
223077
|
}
|
|
223042
223078
|
async function gitStatusFor(file) {
|
|
223043
|
-
let run = async (args) =>
|
|
223079
|
+
let run = async (args) => gitProbe(dirname(file.absolutePath), args), name = basename(file.absolutePath), inRepo = await run(["rev-parse", "--is-inside-work-tree"]);
|
|
223044
223080
|
if (inRepo.exitCode !== 0 || inRepo.out !== "true")
|
|
223045
223081
|
return {
|
|
223046
223082
|
tracked: void 0,
|
|
@@ -223156,11 +223192,11 @@ var CHECK_DOCS_BASE_URL = "https://shopify.dev/docs/apps/build/security/app-secu
|
|
|
223156
223192
|
},
|
|
223157
223193
|
{
|
|
223158
223194
|
id: "METAFIELD_OFFLINE_TOKEN",
|
|
223159
|
-
title: "Metafield write
|
|
223195
|
+
title: "Metafield write in an unverified offline token context",
|
|
223160
223196
|
severity: "high",
|
|
223161
223197
|
points: -15,
|
|
223162
|
-
description: "
|
|
223163
|
-
fix: "
|
|
223198
|
+
description: "Investigates metafield and metaobject writes made with an offline Admin API context that no verified request for the same shop authorizes.",
|
|
223199
|
+
fix: "Make the write from a request verified with authenticate.admin(request), or derive the shop and values from a verified source.",
|
|
223164
223200
|
guide: "https://shopify.dev/docs/apps/build/authentication-authorization/access-token-types/online-access-tokens",
|
|
223165
223201
|
docsUrl: `${CHECK_DOCS_BASE_URL}/metafield-offline-token`
|
|
223166
223202
|
},
|
|
@@ -223300,7 +223336,7 @@ var CHECK_DOCS_BASE_URL = "https://shopify.dev/docs/apps/build/security/app-secu
|
|
|
223300
223336
|
title: "Embedded app frame-ancestors uses a wildcard",
|
|
223301
223337
|
severity: "high",
|
|
223302
223338
|
points: -12,
|
|
223303
|
-
description: "Detects
|
|
223339
|
+
description: "Detects wildcard or static cross-shop frame-ancestors policies in embedded app code, whether written literally or built from variables.",
|
|
223304
223340
|
fix: "Restrict frame-ancestors to Shopify Admin and the authenticated shop origin.",
|
|
223305
223341
|
guide: "https://shopify.dev/docs/apps/build/security/set-up-iframe-protection",
|
|
223306
223342
|
requires: "embedded_app",
|
|
@@ -223499,7 +223535,8 @@ Rules:
|
|
|
223499
223535
|
- Record unresolved and not_applicable checks with a reason: { "code": "...", "message": "..." }.
|
|
223500
223536
|
- A not_applicable check can't have findings.
|
|
223501
223537
|
- An unsupported or unresolved check didn't pass. Never describe it as passing or complete.
|
|
223502
|
-
- If you can't prove exploitability or affected authority, record the check as unresolved
|
|
223538
|
+
- If you can't prove exploitability or affected authority for a specific candidate, don't report a finding: record the check as unresolved and name the candidate in the reason.
|
|
223539
|
+
- If you investigated and the code establishes the boundary the check asks about, record the check as executed. An unprovable hypothetical is not a reason to leave a check unresolved.
|
|
223503
223540
|
- Don't report things you couldn't confirm \u2014 uncertainty is not a finding.`, catalogEntry = (checkId) => {
|
|
223504
223541
|
let entry = RULE_CATALOG.find((candidate) => candidate.id === checkId);
|
|
223505
223542
|
if (!entry)
|
|
@@ -223815,7 +223852,7 @@ async function listGitIgnoredPaths(directory) {
|
|
|
223815
223852
|
return listing.status !== "listed" && outputDebug(`app security check: git ignore listing skipped (${listing.status})`), listing;
|
|
223816
223853
|
}
|
|
223817
223854
|
async function runGitIgnoreListing(directory) {
|
|
223818
|
-
let location2 = await
|
|
223855
|
+
let location2 = await runGit(directory, ["rev-parse", "--is-inside-work-tree"]);
|
|
223819
223856
|
if (location2 === void 0)
|
|
223820
223857
|
return { status: "failed" };
|
|
223821
223858
|
if (location2.exitCode !== 0)
|
|
@@ -223824,7 +223861,7 @@ async function runGitIgnoreListing(directory) {
|
|
|
223824
223861
|
return { status: "not-a-repository" };
|
|
223825
223862
|
if (location2.stdout.trim() !== "true")
|
|
223826
223863
|
return { status: "failed" };
|
|
223827
|
-
let listed = await
|
|
223864
|
+
let listed = await runGit(directory, [
|
|
223828
223865
|
"ls-files",
|
|
223829
223866
|
"-z",
|
|
223830
223867
|
"--others",
|
|
@@ -223838,10 +223875,10 @@ async function runGitIgnoreListing(directory) {
|
|
|
223838
223875
|
}
|
|
223839
223876
|
async function isIgnoredByParentRepository(directory) {
|
|
223840
223877
|
let parent = dirname(directory);
|
|
223841
|
-
return parent === directory ? !1 : (await
|
|
223878
|
+
return parent === directory ? !1 : (await runGit(parent, ["check-ignore", "--no-index", "-q", "--", basename(directory)]))?.exitCode === 0;
|
|
223842
223879
|
}
|
|
223843
223880
|
async function listTrackedFiles(directory) {
|
|
223844
|
-
let listed = await
|
|
223881
|
+
let listed = await runGit(directory, ["ls-files", "-z", "--cached", "--", "."]);
|
|
223845
223882
|
if (!(listed === void 0 || listed.exitCode !== 0))
|
|
223846
223883
|
return splitNullSeparated(listed.stdout);
|
|
223847
223884
|
}
|
|
@@ -223856,14 +223893,6 @@ async function listNestedRepository(directory) {
|
|
|
223856
223893
|
function splitNullSeparated(output) {
|
|
223857
223894
|
return output.split("\0").filter((path4) => path4 !== "");
|
|
223858
223895
|
}
|
|
223859
|
-
async function runGit2(directory, args) {
|
|
223860
|
-
try {
|
|
223861
|
-
let result = await captureOutputWithExitCode("git", args, { cwd: directory });
|
|
223862
|
-
return { exitCode: result.exitCode, stdout: result.stdout };
|
|
223863
|
-
} catch {
|
|
223864
|
-
return;
|
|
223865
|
-
}
|
|
223866
|
-
}
|
|
223867
223896
|
|
|
223868
223897
|
// ../app/dist/cli/services/app-security-engine/rules/dependency-automation-rules.js
|
|
223869
223898
|
init_cjs_shims();
|
|
@@ -224252,6 +224281,13 @@ function readRepositoryFile(absolutePath) {
|
|
|
224252
224281
|
let located = configuredReader().explicitInputs.has(path4) ? explicitInputPath(path4) : containedRepositoryPath(path4), result = located.path ? readBoundedFile(located.path) : located.failure;
|
|
224253
224282
|
return repositoryFileCache.set(path4, result), result.ok || recordSkippedFile(path4, result), result;
|
|
224254
224283
|
}
|
|
224284
|
+
function readFileContainedBy(directory, path4) {
|
|
224285
|
+
let inspected = inspectRepositoryPath(directory, path4);
|
|
224286
|
+
if (inspected.status === "missing")
|
|
224287
|
+
return;
|
|
224288
|
+
let result = inspected.status === "file" ? readBoundedFile(inspected.path) : repositoryPathFailure(inspected.reason);
|
|
224289
|
+
return result.ok || recordSkippedFile(joinPath(directory, path4), result), result;
|
|
224290
|
+
}
|
|
224255
224291
|
function readRepositoryText(absolutePath) {
|
|
224256
224292
|
let result = readRepositoryFile(absolutePath);
|
|
224257
224293
|
return result.ok ? result.content.toString() : void 0;
|
|
@@ -224354,15 +224390,14 @@ function isProbablyBinary(content) {
|
|
|
224354
224390
|
return sample.length > 0 && suspiciousControlBytes / sample.length > 0.1;
|
|
224355
224391
|
}
|
|
224356
224392
|
function findSensitiveFiles(appRoot, repositoryFiles, selectedAppConfigPath) {
|
|
224357
|
-
return repositoryFiles.filter(isSensitiveFile).filter((path4) => !LOCKFILE_MANAGERS.has(path4)).filter((path4) => !isValidFormatAppConfigurationFileName(basename(path4)) || path4 === selectedAppConfigPath).flatMap((path4) => {
|
|
224393
|
+
return repositoryFiles.filter(isSensitiveFile).filter((path4) => !LOCKFILE_MANAGERS.has(basename(path4))).filter((path4) => !isValidFormatAppConfigurationFileName(basename(path4)) || path4 === selectedAppConfigPath).flatMap((path4) => {
|
|
224358
224394
|
let absolutePath = joinPath(appRoot, path4), result = readRepositoryFile(absolutePath);
|
|
224359
224395
|
return result.ok ? isProbablyBinary(result.content) ? [] : [{ path: path4, absolutePath, ext: extname(path4), content: result.content.toString() }] : [{ path: path4, absolutePath, ext: extname(path4), content: void 0 }];
|
|
224360
224396
|
});
|
|
224361
224397
|
}
|
|
224362
|
-
function
|
|
224398
|
+
function dependencyAutomationRoot(appRoot) {
|
|
224363
224399
|
let marker = findRepositoryMarker(appRoot);
|
|
224364
|
-
|
|
224365
|
-
return marker.status === "ambiguous" ? marker.reason : marker.directory === appRoot ? void 0 : "App root is nested below a parent Git repository";
|
|
224400
|
+
return marker.status === "ambiguous" ? { unresolvedReason: marker.reason } : { directory: marker.status === "found" ? marker.directory : appRoot };
|
|
224366
224401
|
}
|
|
224367
224402
|
function findDependencyAutomationInputs(appRoot, gatheredPaths) {
|
|
224368
224403
|
let canonicalRoot;
|
|
@@ -224372,25 +224407,28 @@ function findDependencyAutomationInputs(appRoot, gatheredPaths) {
|
|
|
224372
224407
|
} catch (error) {
|
|
224373
224408
|
return { files: [], unresolvedReason: inspectErrorReason("app root", error) };
|
|
224374
224409
|
}
|
|
224375
|
-
let
|
|
224376
|
-
if (
|
|
224377
|
-
return { files: [], unresolvedReason:
|
|
224378
|
-
let gathered = new Set(gatheredPaths), files = [], unresolvedReason;
|
|
224379
|
-
for (let
|
|
224380
|
-
|
|
224381
|
-
|
|
224382
|
-
let absolutePath = joinPath(canonicalRoot, relative), result = readRepositoryFile(absolutePath);
|
|
224383
|
-
if (!result.ok) {
|
|
224384
|
-
unresolvedReason ??= result.reason === "too_large" ? `${relative} is too large to inspect` : result.detail ?? `Could not read ${relative}`;
|
|
224410
|
+
let configurationRoot = dependencyAutomationRoot(canonicalRoot);
|
|
224411
|
+
if ("unresolvedReason" in configurationRoot)
|
|
224412
|
+
return { files: [], unresolvedReason: configurationRoot.unresolvedReason };
|
|
224413
|
+
let repositoryRoot = configurationRoot.directory, { scanDirectories } = configuredReader(), isScanned = (absolutePath) => repositoryRoot === canonicalRoot || scanDirectories.some((directory) => isSubpath(directory, absolutePath)), gathered = new Set(gatheredPaths), files = [], unresolvedReason;
|
|
224414
|
+
for (let configurationPath of DEPENDENCY_AUTOMATION_CONFIG_PATHS) {
|
|
224415
|
+
let absolutePath = joinPath(repositoryRoot, configurationPath), relative = normalizePath(relativePath(canonicalRoot, absolutePath)), scanned = isScanned(absolutePath);
|
|
224416
|
+
if (scanned && !gathered.has(relative))
|
|
224385
224417
|
continue;
|
|
224418
|
+
let result = scanned ? readRepositoryFile(absolutePath) : readFileContainedBy(repositoryRoot, configurationPath);
|
|
224419
|
+
if (result !== void 0) {
|
|
224420
|
+
if (!result.ok) {
|
|
224421
|
+
unresolvedReason ??= result.reason === "too_large" ? `${relative} is too large to inspect` : result.detail ?? `Could not read ${relative}`;
|
|
224422
|
+
continue;
|
|
224423
|
+
}
|
|
224424
|
+
files.push({
|
|
224425
|
+
path: relative,
|
|
224426
|
+
absolutePath,
|
|
224427
|
+
ext: extname(relative),
|
|
224428
|
+
content: result.content.toString()
|
|
224429
|
+
});
|
|
224430
|
+
break;
|
|
224386
224431
|
}
|
|
224387
|
-
files.push({
|
|
224388
|
-
path: relative,
|
|
224389
|
-
absolutePath,
|
|
224390
|
-
ext: extname(relative),
|
|
224391
|
-
content: result.content.toString()
|
|
224392
|
-
});
|
|
224393
|
-
break;
|
|
224394
224432
|
}
|
|
224395
224433
|
return files.length > 0 ? { files } : { files, ...unresolvedReason ? { unresolvedReason } : {} };
|
|
224396
224434
|
}
|
|
@@ -224436,6 +224474,7 @@ function findManifests(appRoot, discoveredPaths) {
|
|
|
224436
224474
|
|
|
224437
224475
|
// ../app/dist/cli/services/app-security-engine/capabilities/detect.js
|
|
224438
224476
|
init_cjs_shims();
|
|
224477
|
+
var REACT_ROUTER_PACKAGE = "@shopify/shopify-app-react-router";
|
|
224439
224478
|
function detectCapabilities(appToml, extensions, sourceFiles, appTomls = appToml ? [appToml] : []) {
|
|
224440
224479
|
let themeExtension = extensions.some((extension) => extension.type === "theme"), appEmbed = extensions.some((extension) => extension.type === "theme" && hasAppEmbedBlock(extension)), embeddedApp = appTomls.some((configuration) => configuration.raw.embedded === !0), scriptTags = sourceFiles.some((file) => file.content ? /script[_-]?tags?|ScriptTag/i.test(file.content) : !1), storefrontMetafieldWrites = sourceFiles.some((file) => file.content ? /metafields?Set|metafields?\/.*(?:POST|PUT|create|update)|write.*metafield|metafield.*write/i.test(file.content) : !1), hasBackend = sourceFiles.some(detectRouteDefinitions);
|
|
224441
224480
|
return {
|
|
@@ -224451,11 +224490,49 @@ function detectCapabilities(appToml, extensions, sourceFiles, appTomls = appToml
|
|
|
224451
224490
|
checkout_extension: extensions.some((extension) => extension.type === "checkout_ui" || extension.type === "checkout_ui_extension")
|
|
224452
224491
|
};
|
|
224453
224492
|
}
|
|
224454
|
-
function
|
|
224455
|
-
let
|
|
224456
|
-
|
|
224457
|
-
|
|
224458
|
-
|
|
224493
|
+
function detectReactRouterRoots(manifests, candidates, otherAppDirectories = []) {
|
|
224494
|
+
let declaringManifests = manifests.filter((manifest) => manifest.dependencies[REACT_ROUTER_PACKAGE] !== void 0 || manifest.devDependencies?.[REACT_ROUTER_PACKAGE] !== void 0);
|
|
224495
|
+
if (declaringManifests.length === 0)
|
|
224496
|
+
return [];
|
|
224497
|
+
let candidatePaths = candidates.map((candidate) => candidate.path);
|
|
224498
|
+
return [.../* @__PURE__ */ new Set([".", ...declaringManifests.map((manifest) => dirname(manifest.path))])].filter((root) => hasReactRouterStructure(root, candidatePaths)).filter((root) => !belongsToOtherApp(root, otherAppDirectories)).sort();
|
|
224499
|
+
}
|
|
224500
|
+
function isReactRouterServerPath(root, path4) {
|
|
224501
|
+
let pathInRoot = pathWithinRoot(root, path4);
|
|
224502
|
+
return pathInRoot !== void 0 && /^app\/shopify\.server\.[cm]?[jt]sx?$/.test(pathInRoot);
|
|
224503
|
+
}
|
|
224504
|
+
function isReactRouterSourcePath(path4, reactRouterRoots, otherAppDirectories) {
|
|
224505
|
+
let otherAppCode = otherAppCodeDirectories(otherAppDirectories).filter((directory) => !isInsideReactRouterRoot(directory, reactRouterRoots));
|
|
224506
|
+
return (!climbsOutOfDirectory(path4) || reactRouterRoots.some((root) => pathWithinRoot(root, path4) !== void 0)) && !otherAppCode.some((directory) => pathWithinRoot(directory, path4) !== void 0);
|
|
224507
|
+
}
|
|
224508
|
+
function isInsideReactRouterRoot(directory, reactRouterRoots) {
|
|
224509
|
+
return reactRouterRoots.some((root) => root === "." ? !climbsOutOfDirectory(directory) : directory === root || pathWithinRoot(root, directory) !== void 0);
|
|
224510
|
+
}
|
|
224511
|
+
function climbsOutOfDirectory(path4) {
|
|
224512
|
+
return path4 === ".." || path4.startsWith("../");
|
|
224513
|
+
}
|
|
224514
|
+
function pathWithinRoot(root, path4) {
|
|
224515
|
+
if (root === ".")
|
|
224516
|
+
return path4;
|
|
224517
|
+
if (!path4.startsWith(`${root}/`))
|
|
224518
|
+
return;
|
|
224519
|
+
let pathInRoot = path4.slice(root.length + 1);
|
|
224520
|
+
return climbsOutOfDirectory(pathInRoot) ? void 0 : pathInRoot;
|
|
224521
|
+
}
|
|
224522
|
+
function hasReactRouterStructure(root, paths) {
|
|
224523
|
+
return paths.some((path4) => pathWithinRoot(root, path4)?.startsWith("app/routes/")) && paths.some((path4) => isReactRouterServerPath(root, path4));
|
|
224524
|
+
}
|
|
224525
|
+
function belongsToOtherApp(root, otherAppDirectories) {
|
|
224526
|
+
return root === "." ? !1 : otherAppDirectories.includes(root) || otherAppCodeDirectories(otherAppDirectories).some((directory) => root === directory || pathWithinRoot(directory, root) !== void 0);
|
|
224527
|
+
}
|
|
224528
|
+
function otherAppCodeDirectories(otherAppDirectories) {
|
|
224529
|
+
return otherAppDirectories.flatMap((directory) => isAncestorOfAppDirectory(directory) ? [`${directory}/app`, `${directory}/web`] : [directory]);
|
|
224530
|
+
}
|
|
224531
|
+
function isAncestorOfAppDirectory(directory) {
|
|
224532
|
+
return directory.split("/").every((segment) => segment === "..");
|
|
224533
|
+
}
|
|
224534
|
+
function detectProject(extensions, candidates, reactRouterRoots) {
|
|
224535
|
+
let reactRouter = reactRouterRoots.length > 0, themeExtensions = extensions.filter((extension) => extension.type === "theme"), themeExtension = themeExtensions.length > 0, themePaths = new Set(themeExtensions.flatMap((extension) => extension.files.map((file) => file.path))), hasSources = candidates.length > 0, surface;
|
|
224459
224536
|
reactRouter && themeExtension ? surface = "mixed" : reactRouter ? surface = "react_router" : themeExtension && candidates.some((candidate) => !themePaths.has(candidate.path)) ? surface = "mixed" : themeExtension ? surface = "theme_app_extension" : hasSources ? surface = "unknown" : surface = "config_only";
|
|
224460
224537
|
let framework;
|
|
224461
224538
|
reactRouter ? framework = "react_router" : surface === "config_only" || surface === "theme_app_extension" ? framework = "none" : surface === "mixed" ? framework = "mixed" : framework = "unknown";
|
|
@@ -225115,11 +225192,11 @@ function scanEolApiVersions(context, referenceDate = /* @__PURE__ */ new Date())
|
|
|
225115
225192
|
]);
|
|
225116
225193
|
if (context.detection.framework !== "react_router")
|
|
225117
225194
|
return configIssues;
|
|
225118
|
-
let sourceIssues = context.sourceFiles.flatMap((file) => scanReactRouterApiVersion(file, referenceDate));
|
|
225195
|
+
let sourceIssues = context.sourceFiles.flatMap((file) => scanReactRouterApiVersion(file, context.reactRouterRoots, referenceDate));
|
|
225119
225196
|
return [...configIssues, ...sourceIssues];
|
|
225120
225197
|
}
|
|
225121
|
-
function scanReactRouterApiVersion(file, referenceDate) {
|
|
225122
|
-
if (!file.content ||
|
|
225198
|
+
function scanReactRouterApiVersion(file, reactRouterRoots, referenceDate) {
|
|
225199
|
+
if (!file.content || !reactRouterRoots.some((root) => isReactRouterServerPath(root, file.path)))
|
|
225123
225200
|
return [];
|
|
225124
225201
|
let content = maskStringsExceptVersions(stripComments4(file.content));
|
|
225125
225202
|
return [
|
|
@@ -226064,7 +226141,7 @@ var JAVASCRIPT_EXTENSIONS6 = [".js", ".jsx", ".mjs", ".cjs", ".ts", ".tsx", ".mt
|
|
|
226064
226141
|
configRule(missingComplianceWebhooks),
|
|
226065
226142
|
{
|
|
226066
226143
|
id: "MISSING_DEPENDENCY_SECURITY_AUTOMATION",
|
|
226067
|
-
version:
|
|
226144
|
+
version: 2,
|
|
226068
226145
|
lifecycle: "active",
|
|
226069
226146
|
analysisMode: "structured_config",
|
|
226070
226147
|
target: "dependency_automation",
|
|
@@ -226072,7 +226149,7 @@ var JAVASCRIPT_EXTENSIONS6 = [".js", ".jsx", ".mjs", ".cjs", ".ts", ".tsx", ".mt
|
|
|
226072
226149
|
},
|
|
226073
226150
|
{
|
|
226074
226151
|
id: "EOL_API_VERSION",
|
|
226075
|
-
version:
|
|
226152
|
+
version: 2,
|
|
226076
226153
|
lifecycle: "active",
|
|
226077
226154
|
analysisMode: "regex",
|
|
226078
226155
|
target: "config_and_source",
|
|
@@ -226080,16 +226157,16 @@ var JAVASCRIPT_EXTENSIONS6 = [".js", ".jsx", ".mjs", ".cjs", ".ts", ".tsx", ".mt
|
|
|
226080
226157
|
runner: (context) => scanEolApiVersions(context)
|
|
226081
226158
|
},
|
|
226082
226159
|
{
|
|
226083
|
-
...jsCheck("EXPIRING_OFFLINE_TOKEN", (context) => scanExpiringOfflineTokens(context)),
|
|
226160
|
+
...jsCheck("EXPIRING_OFFLINE_TOKEN", (context) => scanExpiringOfflineTokens(context), "source", 2),
|
|
226084
226161
|
extensions: [...JAVASCRIPT_EXTENSIONS6, ".prisma"]
|
|
226085
226162
|
},
|
|
226086
226163
|
{
|
|
226087
|
-
...jsCheck("UNAUTHENTICATED_ENDPOINT", (context) => scanUnauthenticatedEndpoints(context.sourceFiles), "source",
|
|
226164
|
+
...jsCheck("UNAUTHENTICATED_ENDPOINT", (context) => scanUnauthenticatedEndpoints(context.sourceFiles), "source", 3),
|
|
226088
226165
|
requires: "has_backend"
|
|
226089
226166
|
},
|
|
226090
|
-
jsCheck("REQUEST_CONTROLLED_ADMIN_CONTEXT", (context) => scanRequestControlledAdminContext(context.sourceFiles), "source",
|
|
226167
|
+
jsCheck("REQUEST_CONTROLLED_ADMIN_CONTEXT", (context) => scanRequestControlledAdminContext(context.sourceFiles), "source", 4),
|
|
226091
226168
|
{
|
|
226092
|
-
...configRule(deprecatedScriptTagScope),
|
|
226169
|
+
...configRule(deprecatedScriptTagScope, 2),
|
|
226093
226170
|
target: "config_and_source",
|
|
226094
226171
|
analysisMode: "regex",
|
|
226095
226172
|
extensions: JAVASCRIPT_EXTENSIONS6,
|
|
@@ -226101,14 +226178,14 @@ var JAVASCRIPT_EXTENSIONS6 = [".js", ".jsx", ".mjs", ".cjs", ".ts", ".tsx", ".mt
|
|
|
226101
226178
|
configRule(insecureWebhookUrl, 2),
|
|
226102
226179
|
{
|
|
226103
226180
|
id: "COMMITTED_SECRET",
|
|
226104
|
-
version:
|
|
226181
|
+
version: 4,
|
|
226105
226182
|
lifecycle: "active",
|
|
226106
226183
|
analysisMode: "regex",
|
|
226107
226184
|
target: "secrets",
|
|
226108
226185
|
runner: (context) => scanCommittedSecrets(context.sensitiveFiles, context.appRoot, context.gitIgnoreListing)
|
|
226109
226186
|
},
|
|
226110
|
-
jsCheck("CREDENTIAL_LOG_LEAKAGE", (context) => scanCredentialLogLeakage(context.sourceFiles)),
|
|
226111
|
-
jsCheck("CREDENTIAL_BROWSER_LEAKAGE", (context) => scanCredentialBrowserLeakage(context.sourceFiles)),
|
|
226187
|
+
jsCheck("CREDENTIAL_LOG_LEAKAGE", (context) => scanCredentialLogLeakage(context.sourceFiles), "source", 2),
|
|
226188
|
+
jsCheck("CREDENTIAL_BROWSER_LEAKAGE", (context) => scanCredentialBrowserLeakage(context.sourceFiles), "source", 2),
|
|
226112
226189
|
{
|
|
226113
226190
|
id: "LIQUID_UNSAFE_RENDER",
|
|
226114
226191
|
version: 1,
|
|
@@ -226120,16 +226197,16 @@ var JAVASCRIPT_EXTENSIONS6 = [".js", ".jsx", ".mjs", ".cjs", ".ts", ".tsx", ".mt
|
|
|
226120
226197
|
runner: (context) => liquidRunner(context, "LIQUID_UNSAFE_RENDER")
|
|
226121
226198
|
},
|
|
226122
226199
|
{
|
|
226123
|
-
...jsCheck("UNSAFE_INNERHTML", unsafeInnerHtmlRunner, "source_and_theme",
|
|
226200
|
+
...jsCheck("UNSAFE_INNERHTML", unsafeInnerHtmlRunner, "source_and_theme", 3),
|
|
226124
226201
|
analysisMode: "regex",
|
|
226125
226202
|
extensions: [...JAVASCRIPT_EXTENSIONS6, ".liquid", ".html"]
|
|
226126
226203
|
},
|
|
226127
226204
|
{
|
|
226128
|
-
...jsCheck("APP_PROXY_LIQUID_INJECTION", (context) => scanAppProxyLiquidInjection(context.sourceFiles), "source",
|
|
226205
|
+
...jsCheck("APP_PROXY_LIQUID_INJECTION", (context) => scanAppProxyLiquidInjection(context.sourceFiles), "source", 3),
|
|
226129
226206
|
requires: "app_proxy"
|
|
226130
226207
|
},
|
|
226131
226208
|
{
|
|
226132
|
-
...jsCheck("STATIC_FRAME_ANCESTORS", (context) => scanStaticFrameAncestors(context.sourceFiles), "app_source"),
|
|
226209
|
+
...jsCheck("STATIC_FRAME_ANCESTORS", (context) => scanStaticFrameAncestors(context.sourceFiles), "app_source", 2),
|
|
226133
226210
|
requires: "embedded_app"
|
|
226134
226211
|
}
|
|
226135
226212
|
];
|
|
@@ -226237,8 +226314,11 @@ function appSourceFiles(context) {
|
|
|
226237
226314
|
let themePaths = new Set(themeFiles(context).map((file) => file.path));
|
|
226238
226315
|
return context.sourceFiles.filter((file) => !themePaths.has(file.path));
|
|
226239
226316
|
}
|
|
226317
|
+
function isReactRouterFilePath(path4, context) {
|
|
226318
|
+
return context.detection.framework !== "react_router" || isReactRouterSourcePath(path4, context.reactRouterRoots, context.otherAppDirectories);
|
|
226319
|
+
}
|
|
226240
226320
|
function reactRouterFiles(context) {
|
|
226241
|
-
return appSourceFiles(context);
|
|
226321
|
+
return appSourceFiles(context).filter((file) => isReactRouterFilePath(file.path, context));
|
|
226242
226322
|
}
|
|
226243
226323
|
function selectedFiles(definition, context) {
|
|
226244
226324
|
let configurations = context.appTomls.map((toml) => relativePath(context.appRoot, toml.path).replace(/\\/g, "/"));
|
|
@@ -226345,8 +226425,8 @@ function manifestHasDependencies(manifest) {
|
|
|
226345
226425
|
return Object.keys(manifest.dependencies).length > 0 || Object.keys(manifest.devDependencies ?? {}).length > 0;
|
|
226346
226426
|
}
|
|
226347
226427
|
function skippedInputsForCheck(definition, context, skippedFiles2) {
|
|
226348
|
-
let themeDirectories = context.extensions.filter((extension) => extension.type === "theme").map((extension) => extension.path.replace(/shopify\.extension\.toml$/, "")), isThemePath = (path4) => themeDirectories.some((directory) => path4.startsWith(directory)) || path4.endsWith("shopify.extension.toml"), isSourcePath = (path4) => !isThemePath(path4) && !!definition.extensions?.some((extension) => path4.endsWith(extension)), isConfig = (path4) => /^shopify\.app(?:\.[^/]+)?\.toml$/.test(path4), isDependencyAutomationInput = (path4) => /(^|\/)package\.json$/.test(path4) || context.dependencyAutomation.files.some((file) => file.path === path4), isSecretInput = (file) => !file.detail?.includes("could not be parsed") && (context.sourceCandidates.some((candidate) => candidate.path === file.path) || context.sensitiveFiles.some((sensitiveFile) => sensitiveFile.path === file.path) || /(^|\/)(?:\.env(?:\.[^/]+)?|secrets\.json|credentials\.json)$/.test(file.path));
|
|
226349
|
-
return skippedFiles2.filter((file) => definition.target === "config" ? isConfig(file.path) : definition.target === "dependency_automation" ? isDependencyAutomationInput(file.path) : definition.target === "config_and_source" ? isConfig(file.path) ||
|
|
226428
|
+
let themeDirectories = context.extensions.filter((extension) => extension.type === "theme").map((extension) => extension.path.replace(/shopify\.extension\.toml$/, "")), isThemePath = (path4) => themeDirectories.some((directory) => path4.startsWith(directory)) || path4.endsWith("shopify.extension.toml"), isSourcePath = (path4) => !isThemePath(path4) && !!definition.extensions?.some((extension) => path4.endsWith(extension)), isReactRouterInput = (path4) => isSourcePath(path4) && isReactRouterFilePath(path4, context), isConfig = (path4) => /^shopify\.app(?:\.[^/]+)?\.toml$/.test(path4), isDependencyAutomationInput = (path4) => /(^|\/)package\.json$/.test(path4) || context.dependencyAutomation.files.some((file) => file.path === path4), isSecretInput = (file) => !file.detail?.includes("could not be parsed") && (context.sourceCandidates.some((candidate) => candidate.path === file.path) || context.sensitiveFiles.some((sensitiveFile) => sensitiveFile.path === file.path) || /(^|\/)(?:\.env(?:\.[^/]+)?|secrets\.json|credentials\.json)$/.test(file.path));
|
|
226429
|
+
return skippedFiles2.filter((file) => definition.target === "config" ? isConfig(file.path) : definition.target === "dependency_automation" ? isDependencyAutomationInput(file.path) : definition.target === "config_and_source" ? isConfig(file.path) || isReactRouterInput(file.path) : definition.target === "source" ? isReactRouterInput(file.path) : definition.target === "app_source" ? isSourcePath(file.path) : definition.target === "theme" ? isThemePath(file.path) : definition.target === "source_and_theme" ? isReactRouterInput(file.path) || isThemePath(file.path) : isSecretInput(file));
|
|
226350
226430
|
}
|
|
226351
226431
|
function skippedInputReason(definition, files) {
|
|
226352
226432
|
return {
|
|
@@ -226385,7 +226465,7 @@ async function scan(input, options = {}) {
|
|
|
226385
226465
|
scanDirectories,
|
|
226386
226466
|
explicitInputs: new Set(appConfigFilePath ? [appConfigFilePath] : [])
|
|
226387
226467
|
});
|
|
226388
|
-
let selectedAppConfigPath = appConfigFilePath ? normalizePath(relativePath(appRoot, appConfigFilePath)) : void 0, appToml = appConfigFilePath ? loadAppToml(appConfigFilePath, appRoot) : null, appTomls = appToml ? [appToml] : [], { paths: repositoryFiles, ignoredScanDirectories, otherAppDirectories, listingStatus } = await gatherScanPaths(input, options), extensions = findExtensions(appRoot, repositoryFiles), sourceCandidates = findSourceCandidates(repositoryFiles), sourceFiles = findAppSourceFiles(appRoot, repositoryFiles), sensitiveFiles = findSensitiveFiles(appRoot, repositoryFiles, selectedAppConfigPath), manifestPaths = findManifestPaths(repositoryFiles), manifests = findManifests(appRoot, manifestPaths), dependencyAutomation = manifests.some(manifestHasDependencies) ? findDependencyAutomationInputs(appRoot, repositoryFiles) : { files: [] }, capabilities = detectCapabilities(appToml, extensions, sourceFiles, appTomls),
|
|
226468
|
+
let selectedAppConfigPath = appConfigFilePath ? normalizePath(relativePath(appRoot, appConfigFilePath)) : void 0, appToml = appConfigFilePath ? loadAppToml(appConfigFilePath, appRoot) : null, appTomls = appToml ? [appToml] : [], { paths: repositoryFiles, ignoredScanDirectories, otherAppDirectories, listingStatus } = await gatherScanPaths(input, options), extensions = findExtensions(appRoot, repositoryFiles), sourceCandidates = findSourceCandidates(repositoryFiles), sourceFiles = findAppSourceFiles(appRoot, repositoryFiles), sensitiveFiles = findSensitiveFiles(appRoot, repositoryFiles, selectedAppConfigPath), manifestPaths = findManifestPaths(repositoryFiles), manifests = findManifests(appRoot, manifestPaths), dependencyAutomation = manifests.some(manifestHasDependencies) ? findDependencyAutomationInputs(appRoot, repositoryFiles) : { files: [] }, capabilities = detectCapabilities(appToml, extensions, sourceFiles, appTomls), relativeOtherAppDirectories = otherAppDirectories.map((directory) => normalizePath(relativePath(appRoot, directory))), reactRouterRoots = detectReactRouterRoots(manifests, sourceCandidates, relativeOtherAppDirectories), detection = detectProject(extensions, sourceCandidates, reactRouterRoots), context = {
|
|
226389
226469
|
appRoot,
|
|
226390
226470
|
appToml,
|
|
226391
226471
|
appTomls,
|
|
@@ -226396,6 +226476,8 @@ async function scan(input, options = {}) {
|
|
|
226396
226476
|
sensitiveFiles,
|
|
226397
226477
|
capabilities,
|
|
226398
226478
|
detection,
|
|
226479
|
+
reactRouterRoots,
|
|
226480
|
+
otherAppDirectories: relativeOtherAppDirectories,
|
|
226399
226481
|
sourceCandidates,
|
|
226400
226482
|
gitIgnoreListing: listingStatus
|
|
226401
226483
|
}, issues = [], checksExecuted = [], requiredCheckIds = /* @__PURE__ */ new Set();
|
|
@@ -228914,7 +228996,7 @@ var SecurityCheck = class _SecurityCheck extends base_command_default {
|
|
|
228914
228996
|
env: "SHOPIFY_FLAG_YES"
|
|
228915
228997
|
}),
|
|
228916
228998
|
"skip-instructions": import_core32.Flags.boolean({
|
|
228917
|
-
description: "Don't offer
|
|
228999
|
+
description: "Don't offer the coding-agent instructions after the scan. Use it when you want only the deterministic scan results.",
|
|
228918
229000
|
default: !1,
|
|
228919
229001
|
exclusive: ["yes"],
|
|
228920
229002
|
env: "SHOPIFY_FLAG_APP_SECURITY_SKIP_INSTRUCTIONS"
|