expo-harmony-toolkit 1.5.0

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 (83) hide show
  1. package/LICENSE +21 -0
  2. package/README.en.md +197 -0
  3. package/README.md +197 -0
  4. package/app.plugin.js +1 -0
  5. package/bin/expo-harmony.js +9 -0
  6. package/build/cli.d.ts +1 -0
  7. package/build/cli.js +56 -0
  8. package/build/commands/buildHap.d.ts +5 -0
  9. package/build/commands/buildHap.js +26 -0
  10. package/build/commands/bundle.d.ts +4 -0
  11. package/build/commands/bundle.js +18 -0
  12. package/build/commands/doctor.d.ts +7 -0
  13. package/build/commands/doctor.js +24 -0
  14. package/build/commands/env.d.ts +5 -0
  15. package/build/commands/env.js +22 -0
  16. package/build/commands/init.d.ts +5 -0
  17. package/build/commands/init.js +29 -0
  18. package/build/commands/syncTemplate.d.ts +5 -0
  19. package/build/commands/syncTemplate.js +23 -0
  20. package/build/core/build.d.ts +25 -0
  21. package/build/core/build.js +434 -0
  22. package/build/core/constants.d.ts +21 -0
  23. package/build/core/constants.js +32 -0
  24. package/build/core/env.d.ts +8 -0
  25. package/build/core/env.js +185 -0
  26. package/build/core/metadata.d.ts +9 -0
  27. package/build/core/metadata.js +54 -0
  28. package/build/core/project.d.ts +18 -0
  29. package/build/core/project.js +206 -0
  30. package/build/core/report.d.ts +4 -0
  31. package/build/core/report.js +319 -0
  32. package/build/core/template.d.ts +6 -0
  33. package/build/core/template.js +1030 -0
  34. package/build/data/compatibilityMatrix.d.ts +2 -0
  35. package/build/data/compatibilityMatrix.js +99 -0
  36. package/build/data/dependencyCatalog.d.ts +2 -0
  37. package/build/data/dependencyCatalog.js +108 -0
  38. package/build/data/uiStack.d.ts +39 -0
  39. package/build/data/uiStack.js +48 -0
  40. package/build/data/validatedMatrices.d.ts +3 -0
  41. package/build/data/validatedMatrices.js +94 -0
  42. package/build/index.d.ts +4 -0
  43. package/build/index.js +27 -0
  44. package/build/plugin.d.ts +7 -0
  45. package/build/plugin.js +76 -0
  46. package/build/types.d.ts +182 -0
  47. package/build/types.js +2 -0
  48. package/docs/cli-build.md +99 -0
  49. package/docs/npm-release.md +89 -0
  50. package/docs/official-app-shell-sample.md +39 -0
  51. package/docs/official-minimal-sample.md +32 -0
  52. package/docs/official-ui-stack-sample.md +77 -0
  53. package/docs/roadmap.md +67 -0
  54. package/docs/signing-and-release.md +57 -0
  55. package/docs/support-matrix.md +149 -0
  56. package/package.json +78 -0
  57. package/templates/harmony/AppScope/app.json5 +10 -0
  58. package/templates/harmony/AppScope/resources/base/element/string.json +8 -0
  59. package/templates/harmony/AppScope/resources/base/media/app_icon.png +0 -0
  60. package/templates/harmony/README.md +31 -0
  61. package/templates/harmony/build-profile.json5 +37 -0
  62. package/templates/harmony/codelinter.json +19 -0
  63. package/templates/harmony/entry/build-profile.json5 +18 -0
  64. package/templates/harmony/entry/hvigorfile.ts +13 -0
  65. package/templates/harmony/entry/oh-package.json5 +14 -0
  66. package/templates/harmony/entry/src/main/cpp/CMakeLists.txt +55 -0
  67. package/templates/harmony/entry/src/main/cpp/PackageProvider.cpp +12 -0
  68. package/templates/harmony/entry/src/main/ets/PackageProvider.ets +6 -0
  69. package/templates/harmony/entry/src/main/ets/entryability/EntryAbility.ets +11 -0
  70. package/templates/harmony/entry/src/main/ets/pages/Index.ets +42 -0
  71. package/templates/harmony/entry/src/main/ets/workers/RNOHWorker.ets +8 -0
  72. package/templates/harmony/entry/src/main/module.json5 +31 -0
  73. package/templates/harmony/entry/src/main/resources/base/element/color.json +8 -0
  74. package/templates/harmony/entry/src/main/resources/base/element/string.json +16 -0
  75. package/templates/harmony/entry/src/main/resources/base/media/background.png +0 -0
  76. package/templates/harmony/entry/src/main/resources/base/media/foreground.png +0 -0
  77. package/templates/harmony/entry/src/main/resources/base/media/layered_image.json +6 -0
  78. package/templates/harmony/entry/src/main/resources/base/media/startIcon.png +0 -0
  79. package/templates/harmony/entry/src/main/resources/base/profile/main_pages.json +5 -0
  80. package/templates/harmony/entry/src/main/resources/rawfile/.gitkeep +1 -0
  81. package/templates/harmony/hvigor/hvigor-config.json5 +10 -0
  82. package/templates/harmony/hvigorfile.ts +7 -0
  83. package/templates/harmony/oh-package.json5 +13 -0
@@ -0,0 +1,2 @@
1
+ import { CompatibilityRecord } from '../types';
2
+ export declare const COMPATIBILITY_MATRIX: Record<string, CompatibilityRecord>;
@@ -0,0 +1,99 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.COMPATIBILITY_MATRIX = void 0;
4
+ exports.COMPATIBILITY_MATRIX = {
5
+ expo: {
6
+ status: 'supported',
7
+ note: 'Toolkit can parse Expo config and scaffold Harmony sidecar files for managed/CNG projects.',
8
+ },
9
+ '@babel/runtime': {
10
+ status: 'supported',
11
+ note: 'Runtime helpers are required for offline bundling in the official minimal sample.',
12
+ },
13
+ '@react-native-community/cli': {
14
+ status: 'supported',
15
+ note: 'The React Native CLI is required to expose the bundle-harmony command in the official sample chain.',
16
+ },
17
+ '@react-native-oh/react-native-harmony': {
18
+ status: 'supported',
19
+ note: 'This is the RNOH runtime package used by the vendored Harmony sidecar template.',
20
+ },
21
+ '@react-native-oh/react-native-harmony-cli': {
22
+ status: 'supported',
23
+ note: 'This package provides the bundle-harmony command used by the official minimal sample.',
24
+ },
25
+ react: {
26
+ status: 'supported',
27
+ note: 'React is treated as a baseline JavaScript dependency.',
28
+ },
29
+ 'react-native': {
30
+ status: 'supported',
31
+ note: 'React Native is supported as managed Expo input, but runtime portability is not guaranteed.',
32
+ },
33
+ metro: {
34
+ status: 'supported',
35
+ note: 'Metro is part of the official sample bundling chain.',
36
+ },
37
+ 'expo-asset': {
38
+ status: 'manual',
39
+ note: 'Asset handling often needs Harmony-specific verification after bundling.',
40
+ },
41
+ 'expo-constants': {
42
+ status: 'manual',
43
+ note: 'Usually reachable from JavaScript, but runtime assumptions still need verification on Harmony.',
44
+ },
45
+ 'expo-linking': {
46
+ status: 'manual',
47
+ note: 'Deep-link integration needs Harmony-side routing and intent validation.',
48
+ },
49
+ 'expo-router': {
50
+ status: 'manual',
51
+ note: 'The router can stay at the JS layer, but native navigation dependencies still need validation.',
52
+ },
53
+ 'expo-camera': {
54
+ status: 'unknown',
55
+ note: 'No verified Harmony migration path is shipped in v0.1.',
56
+ },
57
+ 'expo-status-bar': {
58
+ status: 'supported',
59
+ note: 'Status bar rendering stays in the JavaScript/UI layer for the official minimal sample.',
60
+ },
61
+ 'expo-file-system': {
62
+ status: 'unknown',
63
+ note: 'File-system APIs need a verified Harmony implementation before they can be treated as supported.',
64
+ },
65
+ 'expo-image-picker': {
66
+ status: 'unknown',
67
+ note: 'Media-picker flows need dedicated Harmony integration and testing.',
68
+ },
69
+ 'expo-location': {
70
+ status: 'unknown',
71
+ note: 'Location permissions and runtime hooks are not validated in v0.1.',
72
+ },
73
+ 'expo-notifications': {
74
+ status: 'unknown',
75
+ note: 'Notifications need platform-specific services that are out of scope for v0.1.',
76
+ },
77
+ 'react-native-gesture-handler': {
78
+ status: 'manual',
79
+ note: 'A Harmony adaptation exists, but this toolkit does not auto-wire it yet.',
80
+ replacement: 'react-native-oh-library/react-native-harmony-gesture-handler',
81
+ docsUrl: 'https://github.com/react-native-oh-library/react-native-harmony-gesture-handler',
82
+ },
83
+ 'react-native-reanimated': {
84
+ status: 'manual',
85
+ note: 'A Harmony adaptation exists, but integration must be verified app by app.',
86
+ replacement: 'react-native-oh-library/react-native-harmony-reanimated',
87
+ docsUrl: 'https://github.com/react-native-oh-library/react-native-harmony-reanimated',
88
+ },
89
+ 'react-native-svg': {
90
+ status: 'manual',
91
+ note: 'A Harmony adaptation exists, but this toolkit does not patch it automatically.',
92
+ replacement: 'react-native-oh-library/react-native-harmony-svg',
93
+ docsUrl: 'https://github.com/react-native-oh-library/react-native-harmony-svg',
94
+ },
95
+ 'expo-build-properties': {
96
+ status: 'manual',
97
+ note: 'Native property overrides should be reviewed manually because Harmony uses a separate sidecar project.',
98
+ },
99
+ };
@@ -0,0 +1,2 @@
1
+ import { CompatibilityRecord } from '../types';
2
+ export declare const DEPENDENCY_CATALOG: Record<string, CompatibilityRecord>;
@@ -0,0 +1,108 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.DEPENDENCY_CATALOG = void 0;
4
+ const constants_1 = require("../core/constants");
5
+ const uiStack_1 = require("./uiStack");
6
+ const UI_STACK_COMPATIBILITY_RECORDS = Object.fromEntries(uiStack_1.UI_STACK_VALIDATED_ADAPTERS.flatMap((entry) => [
7
+ [
8
+ entry.canonicalPackageName,
9
+ {
10
+ status: 'supported',
11
+ note: `Supported in the validated UI-stack matrix when paired with ${entry.adapterPackageName} and the managed Harmony autolinking output.`,
12
+ replacement: entry.adapterPackageName,
13
+ docsUrl: entry.docsUrl,
14
+ },
15
+ ],
16
+ [
17
+ entry.adapterPackageName,
18
+ {
19
+ status: 'supported',
20
+ note: `Harmony adapter pinned to ${entry.adapterVersion}. The validated matrix requires the exact Git spec ${(0, uiStack_1.getUiStackAdapterSpecifier)(entry)}.`,
21
+ replacement: entry.canonicalPackageName,
22
+ docsUrl: entry.docsUrl,
23
+ },
24
+ ],
25
+ ]));
26
+ exports.DEPENDENCY_CATALOG = {
27
+ [constants_1.TOOLKIT_PACKAGE_NAME]: {
28
+ status: 'supported',
29
+ note: 'The published toolkit package may be installed locally to provide the CLI and config plugin inside a validated project.',
30
+ },
31
+ expo: {
32
+ status: 'supported',
33
+ note: 'Toolkit can parse Expo config and scaffold Harmony sidecar files for managed/CNG projects.',
34
+ },
35
+ '@babel/runtime': {
36
+ status: 'supported',
37
+ note: 'Runtime helpers are used by the official minimal sample bundling chain.',
38
+ },
39
+ '@react-native-community/cli': {
40
+ status: 'supported',
41
+ note: 'The React Native CLI exposes the bundle-harmony command used by the official sample.',
42
+ },
43
+ '@react-native-oh/react-native-harmony': {
44
+ status: 'supported',
45
+ note: 'This is the RNOH runtime package used by the vendored Harmony sidecar template.',
46
+ },
47
+ '@react-native-oh/react-native-harmony-cli': {
48
+ status: 'supported',
49
+ note: 'This package provides the bundle-harmony command used by the official minimal sample.',
50
+ },
51
+ react: {
52
+ status: 'supported',
53
+ note: 'React is treated as a baseline JavaScript dependency.',
54
+ },
55
+ 'react-native': {
56
+ status: 'supported',
57
+ note: 'React Native is supported as managed Expo input, but runtime portability is only promised inside the validated matrix.',
58
+ },
59
+ metro: {
60
+ status: 'supported',
61
+ note: 'Metro is part of the official sample bundling chain.',
62
+ },
63
+ 'expo-status-bar': {
64
+ status: 'supported',
65
+ note: 'Status bar rendering stays in the JavaScript/UI layer for the official minimal sample.',
66
+ },
67
+ 'expo-asset': {
68
+ status: 'manual',
69
+ note: 'Asset handling often needs Harmony-specific verification after bundling.',
70
+ },
71
+ 'expo-build-properties': {
72
+ status: 'manual',
73
+ note: 'Native property overrides should be reviewed manually because Harmony uses a separate sidecar project.',
74
+ },
75
+ 'expo-constants': {
76
+ status: 'supported',
77
+ note: 'Constants reads are treated as part of the validated App Shell matrix when they stay in the JavaScript layer.',
78
+ },
79
+ 'expo-linking': {
80
+ status: 'supported',
81
+ note: 'URL generation and JS-layer linking are treated as part of the validated App Shell matrix.',
82
+ },
83
+ 'expo-router': {
84
+ status: 'supported',
85
+ note: 'File-based routing is treated as part of the validated App Shell matrix when router peers, scheme, and plugin config are present.',
86
+ },
87
+ ...UI_STACK_COMPATIBILITY_RECORDS,
88
+ 'expo-camera': {
89
+ status: 'unknown',
90
+ note: 'No verified Harmony migration path is shipped in v1.0.',
91
+ },
92
+ 'expo-file-system': {
93
+ status: 'unknown',
94
+ note: 'File-system APIs need a verified Harmony implementation before they can be treated as supported.',
95
+ },
96
+ 'expo-image-picker': {
97
+ status: 'unknown',
98
+ note: 'Media-picker flows need dedicated Harmony integration and testing.',
99
+ },
100
+ 'expo-location': {
101
+ status: 'unknown',
102
+ note: 'Location permissions and runtime hooks are not validated in v1.0.',
103
+ },
104
+ 'expo-notifications': {
105
+ status: 'unknown',
106
+ note: 'Notifications need platform-specific services that are out of scope for v1.0.',
107
+ },
108
+ };
@@ -0,0 +1,39 @@
1
+ export declare const UI_STACK_VALIDATED_ADAPTERS: readonly [{
2
+ readonly canonicalPackageName: "react-native-reanimated";
3
+ readonly canonicalVersion: "3.6.0";
4
+ readonly adapterPackageName: "@react-native-oh-tpl/react-native-reanimated";
5
+ readonly adapterVersion: "3.6.4-rc.5";
6
+ readonly adapterRepository: "react-native-oh-library/react-native-harmony-reanimated";
7
+ readonly adapterPath: "react-native-harmony-reanimated";
8
+ readonly adapterCommit: "9fdbe676209937383907be0592291223c6ca7ad7";
9
+ readonly harmonyHarFileName: "reanimated.har";
10
+ readonly supportsAutolinking: false;
11
+ readonly docsUrl: "https://github.com/react-native-oh-library/react-native-harmony-reanimated";
12
+ }, {
13
+ readonly canonicalPackageName: "react-native-svg";
14
+ readonly canonicalVersion: "15.0.0";
15
+ readonly adapterPackageName: "@react-native-oh-tpl/react-native-svg";
16
+ readonly adapterVersion: "15.0.1-rc.12";
17
+ readonly adapterRepository: "react-native-oh-library/react-native-harmony-svg";
18
+ readonly adapterPath: "react-native-harmony-svg";
19
+ readonly adapterCommit: "97c31d2f72559931d62fa84a9c86e86d343753d3";
20
+ readonly harmonyHarFileName: "svg.har";
21
+ readonly supportsAutolinking: false;
22
+ readonly docsUrl: "https://github.com/react-native-oh-library/react-native-harmony-svg";
23
+ }, {
24
+ readonly canonicalPackageName: "react-native-gesture-handler";
25
+ readonly canonicalVersion: "2.14.1";
26
+ readonly adapterPackageName: "@react-native-oh-tpl/react-native-gesture-handler";
27
+ readonly adapterVersion: "2.14.17-rc.2";
28
+ readonly adapterRepository: "react-native-oh-library/react-native-harmony-gesture-handler";
29
+ readonly adapterPath: "react-native-harmony-gesture-handler";
30
+ readonly adapterCommit: "ed5bcf2ada6e83f9ec0d50cf239c8d84db3c6462";
31
+ readonly harmonyHarFileName: "gesture_handler.har";
32
+ readonly supportsAutolinking: true;
33
+ readonly docsUrl: "https://github.com/react-native-oh-library/react-native-harmony-gesture-handler";
34
+ }];
35
+ export type UiStackValidatedAdapter = (typeof UI_STACK_VALIDATED_ADAPTERS)[number];
36
+ export declare const UI_STACK_CANONICAL_TO_ADAPTER: Record<string, string>;
37
+ export declare const UI_STACK_ADAPTER_TO_CANONICAL: Record<string, string>;
38
+ export declare const UI_STACK_ADAPTER_PACKAGE_NAMES: ("@react-native-oh-tpl/react-native-reanimated" | "@react-native-oh-tpl/react-native-svg" | "@react-native-oh-tpl/react-native-gesture-handler")[];
39
+ export declare function getUiStackAdapterSpecifier(adapter: UiStackValidatedAdapter): string;
@@ -0,0 +1,48 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.UI_STACK_ADAPTER_PACKAGE_NAMES = exports.UI_STACK_ADAPTER_TO_CANONICAL = exports.UI_STACK_CANONICAL_TO_ADAPTER = exports.UI_STACK_VALIDATED_ADAPTERS = void 0;
4
+ exports.getUiStackAdapterSpecifier = getUiStackAdapterSpecifier;
5
+ exports.UI_STACK_VALIDATED_ADAPTERS = [
6
+ {
7
+ canonicalPackageName: 'react-native-reanimated',
8
+ canonicalVersion: '3.6.0',
9
+ adapterPackageName: '@react-native-oh-tpl/react-native-reanimated',
10
+ adapterVersion: '3.6.4-rc.5',
11
+ adapterRepository: 'react-native-oh-library/react-native-harmony-reanimated',
12
+ adapterPath: 'react-native-harmony-reanimated',
13
+ adapterCommit: '9fdbe676209937383907be0592291223c6ca7ad7',
14
+ harmonyHarFileName: 'reanimated.har',
15
+ supportsAutolinking: false,
16
+ docsUrl: 'https://github.com/react-native-oh-library/react-native-harmony-reanimated',
17
+ },
18
+ {
19
+ canonicalPackageName: 'react-native-svg',
20
+ canonicalVersion: '15.0.0',
21
+ adapterPackageName: '@react-native-oh-tpl/react-native-svg',
22
+ adapterVersion: '15.0.1-rc.12',
23
+ adapterRepository: 'react-native-oh-library/react-native-harmony-svg',
24
+ adapterPath: 'react-native-harmony-svg',
25
+ adapterCommit: '97c31d2f72559931d62fa84a9c86e86d343753d3',
26
+ harmonyHarFileName: 'svg.har',
27
+ supportsAutolinking: false,
28
+ docsUrl: 'https://github.com/react-native-oh-library/react-native-harmony-svg',
29
+ },
30
+ {
31
+ canonicalPackageName: 'react-native-gesture-handler',
32
+ canonicalVersion: '2.14.1',
33
+ adapterPackageName: '@react-native-oh-tpl/react-native-gesture-handler',
34
+ adapterVersion: '2.14.17-rc.2',
35
+ adapterRepository: 'react-native-oh-library/react-native-harmony-gesture-handler',
36
+ adapterPath: 'react-native-harmony-gesture-handler',
37
+ adapterCommit: 'ed5bcf2ada6e83f9ec0d50cf239c8d84db3c6462',
38
+ harmonyHarFileName: 'gesture_handler.har',
39
+ supportsAutolinking: true,
40
+ docsUrl: 'https://github.com/react-native-oh-library/react-native-harmony-gesture-handler',
41
+ },
42
+ ];
43
+ exports.UI_STACK_CANONICAL_TO_ADAPTER = Object.fromEntries(exports.UI_STACK_VALIDATED_ADAPTERS.map((entry) => [entry.canonicalPackageName, entry.adapterPackageName]));
44
+ exports.UI_STACK_ADAPTER_TO_CANONICAL = Object.fromEntries(exports.UI_STACK_VALIDATED_ADAPTERS.map((entry) => [entry.adapterPackageName, entry.canonicalPackageName]));
45
+ exports.UI_STACK_ADAPTER_PACKAGE_NAMES = exports.UI_STACK_VALIDATED_ADAPTERS.map((entry) => entry.adapterPackageName);
46
+ function getUiStackAdapterSpecifier(adapter) {
47
+ return `github:${adapter.adapterRepository}#${adapter.adapterCommit}&path:${adapter.adapterPath}`;
48
+ }
@@ -0,0 +1,3 @@
1
+ import { ValidatedReleaseMatrix } from '../types';
2
+ export declare const DEFAULT_VALIDATED_MATRIX_ID = "expo55-rnoh082-ui-stack";
3
+ export declare const VALIDATED_RELEASE_MATRICES: Record<string, ValidatedReleaseMatrix>;
@@ -0,0 +1,94 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.VALIDATED_RELEASE_MATRICES = exports.DEFAULT_VALIDATED_MATRIX_ID = void 0;
4
+ const constants_1 = require("../core/constants");
5
+ const uiStack_1 = require("./uiStack");
6
+ exports.DEFAULT_VALIDATED_MATRIX_ID = 'expo55-rnoh082-ui-stack';
7
+ const BASE_ALLOWED_DEPENDENCIES = [
8
+ 'expo',
9
+ 'expo-constants',
10
+ 'expo-linking',
11
+ 'expo-router',
12
+ 'react',
13
+ 'react-native',
14
+ 'expo-status-bar',
15
+ '@babel/runtime',
16
+ '@react-native-community/cli',
17
+ 'metro',
18
+ '@react-native-oh/react-native-harmony',
19
+ '@react-native-oh/react-native-harmony-cli',
20
+ constants_1.TOOLKIT_PACKAGE_NAME,
21
+ ];
22
+ exports.VALIDATED_RELEASE_MATRICES = {
23
+ [exports.DEFAULT_VALIDATED_MATRIX_ID]: {
24
+ id: exports.DEFAULT_VALIDATED_MATRIX_ID,
25
+ expoSdkVersion: 55,
26
+ nativeIdentifierRequirement: 'android_or_ios',
27
+ allowedDependencies: [
28
+ ...BASE_ALLOWED_DEPENDENCIES,
29
+ ...uiStack_1.UI_STACK_VALIDATED_ADAPTERS.flatMap((entry) => [
30
+ entry.canonicalPackageName,
31
+ entry.adapterPackageName,
32
+ ]),
33
+ ],
34
+ dependencyRules: {
35
+ expo: {
36
+ required: true,
37
+ version: '>=55.0.0 <56.0.0',
38
+ },
39
+ 'expo-constants': {
40
+ version: '>=55.0.0 <56.0.0',
41
+ },
42
+ 'expo-linking': {
43
+ version: '>=55.0.0 <56.0.0',
44
+ },
45
+ 'expo-router': {
46
+ version: '>=6.0.0 <7.0.0',
47
+ },
48
+ react: {
49
+ required: true,
50
+ version: '>=19.2.0 <19.3.0',
51
+ },
52
+ 'react-native': {
53
+ required: true,
54
+ version: '>=0.83.0 <0.84.0',
55
+ },
56
+ '@react-native-oh/react-native-harmony': {
57
+ required: true,
58
+ version: '0.82.18',
59
+ },
60
+ '@react-native-oh/react-native-harmony-cli': {
61
+ required: true,
62
+ version: '0.82.18',
63
+ },
64
+ '@react-native-community/cli': {
65
+ required: true,
66
+ version: '>=20.0.0 <21.0.0',
67
+ },
68
+ metro: {
69
+ required: true,
70
+ version: '>=0.83.0 <0.84.0',
71
+ },
72
+ '@babel/runtime': {
73
+ version: '>=7.0.0 <8.0.0',
74
+ },
75
+ 'expo-status-bar': {
76
+ version: '>=3.0.0 <4.0.0',
77
+ },
78
+ ...Object.fromEntries(uiStack_1.UI_STACK_VALIDATED_ADAPTERS.flatMap((entry) => [
79
+ [
80
+ entry.canonicalPackageName,
81
+ {
82
+ version: entry.canonicalVersion,
83
+ },
84
+ ],
85
+ [
86
+ entry.adapterPackageName,
87
+ {
88
+ specifier: (0, uiStack_1.getUiStackAdapterSpecifier)(entry),
89
+ },
90
+ ],
91
+ ])),
92
+ },
93
+ },
94
+ };
@@ -0,0 +1,4 @@
1
+ export { default } from './plugin';
2
+ export { default as withExpoHarmony } from './plugin';
3
+ export { run } from './cli';
4
+ export * from './types';
package/build/index.js ADDED
@@ -0,0 +1,27 @@
1
+ "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __exportStar = (this && this.__exportStar) || function(m, exports) {
14
+ for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
15
+ };
16
+ var __importDefault = (this && this.__importDefault) || function (mod) {
17
+ return (mod && mod.__esModule) ? mod : { "default": mod };
18
+ };
19
+ Object.defineProperty(exports, "__esModule", { value: true });
20
+ exports.run = exports.withExpoHarmony = exports.default = void 0;
21
+ var plugin_1 = require("./plugin");
22
+ Object.defineProperty(exports, "default", { enumerable: true, get: function () { return __importDefault(plugin_1).default; } });
23
+ var plugin_2 = require("./plugin");
24
+ Object.defineProperty(exports, "withExpoHarmony", { enumerable: true, get: function () { return __importDefault(plugin_2).default; } });
25
+ var cli_1 = require("./cli");
26
+ Object.defineProperty(exports, "run", { enumerable: true, get: function () { return cli_1.run; } });
27
+ __exportStar(require("./types"), exports);
@@ -0,0 +1,7 @@
1
+ import { ConfigPlugin } from 'expo/config-plugins';
2
+ import { ExpoHarmonyPluginProps, HarmonyIdentifiers } from './types';
3
+ export declare const withExpoHarmony: ConfigPlugin<ExpoHarmonyPluginProps>;
4
+ export declare function buildPrebuildMetadata(config: Record<string, any>, identifiers: HarmonyIdentifiers, props?: ExpoHarmonyPluginProps): Record<string, any>;
5
+ export declare function validatePluginProps(props: ExpoHarmonyPluginProps): void;
6
+ declare const _default: ConfigPlugin<ExpoHarmonyPluginProps>;
7
+ export default _default;
@@ -0,0 +1,76 @@
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.withExpoHarmony = void 0;
7
+ exports.buildPrebuildMetadata = buildPrebuildMetadata;
8
+ exports.validatePluginProps = validatePluginProps;
9
+ const fs_extra_1 = __importDefault(require("fs-extra"));
10
+ const path_1 = __importDefault(require("path"));
11
+ const config_plugins_1 = require("expo/config-plugins");
12
+ const validatedMatrices_1 = require("./data/validatedMatrices");
13
+ const constants_1 = require("./core/constants");
14
+ const project_1 = require("./core/project");
15
+ const project_2 = require("./core/project");
16
+ const withExpoHarmony = (config, props = {}) => {
17
+ validatePluginProps(props);
18
+ const identifiers = (0, project_1.deriveHarmonyIdentifiers)(config, undefined, props);
19
+ config.extra = {
20
+ ...(config.extra ?? {}),
21
+ expoHarmony: {
22
+ bundleName: identifiers.bundleName,
23
+ entryModuleName: identifiers.entryModuleName,
24
+ templateVersion: props.templateVersion ?? constants_1.TEMPLATE_VERSION,
25
+ overwrite: props.overwrite ?? false,
26
+ },
27
+ };
28
+ config = registerMetadataDangerousMod(config, 'android', identifiers, props);
29
+ config = registerMetadataDangerousMod(config, 'ios', identifiers, props);
30
+ return config;
31
+ };
32
+ exports.withExpoHarmony = withExpoHarmony;
33
+ function buildPrebuildMetadata(config, identifiers, props = {}) {
34
+ return {
35
+ generatedAt: new Date().toISOString(),
36
+ generatedBy: `${constants_1.TOOLKIT_PACKAGE_NAME}@${constants_1.TOOLKIT_VERSION}`,
37
+ matrixId: validatedMatrices_1.DEFAULT_VALIDATED_MATRIX_ID,
38
+ templateVersion: props.templateVersion ?? constants_1.TEMPLATE_VERSION,
39
+ app: {
40
+ name: config.name ?? null,
41
+ slug: config.slug ?? null,
42
+ version: config.version ?? null,
43
+ schemes: (0, project_2.collectExpoSchemes)(config),
44
+ plugins: (0, project_2.collectExpoPlugins)(config),
45
+ },
46
+ identifiers,
47
+ props: {
48
+ overwrite: props.overwrite ?? false,
49
+ },
50
+ };
51
+ }
52
+ function registerMetadataDangerousMod(config, platform, identifiers, props) {
53
+ return (0, config_plugins_1.withDangerousMod)(config, [
54
+ platform,
55
+ async (currentConfig) => {
56
+ const metadata = buildPrebuildMetadata(currentConfig, identifiers, props);
57
+ const projectRoot = currentConfig.modRequest.projectRoot;
58
+ const targetPath = path_1.default.join(projectRoot, constants_1.GENERATED_DIR, constants_1.PREBUILD_METADATA_FILENAME);
59
+ await fs_extra_1.default.ensureDir(path_1.default.dirname(targetPath));
60
+ await fs_extra_1.default.writeJson(targetPath, metadata, { spaces: 2 });
61
+ return currentConfig;
62
+ },
63
+ ]);
64
+ }
65
+ function validatePluginProps(props) {
66
+ if (props.bundleName !== undefined && !/^[a-zA-Z][a-zA-Z0-9_.]+$/.test(props.bundleName)) {
67
+ throw new Error('[expo-harmony-toolkit] bundleName must be a valid identifier such as com.example.app');
68
+ }
69
+ if (props.entryModuleName !== undefined && props.entryModuleName.trim().length === 0) {
70
+ throw new Error('[expo-harmony-toolkit] entryModuleName cannot be empty');
71
+ }
72
+ if (props.templateVersion !== undefined && props.templateVersion.trim().length === 0) {
73
+ throw new Error('[expo-harmony-toolkit] templateVersion cannot be empty');
74
+ }
75
+ }
76
+ exports.default = (0, config_plugins_1.createRunOncePlugin)(exports.withExpoHarmony, constants_1.TOOLKIT_PACKAGE_NAME, constants_1.TOOLKIT_VERSION);