@plasmicapp/loader-fetcher 1.0.60 → 2.0.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.
- package/dist/index.d.ts +0 -15
- package/dist/index.esm.js +6 -12
- package/dist/index.esm.js.map +2 -2
- package/dist/index.js +6 -12
- package/dist/index.js.map +2 -2
- package/package.json +2 -2
package/dist/index.d.ts
CHANGED
|
@@ -30,13 +30,6 @@ export declare class Api {
|
|
|
30
30
|
}): Promise<LoaderBundleOutput>;
|
|
31
31
|
private verifyAndParseJsonResponse;
|
|
32
32
|
private parseJsonResponse;
|
|
33
|
-
/** @deprecated */
|
|
34
|
-
fetchHtmlData(_opts: {
|
|
35
|
-
projectId: string;
|
|
36
|
-
component: string;
|
|
37
|
-
hydrate?: boolean;
|
|
38
|
-
embedHydrate?: boolean;
|
|
39
|
-
}): Promise<LoaderHtmlOutput>;
|
|
40
33
|
private makeGetHeaders;
|
|
41
34
|
private makeAuthHeaders;
|
|
42
35
|
getChunksUrl(bundle: LoaderBundleOutput, modules: CodeModule[]): string;
|
|
@@ -126,10 +119,6 @@ export declare interface FetcherOptions {
|
|
|
126
119
|
apiHost?: string;
|
|
127
120
|
/** Used for fetching published content. */
|
|
128
121
|
cdnHost?: string;
|
|
129
|
-
/**
|
|
130
|
-
* @deprecated use i18n.keyScheme instead
|
|
131
|
-
*/
|
|
132
|
-
i18nKeyScheme?: "content" | "hash" | "path";
|
|
133
122
|
i18n?: {
|
|
134
123
|
keyScheme: "content" | "hash" | "path";
|
|
135
124
|
tagPrefix?: string;
|
|
@@ -170,10 +159,6 @@ export declare interface LoaderBundleOutput extends ApiLoaderBundleOutput {
|
|
|
170
159
|
filteredIds: Record<string, string[]>;
|
|
171
160
|
}
|
|
172
161
|
|
|
173
|
-
export declare interface LoaderHtmlOutput {
|
|
174
|
-
html: string;
|
|
175
|
-
}
|
|
176
|
-
|
|
177
162
|
export declare interface PageMeta extends ComponentMeta {
|
|
178
163
|
isPage: true;
|
|
179
164
|
path: string;
|
package/dist/index.esm.js
CHANGED
|
@@ -149,12 +149,6 @@ var Api = class {
|
|
|
149
149
|
}
|
|
150
150
|
});
|
|
151
151
|
}
|
|
152
|
-
/** @deprecated */
|
|
153
|
-
fetchHtmlData(_opts) {
|
|
154
|
-
return __async(this, null, function* () {
|
|
155
|
-
throw new Error("deprecated");
|
|
156
|
-
});
|
|
157
|
-
}
|
|
158
152
|
makeGetHeaders() {
|
|
159
153
|
return __spreadValues({
|
|
160
154
|
"x-plasmic-loader-version": VERSION
|
|
@@ -229,7 +223,7 @@ var PlasmicModulesFetcher = class {
|
|
|
229
223
|
}
|
|
230
224
|
doFetch() {
|
|
231
225
|
return __async(this, null, function* () {
|
|
232
|
-
var _a, _b, _c
|
|
226
|
+
var _a, _b, _c;
|
|
233
227
|
const data = yield this.api.fetchLoaderData(
|
|
234
228
|
this.opts.projects.map(
|
|
235
229
|
(p) => p.version ? `${p.id}@${p.version}` : p.id
|
|
@@ -238,8 +232,8 @@ var PlasmicModulesFetcher = class {
|
|
|
238
232
|
platform: this.opts.platform,
|
|
239
233
|
platformOptions: this.opts.platformOptions,
|
|
240
234
|
preview: this.opts.preview,
|
|
241
|
-
i18nKeyScheme: (
|
|
242
|
-
i18nTagPrefix: (
|
|
235
|
+
i18nKeyScheme: (_a = this.opts.i18n) == null ? void 0 : _a.keyScheme,
|
|
236
|
+
i18nTagPrefix: (_b = this.opts.i18n) == null ? void 0 : _b.tagPrefix,
|
|
243
237
|
browserOnly: isBrowser,
|
|
244
238
|
skipHead: this.opts.skipHead
|
|
245
239
|
}
|
|
@@ -247,7 +241,7 @@ var PlasmicModulesFetcher = class {
|
|
|
247
241
|
if (this.opts.cache) {
|
|
248
242
|
yield this.opts.cache.set(data);
|
|
249
243
|
}
|
|
250
|
-
if (typeof process === "undefined" || !((
|
|
244
|
+
if (typeof process === "undefined" || !((_c = process.env) == null ? void 0 : _c.PLASMIC_QUIET)) {
|
|
251
245
|
console.debug(
|
|
252
246
|
`Plasmic: fetched designs for ${data.projects.map((p) => `"${p.name}" (${p.id}@${p.version})`).join(", ")}`
|
|
253
247
|
);
|
|
@@ -277,7 +271,7 @@ function internal_getCachedBundleInNodeServer(opts) {
|
|
|
277
271
|
function getBundleKey({
|
|
278
272
|
host,
|
|
279
273
|
platform,
|
|
280
|
-
|
|
274
|
+
i18n,
|
|
281
275
|
preview,
|
|
282
276
|
projects,
|
|
283
277
|
skipHead
|
|
@@ -285,7 +279,7 @@ function getBundleKey({
|
|
|
285
279
|
return JSON.stringify({
|
|
286
280
|
host,
|
|
287
281
|
platform,
|
|
288
|
-
i18nKeyScheme,
|
|
282
|
+
i18nKeyScheme: i18n == null ? void 0 : i18n.keyScheme,
|
|
289
283
|
preview,
|
|
290
284
|
projects,
|
|
291
285
|
skipHead
|
package/dist/index.esm.js.map
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../src/api.ts", "../src/fetcher.ts"],
|
|
4
|
-
"sourcesContent": ["import unfetch from \"@plasmicapp/isomorphic-unfetch\";\n\nexport interface ComponentMeta {\n id: string;\n usedComponents: string[];\n projectId: string;\n name: string;\n displayName: string;\n cssFile: string;\n path: string | undefined;\n isPage: boolean;\n plumeType?: string;\n entry: string;\n isCode: boolean;\n isGlobalContextProvider: boolean;\n pageMetadata?: PageMetadata;\n metadata?: Record<string, string>;\n serverQueriesExecFuncFileName?: string;\n}\n\nexport interface PageMeta extends ComponentMeta {\n isPage: true;\n path: string;\n plumeType: never;\n pageMetadata: PageMetadata;\n}\n\nexport interface PageMetadata {\n path: string;\n title?: string | null;\n description?: string | null;\n openGraphImageUrl?: string | null;\n canonical?: string | null;\n}\n\nexport interface GlobalGroupMeta {\n id: string;\n projectId: string;\n name: string;\n type: string;\n contextFile: string;\n useName: string;\n}\n\n// Keep in sync with platform/wab ProjectMeta\nexport interface ProjectMeta {\n id: string;\n teamId?: string;\n indirect: boolean;\n name: string;\n version: string;\n remoteFonts: FontMeta[];\n hasStyleTokenOverrides: boolean;\n styleTokensProviderFileName: string;\n globalContextsProviderFileName: string;\n}\n\nexport interface FontMeta {\n url: string;\n}\n\ninterface GlobalVariantSplitContent {\n type: \"global-variant\";\n projectId: string;\n group: string;\n variant: string;\n}\n\ninterface Slice {\n id: string;\n contents: GlobalVariantSplitContent[];\n externalId?: string;\n}\n\nexport interface ExperimentSlice extends Slice {\n prob: number;\n}\n\nexport interface SegmentSlice extends Slice {\n cond: any;\n}\n\ninterface BareSplit {\n id: string;\n projectId: string;\n name: string;\n externalId?: string;\n description?: string;\n pagesPaths: string[];\n}\n\nexport interface ExperimentSplit extends BareSplit {\n type: \"experiment\";\n slices: ExperimentSlice[];\n}\n\nexport interface SegmentSplit extends BareSplit {\n type: \"segment\";\n slices: SegmentSlice[];\n}\n\nexport type Split = ExperimentSplit | SegmentSplit;\n\ninterface ApiLoaderBundleOutput {\n modules: {\n browser: (CodeModule | AssetModule)[];\n server: (CodeModule | AssetModule)[];\n };\n components: ComponentMeta[];\n globalGroups: GlobalGroupMeta[];\n projects: ProjectMeta[];\n activeSplits: Split[];\n bundleKey: string | null;\n deferChunksByDefault: boolean;\n disableRootLoadingBoundaryByDefault: boolean;\n redirectUrl?: string;\n}\n\nexport interface LoaderBundleOutput extends ApiLoaderBundleOutput {\n // A map from project ID to the list of component IDs that are not included in the bundle\n // this is used to know which components exist in the project, which allow us to properly\n // handle bundle merging being aware of the deleted components.\n filteredIds: Record<string, string[]>;\n}\n\nexport interface LoaderHtmlOutput {\n html: string;\n}\n\nexport interface CodeModule {\n fileName: string;\n code: string;\n imports: string[];\n type: \"code\";\n}\n\nexport interface AssetModule {\n fileName: string;\n source: string;\n type: \"asset\";\n}\n\nconst VERSION = \"10\";\n\nexport const isBrowser =\n typeof window !== \"undefined\" &&\n window != null &&\n typeof window.document !== \"undefined\";\n\nexport function transformApiLoaderBundleOutput(\n bundle: ApiLoaderBundleOutput\n): LoaderBundleOutput {\n return {\n ...bundle,\n filteredIds: Object.fromEntries(bundle.projects.map((p) => [p.id, []])),\n };\n}\n\nexport class Api {\n private readonly apiHost: string;\n private readonly cdnHost: string;\n private fetch: typeof globalThis.fetch;\n\n private lastResponse:\n | {\n bundle: LoaderBundleOutput;\n key: string;\n }\n | undefined = undefined;\n\n constructor(\n private opts: {\n projects: { id: string; token: string }[];\n host?: string;\n apiHost?: string;\n cdnHost?: string;\n nativeFetch?: boolean;\n manualRedirect?: boolean;\n }\n ) {\n this.apiHost =\n opts.apiHost ?? opts.host ?? \"https://codegen-origin.plasmic.app\";\n this.cdnHost = opts.cdnHost ?? opts.host ?? \"https://codegen.plasmic.app\";\n this.fetch = (\n opts.nativeFetch && globalThis.fetch ? globalThis.fetch : unfetch\n ).bind(globalThis);\n }\n\n async fetchLoaderData(\n projectIds: string[],\n opts: {\n platform?: \"react\" | \"nextjs\" | \"gatsby\";\n platformOptions?: {\n nextjs?: {\n appDir: boolean;\n };\n };\n preview?: boolean;\n browserOnly?: boolean;\n i18nKeyScheme?: \"content\" | \"hash\" | \"path\";\n i18nTagPrefix?: string;\n skipHead?: boolean;\n }\n ): Promise<LoaderBundleOutput> {\n const { platform, preview } = opts;\n const query = new URLSearchParams([\n [\"platform\", platform ?? \"react\"],\n ...(opts.platformOptions?.nextjs?.appDir\n ? [[\"nextjsAppDir\", \"true\"]]\n : []),\n ...projectIds.map((projectId) => [\"projectId\", projectId]),\n ...(opts.browserOnly ? [[\"browserOnly\", \"true\"]] : []),\n ...(opts.i18nKeyScheme ? [[\"i18nKeyScheme\", opts.i18nKeyScheme]] : []),\n ...(opts.i18nTagPrefix ? [[\"i18nTagPrefix\", opts.i18nTagPrefix]] : []),\n ...(opts.skipHead ? [[\"skipHead\", \"true\"]] : []),\n ]).toString();\n\n const host = preview ? this.apiHost : this.cdnHost;\n const url = preview\n ? `${host}/api/v1/loader/code/preview?${query}`\n : `${host}/api/v1/loader/code/published?${query}`;\n\n // We only expect a redirect when we're dealing with published mode, as there should be\n // a stable set of versions to be used. As in browser, we could receive a opaque response\n // with a redirect, we don't try to use last response in browser.\n const useLastReponse =\n // We consider that manualRedirect is true by default, only by setting it to false\n // we disable it.\n !(this.opts.manualRedirect === false) && !preview && !isBrowser;\n\n if (useLastReponse) {\n const redirectResp = await this.fetch(url, {\n method: \"GET\",\n headers: this.makeGetHeaders(),\n redirect: \"manual\",\n });\n\n if (redirectResp.status !== 301 && redirectResp.status !== 302) {\n const error = await this.parseJsonResponse(redirectResp);\n throw new Error(\n `Error fetching loader data, a redirect was expected: ${\n error?.error?.message ?? redirectResp.statusText\n }`\n );\n }\n\n const nextLocation = redirectResp.headers.get(\"location\");\n if (!nextLocation) {\n throw new Error(\n `Error fetching loader data, a redirect was expected but no location header was found`\n );\n }\n\n if (this.lastResponse?.key === nextLocation) {\n return this.lastResponse.bundle;\n }\n\n const resp = await this.fetch(`${host}${nextLocation}`, {\n method: \"GET\",\n headers: this.makeGetHeaders(),\n });\n\n const json = transformApiLoaderBundleOutput(\n await this.verifyAndParseJsonResponse(resp)\n );\n this.lastResponse = {\n bundle: json,\n key: nextLocation,\n };\n\n return json;\n }\n\n const resp = await this.fetch(url, {\n method: \"GET\",\n headers: this.makeGetHeaders(),\n });\n\n let json = await this.verifyAndParseJsonResponse(resp);\n\n // An Angular polyfill can cause 302 redirects to fail in Safari, due to missing headers.\n // This 200 response with `redirectUrl` is a workaround for specific projects that need it.\n if (json.redirectUrl) {\n const redirectResp = await this.fetch(`${host}${json.redirectUrl}`, {\n method: \"GET\",\n headers: this.makeGetHeaders(),\n });\n json = await this.verifyAndParseJsonResponse(redirectResp);\n }\n\n return transformApiLoaderBundleOutput(json);\n }\n\n private async verifyAndParseJsonResponse(\n resp: Response,\n errorText = \"Error fetching loader data\"\n ) {\n if (resp.status >= 400) {\n const error = await this.parseJsonResponse(resp);\n throw new Error(\n `${errorText}: ${error?.error?.message ?? resp.statusText}`\n );\n }\n return (await this.parseJsonResponse(resp)) as ApiLoaderBundleOutput;\n }\n\n private async parseJsonResponse(resp: Response) {\n const text = await resp.text();\n try {\n return JSON.parse(text);\n } catch (err) {\n throw new Error(\n `Error parsing JSON response: ${err}; status: ${resp.status}; response: ${text}`\n );\n }\n }\n\n /** @deprecated */\n async fetchHtmlData(_opts: {\n projectId: string;\n component: string;\n hydrate?: boolean;\n embedHydrate?: boolean;\n }): Promise<LoaderHtmlOutput> {\n throw new Error(\"deprecated\");\n }\n\n private makeGetHeaders() {\n return {\n \"x-plasmic-loader-version\": VERSION,\n ...this.makeAuthHeaders(),\n };\n }\n\n private makeAuthHeaders() {\n const tokens = this.opts.projects\n .map((p) => `${p.id}:${p.token}`)\n .join(\",\");\n return {\n \"x-plasmic-api-project-tokens\": tokens,\n };\n }\n\n getChunksUrl(bundle: LoaderBundleOutput, modules: CodeModule[]) {\n return `${this.cdnHost}/api/v1/loader/chunks?bundleKey=${encodeURIComponent(\n bundle.bundleKey ?? \"null\"\n )}&fileName=${encodeURIComponent(\n modules\n .map((m) => m.fileName)\n .sort()\n .join(\",\")\n )}`;\n }\n}\n", "import { Api, CodeModule, isBrowser, LoaderBundleOutput } from \"./api\";\n\nexport interface FetcherOptions {\n projects: {\n id: string;\n version?: string;\n token: string;\n }[];\n cache?: LoaderBundleCache;\n platform?: \"react\" | \"nextjs\" | \"gatsby\";\n platformOptions?: {\n nextjs?: {\n appDir: boolean;\n };\n };\n preview?: boolean;\n /** Fallback for apiHost and cdnHost. */\n host?: string;\n /** Used for fetching/previewing unpublished content. */\n apiHost?: string;\n /** Used for fetching published content. */\n cdnHost?: string;\n /**\n * @deprecated use i18n.keyScheme instead\n */\n i18nKeyScheme?: \"content\" | \"hash\" | \"path\";\n i18n?: {\n keyScheme: \"content\" | \"hash\" | \"path\";\n tagPrefix?: string;\n };\n skipHead?: boolean;\n nativeFetch?: boolean;\n manualRedirect?: boolean;\n}\n\nexport interface LoaderBundleCache {\n set: (data: LoaderBundleOutput) => Promise<void>;\n get: () => Promise<LoaderBundleOutput>;\n}\n\nexport class PlasmicModulesFetcher {\n private api: Api;\n private curFetch: Promise<LoaderBundleOutput> | undefined = undefined;\n constructor(private opts: FetcherOptions) {\n this.api = new Api({\n projects: opts.projects,\n host: opts.host,\n apiHost: opts.apiHost,\n cdnHost: opts.cdnHost,\n nativeFetch: opts.nativeFetch,\n manualRedirect: opts.manualRedirect,\n });\n }\n\n getChunksUrl(bundle: LoaderBundleOutput, modules: CodeModule[]) {\n return this.api.getChunksUrl(bundle, modules);\n }\n\n async fetchAllData() {\n // getCachedOrFetched uses a cache defined by the user.\n const bundle = await this.getCachedOrFetch();\n\n // For React Server Components (Next.js 13+),\n // we need to pass server modules in LoaderBundleOutput from Server Components to Client Components.\n // We don't want to pass them via normal page props because that will be serialized to the browser.\n // Instead, we pass the bundle (including the server modules) via the Node `global` variable.\n //\n // cacheBundleInNodeServer caches a bundle in the Node server process.\n this.cacheBundleInNodeServer(bundle);\n\n return bundle;\n }\n\n private async getCachedOrFetch() {\n if (this.opts.cache) {\n const cachedData = await this.opts.cache.get();\n if (cachedData) {\n return cachedData;\n }\n }\n if (this.curFetch) {\n return await this.curFetch;\n }\n if (typeof process === \"undefined\" || !process.env?.PLASMIC_QUIET) {\n console.debug(\"Plasmic: doing a fresh fetch...\");\n }\n const fetchPromise = this.doFetch();\n this.curFetch = fetchPromise;\n try {\n const data = await fetchPromise;\n return data;\n } finally {\n // Reset this.curFetch only if it still holds the original fetch promise\n if (this.curFetch === fetchPromise) {\n this.curFetch = undefined;\n }\n }\n }\n\n private async doFetch() {\n const data = await this.api.fetchLoaderData(\n this.opts.projects.map((p) =>\n p.version ? `${p.id}@${p.version}` : p.id\n ),\n {\n platform: this.opts.platform,\n platformOptions: this.opts.platformOptions,\n preview: this.opts.preview,\n i18nKeyScheme: this.opts.i18n?.keyScheme ?? this.opts.i18nKeyScheme,\n i18nTagPrefix: this.opts.i18n?.tagPrefix,\n browserOnly: isBrowser,\n skipHead: this.opts.skipHead,\n }\n );\n if (this.opts.cache) {\n await this.opts.cache.set(data);\n }\n if (typeof process === \"undefined\" || !process.env?.PLASMIC_QUIET) {\n console.debug(\n `Plasmic: fetched designs for ${data.projects\n .map((p) => `\"${p.name}\" (${p.id}@${p.version})`)\n .join(\", \")}`\n );\n }\n return data;\n }\n\n private cacheBundleInNodeServer(bundle: LoaderBundleOutput) {\n if (isBrowser) {\n return;\n }\n\n const global = globalThis as GlobalWithBundles;\n if (global.__PLASMIC_BUNDLES === undefined) {\n global.__PLASMIC_BUNDLES = {};\n }\n global.__PLASMIC_BUNDLES[getBundleKey(this.opts)] = bundle;\n }\n}\n\nexport function internal_getCachedBundleInNodeServer(\n opts: FetcherOptions\n): LoaderBundleOutput | undefined {\n if (isBrowser) {\n throw new Error(`Should not be consulting Node server cache in browser`);\n }\n\n const global = globalThis as GlobalWithBundles;\n return global.__PLASMIC_BUNDLES?.[getBundleKey(opts)];\n}\n\nfunction getBundleKey({\n host,\n platform,\n i18nKeyScheme,\n preview,\n projects,\n skipHead,\n}: FetcherOptions) {\n return JSON.stringify({\n host,\n platform,\n i18nKeyScheme,\n preview,\n projects,\n skipHead,\n });\n}\n\ninterface GlobalWithBundles {\n __PLASMIC_BUNDLES?: { [bundleKey: string]: LoaderBundleOutput };\n}\n"],
|
|
5
|
-
"mappings": ";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAAA,OAAO,aAAa;
|
|
4
|
+
"sourcesContent": ["import unfetch from \"@plasmicapp/isomorphic-unfetch\";\n\nexport interface ComponentMeta {\n id: string;\n usedComponents: string[];\n projectId: string;\n name: string;\n displayName: string;\n cssFile: string;\n path: string | undefined;\n isPage: boolean;\n plumeType?: string;\n entry: string;\n isCode: boolean;\n isGlobalContextProvider: boolean;\n pageMetadata?: PageMetadata;\n metadata?: Record<string, string>;\n serverQueriesExecFuncFileName?: string;\n}\n\nexport interface PageMeta extends ComponentMeta {\n isPage: true;\n path: string;\n plumeType: never;\n pageMetadata: PageMetadata;\n}\n\nexport interface PageMetadata {\n path: string;\n title?: string | null;\n description?: string | null;\n openGraphImageUrl?: string | null;\n canonical?: string | null;\n}\n\nexport interface GlobalGroupMeta {\n id: string;\n projectId: string;\n name: string;\n type: string;\n contextFile: string;\n useName: string;\n}\n\n// Keep in sync with platform/wab ProjectMeta\nexport interface ProjectMeta {\n id: string;\n teamId?: string;\n indirect: boolean;\n name: string;\n version: string;\n remoteFonts: FontMeta[];\n hasStyleTokenOverrides: boolean;\n styleTokensProviderFileName: string;\n globalContextsProviderFileName: string;\n}\n\nexport interface FontMeta {\n url: string;\n}\n\ninterface GlobalVariantSplitContent {\n type: \"global-variant\";\n projectId: string;\n group: string;\n variant: string;\n}\n\ninterface Slice {\n id: string;\n contents: GlobalVariantSplitContent[];\n externalId?: string;\n}\n\nexport interface ExperimentSlice extends Slice {\n prob: number;\n}\n\nexport interface SegmentSlice extends Slice {\n cond: any;\n}\n\ninterface BareSplit {\n id: string;\n projectId: string;\n name: string;\n externalId?: string;\n description?: string;\n pagesPaths: string[];\n}\n\nexport interface ExperimentSplit extends BareSplit {\n type: \"experiment\";\n slices: ExperimentSlice[];\n}\n\nexport interface SegmentSplit extends BareSplit {\n type: \"segment\";\n slices: SegmentSlice[];\n}\n\nexport type Split = ExperimentSplit | SegmentSplit;\n\ninterface ApiLoaderBundleOutput {\n modules: {\n browser: (CodeModule | AssetModule)[];\n server: (CodeModule | AssetModule)[];\n };\n components: ComponentMeta[];\n globalGroups: GlobalGroupMeta[];\n projects: ProjectMeta[];\n activeSplits: Split[];\n bundleKey: string | null;\n deferChunksByDefault: boolean;\n disableRootLoadingBoundaryByDefault: boolean;\n redirectUrl?: string;\n}\n\nexport interface LoaderBundleOutput extends ApiLoaderBundleOutput {\n // A map from project ID to the list of component IDs that are not included in the bundle\n // this is used to know which components exist in the project, which allow us to properly\n // handle bundle merging being aware of the deleted components.\n filteredIds: Record<string, string[]>;\n}\n\nexport interface CodeModule {\n fileName: string;\n code: string;\n imports: string[];\n type: \"code\";\n}\n\nexport interface AssetModule {\n fileName: string;\n source: string;\n type: \"asset\";\n}\n\nconst VERSION = \"10\";\n\nexport const isBrowser =\n typeof window !== \"undefined\" &&\n window != null &&\n typeof window.document !== \"undefined\";\n\nexport function transformApiLoaderBundleOutput(\n bundle: ApiLoaderBundleOutput\n): LoaderBundleOutput {\n return {\n ...bundle,\n filteredIds: Object.fromEntries(bundle.projects.map((p) => [p.id, []])),\n };\n}\n\nexport class Api {\n private readonly apiHost: string;\n private readonly cdnHost: string;\n private fetch: typeof globalThis.fetch;\n\n private lastResponse:\n | {\n bundle: LoaderBundleOutput;\n key: string;\n }\n | undefined = undefined;\n\n constructor(\n private opts: {\n projects: { id: string; token: string }[];\n host?: string;\n apiHost?: string;\n cdnHost?: string;\n nativeFetch?: boolean;\n manualRedirect?: boolean;\n }\n ) {\n this.apiHost =\n opts.apiHost ?? opts.host ?? \"https://codegen-origin.plasmic.app\";\n this.cdnHost = opts.cdnHost ?? opts.host ?? \"https://codegen.plasmic.app\";\n this.fetch = (\n opts.nativeFetch && globalThis.fetch ? globalThis.fetch : unfetch\n ).bind(globalThis);\n }\n\n async fetchLoaderData(\n projectIds: string[],\n opts: {\n platform?: \"react\" | \"nextjs\" | \"gatsby\";\n platformOptions?: {\n nextjs?: {\n appDir: boolean;\n };\n };\n preview?: boolean;\n browserOnly?: boolean;\n i18nKeyScheme?: \"content\" | \"hash\" | \"path\";\n i18nTagPrefix?: string;\n skipHead?: boolean;\n }\n ): Promise<LoaderBundleOutput> {\n const { platform, preview } = opts;\n const query = new URLSearchParams([\n [\"platform\", platform ?? \"react\"],\n ...(opts.platformOptions?.nextjs?.appDir\n ? [[\"nextjsAppDir\", \"true\"]]\n : []),\n ...projectIds.map((projectId) => [\"projectId\", projectId]),\n ...(opts.browserOnly ? [[\"browserOnly\", \"true\"]] : []),\n ...(opts.i18nKeyScheme ? [[\"i18nKeyScheme\", opts.i18nKeyScheme]] : []),\n ...(opts.i18nTagPrefix ? [[\"i18nTagPrefix\", opts.i18nTagPrefix]] : []),\n ...(opts.skipHead ? [[\"skipHead\", \"true\"]] : []),\n ]).toString();\n\n const host = preview ? this.apiHost : this.cdnHost;\n const url = preview\n ? `${host}/api/v1/loader/code/preview?${query}`\n : `${host}/api/v1/loader/code/published?${query}`;\n\n // We only expect a redirect when we're dealing with published mode, as there should be\n // a stable set of versions to be used. As in browser, we could receive a opaque response\n // with a redirect, we don't try to use last response in browser.\n const useLastReponse =\n // We consider that manualRedirect is true by default, only by setting it to false\n // we disable it.\n !(this.opts.manualRedirect === false) && !preview && !isBrowser;\n\n if (useLastReponse) {\n const redirectResp = await this.fetch(url, {\n method: \"GET\",\n headers: this.makeGetHeaders(),\n redirect: \"manual\",\n });\n\n if (redirectResp.status !== 301 && redirectResp.status !== 302) {\n const error = await this.parseJsonResponse(redirectResp);\n throw new Error(\n `Error fetching loader data, a redirect was expected: ${\n error?.error?.message ?? redirectResp.statusText\n }`\n );\n }\n\n const nextLocation = redirectResp.headers.get(\"location\");\n if (!nextLocation) {\n throw new Error(\n `Error fetching loader data, a redirect was expected but no location header was found`\n );\n }\n\n if (this.lastResponse?.key === nextLocation) {\n return this.lastResponse.bundle;\n }\n\n const resp = await this.fetch(`${host}${nextLocation}`, {\n method: \"GET\",\n headers: this.makeGetHeaders(),\n });\n\n const json = transformApiLoaderBundleOutput(\n await this.verifyAndParseJsonResponse(resp)\n );\n this.lastResponse = {\n bundle: json,\n key: nextLocation,\n };\n\n return json;\n }\n\n const resp = await this.fetch(url, {\n method: \"GET\",\n headers: this.makeGetHeaders(),\n });\n\n let json = await this.verifyAndParseJsonResponse(resp);\n\n // An Angular polyfill can cause 302 redirects to fail in Safari, due to missing headers.\n // This 200 response with `redirectUrl` is a workaround for specific projects that need it.\n if (json.redirectUrl) {\n const redirectResp = await this.fetch(`${host}${json.redirectUrl}`, {\n method: \"GET\",\n headers: this.makeGetHeaders(),\n });\n json = await this.verifyAndParseJsonResponse(redirectResp);\n }\n\n return transformApiLoaderBundleOutput(json);\n }\n\n private async verifyAndParseJsonResponse(\n resp: Response,\n errorText = \"Error fetching loader data\"\n ) {\n if (resp.status >= 400) {\n const error = await this.parseJsonResponse(resp);\n throw new Error(\n `${errorText}: ${error?.error?.message ?? resp.statusText}`\n );\n }\n return (await this.parseJsonResponse(resp)) as ApiLoaderBundleOutput;\n }\n\n private async parseJsonResponse(resp: Response) {\n const text = await resp.text();\n try {\n return JSON.parse(text);\n } catch (err) {\n throw new Error(\n `Error parsing JSON response: ${err}; status: ${resp.status}; response: ${text}`\n );\n }\n }\n\n private makeGetHeaders() {\n return {\n \"x-plasmic-loader-version\": VERSION,\n ...this.makeAuthHeaders(),\n };\n }\n\n private makeAuthHeaders() {\n const tokens = this.opts.projects\n .map((p) => `${p.id}:${p.token}`)\n .join(\",\");\n return {\n \"x-plasmic-api-project-tokens\": tokens,\n };\n }\n\n getChunksUrl(bundle: LoaderBundleOutput, modules: CodeModule[]) {\n return `${this.cdnHost}/api/v1/loader/chunks?bundleKey=${encodeURIComponent(\n bundle.bundleKey ?? \"null\"\n )}&fileName=${encodeURIComponent(\n modules\n .map((m) => m.fileName)\n .sort()\n .join(\",\")\n )}`;\n }\n}\n", "import { Api, CodeModule, isBrowser, LoaderBundleOutput } from \"./api\";\n\nexport interface FetcherOptions {\n projects: {\n id: string;\n version?: string;\n token: string;\n }[];\n cache?: LoaderBundleCache;\n platform?: \"react\" | \"nextjs\" | \"gatsby\";\n platformOptions?: {\n nextjs?: {\n appDir: boolean;\n };\n };\n preview?: boolean;\n /** Fallback for apiHost and cdnHost. */\n host?: string;\n /** Used for fetching/previewing unpublished content. */\n apiHost?: string;\n /** Used for fetching published content. */\n cdnHost?: string;\n i18n?: {\n keyScheme: \"content\" | \"hash\" | \"path\";\n tagPrefix?: string;\n };\n skipHead?: boolean;\n nativeFetch?: boolean;\n manualRedirect?: boolean;\n}\n\nexport interface LoaderBundleCache {\n set: (data: LoaderBundleOutput) => Promise<void>;\n get: () => Promise<LoaderBundleOutput>;\n}\n\nexport class PlasmicModulesFetcher {\n private api: Api;\n private curFetch: Promise<LoaderBundleOutput> | undefined = undefined;\n constructor(private opts: FetcherOptions) {\n this.api = new Api({\n projects: opts.projects,\n host: opts.host,\n apiHost: opts.apiHost,\n cdnHost: opts.cdnHost,\n nativeFetch: opts.nativeFetch,\n manualRedirect: opts.manualRedirect,\n });\n }\n\n getChunksUrl(bundle: LoaderBundleOutput, modules: CodeModule[]) {\n return this.api.getChunksUrl(bundle, modules);\n }\n\n async fetchAllData() {\n // getCachedOrFetched uses a cache defined by the user.\n const bundle = await this.getCachedOrFetch();\n\n // For React Server Components (Next.js 13+),\n // we need to pass server modules in LoaderBundleOutput from Server Components to Client Components.\n // We don't want to pass them via normal page props because that will be serialized to the browser.\n // Instead, we pass the bundle (including the server modules) via the Node `global` variable.\n //\n // cacheBundleInNodeServer caches a bundle in the Node server process.\n this.cacheBundleInNodeServer(bundle);\n\n return bundle;\n }\n\n private async getCachedOrFetch() {\n if (this.opts.cache) {\n const cachedData = await this.opts.cache.get();\n if (cachedData) {\n return cachedData;\n }\n }\n if (this.curFetch) {\n return await this.curFetch;\n }\n if (typeof process === \"undefined\" || !process.env?.PLASMIC_QUIET) {\n console.debug(\"Plasmic: doing a fresh fetch...\");\n }\n const fetchPromise = this.doFetch();\n this.curFetch = fetchPromise;\n try {\n const data = await fetchPromise;\n return data;\n } finally {\n // Reset this.curFetch only if it still holds the original fetch promise\n if (this.curFetch === fetchPromise) {\n this.curFetch = undefined;\n }\n }\n }\n\n private async doFetch() {\n const data = await this.api.fetchLoaderData(\n this.opts.projects.map((p) =>\n p.version ? `${p.id}@${p.version}` : p.id\n ),\n {\n platform: this.opts.platform,\n platformOptions: this.opts.platformOptions,\n preview: this.opts.preview,\n i18nKeyScheme: this.opts.i18n?.keyScheme,\n i18nTagPrefix: this.opts.i18n?.tagPrefix,\n browserOnly: isBrowser,\n skipHead: this.opts.skipHead,\n }\n );\n if (this.opts.cache) {\n await this.opts.cache.set(data);\n }\n if (typeof process === \"undefined\" || !process.env?.PLASMIC_QUIET) {\n console.debug(\n `Plasmic: fetched designs for ${data.projects\n .map((p) => `\"${p.name}\" (${p.id}@${p.version})`)\n .join(\", \")}`\n );\n }\n return data;\n }\n\n private cacheBundleInNodeServer(bundle: LoaderBundleOutput) {\n if (isBrowser) {\n return;\n }\n\n const global = globalThis as GlobalWithBundles;\n if (global.__PLASMIC_BUNDLES === undefined) {\n global.__PLASMIC_BUNDLES = {};\n }\n global.__PLASMIC_BUNDLES[getBundleKey(this.opts)] = bundle;\n }\n}\n\nexport function internal_getCachedBundleInNodeServer(\n opts: FetcherOptions\n): LoaderBundleOutput | undefined {\n if (isBrowser) {\n throw new Error(`Should not be consulting Node server cache in browser`);\n }\n\n const global = globalThis as GlobalWithBundles;\n return global.__PLASMIC_BUNDLES?.[getBundleKey(opts)];\n}\n\nfunction getBundleKey({\n host,\n platform,\n i18n,\n preview,\n projects,\n skipHead,\n}: FetcherOptions) {\n return JSON.stringify({\n host,\n platform,\n i18nKeyScheme: i18n?.keyScheme,\n preview,\n projects,\n skipHead,\n });\n}\n\ninterface GlobalWithBundles {\n __PLASMIC_BUNDLES?: { [bundleKey: string]: LoaderBundleOutput };\n}\n"],
|
|
5
|
+
"mappings": "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",
|
|
6
6
|
"names": ["resp", "json"]
|
|
7
7
|
}
|
package/dist/index.js
CHANGED
|
@@ -184,12 +184,6 @@ var Api = class {
|
|
|
184
184
|
}
|
|
185
185
|
});
|
|
186
186
|
}
|
|
187
|
-
/** @deprecated */
|
|
188
|
-
fetchHtmlData(_opts) {
|
|
189
|
-
return __async(this, null, function* () {
|
|
190
|
-
throw new Error("deprecated");
|
|
191
|
-
});
|
|
192
|
-
}
|
|
193
187
|
makeGetHeaders() {
|
|
194
188
|
return __spreadValues({
|
|
195
189
|
"x-plasmic-loader-version": VERSION
|
|
@@ -264,7 +258,7 @@ var PlasmicModulesFetcher = class {
|
|
|
264
258
|
}
|
|
265
259
|
doFetch() {
|
|
266
260
|
return __async(this, null, function* () {
|
|
267
|
-
var _a, _b, _c
|
|
261
|
+
var _a, _b, _c;
|
|
268
262
|
const data = yield this.api.fetchLoaderData(
|
|
269
263
|
this.opts.projects.map(
|
|
270
264
|
(p) => p.version ? `${p.id}@${p.version}` : p.id
|
|
@@ -273,8 +267,8 @@ var PlasmicModulesFetcher = class {
|
|
|
273
267
|
platform: this.opts.platform,
|
|
274
268
|
platformOptions: this.opts.platformOptions,
|
|
275
269
|
preview: this.opts.preview,
|
|
276
|
-
i18nKeyScheme: (
|
|
277
|
-
i18nTagPrefix: (
|
|
270
|
+
i18nKeyScheme: (_a = this.opts.i18n) == null ? void 0 : _a.keyScheme,
|
|
271
|
+
i18nTagPrefix: (_b = this.opts.i18n) == null ? void 0 : _b.tagPrefix,
|
|
278
272
|
browserOnly: isBrowser,
|
|
279
273
|
skipHead: this.opts.skipHead
|
|
280
274
|
}
|
|
@@ -282,7 +276,7 @@ var PlasmicModulesFetcher = class {
|
|
|
282
276
|
if (this.opts.cache) {
|
|
283
277
|
yield this.opts.cache.set(data);
|
|
284
278
|
}
|
|
285
|
-
if (typeof process === "undefined" || !((
|
|
279
|
+
if (typeof process === "undefined" || !((_c = process.env) == null ? void 0 : _c.PLASMIC_QUIET)) {
|
|
286
280
|
console.debug(
|
|
287
281
|
`Plasmic: fetched designs for ${data.projects.map((p) => `"${p.name}" (${p.id}@${p.version})`).join(", ")}`
|
|
288
282
|
);
|
|
@@ -312,7 +306,7 @@ function internal_getCachedBundleInNodeServer(opts) {
|
|
|
312
306
|
function getBundleKey({
|
|
313
307
|
host,
|
|
314
308
|
platform,
|
|
315
|
-
|
|
309
|
+
i18n,
|
|
316
310
|
preview,
|
|
317
311
|
projects,
|
|
318
312
|
skipHead
|
|
@@ -320,7 +314,7 @@ function getBundleKey({
|
|
|
320
314
|
return JSON.stringify({
|
|
321
315
|
host,
|
|
322
316
|
platform,
|
|
323
|
-
i18nKeyScheme,
|
|
317
|
+
i18nKeyScheme: i18n == null ? void 0 : i18n.keyScheme,
|
|
324
318
|
preview,
|
|
325
319
|
projects,
|
|
326
320
|
skipHead
|
package/dist/index.js.map
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../src/index.ts", "../src/api.ts", "../src/fetcher.ts"],
|
|
4
|
-
"sourcesContent": ["export type {\n AssetModule,\n CodeModule,\n ComponentMeta,\n ExperimentSlice,\n FontMeta,\n GlobalGroupMeta,\n LoaderBundleOutput,\n LoaderHtmlOutput,\n PageMeta,\n PageMetadata,\n ProjectMeta,\n SegmentSlice,\n Split,\n} from \"./api\";\nexport { Api } from \"./api\";\nexport type { FetcherOptions, LoaderBundleCache } from \"./fetcher\";\nexport {\n internal_getCachedBundleInNodeServer,\n PlasmicModulesFetcher,\n} from \"./fetcher\";\n", "import unfetch from \"@plasmicapp/isomorphic-unfetch\";\n\nexport interface ComponentMeta {\n id: string;\n usedComponents: string[];\n projectId: string;\n name: string;\n displayName: string;\n cssFile: string;\n path: string | undefined;\n isPage: boolean;\n plumeType?: string;\n entry: string;\n isCode: boolean;\n isGlobalContextProvider: boolean;\n pageMetadata?: PageMetadata;\n metadata?: Record<string, string>;\n serverQueriesExecFuncFileName?: string;\n}\n\nexport interface PageMeta extends ComponentMeta {\n isPage: true;\n path: string;\n plumeType: never;\n pageMetadata: PageMetadata;\n}\n\nexport interface PageMetadata {\n path: string;\n title?: string | null;\n description?: string | null;\n openGraphImageUrl?: string | null;\n canonical?: string | null;\n}\n\nexport interface GlobalGroupMeta {\n id: string;\n projectId: string;\n name: string;\n type: string;\n contextFile: string;\n useName: string;\n}\n\n// Keep in sync with platform/wab ProjectMeta\nexport interface ProjectMeta {\n id: string;\n teamId?: string;\n indirect: boolean;\n name: string;\n version: string;\n remoteFonts: FontMeta[];\n hasStyleTokenOverrides: boolean;\n styleTokensProviderFileName: string;\n globalContextsProviderFileName: string;\n}\n\nexport interface FontMeta {\n url: string;\n}\n\ninterface GlobalVariantSplitContent {\n type: \"global-variant\";\n projectId: string;\n group: string;\n variant: string;\n}\n\ninterface Slice {\n id: string;\n contents: GlobalVariantSplitContent[];\n externalId?: string;\n}\n\nexport interface ExperimentSlice extends Slice {\n prob: number;\n}\n\nexport interface SegmentSlice extends Slice {\n cond: any;\n}\n\ninterface BareSplit {\n id: string;\n projectId: string;\n name: string;\n externalId?: string;\n description?: string;\n pagesPaths: string[];\n}\n\nexport interface ExperimentSplit extends BareSplit {\n type: \"experiment\";\n slices: ExperimentSlice[];\n}\n\nexport interface SegmentSplit extends BareSplit {\n type: \"segment\";\n slices: SegmentSlice[];\n}\n\nexport type Split = ExperimentSplit | SegmentSplit;\n\ninterface ApiLoaderBundleOutput {\n modules: {\n browser: (CodeModule | AssetModule)[];\n server: (CodeModule | AssetModule)[];\n };\n components: ComponentMeta[];\n globalGroups: GlobalGroupMeta[];\n projects: ProjectMeta[];\n activeSplits: Split[];\n bundleKey: string | null;\n deferChunksByDefault: boolean;\n disableRootLoadingBoundaryByDefault: boolean;\n redirectUrl?: string;\n}\n\nexport interface LoaderBundleOutput extends ApiLoaderBundleOutput {\n // A map from project ID to the list of component IDs that are not included in the bundle\n // this is used to know which components exist in the project, which allow us to properly\n // handle bundle merging being aware of the deleted components.\n filteredIds: Record<string, string[]>;\n}\n\nexport interface LoaderHtmlOutput {\n html: string;\n}\n\nexport interface CodeModule {\n fileName: string;\n code: string;\n imports: string[];\n type: \"code\";\n}\n\nexport interface AssetModule {\n fileName: string;\n source: string;\n type: \"asset\";\n}\n\nconst VERSION = \"10\";\n\nexport const isBrowser =\n typeof window !== \"undefined\" &&\n window != null &&\n typeof window.document !== \"undefined\";\n\nexport function transformApiLoaderBundleOutput(\n bundle: ApiLoaderBundleOutput\n): LoaderBundleOutput {\n return {\n ...bundle,\n filteredIds: Object.fromEntries(bundle.projects.map((p) => [p.id, []])),\n };\n}\n\nexport class Api {\n private readonly apiHost: string;\n private readonly cdnHost: string;\n private fetch: typeof globalThis.fetch;\n\n private lastResponse:\n | {\n bundle: LoaderBundleOutput;\n key: string;\n }\n | undefined = undefined;\n\n constructor(\n private opts: {\n projects: { id: string; token: string }[];\n host?: string;\n apiHost?: string;\n cdnHost?: string;\n nativeFetch?: boolean;\n manualRedirect?: boolean;\n }\n ) {\n this.apiHost =\n opts.apiHost ?? opts.host ?? \"https://codegen-origin.plasmic.app\";\n this.cdnHost = opts.cdnHost ?? opts.host ?? \"https://codegen.plasmic.app\";\n this.fetch = (\n opts.nativeFetch && globalThis.fetch ? globalThis.fetch : unfetch\n ).bind(globalThis);\n }\n\n async fetchLoaderData(\n projectIds: string[],\n opts: {\n platform?: \"react\" | \"nextjs\" | \"gatsby\";\n platformOptions?: {\n nextjs?: {\n appDir: boolean;\n };\n };\n preview?: boolean;\n browserOnly?: boolean;\n i18nKeyScheme?: \"content\" | \"hash\" | \"path\";\n i18nTagPrefix?: string;\n skipHead?: boolean;\n }\n ): Promise<LoaderBundleOutput> {\n const { platform, preview } = opts;\n const query = new URLSearchParams([\n [\"platform\", platform ?? \"react\"],\n ...(opts.platformOptions?.nextjs?.appDir\n ? [[\"nextjsAppDir\", \"true\"]]\n : []),\n ...projectIds.map((projectId) => [\"projectId\", projectId]),\n ...(opts.browserOnly ? [[\"browserOnly\", \"true\"]] : []),\n ...(opts.i18nKeyScheme ? [[\"i18nKeyScheme\", opts.i18nKeyScheme]] : []),\n ...(opts.i18nTagPrefix ? [[\"i18nTagPrefix\", opts.i18nTagPrefix]] : []),\n ...(opts.skipHead ? [[\"skipHead\", \"true\"]] : []),\n ]).toString();\n\n const host = preview ? this.apiHost : this.cdnHost;\n const url = preview\n ? `${host}/api/v1/loader/code/preview?${query}`\n : `${host}/api/v1/loader/code/published?${query}`;\n\n // We only expect a redirect when we're dealing with published mode, as there should be\n // a stable set of versions to be used. As in browser, we could receive a opaque response\n // with a redirect, we don't try to use last response in browser.\n const useLastReponse =\n // We consider that manualRedirect is true by default, only by setting it to false\n // we disable it.\n !(this.opts.manualRedirect === false) && !preview && !isBrowser;\n\n if (useLastReponse) {\n const redirectResp = await this.fetch(url, {\n method: \"GET\",\n headers: this.makeGetHeaders(),\n redirect: \"manual\",\n });\n\n if (redirectResp.status !== 301 && redirectResp.status !== 302) {\n const error = await this.parseJsonResponse(redirectResp);\n throw new Error(\n `Error fetching loader data, a redirect was expected: ${\n error?.error?.message ?? redirectResp.statusText\n }`\n );\n }\n\n const nextLocation = redirectResp.headers.get(\"location\");\n if (!nextLocation) {\n throw new Error(\n `Error fetching loader data, a redirect was expected but no location header was found`\n );\n }\n\n if (this.lastResponse?.key === nextLocation) {\n return this.lastResponse.bundle;\n }\n\n const resp = await this.fetch(`${host}${nextLocation}`, {\n method: \"GET\",\n headers: this.makeGetHeaders(),\n });\n\n const json = transformApiLoaderBundleOutput(\n await this.verifyAndParseJsonResponse(resp)\n );\n this.lastResponse = {\n bundle: json,\n key: nextLocation,\n };\n\n return json;\n }\n\n const resp = await this.fetch(url, {\n method: \"GET\",\n headers: this.makeGetHeaders(),\n });\n\n let json = await this.verifyAndParseJsonResponse(resp);\n\n // An Angular polyfill can cause 302 redirects to fail in Safari, due to missing headers.\n // This 200 response with `redirectUrl` is a workaround for specific projects that need it.\n if (json.redirectUrl) {\n const redirectResp = await this.fetch(`${host}${json.redirectUrl}`, {\n method: \"GET\",\n headers: this.makeGetHeaders(),\n });\n json = await this.verifyAndParseJsonResponse(redirectResp);\n }\n\n return transformApiLoaderBundleOutput(json);\n }\n\n private async verifyAndParseJsonResponse(\n resp: Response,\n errorText = \"Error fetching loader data\"\n ) {\n if (resp.status >= 400) {\n const error = await this.parseJsonResponse(resp);\n throw new Error(\n `${errorText}: ${error?.error?.message ?? resp.statusText}`\n );\n }\n return (await this.parseJsonResponse(resp)) as ApiLoaderBundleOutput;\n }\n\n private async parseJsonResponse(resp: Response) {\n const text = await resp.text();\n try {\n return JSON.parse(text);\n } catch (err) {\n throw new Error(\n `Error parsing JSON response: ${err}; status: ${resp.status}; response: ${text}`\n );\n }\n }\n\n /** @deprecated */\n async fetchHtmlData(_opts: {\n projectId: string;\n component: string;\n hydrate?: boolean;\n embedHydrate?: boolean;\n }): Promise<LoaderHtmlOutput> {\n throw new Error(\"deprecated\");\n }\n\n private makeGetHeaders() {\n return {\n \"x-plasmic-loader-version\": VERSION,\n ...this.makeAuthHeaders(),\n };\n }\n\n private makeAuthHeaders() {\n const tokens = this.opts.projects\n .map((p) => `${p.id}:${p.token}`)\n .join(\",\");\n return {\n \"x-plasmic-api-project-tokens\": tokens,\n };\n }\n\n getChunksUrl(bundle: LoaderBundleOutput, modules: CodeModule[]) {\n return `${this.cdnHost}/api/v1/loader/chunks?bundleKey=${encodeURIComponent(\n bundle.bundleKey ?? \"null\"\n )}&fileName=${encodeURIComponent(\n modules\n .map((m) => m.fileName)\n .sort()\n .join(\",\")\n )}`;\n }\n}\n", "import { Api, CodeModule, isBrowser, LoaderBundleOutput } from \"./api\";\n\nexport interface FetcherOptions {\n projects: {\n id: string;\n version?: string;\n token: string;\n }[];\n cache?: LoaderBundleCache;\n platform?: \"react\" | \"nextjs\" | \"gatsby\";\n platformOptions?: {\n nextjs?: {\n appDir: boolean;\n };\n };\n preview?: boolean;\n /** Fallback for apiHost and cdnHost. */\n host?: string;\n /** Used for fetching/previewing unpublished content. */\n apiHost?: string;\n /** Used for fetching published content. */\n cdnHost?: string;\n /**\n * @deprecated use i18n.keyScheme instead\n */\n i18nKeyScheme?: \"content\" | \"hash\" | \"path\";\n i18n?: {\n keyScheme: \"content\" | \"hash\" | \"path\";\n tagPrefix?: string;\n };\n skipHead?: boolean;\n nativeFetch?: boolean;\n manualRedirect?: boolean;\n}\n\nexport interface LoaderBundleCache {\n set: (data: LoaderBundleOutput) => Promise<void>;\n get: () => Promise<LoaderBundleOutput>;\n}\n\nexport class PlasmicModulesFetcher {\n private api: Api;\n private curFetch: Promise<LoaderBundleOutput> | undefined = undefined;\n constructor(private opts: FetcherOptions) {\n this.api = new Api({\n projects: opts.projects,\n host: opts.host,\n apiHost: opts.apiHost,\n cdnHost: opts.cdnHost,\n nativeFetch: opts.nativeFetch,\n manualRedirect: opts.manualRedirect,\n });\n }\n\n getChunksUrl(bundle: LoaderBundleOutput, modules: CodeModule[]) {\n return this.api.getChunksUrl(bundle, modules);\n }\n\n async fetchAllData() {\n // getCachedOrFetched uses a cache defined by the user.\n const bundle = await this.getCachedOrFetch();\n\n // For React Server Components (Next.js 13+),\n // we need to pass server modules in LoaderBundleOutput from Server Components to Client Components.\n // We don't want to pass them via normal page props because that will be serialized to the browser.\n // Instead, we pass the bundle (including the server modules) via the Node `global` variable.\n //\n // cacheBundleInNodeServer caches a bundle in the Node server process.\n this.cacheBundleInNodeServer(bundle);\n\n return bundle;\n }\n\n private async getCachedOrFetch() {\n if (this.opts.cache) {\n const cachedData = await this.opts.cache.get();\n if (cachedData) {\n return cachedData;\n }\n }\n if (this.curFetch) {\n return await this.curFetch;\n }\n if (typeof process === \"undefined\" || !process.env?.PLASMIC_QUIET) {\n console.debug(\"Plasmic: doing a fresh fetch...\");\n }\n const fetchPromise = this.doFetch();\n this.curFetch = fetchPromise;\n try {\n const data = await fetchPromise;\n return data;\n } finally {\n // Reset this.curFetch only if it still holds the original fetch promise\n if (this.curFetch === fetchPromise) {\n this.curFetch = undefined;\n }\n }\n }\n\n private async doFetch() {\n const data = await this.api.fetchLoaderData(\n this.opts.projects.map((p) =>\n p.version ? `${p.id}@${p.version}` : p.id\n ),\n {\n platform: this.opts.platform,\n platformOptions: this.opts.platformOptions,\n preview: this.opts.preview,\n i18nKeyScheme: this.opts.i18n?.keyScheme ?? this.opts.i18nKeyScheme,\n i18nTagPrefix: this.opts.i18n?.tagPrefix,\n browserOnly: isBrowser,\n skipHead: this.opts.skipHead,\n }\n );\n if (this.opts.cache) {\n await this.opts.cache.set(data);\n }\n if (typeof process === \"undefined\" || !process.env?.PLASMIC_QUIET) {\n console.debug(\n `Plasmic: fetched designs for ${data.projects\n .map((p) => `\"${p.name}\" (${p.id}@${p.version})`)\n .join(\", \")}`\n );\n }\n return data;\n }\n\n private cacheBundleInNodeServer(bundle: LoaderBundleOutput) {\n if (isBrowser) {\n return;\n }\n\n const global = globalThis as GlobalWithBundles;\n if (global.__PLASMIC_BUNDLES === undefined) {\n global.__PLASMIC_BUNDLES = {};\n }\n global.__PLASMIC_BUNDLES[getBundleKey(this.opts)] = bundle;\n }\n}\n\nexport function internal_getCachedBundleInNodeServer(\n opts: FetcherOptions\n): LoaderBundleOutput | undefined {\n if (isBrowser) {\n throw new Error(`Should not be consulting Node server cache in browser`);\n }\n\n const global = globalThis as GlobalWithBundles;\n return global.__PLASMIC_BUNDLES?.[getBundleKey(opts)];\n}\n\nfunction getBundleKey({\n host,\n platform,\n i18nKeyScheme,\n preview,\n projects,\n skipHead,\n}: FetcherOptions) {\n return JSON.stringify({\n host,\n platform,\n i18nKeyScheme,\n preview,\n projects,\n skipHead,\n });\n}\n\ninterface GlobalWithBundles {\n __PLASMIC_BUNDLES?: { [bundleKey: string]: LoaderBundleOutput };\n}\n"],
|
|
5
|
-
"mappings": ";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;;ACAA,gCAAoB;
|
|
4
|
+
"sourcesContent": ["export { Api } from \"./api\";\nexport type {\n AssetModule,\n CodeModule,\n ComponentMeta,\n ExperimentSlice,\n FontMeta,\n GlobalGroupMeta,\n LoaderBundleOutput,\n PageMeta,\n PageMetadata,\n ProjectMeta,\n SegmentSlice,\n Split,\n} from \"./api\";\nexport {\n PlasmicModulesFetcher,\n internal_getCachedBundleInNodeServer,\n} from \"./fetcher\";\nexport type { FetcherOptions, LoaderBundleCache } from \"./fetcher\";\n", "import unfetch from \"@plasmicapp/isomorphic-unfetch\";\n\nexport interface ComponentMeta {\n id: string;\n usedComponents: string[];\n projectId: string;\n name: string;\n displayName: string;\n cssFile: string;\n path: string | undefined;\n isPage: boolean;\n plumeType?: string;\n entry: string;\n isCode: boolean;\n isGlobalContextProvider: boolean;\n pageMetadata?: PageMetadata;\n metadata?: Record<string, string>;\n serverQueriesExecFuncFileName?: string;\n}\n\nexport interface PageMeta extends ComponentMeta {\n isPage: true;\n path: string;\n plumeType: never;\n pageMetadata: PageMetadata;\n}\n\nexport interface PageMetadata {\n path: string;\n title?: string | null;\n description?: string | null;\n openGraphImageUrl?: string | null;\n canonical?: string | null;\n}\n\nexport interface GlobalGroupMeta {\n id: string;\n projectId: string;\n name: string;\n type: string;\n contextFile: string;\n useName: string;\n}\n\n// Keep in sync with platform/wab ProjectMeta\nexport interface ProjectMeta {\n id: string;\n teamId?: string;\n indirect: boolean;\n name: string;\n version: string;\n remoteFonts: FontMeta[];\n hasStyleTokenOverrides: boolean;\n styleTokensProviderFileName: string;\n globalContextsProviderFileName: string;\n}\n\nexport interface FontMeta {\n url: string;\n}\n\ninterface GlobalVariantSplitContent {\n type: \"global-variant\";\n projectId: string;\n group: string;\n variant: string;\n}\n\ninterface Slice {\n id: string;\n contents: GlobalVariantSplitContent[];\n externalId?: string;\n}\n\nexport interface ExperimentSlice extends Slice {\n prob: number;\n}\n\nexport interface SegmentSlice extends Slice {\n cond: any;\n}\n\ninterface BareSplit {\n id: string;\n projectId: string;\n name: string;\n externalId?: string;\n description?: string;\n pagesPaths: string[];\n}\n\nexport interface ExperimentSplit extends BareSplit {\n type: \"experiment\";\n slices: ExperimentSlice[];\n}\n\nexport interface SegmentSplit extends BareSplit {\n type: \"segment\";\n slices: SegmentSlice[];\n}\n\nexport type Split = ExperimentSplit | SegmentSplit;\n\ninterface ApiLoaderBundleOutput {\n modules: {\n browser: (CodeModule | AssetModule)[];\n server: (CodeModule | AssetModule)[];\n };\n components: ComponentMeta[];\n globalGroups: GlobalGroupMeta[];\n projects: ProjectMeta[];\n activeSplits: Split[];\n bundleKey: string | null;\n deferChunksByDefault: boolean;\n disableRootLoadingBoundaryByDefault: boolean;\n redirectUrl?: string;\n}\n\nexport interface LoaderBundleOutput extends ApiLoaderBundleOutput {\n // A map from project ID to the list of component IDs that are not included in the bundle\n // this is used to know which components exist in the project, which allow us to properly\n // handle bundle merging being aware of the deleted components.\n filteredIds: Record<string, string[]>;\n}\n\nexport interface CodeModule {\n fileName: string;\n code: string;\n imports: string[];\n type: \"code\";\n}\n\nexport interface AssetModule {\n fileName: string;\n source: string;\n type: \"asset\";\n}\n\nconst VERSION = \"10\";\n\nexport const isBrowser =\n typeof window !== \"undefined\" &&\n window != null &&\n typeof window.document !== \"undefined\";\n\nexport function transformApiLoaderBundleOutput(\n bundle: ApiLoaderBundleOutput\n): LoaderBundleOutput {\n return {\n ...bundle,\n filteredIds: Object.fromEntries(bundle.projects.map((p) => [p.id, []])),\n };\n}\n\nexport class Api {\n private readonly apiHost: string;\n private readonly cdnHost: string;\n private fetch: typeof globalThis.fetch;\n\n private lastResponse:\n | {\n bundle: LoaderBundleOutput;\n key: string;\n }\n | undefined = undefined;\n\n constructor(\n private opts: {\n projects: { id: string; token: string }[];\n host?: string;\n apiHost?: string;\n cdnHost?: string;\n nativeFetch?: boolean;\n manualRedirect?: boolean;\n }\n ) {\n this.apiHost =\n opts.apiHost ?? opts.host ?? \"https://codegen-origin.plasmic.app\";\n this.cdnHost = opts.cdnHost ?? opts.host ?? \"https://codegen.plasmic.app\";\n this.fetch = (\n opts.nativeFetch && globalThis.fetch ? globalThis.fetch : unfetch\n ).bind(globalThis);\n }\n\n async fetchLoaderData(\n projectIds: string[],\n opts: {\n platform?: \"react\" | \"nextjs\" | \"gatsby\";\n platformOptions?: {\n nextjs?: {\n appDir: boolean;\n };\n };\n preview?: boolean;\n browserOnly?: boolean;\n i18nKeyScheme?: \"content\" | \"hash\" | \"path\";\n i18nTagPrefix?: string;\n skipHead?: boolean;\n }\n ): Promise<LoaderBundleOutput> {\n const { platform, preview } = opts;\n const query = new URLSearchParams([\n [\"platform\", platform ?? \"react\"],\n ...(opts.platformOptions?.nextjs?.appDir\n ? [[\"nextjsAppDir\", \"true\"]]\n : []),\n ...projectIds.map((projectId) => [\"projectId\", projectId]),\n ...(opts.browserOnly ? [[\"browserOnly\", \"true\"]] : []),\n ...(opts.i18nKeyScheme ? [[\"i18nKeyScheme\", opts.i18nKeyScheme]] : []),\n ...(opts.i18nTagPrefix ? [[\"i18nTagPrefix\", opts.i18nTagPrefix]] : []),\n ...(opts.skipHead ? [[\"skipHead\", \"true\"]] : []),\n ]).toString();\n\n const host = preview ? this.apiHost : this.cdnHost;\n const url = preview\n ? `${host}/api/v1/loader/code/preview?${query}`\n : `${host}/api/v1/loader/code/published?${query}`;\n\n // We only expect a redirect when we're dealing with published mode, as there should be\n // a stable set of versions to be used. As in browser, we could receive a opaque response\n // with a redirect, we don't try to use last response in browser.\n const useLastReponse =\n // We consider that manualRedirect is true by default, only by setting it to false\n // we disable it.\n !(this.opts.manualRedirect === false) && !preview && !isBrowser;\n\n if (useLastReponse) {\n const redirectResp = await this.fetch(url, {\n method: \"GET\",\n headers: this.makeGetHeaders(),\n redirect: \"manual\",\n });\n\n if (redirectResp.status !== 301 && redirectResp.status !== 302) {\n const error = await this.parseJsonResponse(redirectResp);\n throw new Error(\n `Error fetching loader data, a redirect was expected: ${\n error?.error?.message ?? redirectResp.statusText\n }`\n );\n }\n\n const nextLocation = redirectResp.headers.get(\"location\");\n if (!nextLocation) {\n throw new Error(\n `Error fetching loader data, a redirect was expected but no location header was found`\n );\n }\n\n if (this.lastResponse?.key === nextLocation) {\n return this.lastResponse.bundle;\n }\n\n const resp = await this.fetch(`${host}${nextLocation}`, {\n method: \"GET\",\n headers: this.makeGetHeaders(),\n });\n\n const json = transformApiLoaderBundleOutput(\n await this.verifyAndParseJsonResponse(resp)\n );\n this.lastResponse = {\n bundle: json,\n key: nextLocation,\n };\n\n return json;\n }\n\n const resp = await this.fetch(url, {\n method: \"GET\",\n headers: this.makeGetHeaders(),\n });\n\n let json = await this.verifyAndParseJsonResponse(resp);\n\n // An Angular polyfill can cause 302 redirects to fail in Safari, due to missing headers.\n // This 200 response with `redirectUrl` is a workaround for specific projects that need it.\n if (json.redirectUrl) {\n const redirectResp = await this.fetch(`${host}${json.redirectUrl}`, {\n method: \"GET\",\n headers: this.makeGetHeaders(),\n });\n json = await this.verifyAndParseJsonResponse(redirectResp);\n }\n\n return transformApiLoaderBundleOutput(json);\n }\n\n private async verifyAndParseJsonResponse(\n resp: Response,\n errorText = \"Error fetching loader data\"\n ) {\n if (resp.status >= 400) {\n const error = await this.parseJsonResponse(resp);\n throw new Error(\n `${errorText}: ${error?.error?.message ?? resp.statusText}`\n );\n }\n return (await this.parseJsonResponse(resp)) as ApiLoaderBundleOutput;\n }\n\n private async parseJsonResponse(resp: Response) {\n const text = await resp.text();\n try {\n return JSON.parse(text);\n } catch (err) {\n throw new Error(\n `Error parsing JSON response: ${err}; status: ${resp.status}; response: ${text}`\n );\n }\n }\n\n private makeGetHeaders() {\n return {\n \"x-plasmic-loader-version\": VERSION,\n ...this.makeAuthHeaders(),\n };\n }\n\n private makeAuthHeaders() {\n const tokens = this.opts.projects\n .map((p) => `${p.id}:${p.token}`)\n .join(\",\");\n return {\n \"x-plasmic-api-project-tokens\": tokens,\n };\n }\n\n getChunksUrl(bundle: LoaderBundleOutput, modules: CodeModule[]) {\n return `${this.cdnHost}/api/v1/loader/chunks?bundleKey=${encodeURIComponent(\n bundle.bundleKey ?? \"null\"\n )}&fileName=${encodeURIComponent(\n modules\n .map((m) => m.fileName)\n .sort()\n .join(\",\")\n )}`;\n }\n}\n", "import { Api, CodeModule, isBrowser, LoaderBundleOutput } from \"./api\";\n\nexport interface FetcherOptions {\n projects: {\n id: string;\n version?: string;\n token: string;\n }[];\n cache?: LoaderBundleCache;\n platform?: \"react\" | \"nextjs\" | \"gatsby\";\n platformOptions?: {\n nextjs?: {\n appDir: boolean;\n };\n };\n preview?: boolean;\n /** Fallback for apiHost and cdnHost. */\n host?: string;\n /** Used for fetching/previewing unpublished content. */\n apiHost?: string;\n /** Used for fetching published content. */\n cdnHost?: string;\n i18n?: {\n keyScheme: \"content\" | \"hash\" | \"path\";\n tagPrefix?: string;\n };\n skipHead?: boolean;\n nativeFetch?: boolean;\n manualRedirect?: boolean;\n}\n\nexport interface LoaderBundleCache {\n set: (data: LoaderBundleOutput) => Promise<void>;\n get: () => Promise<LoaderBundleOutput>;\n}\n\nexport class PlasmicModulesFetcher {\n private api: Api;\n private curFetch: Promise<LoaderBundleOutput> | undefined = undefined;\n constructor(private opts: FetcherOptions) {\n this.api = new Api({\n projects: opts.projects,\n host: opts.host,\n apiHost: opts.apiHost,\n cdnHost: opts.cdnHost,\n nativeFetch: opts.nativeFetch,\n manualRedirect: opts.manualRedirect,\n });\n }\n\n getChunksUrl(bundle: LoaderBundleOutput, modules: CodeModule[]) {\n return this.api.getChunksUrl(bundle, modules);\n }\n\n async fetchAllData() {\n // getCachedOrFetched uses a cache defined by the user.\n const bundle = await this.getCachedOrFetch();\n\n // For React Server Components (Next.js 13+),\n // we need to pass server modules in LoaderBundleOutput from Server Components to Client Components.\n // We don't want to pass them via normal page props because that will be serialized to the browser.\n // Instead, we pass the bundle (including the server modules) via the Node `global` variable.\n //\n // cacheBundleInNodeServer caches a bundle in the Node server process.\n this.cacheBundleInNodeServer(bundle);\n\n return bundle;\n }\n\n private async getCachedOrFetch() {\n if (this.opts.cache) {\n const cachedData = await this.opts.cache.get();\n if (cachedData) {\n return cachedData;\n }\n }\n if (this.curFetch) {\n return await this.curFetch;\n }\n if (typeof process === \"undefined\" || !process.env?.PLASMIC_QUIET) {\n console.debug(\"Plasmic: doing a fresh fetch...\");\n }\n const fetchPromise = this.doFetch();\n this.curFetch = fetchPromise;\n try {\n const data = await fetchPromise;\n return data;\n } finally {\n // Reset this.curFetch only if it still holds the original fetch promise\n if (this.curFetch === fetchPromise) {\n this.curFetch = undefined;\n }\n }\n }\n\n private async doFetch() {\n const data = await this.api.fetchLoaderData(\n this.opts.projects.map((p) =>\n p.version ? `${p.id}@${p.version}` : p.id\n ),\n {\n platform: this.opts.platform,\n platformOptions: this.opts.platformOptions,\n preview: this.opts.preview,\n i18nKeyScheme: this.opts.i18n?.keyScheme,\n i18nTagPrefix: this.opts.i18n?.tagPrefix,\n browserOnly: isBrowser,\n skipHead: this.opts.skipHead,\n }\n );\n if (this.opts.cache) {\n await this.opts.cache.set(data);\n }\n if (typeof process === \"undefined\" || !process.env?.PLASMIC_QUIET) {\n console.debug(\n `Plasmic: fetched designs for ${data.projects\n .map((p) => `\"${p.name}\" (${p.id}@${p.version})`)\n .join(\", \")}`\n );\n }\n return data;\n }\n\n private cacheBundleInNodeServer(bundle: LoaderBundleOutput) {\n if (isBrowser) {\n return;\n }\n\n const global = globalThis as GlobalWithBundles;\n if (global.__PLASMIC_BUNDLES === undefined) {\n global.__PLASMIC_BUNDLES = {};\n }\n global.__PLASMIC_BUNDLES[getBundleKey(this.opts)] = bundle;\n }\n}\n\nexport function internal_getCachedBundleInNodeServer(\n opts: FetcherOptions\n): LoaderBundleOutput | undefined {\n if (isBrowser) {\n throw new Error(`Should not be consulting Node server cache in browser`);\n }\n\n const global = globalThis as GlobalWithBundles;\n return global.__PLASMIC_BUNDLES?.[getBundleKey(opts)];\n}\n\nfunction getBundleKey({\n host,\n platform,\n i18n,\n preview,\n projects,\n skipHead,\n}: FetcherOptions) {\n return JSON.stringify({\n host,\n platform,\n i18nKeyScheme: i18n?.keyScheme,\n preview,\n projects,\n skipHead,\n });\n}\n\ninterface GlobalWithBundles {\n __PLASMIC_BUNDLES?: { [bundleKey: string]: LoaderBundleOutput };\n}\n"],
|
|
5
|
+
"mappings": "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",
|
|
6
6
|
"names": ["unfetch", "resp", "json"]
|
|
7
7
|
}
|
package/package.json
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
{
|
|
2
|
-
"version": "
|
|
2
|
+
"version": "2.0.0",
|
|
3
3
|
"license": "MIT",
|
|
4
4
|
"types": "./dist/index.d.ts",
|
|
5
5
|
"main": "./dist/index.js",
|
|
@@ -47,5 +47,5 @@
|
|
|
47
47
|
"publishConfig": {
|
|
48
48
|
"access": "public"
|
|
49
49
|
},
|
|
50
|
-
"gitHead": "
|
|
50
|
+
"gitHead": "cf4b7bfc318b5360730e4e080925370e37870858"
|
|
51
51
|
}
|