expo-harmony-toolkit 1.7.1 → 1.7.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.
Files changed (67) hide show
  1. package/README.en.md +20 -9
  2. package/README.md +22 -11
  3. package/build/core/autolinking.d.ts +10 -0
  4. package/build/core/autolinking.js +421 -0
  5. package/build/core/build/commands.d.ts +19 -0
  6. package/build/core/build/commands.js +61 -0
  7. package/build/core/build/compatibilityShims.d.ts +1 -0
  8. package/build/core/build/compatibilityShims.js +272 -0
  9. package/build/core/build/localHar.d.ts +13 -0
  10. package/build/core/build/localHar.js +337 -0
  11. package/build/core/build/reporting.d.ts +19 -0
  12. package/build/core/build/reporting.js +67 -0
  13. package/build/core/build/rnohCompatibility.d.ts +1 -0
  14. package/build/core/build/rnohCompatibility.js +38 -0
  15. package/build/core/build.d.ts +4 -12
  16. package/build/core/build.js +70 -762
  17. package/build/core/constants.d.ts +2 -1
  18. package/build/core/constants.js +3 -2
  19. package/build/core/dependencyInspection.d.ts +2 -0
  20. package/build/core/dependencyInspection.js +112 -0
  21. package/build/core/env.js +1 -1
  22. package/build/core/report.js +33 -10
  23. package/build/core/signing.d.ts +2 -0
  24. package/build/core/signing.js +30 -0
  25. package/build/core/template/capabilityRegistry.d.ts +9 -0
  26. package/build/core/template/capabilityRegistry.js +84 -0
  27. package/build/core/template/expoModulesCoreShim.d.ts +2 -0
  28. package/build/core/template/expoModulesCoreShim.js +279 -0
  29. package/build/core/template/metro.d.ts +2 -0
  30. package/build/core/template/metro.js +213 -0
  31. package/build/core/template/nativeFiles.d.ts +8 -0
  32. package/build/core/template/nativeFiles.js +333 -0
  33. package/build/core/template/renderers/camera.d.ts +4 -0
  34. package/build/core/template/renderers/camera.js +612 -0
  35. package/build/core/template/renderers/fileSystem.d.ts +4 -0
  36. package/build/core/template/renderers/fileSystem.js +814 -0
  37. package/build/core/template/renderers/imagePicker.d.ts +4 -0
  38. package/build/core/template/renderers/imagePicker.js +753 -0
  39. package/build/core/template/renderers/location.d.ts +4 -0
  40. package/build/core/template/renderers/location.js +836 -0
  41. package/build/core/template/runtimeShims.d.ts +2 -0
  42. package/build/core/template/runtimeShims.js +192 -0
  43. package/build/core/template/support.d.ts +11 -0
  44. package/build/core/template/support.js +108 -0
  45. package/build/core/template.d.ts +2 -6
  46. package/build/core/template.js +47 -3966
  47. package/build/data/capabilities.js +45 -19
  48. package/build/data/dependencyCatalog.js +10 -0
  49. package/build/data/publicDocs.d.ts +11 -0
  50. package/build/data/publicDocs.js +28 -0
  51. package/build/data/validatedMatrices.js +9 -1
  52. package/build/docs/render.d.ts +9 -0
  53. package/build/docs/render.js +248 -0
  54. package/build/types.d.ts +12 -0
  55. package/docs/cli-build.md +1 -1
  56. package/docs/npm-release.md +1 -0
  57. package/docs/official-app-shell-sample.md +2 -1
  58. package/docs/official-minimal-sample.md +2 -1
  59. package/docs/official-native-capabilities-sample.md +28 -47
  60. package/docs/official-ui-stack-sample.md +2 -1
  61. package/docs/signing-and-release.md +3 -0
  62. package/docs/support-matrix.md +38 -16
  63. package/package.json +13 -5
  64. package/docs/v1.5.1-acceptance.md +0 -385
  65. package/docs/v1.6.0-acceptance.md +0 -193
  66. package/docs/v1.7.0-acceptance.md +0 -111
  67. package/docs/v1.7.1-acceptance.md +0 -111
@@ -1,6 +1,6 @@
1
1
  export declare const TOOLKIT_PACKAGE_NAME = "expo-harmony-toolkit";
2
2
  export declare const CLI_NAME = "expo-harmony";
3
- export declare const TOOLKIT_VERSION = "1.7.1";
3
+ export declare const TOOLKIT_VERSION = "1.7.3";
4
4
  export declare const TEMPLATE_VERSION = "rnoh-0.82.18";
5
5
  export declare const RNOH_VERSION = "0.82.18";
6
6
  export declare const RNOH_CLI_VERSION = "0.82.18";
@@ -8,6 +8,7 @@ export declare const SUPPORTED_EXPO_SDKS: number[];
8
8
  export declare const GENERATED_DIR = ".expo-harmony";
9
9
  export declare const GENERATED_SHIMS_DIR = ".expo-harmony/shims";
10
10
  export declare const SIGNING_LOCAL_FILENAME = "signing.local.json";
11
+ export declare const SIGNING_LOCAL_EXAMPLE_FILENAME = "signing.local.example.json";
11
12
  export declare const MANIFEST_FILENAME = "manifest.json";
12
13
  export declare const DOCTOR_REPORT_FILENAME = "doctor-report.json";
13
14
  export declare const ENV_REPORT_FILENAME = "env-report.json";
@@ -1,9 +1,9 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.DESIRED_PACKAGE_SCRIPTS = exports.HARMONY_RUNTIME_PRELUDE_RELATIVE_PATH = exports.HARMONY_ROUTER_ENTRY_FILENAME = exports.STRICT_ENV_EXIT_CODE = exports.STRICT_DOCTOR_EXIT_CODE = exports.DEFAULT_HVIGOR_PLUGIN_FILENAME = exports.PREBUILD_METADATA_FILENAME = exports.TOOLKIT_CONFIG_FILENAME = exports.BUILD_REPORT_FILENAME = exports.ENV_REPORT_FILENAME = exports.DOCTOR_REPORT_FILENAME = exports.MANIFEST_FILENAME = exports.SIGNING_LOCAL_FILENAME = exports.GENERATED_SHIMS_DIR = exports.GENERATED_DIR = exports.SUPPORTED_EXPO_SDKS = exports.RNOH_CLI_VERSION = exports.RNOH_VERSION = exports.TEMPLATE_VERSION = exports.TOOLKIT_VERSION = exports.CLI_NAME = exports.TOOLKIT_PACKAGE_NAME = void 0;
3
+ exports.DESIRED_PACKAGE_SCRIPTS = exports.HARMONY_RUNTIME_PRELUDE_RELATIVE_PATH = exports.HARMONY_ROUTER_ENTRY_FILENAME = exports.STRICT_ENV_EXIT_CODE = exports.STRICT_DOCTOR_EXIT_CODE = exports.DEFAULT_HVIGOR_PLUGIN_FILENAME = exports.PREBUILD_METADATA_FILENAME = exports.TOOLKIT_CONFIG_FILENAME = exports.BUILD_REPORT_FILENAME = exports.ENV_REPORT_FILENAME = exports.DOCTOR_REPORT_FILENAME = exports.MANIFEST_FILENAME = exports.SIGNING_LOCAL_EXAMPLE_FILENAME = exports.SIGNING_LOCAL_FILENAME = exports.GENERATED_SHIMS_DIR = exports.GENERATED_DIR = exports.SUPPORTED_EXPO_SDKS = exports.RNOH_CLI_VERSION = exports.RNOH_VERSION = exports.TEMPLATE_VERSION = exports.TOOLKIT_VERSION = exports.CLI_NAME = exports.TOOLKIT_PACKAGE_NAME = void 0;
4
4
  exports.TOOLKIT_PACKAGE_NAME = 'expo-harmony-toolkit';
5
5
  exports.CLI_NAME = 'expo-harmony';
6
- exports.TOOLKIT_VERSION = '1.7.1';
6
+ exports.TOOLKIT_VERSION = '1.7.3';
7
7
  exports.TEMPLATE_VERSION = 'rnoh-0.82.18';
8
8
  exports.RNOH_VERSION = '0.82.18';
9
9
  exports.RNOH_CLI_VERSION = '0.82.18';
@@ -11,6 +11,7 @@ exports.SUPPORTED_EXPO_SDKS = [53, 55];
11
11
  exports.GENERATED_DIR = '.expo-harmony';
12
12
  exports.GENERATED_SHIMS_DIR = `${exports.GENERATED_DIR}/shims`;
13
13
  exports.SIGNING_LOCAL_FILENAME = 'signing.local.json';
14
+ exports.SIGNING_LOCAL_EXAMPLE_FILENAME = 'signing.local.example.json';
14
15
  exports.MANIFEST_FILENAME = 'manifest.json';
15
16
  exports.DOCTOR_REPORT_FILENAME = 'doctor-report.json';
16
17
  exports.ENV_REPORT_FILENAME = 'env-report.json';
@@ -0,0 +1,2 @@
1
+ import { DetectedDependency } from '../types';
2
+ export declare function annotateDependencyBuildability(projectRoot: string, dependencies: DetectedDependency[]): Promise<DetectedDependency[]>;
@@ -0,0 +1,112 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ exports.annotateDependencyBuildability = annotateDependencyBuildability;
7
+ const node_module_1 = require("node:module");
8
+ const fs_extra_1 = __importDefault(require("fs-extra"));
9
+ const path_1 = __importDefault(require("path"));
10
+ const NATIVE_DIRECTORY_CANDIDATES = ['android', 'ios', 'harmony'];
11
+ const NATIVE_CONFIG_CANDIDATES = [
12
+ 'oh-package.json5',
13
+ 'react-native.config.js',
14
+ 'react-native.config.cjs',
15
+ 'react-native.config.mjs',
16
+ 'react-native.config.ts',
17
+ 'expo-module.config.json',
18
+ 'expo-module.config.js',
19
+ 'expo-module.config.cjs',
20
+ 'expo-module.config.mjs',
21
+ 'expo-module.config.ts',
22
+ ];
23
+ const PACKAGE_JSON_NATIVE_HINT_KEYS = [
24
+ 'codegenConfig',
25
+ 'expo-module',
26
+ 'harmony',
27
+ 'nativePackageName',
28
+ 'podspecPath',
29
+ 'react-native',
30
+ 'react-native-builder-bob',
31
+ ];
32
+ const PACKAGE_NAME_NATIVE_PATTERNS = [
33
+ /^expo(?:-|$)/,
34
+ /^@expo\//,
35
+ /^react-native(?:-|$)/,
36
+ /^@react-native\//,
37
+ /^@react-native-community\//,
38
+ ];
39
+ async function annotateDependencyBuildability(projectRoot, dependencies) {
40
+ return Promise.all(dependencies.map(async (dependency) => ({
41
+ ...dependency,
42
+ buildabilityRisk: await resolveDependencyBuildabilityRisk(projectRoot, dependency),
43
+ })));
44
+ }
45
+ async function resolveDependencyBuildabilityRisk(projectRoot, dependency) {
46
+ if (dependency.status !== 'unknown') {
47
+ return 'known';
48
+ }
49
+ const packageJsonPath = resolveInstalledDependencyPackageJson(projectRoot, dependency.name);
50
+ if (!packageJsonPath || !(await fs_extra_1.default.pathExists(packageJsonPath))) {
51
+ return 'unresolved';
52
+ }
53
+ const packageRoot = path_1.default.dirname(packageJsonPath);
54
+ const dependencyPackageJson = (await fs_extra_1.default.readJson(packageJsonPath));
55
+ if (looksLikeNativeDependencyByPackageName(dependency.name)) {
56
+ return 'native-risk';
57
+ }
58
+ if (await hasNativeSurface(packageRoot, dependencyPackageJson)) {
59
+ return 'native-risk';
60
+ }
61
+ return 'js-only-unknown';
62
+ }
63
+ function resolveInstalledDependencyPackageJson(projectRoot, dependencyName) {
64
+ try {
65
+ const projectRequire = (0, node_module_1.createRequire)(path_1.default.join(projectRoot, 'package.json'));
66
+ return projectRequire.resolve(`${dependencyName}/package.json`);
67
+ }
68
+ catch {
69
+ return null;
70
+ }
71
+ }
72
+ function looksLikeNativeDependencyByPackageName(dependencyName) {
73
+ return PACKAGE_NAME_NATIVE_PATTERNS.some((pattern) => pattern.test(dependencyName));
74
+ }
75
+ async function hasNativeSurface(packageRoot, dependencyPackageJson) {
76
+ for (const directoryName of NATIVE_DIRECTORY_CANDIDATES) {
77
+ if (await fs_extra_1.default.pathExists(path_1.default.join(packageRoot, directoryName))) {
78
+ return true;
79
+ }
80
+ }
81
+ for (const fileName of NATIVE_CONFIG_CANDIDATES) {
82
+ if (await fs_extra_1.default.pathExists(path_1.default.join(packageRoot, fileName))) {
83
+ return true;
84
+ }
85
+ }
86
+ if (await hasPodspecFile(packageRoot)) {
87
+ return true;
88
+ }
89
+ if (PACKAGE_JSON_NATIVE_HINT_KEYS.some((key) => dependencyPackageJson[key] !== undefined)) {
90
+ return true;
91
+ }
92
+ const files = Array.isArray(dependencyPackageJson.files)
93
+ ? dependencyPackageJson.files.filter((entry) => typeof entry === 'string')
94
+ : [];
95
+ if (files.some((entry) => hasNativePathHint(entry))) {
96
+ return true;
97
+ }
98
+ const keywords = Array.isArray(dependencyPackageJson.keywords)
99
+ ? dependencyPackageJson.keywords.filter((entry) => typeof entry === 'string')
100
+ : [];
101
+ if (keywords.some((keyword) => keyword === 'react-native' || keyword === 'expo-module')) {
102
+ return true;
103
+ }
104
+ return false;
105
+ }
106
+ async function hasPodspecFile(packageRoot) {
107
+ const entries = await fs_extra_1.default.readdir(packageRoot);
108
+ return entries.some((entry) => entry.endsWith('.podspec'));
109
+ }
110
+ function hasNativePathHint(value) {
111
+ return /(^|\/)(android|ios|harmony)(\/|$)/.test(value) || value.endsWith('.podspec');
112
+ }
package/build/core/env.js CHANGED
@@ -95,7 +95,7 @@ async function buildEnvReport(projectRoot, options = {}) {
95
95
  else if (!signingConfigured) {
96
96
  advisories.push({
97
97
  code: 'env.signing.missing',
98
- message: 'Neither .expo-harmony/signing.local.json nor harmony/build-profile.json5 declares usable signingConfigs yet. Debug GUI flows may still work, but release builds require signing.',
98
+ message: 'Neither .expo-harmony/signing.local.json nor harmony/build-profile.json5 declares usable signingConfigs yet. Copy .expo-harmony/signing.local.example.json to signing.local.json and fill your real release credentials before running release builds.',
99
99
  });
100
100
  }
101
101
  return {
@@ -10,6 +10,7 @@ const fs_extra_1 = __importDefault(require("fs-extra"));
10
10
  const path_1 = __importDefault(require("path"));
11
11
  const semver_1 = __importDefault(require("semver"));
12
12
  const constants_1 = require("./constants");
13
+ const dependencyInspection_1 = require("./dependencyInspection");
13
14
  const dependencyCatalog_1 = require("../data/dependencyCatalog");
14
15
  const validatedMatrices_1 = require("../data/validatedMatrices");
15
16
  const capabilities_1 = require("../data/capabilities");
@@ -39,7 +40,7 @@ async function buildDoctorReport(projectRoot, options = {}) {
39
40
  dependencyRecords.set(pluginName, createDependencyRecord(pluginName, 'configured', 'expo-plugin'));
40
41
  }
41
42
  }
42
- const dependencies = [...dependencyRecords.values()].sort((left, right) => left.name.localeCompare(right.name));
43
+ const dependencies = await (0, dependencyInspection_1.annotateDependencyBuildability)(loadedProject.projectRoot, [...dependencyRecords.values()].sort((left, right) => left.name.localeCompare(right.name)));
43
44
  const blockingIssues = await collectBlockingIssues(loadedProject.projectRoot, loadedProject.expoConfig, loadedProject.packageJson, expoPlugins, expoSchemes, expoSdkVersion, dependencies, matrix, targetTier);
44
45
  const capabilities = (0, capabilities_1.getCapabilityDefinitionsForProject)(loadedProject.packageJson).map((definition) => ({
45
46
  id: definition.id,
@@ -48,6 +49,7 @@ async function buildDoctorReport(projectRoot, options = {}) {
48
49
  supportTier: definition.supportTier,
49
50
  runtimeMode: definition.runtimeMode,
50
51
  evidence: { ...definition.evidence },
52
+ evidenceSource: { ...definition.evidenceSource },
51
53
  note: definition.note,
52
54
  docsUrl: definition.docsUrl,
53
55
  nativePackageNames: [...definition.nativePackageNames],
@@ -129,7 +131,7 @@ function renderDoctorReport(report) {
129
131
  ...report.dependencies.map((dependency) => {
130
132
  const replacement = dependency.replacement ? ` | replacement: ${dependency.replacement}` : '';
131
133
  const blocking = dependency.blocking ? ' | blocking: yes' : '';
132
- return `- [${dependency.status}/${dependency.supportTier}] ${dependency.name}@${dependency.version} (${dependency.source}) - ${dependency.note}${replacement}${blocking}`;
134
+ return `- [${dependency.status}/${dependency.supportTier}] ${dependency.name}@${dependency.version} (${dependency.source}) - ${dependency.note} | buildability: ${renderDependencyBuildabilityRisk(dependency.buildabilityRisk)}${replacement}${blocking}`;
133
135
  }),
134
136
  ];
135
137
  if (report.capabilities.length > 0) {
@@ -138,7 +140,7 @@ function renderDoctorReport(report) {
138
140
  ? ` | permissions: ${capability.harmonyPermissions.join(', ')}`
139
141
  : '';
140
142
  const missingEvidence = getMissingCapabilityEvidence(capability.evidence);
141
- const evidence = ` | evidence: ${renderCapabilityEvidence(capability.evidence)}`;
143
+ const evidence = ` | evidence: ${renderCapabilityEvidence(capability.evidence, capability.evidenceSource)}`;
142
144
  const promotionGaps = buildCapabilityPromotionGaps(capability.runtimeMode, missingEvidence);
143
145
  const gapSuffix = promotionGaps.length > 0
144
146
  ? ` | verified gaps: ${promotionGaps.join(', ')}`
@@ -157,12 +159,12 @@ function renderDoctorReport(report) {
157
159
  }
158
160
  return sections.join('\n');
159
161
  }
160
- function renderCapabilityEvidence(evidence) {
162
+ function renderCapabilityEvidence(evidence, evidenceSource) {
161
163
  return [
162
- `bundle=${evidence.bundle ? 'yes' : 'no'}`,
163
- `debugBuild=${evidence.debugBuild ? 'yes' : 'no'}`,
164
- `device=${evidence.device ? 'yes' : 'no'}`,
165
- `release=${evidence.release ? 'yes' : 'no'}`,
164
+ `bundle=${evidence.bundle ? 'yes' : 'no'}[${evidenceSource.bundle}]`,
165
+ `debugBuild=${evidence.debugBuild ? 'yes' : 'no'}[${evidenceSource.debugBuild}]`,
166
+ `device=${evidence.device ? 'yes' : 'no'}[${evidenceSource.device}]`,
167
+ `release=${evidence.release ? 'yes' : 'no'}[${evidenceSource.release}]`,
166
168
  ].join(', ');
167
169
  }
168
170
  function getMissingCapabilityEvidence(evidence) {
@@ -185,6 +187,7 @@ function createDependencyRecord(name, version, source) {
185
187
  source,
186
188
  status: matrixRecord.status,
187
189
  supportTier: matrixRecord.supportTier,
190
+ buildabilityRisk: 'known',
188
191
  blocking: false,
189
192
  note: matrixRecord.note,
190
193
  replacement: matrixRecord.replacement,
@@ -350,8 +353,14 @@ function buildWarnings(expoConfig, expoSdkVersion, dependencies) {
350
353
  if (dependencies.some((dependency) => dependency.supportTier === 'experimental')) {
351
354
  warnings.push('Experimental-tier dependencies were detected. Expect bridge drift, runtime gaps, or additional manual validation before claiming release readiness.');
352
355
  }
353
- if (dependencies.some((dependency) => dependency.status === 'unknown')) {
354
- warnings.push('Unknown dependencies were detected. The toolkit can scaffold the project, but runtime portability is not guaranteed.');
356
+ if (dependencies.some((dependency) => dependency.buildabilityRisk === 'js-only-unknown')) {
357
+ warnings.push('Some unknown dependencies look JavaScript-only. They remain outside the public matrix, but they are less likely to block bundling or a debug HAP build outright.');
358
+ }
359
+ if (dependencies.some((dependency) => dependency.buildabilityRisk === 'native-risk')) {
360
+ warnings.push('Some unknown dependencies appear to carry native surfaces. Treat them as real Harmony portability risks until they are explicitly onboarded.');
361
+ }
362
+ if (dependencies.some((dependency) => dependency.buildabilityRisk === 'unresolved')) {
363
+ warnings.push('Some unknown dependencies could not be inspected because their installed package metadata was unavailable. Install dependencies before treating the doctor report as a buildability signal.');
355
364
  }
356
365
  return warnings;
357
366
  }
@@ -384,6 +393,20 @@ function matchesVersionRange(rawVersion, range) {
384
393
  function matchesDependencySpecifier(rawSpecifier, expectedSpecifier) {
385
394
  return rawSpecifier.trim() === expectedSpecifier.trim();
386
395
  }
396
+ function renderDependencyBuildabilityRisk(buildabilityRisk) {
397
+ switch (buildabilityRisk) {
398
+ case 'known':
399
+ return 'known';
400
+ case 'js-only-unknown':
401
+ return 'unknown-js';
402
+ case 'native-risk':
403
+ return 'unknown-native';
404
+ case 'unresolved':
405
+ return 'unresolved';
406
+ default:
407
+ return buildabilityRisk;
408
+ }
409
+ }
387
410
  function dedupeIssues(issues) {
388
411
  const seen = new Set();
389
412
  return issues.filter((issue) => {
@@ -4,8 +4,10 @@ type SigningLocalAppFragment = {
4
4
  products?: JsonRecord[];
5
5
  };
6
6
  export declare function getSigningLocalPath(projectRoot: string): string;
7
+ export declare function getSigningLocalExamplePath(projectRoot: string): string;
7
8
  export declare function readSigningLocalConfig(projectRoot: string): Promise<SigningLocalAppFragment | null>;
8
9
  export declare function mergeSigningLocalConfigIntoBuildProfile(rawBuildProfileContents: string, signingLocalConfig: SigningLocalAppFragment | null): string;
9
10
  export declare function hasSigningConfiguration(rawBuildProfileContents: string | null, signingLocalConfig?: SigningLocalAppFragment | null): boolean;
10
11
  export declare function hasSigningLocalConfiguration(signingLocalConfig: SigningLocalAppFragment | null): boolean;
12
+ export declare function renderSigningLocalExampleConfig(): string;
11
13
  export {};
@@ -4,10 +4,12 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
4
4
  };
5
5
  Object.defineProperty(exports, "__esModule", { value: true });
6
6
  exports.getSigningLocalPath = getSigningLocalPath;
7
+ exports.getSigningLocalExamplePath = getSigningLocalExamplePath;
7
8
  exports.readSigningLocalConfig = readSigningLocalConfig;
8
9
  exports.mergeSigningLocalConfigIntoBuildProfile = mergeSigningLocalConfigIntoBuildProfile;
9
10
  exports.hasSigningConfiguration = hasSigningConfiguration;
10
11
  exports.hasSigningLocalConfiguration = hasSigningLocalConfiguration;
12
+ exports.renderSigningLocalExampleConfig = renderSigningLocalExampleConfig;
11
13
  const fs_extra_1 = __importDefault(require("fs-extra"));
12
14
  const json5_1 = __importDefault(require("json5"));
13
15
  const path_1 = __importDefault(require("path"));
@@ -15,6 +17,9 @@ const constants_1 = require("./constants");
15
17
  function getSigningLocalPath(projectRoot) {
16
18
  return path_1.default.join(projectRoot, constants_1.GENERATED_DIR, constants_1.SIGNING_LOCAL_FILENAME);
17
19
  }
20
+ function getSigningLocalExamplePath(projectRoot) {
21
+ return path_1.default.join(projectRoot, constants_1.GENERATED_DIR, constants_1.SIGNING_LOCAL_EXAMPLE_FILENAME);
22
+ }
18
23
  async function readSigningLocalConfig(projectRoot) {
19
24
  const signingLocalPath = getSigningLocalPath(projectRoot);
20
25
  if (!(await fs_extra_1.default.pathExists(signingLocalPath))) {
@@ -49,6 +54,31 @@ function hasSigningConfiguration(rawBuildProfileContents, signingLocalConfig = n
49
54
  function hasSigningLocalConfiguration(signingLocalConfig) {
50
55
  return hasNonEmptySigningConfigList(signingLocalConfig?.signingConfigs);
51
56
  }
57
+ function renderSigningLocalExampleConfig() {
58
+ return (JSON.stringify({
59
+ signingConfigs: [
60
+ {
61
+ name: 'default',
62
+ type: 'HarmonyOS',
63
+ material: {
64
+ storeFile: './signing/release.p12',
65
+ storePassword: '<replace-with-store-password>',
66
+ keyAlias: '<replace-with-key-alias>',
67
+ keyPassword: '<replace-with-key-password>',
68
+ signAlg: 'SHA256withECDSA',
69
+ profile: './signing/release.p7b',
70
+ certpath: './signing/release.cer',
71
+ },
72
+ },
73
+ ],
74
+ products: [
75
+ {
76
+ name: 'default',
77
+ signingConfig: 'default',
78
+ },
79
+ ],
80
+ }, null, 2) + '\n');
81
+ }
52
82
  function normalizeSigningLocalConfig(rawConfig) {
53
83
  const candidate = rawConfig && typeof rawConfig === 'object' && !Array.isArray(rawConfig)
54
84
  ? 'app' in rawConfig &&
@@ -0,0 +1,9 @@
1
+ import { CapabilityDefinition } from '../../types';
2
+ type ManagedExpoHarmonyModuleRenderer = {
3
+ filename: string;
4
+ render: () => string;
5
+ };
6
+ export declare const MANAGED_EXPO_HARMONY_MODULE_RENDERERS: readonly ManagedExpoHarmonyModuleRenderer[];
7
+ export declare function renderCapabilityModuleShim(capability: CapabilityDefinition): string;
8
+ export declare function renderUnsupportedCapabilityShim(capability: CapabilityDefinition): string;
9
+ export {};
@@ -0,0 +1,84 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.MANAGED_EXPO_HARMONY_MODULE_RENDERERS = void 0;
4
+ exports.renderCapabilityModuleShim = renderCapabilityModuleShim;
5
+ exports.renderUnsupportedCapabilityShim = renderUnsupportedCapabilityShim;
6
+ const camera_1 = require("./renderers/camera");
7
+ const fileSystem_1 = require("./renderers/fileSystem");
8
+ const imagePicker_1 = require("./renderers/imagePicker");
9
+ const location_1 = require("./renderers/location");
10
+ const CAPABILITY_SHIM_RENDERERS = {
11
+ 'expo-file-system': {
12
+ adapter: fileSystem_1.renderExpoFileSystemHarmonyAdapterShim,
13
+ preview: fileSystem_1.renderExpoFileSystemPreviewShim,
14
+ },
15
+ 'expo-image-picker': {
16
+ adapter: imagePicker_1.renderExpoImagePickerHarmonyAdapterShim,
17
+ preview: imagePicker_1.renderExpoImagePickerPreviewShim,
18
+ },
19
+ 'expo-location': {
20
+ adapter: location_1.renderExpoLocationHarmonyAdapterShim,
21
+ preview: location_1.renderExpoLocationPreviewShim,
22
+ },
23
+ 'expo-camera': {
24
+ adapter: camera_1.renderExpoCameraHarmonyAdapterShim,
25
+ preview: camera_1.renderExpoCameraPreviewShim,
26
+ },
27
+ };
28
+ exports.MANAGED_EXPO_HARMONY_MODULE_RENDERERS = [
29
+ {
30
+ filename: 'ExpoHarmonyFileSystemTurboModule.ts',
31
+ render: fileSystem_1.renderExpoHarmonyFileSystemTurboModule,
32
+ },
33
+ {
34
+ filename: 'ExpoHarmonyImagePickerTurboModule.ts',
35
+ render: imagePicker_1.renderExpoHarmonyImagePickerTurboModule,
36
+ },
37
+ {
38
+ filename: 'ExpoHarmonyLocationTurboModule.ts',
39
+ render: location_1.renderExpoHarmonyLocationTurboModule,
40
+ },
41
+ {
42
+ filename: 'ExpoHarmonyCameraTurboModule.ts',
43
+ render: camera_1.renderExpoHarmonyCameraTurboModule,
44
+ },
45
+ ];
46
+ function renderCapabilityModuleShim(capability) {
47
+ const renderer = CAPABILITY_SHIM_RENDERERS[capability.packageName];
48
+ if (!renderer) {
49
+ return renderUnsupportedCapabilityShim(capability);
50
+ }
51
+ return capability.runtimeMode !== 'shim'
52
+ ? renderer.adapter(capability)
53
+ : renderer.preview(capability);
54
+ }
55
+ function renderUnsupportedCapabilityShim(capability) {
56
+ return `'use strict';
57
+
58
+ const { CodedError } = require('expo-modules-core');
59
+
60
+ function createPreviewError() {
61
+ return new CodedError(
62
+ 'ERR_EXPO_HARMONY_PREVIEW',
63
+ '${capability.packageName} is classified as ${capability.supportTier} for Harmony, but no managed runtime shim has been wired yet.',
64
+ );
65
+ }
66
+
67
+ function unavailable() {
68
+ throw createPreviewError();
69
+ }
70
+
71
+ module.exports = new Proxy(
72
+ {},
73
+ {
74
+ get(_target, propertyName) {
75
+ if (propertyName === '__esModule') {
76
+ return true;
77
+ }
78
+
79
+ return unavailable;
80
+ },
81
+ },
82
+ );
83
+ `;
84
+ }
@@ -0,0 +1,2 @@
1
+ import { HarmonyIdentifiers } from '../../types';
2
+ export declare function renderExpoModulesCoreHarmonyShim(expoConfig: Record<string, any>, identifiers: HarmonyIdentifiers): string;