@expofp/loader 1.0.78 → 1.0.91

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 (96) hide show
  1. package/dist/bundle/ImportHttpRuntime.node-B85BNHJG.js +92 -0
  2. package/dist/bundle/ImportHttpRuntime.node-B85BNHJG.js.map +1 -0
  3. package/dist/bundle/bundle.js +236 -768
  4. package/dist/bundle/bundle.js.map +1 -1
  5. package/dist/bundle/fetch-retry.umd-g1itNdNw.js +115 -0
  6. package/dist/bundle/fetch-retry.umd-g1itNdNw.js.map +1 -0
  7. package/dist/esm/ImportHttpRuntime.node.d.ts +28 -0
  8. package/dist/esm/ImportHttpRuntime.node.js +139 -0
  9. package/dist/esm/_OLD_resolveRuntimeUrl.d.ts +1 -0
  10. package/dist/esm/_OLD_resolveRuntimeUrl.js +10 -0
  11. package/dist/esm/fetch.d.ts +1 -0
  12. package/dist/esm/fetch.js +14 -0
  13. package/dist/esm/importHttpRuntime.d.ts +1 -0
  14. package/dist/esm/importHttpRuntime.js +12 -0
  15. package/dist/esm/index.d.ts +10 -7
  16. package/dist/esm/index.js +40 -19
  17. package/dist/esm/resolve.d.ts +10 -44
  18. package/dist/esm/resolve.js +91 -295
  19. package/dist/esm/types.d.ts +11 -26
  20. package/package.json +3 -1
  21. package/dist/bundle/cssTextAssetResolver.offlineFunc-CWvHnYni.js +0 -19
  22. package/dist/bundle/cssTextAssetResolver.offlineFunc-CWvHnYni.js.map +0 -1
  23. package/dist/bundle/downloadOfflineZip-CNz_lUGZ.js +0 -2344
  24. package/dist/bundle/downloadOfflineZip-CNz_lUGZ.js.map +0 -1
  25. package/dist/bundle/legacyDataUrlBaseResolver.offlineFunc-DPaSp_zV.js +0 -87
  26. package/dist/bundle/legacyDataUrlBaseResolver.offlineFunc-DPaSp_zV.js.map +0 -1
  27. package/dist/bundle/makeOffline-Dj-0o5_7.js +0 -76
  28. package/dist/bundle/makeOffline-Dj-0o5_7.js.map +0 -1
  29. package/dist/bundle/makeOfflineBundle-D8tePWGI.js +0 -70
  30. package/dist/bundle/makeOfflineBundle-D8tePWGI.js.map +0 -1
  31. package/dist/bundle/saveOfflineZip.browser-BTQeRUY_.js +0 -7
  32. package/dist/bundle/saveOfflineZip.browser-BTQeRUY_.js.map +0 -1
  33. package/dist/bundle/tools-D0u8lBvQ.js +0 -102
  34. package/dist/bundle/tools-D0u8lBvQ.js.map +0 -1
  35. package/dist/esm/_OLD_fetchWithRetry.d.ts +0 -1
  36. package/dist/esm/_OLD_fetchWithRetry.js +0 -101
  37. package/dist/esm/importJson.d.ts +0 -2
  38. package/dist/esm/importJson.js +0 -57
  39. package/dist/esm/loadScript.d.ts +0 -16
  40. package/dist/esm/loadScript.js +0 -167
  41. package/dist/esm/logger.d.ts +0 -1
  42. package/dist/esm/logger.js +0 -5
  43. package/dist/esm/mutateManifest.d.ts +0 -2
  44. package/dist/esm/mutateManifest.js +0 -10
  45. package/dist/esm/offline/downloadOfflineZip.d.ts +0 -4
  46. package/dist/esm/offline/downloadOfflineZip.js +0 -15
  47. package/dist/esm/offline/generateZip.d.ts +0 -4
  48. package/dist/esm/offline/generateZip.js +0 -41
  49. package/dist/esm/offline/hashString.d.ts +0 -1
  50. package/dist/esm/offline/hashString.js +0 -16
  51. package/dist/esm/offline/index.d.ts +0 -14
  52. package/dist/esm/offline/index.js +0 -41
  53. package/dist/esm/offline/makeOffline.d.ts +0 -2
  54. package/dist/esm/offline/makeOffline.js +0 -144
  55. package/dist/esm/offline/makeOfflineBundle.d.ts +0 -4
  56. package/dist/esm/offline/makeOfflineBundle.js +0 -92
  57. package/dist/esm/offline/saveOfflineZip.browser.d.ts +0 -1
  58. package/dist/esm/offline/saveOfflineZip.browser.js +0 -3
  59. package/dist/esm/offline/saveOfflineZip.d.ts +0 -1
  60. package/dist/esm/offline/saveOfflineZip.js +0 -16
  61. package/dist/esm/offline/slugify.d.ts +0 -1
  62. package/dist/esm/offline/slugify.js +0 -61
  63. package/dist/esm/offline/tools.d.ts +0 -3
  64. package/dist/esm/offline/tools.js +0 -85
  65. package/dist/esm/resolvers/_OLD_expoResolver.d.ts +0 -1
  66. package/dist/esm/resolvers/_OLD_expoResolver.js +0 -49
  67. package/dist/esm/resolvers/assetResolver.d.ts +0 -6
  68. package/dist/esm/resolvers/assetResolver.js +0 -26
  69. package/dist/esm/resolvers/bundleAssetsResolver.d.ts +0 -2
  70. package/dist/esm/resolvers/bundleAssetsResolver.js +0 -20
  71. package/dist/esm/resolvers/cssTextAssetResolver.d.ts +0 -8
  72. package/dist/esm/resolvers/cssTextAssetResolver.js +0 -15
  73. package/dist/esm/resolvers/cssTextAssetResolver.offlineFunc.d.ts +0 -2
  74. package/dist/esm/resolvers/cssTextAssetResolver.offlineFunc.js +0 -22
  75. package/dist/esm/resolvers/expoRuntimeBranchResolver.d.ts +0 -2
  76. package/dist/esm/resolvers/expoRuntimeBranchResolver.js +0 -20
  77. package/dist/esm/resolvers/expoRuntimeGetBranchResolver.d.ts +0 -2
  78. package/dist/esm/resolvers/expoRuntimeGetBranchResolver.js +0 -14
  79. package/dist/esm/resolvers/expoRuntimeResolver.d.ts +0 -2
  80. package/dist/esm/resolvers/expoRuntimeResolver.js +0 -39
  81. package/dist/esm/resolvers/httpResolver.d.ts +0 -5
  82. package/dist/esm/resolvers/httpResolver.js +0 -14
  83. package/dist/esm/resolvers/index.d.ts +0 -2
  84. package/dist/esm/resolvers/index.js +0 -22
  85. package/dist/esm/resolvers/legacyAssetUrlsResolver.d.ts +0 -9
  86. package/dist/esm/resolvers/legacyAssetUrlsResolver.js +0 -116
  87. package/dist/esm/resolvers/legacyDataResolver.d.ts +0 -8
  88. package/dist/esm/resolvers/legacyDataResolver.js +0 -20
  89. package/dist/esm/resolvers/legacyDataUrlBaseResolver.d.ts +0 -8
  90. package/dist/esm/resolvers/legacyDataUrlBaseResolver.js +0 -15
  91. package/dist/esm/resolvers/legacyDataUrlBaseResolver.offlineFunc.d.ts +0 -2
  92. package/dist/esm/resolvers/legacyDataUrlBaseResolver.offlineFunc.js +0 -129
  93. package/dist/esm/returnCachedRef.d.ts +0 -1
  94. package/dist/esm/returnCachedRef.js +0 -12
  95. package/dist/esm/shared.d.ts +0 -8
  96. package/dist/esm/shared.js +0 -273
@@ -1,304 +1,100 @@
1
- import { log } from './logger';
2
- import { resolvers } from './resolvers';
3
- import { createMergedObjectWithOverridenNonRefProps, deepFreeze, replaceObjectFields, } from './shared';
4
- const globalRefCache = new Map();
5
- export async function resolve(object, jsonPointer, options) {
6
- log('Resolving:', jsonPointer, 'of', object, options);
7
- // if (typeof window !== 'undefined') {
8
- // (window as any)['__lastResolveObject'] = object;
9
- // }
10
- const resolveContext = {
11
- importCallback: options?.importCallback,
12
- refCache: options?.refCache || globalRefCache,
13
- forceFetch: !!options?.forceFetch,
14
- signal: options?.signal || null,
15
- preResolvedRefs: options?.preResolvedRefs,
16
- };
17
- if (typeof jsonPointer !== 'string') {
18
- throw new Error(`Invalid JSON Pointer (not a string): ${jsonPointer}`);
19
- }
20
- if (!jsonPointer.startsWith('/')) {
21
- throw new Error(`Invalid JSON Pointer: ${jsonPointer}`);
22
- }
23
- if (jsonPointer.length > 1 && jsonPointer.endsWith('/')) {
24
- throw new Error(`Invalid JSON Pointer: ${jsonPointer}`);
25
- }
26
- // if (jsonPointer === '/') {
27
- // const result = await resolveObject(object, resolveContext);
28
- // if (options?.mutate) {
29
- // replaceObjectFields(object, result);
30
- // }
31
- // return result;
32
- // }
33
- let parts;
34
- if (jsonPointer === '/') {
35
- parts = [];
36
- }
37
- else {
38
- parts = jsonPointer.substring(1).split('/');
39
- }
40
- if (parts.some((part) => part.length === 0))
41
- throw new Error(`Invalid JSON Pointer (empty part): ${jsonPointer}`);
42
- if (options?.mutate) {
43
- // prepend parts with 'root'
44
- parts.unshift('root');
45
- const target = { root: object };
46
- await resovlePartsRecursiveMutate(target, parts, 0, resolveContext);
47
- replaceObjectFields(object, target.root);
48
- }
49
- else {
50
- return await resovlePartsRecursive(object, parts, 0, resolveContext);
51
- }
52
- // prepend parts with 'root'
53
- // parts.unshift('root');
54
- // // if (parts.some((part) => part.length === 0))
55
- // // throw new Error(`Invalid JSON Pointer (empty part): ${jsonPointer}`);
56
- // const target = { root: object };
57
- // const value = await resovlePartsRecursiveMutate(
58
- // target,
59
- // // 'root',
60
- // parts,
61
- // 0,
62
- // resolveContext
63
- // );
64
- // if (options?.mutate) {
65
- // replaceObjectFields(object, target.root);
66
- // }
67
- // log(`Resolved ${jsonPointer}:`, value);
68
- // return value;
69
- }
70
- // TODO: use library for JSON Pointer resolution
71
- async function resovlePartsRecursiveMutate(node,
72
- // key: string,
73
- parts, partsIndex, context) {
74
- const key = parts[partsIndex];
75
- // console.warn('in', key);
76
- await resolveObjectMutate(node, key, context);
77
- if (partsIndex == parts.length - 1)
78
- return;
79
- if (node[key] === null || typeof node[key] !== 'object') {
80
- // console.error('Cannot resolve path, encountered non-object:', node, key);
81
- throw new Error(`Cannot resolve path, encountered non-object at part '${parts.slice(1).join('/')}', index ${partsIndex - 1}'`);
82
- }
83
- return await resovlePartsRecursiveMutate(node[key], parts, partsIndex + 1, context);
84
- }
85
- async function resolveObjectMutate(node, key, context) {
86
- log('resolveObjectMutate:', node, key);
87
- let obj = node[key];
88
- const result = await resolveObject(obj, context);
89
- if (result !== undefined)
90
- node[key] = result;
91
- }
92
- // TODO: use library for JSON Pointer resolution
93
- async function resovlePartsRecursive(object, parts, index, context) {
94
- // should return undefined if last part not found
95
- // if not last part found - throw error
96
- // do not resolve object if its children are not needed (needed part exist as key)
97
- if (index === parts.length) {
98
- // console.warn('Resolving last part:', object);
99
- return await resolveObject(object, context);
100
- }
101
- if (object === null || typeof object !== 'object') {
102
- throw new Error(`Cannot resolve path, encountered non-object at part '${parts.join('/')}', index ${index}'`);
103
- }
104
- const part = parts[index];
105
- let child = object[part];
106
- if (child === undefined) {
107
- // console.warn('Resolving, part not found during resolve:', part, object);
108
- const resolvedObject = await resolveObject(object, context);
109
- child = resolvedObject[part];
110
- }
111
- return await resovlePartsRecursive(child, parts, index + 1, context);
112
- }
113
- async function resolveObject(object, context) {
114
- log('resolveObject:', object);
115
- let obj = object;
116
- do {
117
- if (typeof obj !== 'object' || obj === null || !('$ref' in obj)) {
118
- return obj;
119
- }
120
- const resolversToUse = resolvers.filter((r) => canResolve(r, obj.$ref));
121
- if (resolversToUse.length === 0) {
122
- if (obj.$ref) {
123
- throw new Error(`No resolver found for ref: ${obj.$ref}`);
1
+ // resolveHttpRefToString.ts
2
+ // Follows $ref chains until finding a value without $ref.
3
+ //
4
+ // Rules:
5
+ // - If value is an object with {$ref: string} -> follow it (fetch if http/https URL)
6
+ // - Otherwise -> return the value as-is
7
+ //
8
+ // Browser: tries `import(url, { with: { type: 'json' } })` first, falls back to fetch.
9
+ // Node: uses fetch (Node 18+ has global fetch).
10
+ import debug from 'debug';
11
+ import { fetch } from './fetch';
12
+ const log = debug('efp:loader:resolve');
13
+ export async function resolve(input, options = {}) {
14
+ const maxHops = options.maxHops ?? 32;
15
+ const seen = new Set();
16
+ let cur = input;
17
+ for (let hop = 0; hop < maxHops; hop++) {
18
+ // If it's an object with $ref, follow it
19
+ if (cur && typeof cur === 'object' && '$ref' in cur) {
20
+ const obj = cur;
21
+ const ref = obj.$ref;
22
+ if (typeof ref !== 'string') {
23
+ throw new Error(`$ref must be a string, got: ${typeof ref}`);
124
24
  }
125
- deepFreeze(obj);
126
- return obj;
127
- }
128
- if (resolversToUse.length > 1) {
129
- throw new Error(`Multiple resolvers can resolve ref: ${obj.$ref}`);
25
+ // If it's an http/https URL, fetch it
26
+ if (isHttpUrl(ref)) {
27
+ if (seen.has(ref)) {
28
+ throw new Error(`Circular $ref detected at: ${ref}`);
29
+ }
30
+ seen.add(ref);
31
+ log('Loading JSON ref:', ref);
32
+ options.fetchCallback?.(ref);
33
+ const json = await loadJson(ref, options.signal);
34
+ options.onHop?.({ hop, ref, via: json.__via });
35
+ cur = json.value;
36
+ continue;
37
+ }
38
+ // Non-http $ref (e.g., relative, custom schema) - return the object as-is
39
+ // (caller is responsible for handling these)
40
+ return cur;
130
41
  }
131
- const data = await resolverResolve(resolversToUse[0], obj.$ref, context);
132
- obj = createMergedObjectWithOverridenNonRefProps(data, obj);
133
- } while (true);
134
- }
135
- export async function resolverResolve(resolver, ref, context) {
136
- if (!canResolve(resolver, ref)) {
137
- throw new Error(`Unexpected ref: ${ref}`);
42
+ // No $ref found - return current value
43
+ return cur;
138
44
  }
139
- return resolver.resolveRef(ref, context);
45
+ throw new Error(`Too many ref hops (>${maxHops}). Possible loop or unexpectedly deep chain.`);
140
46
  }
141
- export function canResolve(resolver, ref) {
142
- if (resolver.canResolve) {
143
- return resolver.canResolve(ref);
144
- }
145
- if (resolver.schema) {
146
- return canResolveRefSchema(ref, resolver.schema);
147
- }
148
- throw new Error('Resolver is missing canResolve method and schema property');
47
+ function isHttpUrl(s) {
48
+ return s.startsWith('http://') || s.startsWith('https://');
149
49
  }
150
- export function canResolveRefSchema(ref, prefixBase) {
151
- const prefixes = [`${prefixBase}+`, `${prefixBase}:`];
152
- for (const prefix of prefixes) {
153
- if (ref.startsWith(prefix)) {
154
- return true;
155
- }
50
+ async function loadJson(url, signal) {
51
+ // Try import() JSON first (browser-friendly; depends on runtime/bundler support + CORS)
52
+ const imported = await tryImportJson(url);
53
+ if (imported.ok)
54
+ return { value: imported.value, __via: 'import' };
55
+ // Fallback to fetch
56
+ const res = await fetch(url, {
57
+ method: 'GET',
58
+ signal,
59
+ headers: {
60
+ // Helps some CDNs/content negotiation setups
61
+ Accept: 'application/json, text/plain;q=0.9, */*;q=0.1',
62
+ },
63
+ });
64
+ if (!res.ok) {
65
+ throw new Error(`Failed to fetch JSON ref: ${url} (${res.status} ${res.statusText})`);
66
+ }
67
+ // Prefer JSON; if server mislabels, fallback to text->JSON parse.
68
+ const ct = res.headers.get('content-type') || '';
69
+ if (ct.includes('application/json') || ct.includes('+json')) {
70
+ return { value: await res.json(), __via: 'fetch' };
71
+ }
72
+ const text = await res.text();
73
+ try {
74
+ return { value: JSON.parse(text), __via: 'fetch' };
75
+ }
76
+ catch {
77
+ // If the endpoint literally returns a plain string (not JSON), accept it.
78
+ return { value: text, __via: 'fetch' };
156
79
  }
157
- return false;
158
80
  }
159
- export function parseRefValue(ref) {
160
- // look for anything before ":" or before +https:// or before +http://
161
- // https://www -> https://www
162
- // so some+base+https://www -> https://www
163
- // base+https://www -> https://www
164
- // base:abc -> abc
165
- // "some-base" can contain only non-:
166
- if (ref.startsWith('http://') || ref.startsWith('https://')) {
167
- return ref;
168
- }
169
- // if it is something+http:// or something+https://
170
- const plusHttpIndex = ref.indexOf('+http://');
171
- const plusHttpsIndex = ref.indexOf('+https://');
172
- if (plusHttpIndex !== -1) {
173
- return ref.substring(plusHttpIndex + 1);
174
- }
175
- if (plusHttpsIndex !== -1) {
176
- return ref.substring(plusHttpsIndex + 1);
177
- }
178
- // if it is something:abc
179
- const colonIndex = ref.indexOf(':');
180
- if (colonIndex !== -1) {
181
- return ref.substring(colonIndex + 1);
81
+ async function tryImportJson(url) {
82
+ // `with: { type: 'json' }` is the modern import assertion form.
83
+ // Some environments still only accept `assert: { type: 'json' }`.
84
+ try {
85
+ //// @ts-expect-error - TS lib definitions differ across versions
86
+ const mod = await import(/* @vite-ignore */ url, { with: { type: 'json' } });
87
+ log('Imported JSON via import():', url);
88
+ return { ok: true, value: mod?.default ?? mod };
89
+ }
90
+ catch (e1) {
91
+ try {
92
+ //// @ts-expect-error - fallback for older assertion syntax
93
+ const mod = await import(/* @vite-ignore */ url, { assert: { type: 'json' } });
94
+ return { ok: true, value: mod?.default ?? mod };
95
+ }
96
+ catch (e2) {
97
+ return { ok: false, error: e2 ?? e1 };
98
+ }
182
99
  }
183
- throw new Error(`Error getting URL from: ${ref}, no valid prefix found`);
184
- }
185
- // export function parseRefValue(ref: string): string {
186
- // // look for anything before ":" or before +https:// or before +http://
187
- // // https://www -> https://www
188
- // // so some+base+https://www -> https://www
189
- // // base+https://www -> https://www
190
- // // base:abc -> abc
191
- // // "some-base" can contain only non-:
192
- // if (ref.startsWith('http://') || ref.startsWith('https://')) {
193
- // return ref;
194
- // }
195
- // // if it is something+http:// or something+https://
196
- // const plusHttpIndex = ref.indexOf('+http://');
197
- // const plusHttpsIndex = ref.indexOf('+https://');
198
- // if (plusHttpIndex !== -1) {
199
- // return ref.substring(plusHttpIndex + 1);
200
- // }
201
- // if (plusHttpsIndex !== -1) {
202
- // return ref.substring(plusHttpsIndex + 1);
203
- // }
204
- // // if it is something:abc
205
- // const colonIndex = ref.indexOf(':');
206
- // if (colonIndex !== -1) {
207
- // return ref.substring(colonIndex + 1);
208
- // }
209
- // throw new Error(`Error getting URL from: ${ref}, no valid prefix found`);
210
- // // const prefixBase = ref.split('+')[0].split(':')[0];
211
- // // if (!prefixBase) {
212
- // // throw new Error(`Invalid ref, missing prefix: ${ref}`);
213
- // // }
214
- // // return ref.substring(prefixBase.length + 1);
215
- // // const prefixes = [`${prefixBase}+`, `${prefixBase}:`];
216
- // // for (const prefix of prefixes) {
217
- // // if (ref.startsWith(prefix)) {
218
- // // const url = ref.substring(prefix.length);
219
- // // if (!url) {
220
- // // throw new Error(`Invalid ref, missing URL after prefix "${prefix}": ${ref}`);
221
- // // }
222
- // // return url;
223
- // // }
224
- // // }
225
- // // throw new Error(
226
- // // `Error getting URL from: ${ref}, none of the prefixes matched: ${prefixes.join(', ')}`
227
- // // );
228
- // }
229
- // export function parseRefValue(ref: string, prefixBase: string): string {
230
- // const prefixes = [`${prefixBase}+`, `${prefixBase}:`];
231
- // for (const prefix of prefixes) {
232
- // if (ref.startsWith(prefix)) {
233
- // const url = ref.substring(prefix.length);
234
- // if (!url) {
235
- // throw new Error(`Invalid ref, missing URL after prefix "${prefix}": ${ref}`);
236
- // }
237
- // return url;
238
- // }
239
- // }
240
- // throw new Error(
241
- // `Error getting URL from: ${ref}, none of the prefixes matched: ${prefixes.join(', ')}`
242
- // );
243
- // }
244
- // const importJsonNative = new Function('url', 'return import(url, { with: { type: "json" } });') as (
245
- // url: string
246
- // ) => Promise<any>;
247
- if (typeof window !== 'undefined') {
248
- window['__debugResolve'] = async function debugResolve(object, jsonPointer, options) {
249
- return await resolve(object, jsonPointer, options);
250
- };
251
- // (window as any)['__dd'] = async function dd() {
252
- // const url = 'https://demo.expofp.com/manifest.json';
253
- // // const imp = import;
254
- // const zz = (await importJsonNative(url)).default;
255
- // console.warn('debugResolve demo manifest:', zz);
256
- // // let object: any;
257
- // // let ref: string;
258
- // // let resolveContext: ResolveOptions | undefined;
259
- // // if (typeof objectOrRef === 'string') {
260
- // // object = (window as any)['__lastResolveObject'];
261
- // // ref = objectOrRef;
262
- // // resolveContext = refOrContext;
263
- // // } else {
264
- // // object = objectOrRef;
265
- // // ref = refOrContext;
266
- // // resolveContext = context;
267
- // // }
268
- // // return await resolve(object, ref, resolveContext);
269
- // };
270
100
  }
271
- // if (index === parts.length - 1) {
272
- // return await resolveObject(object, context);
273
- // }
274
- // if (object === null || typeof object !== 'object') {
275
- // throw new Error(
276
- // `Cannot resolve path, encountered non-object at part '${parts.join('/')}', index ${index}'`
277
- // );
278
- // }
279
- // if (!(parts[0] in object)) {
280
- // return undefined;
281
- // }
282
- // let partIndex = 0;
283
- // let currentObject = await resolveObject(object, context);
284
- // while (partIndex < parts.length) {
285
- // const part = parts[partIndex];
286
- // if (typeof currentObject !== 'object' || currentObject === null) {
287
- // throw new Error(
288
- // `Cannot resolve path, encountered non-object at part '${parts.join(
289
- // '/'
290
- // )}, index ${partIndex}'`
291
- // );
292
- // }
293
- // // console.info(
294
- // // 'resolvePath currentObject:',
295
- // // part,
296
- // // JSON.stringify(currentObject, null, 2),
297
- // // currentObject[part]
298
- // // );
299
- // // debugger;
300
- // const child = currentObject[part];
301
- // currentObject = await resolveObject(child, context);
302
- // partIndex++;
303
- // }
304
- // return currentObject;
@@ -1,26 +1,11 @@
1
- import type { ResolveContextInternal } from './resolve';
2
- export interface Resolver {
3
- schema?: string;
4
- canResolve?(ref: string): boolean;
5
- resolveRef(ref: string, context: ResolveContextInternal): Promise<any>;
6
- offlineFunc: 'localizeRef' | 'resolveRef' | OfflineFunc;
7
- }
8
- export interface LocalFetchFile {
9
- url: string;
10
- targetFilePath: string;
11
- }
12
- export interface LocalTextFile {
13
- text: string;
14
- targetFilePath: string;
15
- }
16
- export interface LocalJsonFile {
17
- data: unknown;
18
- targetFilePath: string;
19
- }
20
- export type ManifestData = any;
21
- export type LocalFile = LocalFetchFile | LocalJsonFile | LocalTextFile;
22
- export interface MakeOfflineResult {
23
- manifest: any;
24
- files: AsyncGenerator<LocalFile, ManifestData, void>;
25
- }
26
- export type OfflineFunc = (ref: string, context: ResolveContextInternal) => AsyncGenerator<LocalFile, string, void>;
1
+ export type Ref = {
2
+ $ref: string;
3
+ };
4
+ export type Runtime = string;
5
+ export type Manifest = {
6
+ runtime: Runtime | Ref | string;
7
+ };
8
+ export type LoaderFn = (manifest: Manifest | Ref | string, ...args: unknown[]) => Promise<unknown>;
9
+ export type LoaderApi = {
10
+ [key: string]: LoaderFn | undefined;
11
+ };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@expofp/loader",
3
- "version": "1.0.78",
3
+ "version": "1.0.91",
4
4
  "description": "ExpoFP JavaScript loader library",
5
5
  "license": "MIT",
6
6
  "homepage": "https://expofp.com",
@@ -28,12 +28,14 @@
28
28
  "clean": "rm -rf dist",
29
29
  "build": "pnpm clean && tsc && vite build",
30
30
  "preview": "vite preview",
31
+ "test": "DEBUG=efp:* tsx watch ./scripts/test.ts",
31
32
  "css": "tsx watch ./scripts/css.ts",
32
33
  "offline:build": "tsx ./scripts/buildOffline.ts",
33
34
  "offline:serve": "http-server ./tmp/offline",
34
35
  "prepare": "husky"
35
36
  },
36
37
  "dependencies": {
38
+ "@apidevtools/json-schema-ref-parser": "^15.1.3",
37
39
  "debug": "^4.4.3",
38
40
  "fetch-retry": "^6.0.0",
39
41
  "jszip": "^3.10.1"
@@ -1,19 +0,0 @@
1
- import { a as i } from "./tools-D0u8lBvQ.js";
2
- import { p, S as u, l as f } from "./bundle.js";
3
- const U = async function* (e, c) {
4
- const t = p(e), { urls: r, css: a } = g(t, i);
5
- for (const { originalUrl: o, replacedUrl: s } of r)
6
- yield { url: o, targetFilePath: s };
7
- return `${u}:${a}`;
8
- };
9
- function g(e, c) {
10
- const t = /url\(\s*(['"]?)(.*?)\1\s*\)/g, r = [], a = e.replace(t, (o, s, l) => {
11
- const n = c(l);
12
- return r.push({ originalUrl: l, replacedUrl: n }), f("Extracted and replaced URL in CSS:", l, "->", n), `url(${s}${n}${s})`;
13
- });
14
- return { urls: r, css: a };
15
- }
16
- export {
17
- U as offlineFunc
18
- };
19
- //# sourceMappingURL=cssTextAssetResolver.offlineFunc-CWvHnYni.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"cssTextAssetResolver.offlineFunc-CWvHnYni.js","sources":["../../src/resolvers/cssTextAssetResolver.offlineFunc.ts"],"sourcesContent":["import { makeTargetPathFromUrl } from '../offline/tools';\nimport { parseRefValue } from '../resolve';\nimport { OfflineFunc } from '../types';\nimport { log, SCHEMA } from './cssTextAssetResolver';\n\nexport const offlineFunc: OfflineFunc = async function* (ref: string, _context: any) {\n const originalCss = parseRefValue(ref);\n const { urls, css } = extractCssUrls(originalCss, makeTargetPathFromUrl);\n\n for (const { originalUrl, replacedUrl } of urls) {\n yield { url: originalUrl, targetFilePath: replacedUrl };\n }\n\n return `${SCHEMA}:${css}`;\n};\n\ninterface UrlReplacement {\n originalUrl: string;\n replacedUrl: string;\n}\n\nfunction extractCssUrls(\n css: string,\n replace: (url: string) => string\n): { urls: UrlReplacement[]; css: string } {\n const urlRegex = /url\\(\\s*(['\"]?)(.*?)\\1\\s*\\)/g;\n const urls: UrlReplacement[] = [];\n\n const replacedCss = css.replace(urlRegex, (_match, quote, url) => {\n const replacedUrl = replace(url);\n urls.push({ originalUrl: url, replacedUrl });\n log('Extracted and replaced URL in CSS:', url, '->', replacedUrl);\n return `url(${quote}${replacedUrl}${quote})`;\n });\n\n return { urls, css: replacedCss };\n}\n"],"names":["offlineFunc","ref","_context","originalCss","parseRefValue","urls","css","extractCssUrls","makeTargetPathFromUrl","originalUrl","replacedUrl","SCHEMA","replace","urlRegex","replacedCss","_match","quote","url","log"],"mappings":";;AAKO,MAAMA,IAA2B,iBAAiBC,GAAaC,GAAe;AACnF,QAAMC,IAAcC,EAAcH,CAAG,GAC/B,EAAE,MAAAI,GAAM,KAAAC,EAAA,IAAQC,EAAeJ,GAAaK,CAAqB;AAEvE,aAAW,EAAE,aAAAC,GAAa,aAAAC,EAAA,KAAiBL;AACzC,UAAM,EAAE,KAAKI,GAAa,gBAAgBC,EAAA;AAG5C,SAAO,GAAGC,CAAM,IAAIL,CAAG;AACzB;AAOA,SAASC,EACPD,GACAM,GACyC;AACzC,QAAMC,IAAW,gCACXR,IAAyB,CAAA,GAEzBS,IAAcR,EAAI,QAAQO,GAAU,CAACE,GAAQC,GAAOC,MAAQ;AAChE,UAAMP,IAAcE,EAAQK,CAAG;AAC/B,WAAAZ,EAAK,KAAK,EAAE,aAAaY,GAAK,aAAAP,GAAa,GAC3CQ,EAAI,sCAAsCD,GAAK,MAAMP,CAAW,GACzD,OAAOM,CAAK,GAAGN,CAAW,GAAGM,CAAK;AAAA,EAC3C,CAAC;AAED,SAAO,EAAE,MAAAX,GAAM,KAAKS,EAAA;AACtB;"}