runcloud 0.2.155 → 0.2.156

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.
@@ -1,6 +1,14 @@
1
1
  import { existsSync, readFileSync, readdirSync, statSync, } from 'node:fs';
2
2
  import path from 'node:path';
3
3
  const PREVIEW_APP_ID = 'app.newly.preview';
4
+ const PLACEHOLDER_COPY = /lorem ipsum|example\.com|\bTBD\b|\bTODO\b|\bplaceholder\b/i;
5
+ const INPUT_PLACEHOLDER = /\bplaceholder\??\s*[=:]\s*(\{[^}]*\}|"[^"]*"|'[^']*'|`[^`]*`|[\w.$]+)/gi;
6
+ const PLACEHOLDER_NAME = /\.placeholder\b|\bplaceholder\b(?=\s*[,})\]])/gi;
7
+ function withoutInputPlaceholders(line) {
8
+ return line
9
+ .replace(INPUT_PLACEHOLDER, (_prop, value) => (/^["'`]/.test(value) ? value.replace(/example\.com/gi, '') : ''))
10
+ .replace(PLACEHOLDER_NAME, '');
11
+ }
4
12
  const CONFIG_RULES = {
5
13
  app_name: { path: ['expo', 'name'], absent: 'fail' },
6
14
  slug: { path: ['expo', 'slug'], absent: 'fail' },
@@ -157,7 +165,9 @@ function evaluateLocalItem(root, appJson, item) {
157
165
  case 'http_endpoints':
158
166
  return patternItem(root, item, /http:\/\/(?!localhost|127\.0\.0\.1)/i, 'warning', 'Non-local HTTP endpoint found.', 'No non-local HTTP endpoints found.');
159
167
  case 'placeholder_content':
160
- return patternItem(root, item, /lorem ipsum|example\.com|\bTBD\b|\bTODO\b|Coming soon|placeholder/i, 'warning', 'Placeholder text found.', 'No placeholder text found.');
168
+ return patternItem(root, item, PLACEHOLDER_COPY, 'warning', 'Placeholder text found.', 'No placeholder text found.', {
169
+ filter: (match) => PLACEHOLDER_COPY.test(withoutInputPlaceholders(match.text)),
170
+ });
161
171
  case 'competitor_reference':
162
172
  return patternItem(root, item, /google play|\.apk\b|samsung|android app/i, 'warning', 'Possible platform/competitor reference found in user-facing copy.', 'No competitor platform references found.', { dirs: ['app', 'src', 'components'] });
163
173
  case 'private_api_usage':
@@ -180,7 +190,7 @@ function evaluateLocalItem(root, appJson, item) {
180
190
  case 'external_payment_digital':
181
191
  return evaluateExternalPayment(root, item);
182
192
  case 'expo_layout_missing':
183
- return evaluateExpoLayout(root, item);
193
+ return makeItem(item, 'pass', 'Expo Router adds a layout where a directory has none.', 'expo-router getRoutesCore.js');
184
194
  case 'expo_duplicate_route':
185
195
  return evaluateDuplicateRoutes(root, item);
186
196
  case 'ios_encryption':
@@ -248,16 +258,6 @@ function evaluateExternalPayment(root, item) {
248
258
  return makeItem(item, 'pass', 'No external payment SDK patterns found.', 'scan: no Stripe/PayPal/Braintree patterns found');
249
259
  return makeItem(item, 'warning', 'External payment SDK found; verify it is not used for digital goods on iOS.', evidence(matches));
250
260
  }
251
- function evaluateExpoLayout(root, item) {
252
- const appDir = path.join(root, 'app');
253
- if (!existsSync(appDir))
254
- return makeItem(item, 'pass', 'No Expo Router app directory found.', 'scan: app/ directory absent');
255
- const dirs = walkDirs(appDir).map((dir) => path.relative(root, dir) || 'app');
256
- const missing = dirs.filter((dir) => !hasLayoutFile(path.join(root, dir)));
257
- if (!missing.length)
258
- return makeItem(item, 'pass', 'Every app route directory has a layout file.', 'scan: app route directories');
259
- return makeItem(item, 'fail', 'Expo Router directories without _layout files found.', missing.slice(0, 8).join(', '));
260
- }
261
261
  function evaluateDuplicateRoutes(root, item) {
262
262
  const appDir = routerDir(root);
263
263
  if (!existsSync(appDir))
@@ -516,17 +516,6 @@ function walkFiles(dir) {
516
516
  }
517
517
  return files;
518
518
  }
519
- function walkDirs(dir) {
520
- const dirs = [dir];
521
- for (const entry of safeReadDir(dir)) {
522
- if (SKIP_DIRS.has(entry.name))
523
- continue;
524
- const full = path.join(dir, entry.name);
525
- if (entry.isDirectory())
526
- dirs.push(...walkDirs(full));
527
- }
528
- return dirs;
529
- }
530
519
  function shouldScanFile(file) {
531
520
  return TEXT_EXTENSIONS.has(path.extname(file));
532
521
  }
@@ -536,9 +525,6 @@ function findByName(root, name) {
536
525
  function sourceText(root, dirs) {
537
526
  return collectScanFiles(root, dirs).map((file) => readText(file) ?? '').join('\n');
538
527
  }
539
- function hasLayoutFile(dir) {
540
- return ['_layout.tsx', '_layout.ts', '_layout.jsx', '_layout.js'].some((name) => existsSync(path.join(dir, name)));
541
- }
542
528
  function routerDir(root) {
543
529
  const src = path.join(root, 'src', 'app');
544
530
  return safeStat(src)?.isDirectory() ? src : path.join(root, 'app');
package/dist/version.js CHANGED
@@ -1 +1 @@
1
- export const CLI_VERSION = '0.2.155';
1
+ export const CLI_VERSION = '0.2.156';
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "runcloud",
3
- "version": "0.2.155",
3
+ "version": "0.2.156",
4
4
  "description": "Create and control run.cloud remote mobile simulators and cloud sandboxes",
5
5
  "license": "Apache-2.0",
6
6
  "keywords": [
Binary file
Binary file