@expo-harmony/config-plugins 55.0.10-harmony.1 → 55.0.10-harmony.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 (55) hide show
  1. package/README.md +203 -11
  2. package/build/compiler.d.ts +7 -0
  3. package/build/compiler.js +12 -0
  4. package/build/composition.d.ts +24 -0
  5. package/build/composition.js +11 -0
  6. package/build/config.d.ts +51 -0
  7. package/build/config.js +6 -0
  8. package/build/customFiles.d.ts +15 -0
  9. package/build/customFiles.js +108 -0
  10. package/build/errors.d.ts +11 -0
  11. package/build/errors.js +14 -0
  12. package/build/files.d.ts +6 -0
  13. package/build/files.js +69 -0
  14. package/build/generatedFiles.d.ts +15 -0
  15. package/build/generatedFiles.js +70 -0
  16. package/build/index.d.ts +27 -0
  17. package/build/index.js +52 -6
  18. package/build/internal.d.ts +3 -0
  19. package/build/internal.js +13 -0
  20. package/build/manifest.d.ts +38 -0
  21. package/build/manifest.js +71 -0
  22. package/build/mods.d.ts +57 -0
  23. package/build/mods.js +428 -0
  24. package/build/nativeInputs.d.ts +14 -0
  25. package/build/nativeInputs.js +81 -0
  26. package/build/normalizeConfig.d.ts +35 -0
  27. package/build/normalizeConfig.js +270 -0
  28. package/build/ownership.d.ts +17 -0
  29. package/build/ownership.js +129 -0
  30. package/build/paths.d.ts +64 -0
  31. package/build/paths.js +129 -0
  32. package/build/permissions.d.ts +12 -0
  33. package/build/permissions.js +60 -0
  34. package/build/pluginTypes.d.ts +15 -0
  35. package/build/pluginTypes.js +2 -0
  36. package/build/resources.d.ts +13 -0
  37. package/build/resources.js +55 -0
  38. package/package.json +9 -9
  39. package/src/compiler.ts +21 -0
  40. package/src/composition.ts +45 -0
  41. package/src/config.ts +3 -19
  42. package/src/customFiles.ts +142 -0
  43. package/src/files.ts +3 -4
  44. package/src/generatedFiles.ts +85 -0
  45. package/src/index.ts +19 -11
  46. package/src/internal.ts +3 -0
  47. package/src/manifest.ts +151 -0
  48. package/src/mods.ts +170 -129
  49. package/src/nativeInputs.ts +0 -1
  50. package/src/normalizeConfig.ts +51 -59
  51. package/src/ownership.ts +25 -5
  52. package/src/paths.ts +38 -46
  53. package/src/permissions.ts +68 -0
  54. package/src/pluginTypes.ts +24 -0
  55. package/src/resources.ts +65 -0
@@ -0,0 +1,151 @@
1
+ import type { HarmonyPermission, HarmonySkill } from './config';
2
+ import { HarmonyConfigPluginError } from './errors';
3
+ import { stableJson } from './files';
4
+
5
+ export interface HarmonyMetadata extends Record<string, unknown> {
6
+ name: string;
7
+ value?: string;
8
+ resource?: string;
9
+ }
10
+
11
+ export interface HarmonyAbility extends Record<string, unknown> {
12
+ name: string;
13
+ srcEntry?: string;
14
+ exported?: boolean;
15
+ skills?: HarmonySkill[];
16
+ backgroundModes?: string[];
17
+ metadata?: HarmonyMetadata[];
18
+ }
19
+
20
+ export interface HarmonyExtensionAbility extends HarmonyAbility {
21
+ type: string;
22
+ }
23
+
24
+ export interface HarmonyModule extends Record<string, unknown> {
25
+ name?: string;
26
+ mainElement?: string;
27
+ abilities?: HarmonyAbility[];
28
+ extensionAbilities?: HarmonyExtensionAbility[];
29
+ metadata?: HarmonyMetadata[];
30
+ requestPermissions?: HarmonyPermission[];
31
+ querySchemes?: string[];
32
+ }
33
+
34
+ export interface HarmonyModuleJson extends Record<string, unknown> {
35
+ module?: HarmonyModule;
36
+ }
37
+
38
+ export function getModuleOrThrow(manifest: HarmonyModuleJson): HarmonyModule {
39
+ const module = manifest.module;
40
+ if (!module || typeof module !== 'object' || Array.isArray(module)) {
41
+ throw new HarmonyConfigPluginError(
42
+ 'ERR_HARMONY_MANIFEST_INVALID',
43
+ 'Harmony module.json5 must contain a module object.',
44
+ { operation: 'edit-manifest' }
45
+ );
46
+ }
47
+
48
+ return module;
49
+ }
50
+
51
+ export function getMainAbilityOrThrow(manifest: HarmonyModuleJson, name?: string): HarmonyAbility {
52
+ const module = getModuleOrThrow(manifest);
53
+ const abilities = module.abilities;
54
+ if (!Array.isArray(abilities)) {
55
+ throw new HarmonyConfigPluginError(
56
+ 'ERR_HARMONY_MANIFEST_INVALID',
57
+ 'Harmony module.json5 must declare an abilities array.',
58
+ { operation: 'edit-manifest' }
59
+ );
60
+ }
61
+
62
+ const selected = name ?? module.mainElement ?? abilities[0]?.name;
63
+ const matches = abilities.filter(ability => ability && typeof ability.name === 'string' && ability.name === selected);
64
+ if (matches.length !== 1) {
65
+ throw new HarmonyConfigPluginError(
66
+ 'ERR_HARMONY_MANIFEST_INVALID',
67
+ `Expected exactly one Harmony Ability '${selected ?? ''}', found ${matches.length}.`,
68
+ { operation: 'edit-manifest' }
69
+ );
70
+ }
71
+
72
+ return matches[0];
73
+ }
74
+
75
+ export function setMetadata(target: { metadata?: HarmonyMetadata[] }, item: HarmonyMetadata): void {
76
+ if (!item || typeof item.name !== 'string' || !item.name.trim()) {
77
+ throw new HarmonyConfigPluginError(
78
+ 'ERR_HARMONY_MANIFEST_INVALID',
79
+ 'Metadata must have a non-empty name.',
80
+ { operation: 'edit-manifest' }
81
+ );
82
+ }
83
+ if (target.metadata !== undefined && !Array.isArray(target.metadata)) {
84
+ throw new HarmonyConfigPluginError(
85
+ 'ERR_HARMONY_MANIFEST_INVALID',
86
+ 'metadata must be an array.',
87
+ { operation: 'edit-manifest' }
88
+ );
89
+ }
90
+
91
+ const items = target.metadata ?? [];
92
+ const existing = items.find(value => value?.name === item.name);
93
+ target.metadata = [...items.filter(value => value?.name !== item.name), { ...existing, ...item }];
94
+ }
95
+
96
+ export function removeMetadata(target: { metadata?: HarmonyMetadata[] }, name: string): void {
97
+ if (target.metadata !== undefined && !Array.isArray(target.metadata)) {
98
+ throw new HarmonyConfigPluginError(
99
+ 'ERR_HARMONY_MANIFEST_INVALID',
100
+ 'metadata must be an array.',
101
+ { operation: 'edit-manifest' }
102
+ );
103
+ }
104
+
105
+ if (target.metadata) target.metadata = target.metadata.filter(item => item?.name !== name);
106
+ }
107
+
108
+ export function ensureExtensionAbility(manifest: HarmonyModuleJson, ability: HarmonyExtensionAbility): void {
109
+ if (!ability || typeof ability.name !== 'string' || !ability.name.trim()
110
+ || typeof ability.type !== 'string' || !ability.type.trim()) {
111
+ throw new HarmonyConfigPluginError(
112
+ 'ERR_HARMONY_MANIFEST_INVALID',
113
+ 'An extension Ability must have a non-empty name and type.',
114
+ { operation: 'edit-manifest' }
115
+ );
116
+ }
117
+
118
+ const module = getModuleOrThrow(manifest);
119
+ if (module.extensionAbilities !== undefined && !Array.isArray(module.extensionAbilities)) {
120
+ throw new HarmonyConfigPluginError(
121
+ 'ERR_HARMONY_MANIFEST_INVALID',
122
+ 'module.extensionAbilities must be an array.',
123
+ { operation: 'edit-manifest' }
124
+ );
125
+ }
126
+
127
+ const abilities = module.extensionAbilities ?? [];
128
+ const matches = abilities.filter(value => value?.name === ability.name);
129
+ if (matches.length > 1) {
130
+ throw new HarmonyConfigPluginError(
131
+ 'ERR_HARMONY_MANIFEST_INVALID',
132
+ `Harmony module declares ${ability.name} more than once.`,
133
+ { operation: 'edit-manifest' }
134
+ );
135
+ }
136
+ if (matches.length === 1) {
137
+ for (const [key, value] of Object.entries(ability)) {
138
+ if (stableJson(matches[0][key]) !== stableJson(value)) {
139
+ throw new HarmonyConfigPluginError(
140
+ 'ERR_HARMONY_MANIFEST_INVALID',
141
+ `Harmony extension Ability '${ability.name}' has an incompatible ${key}.`,
142
+ { operation: 'edit-manifest' }
143
+ );
144
+ }
145
+ }
146
+
147
+ return;
148
+ }
149
+
150
+ module.extensionAbilities = [...abilities, structuredClone(ability)];
151
+ }