@spiffcommerce/theme-bridge 1.28.1-alpha.0 → 1.29.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/README.md +2 -0
- package/dist/bin.cjs +9 -4
- package/dist/bin.cjs.map +1 -1
- package/dist/bin.js +40 -35
- package/dist/bin.js.map +1 -1
- package/dist/generateConfiguration-D0O62bWR.cjs.map +1 -1
- package/dist/generateConfiguration-hQnHNgMM.js.map +1 -1
- package/dist/plugin.cjs +1 -1
- package/dist/plugin.cjs.map +1 -1
- package/dist/plugin.js +1 -1
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -95,6 +95,8 @@ yarn theme-bridge download -k <application-key> --activation-id <id> -o .env.dev
|
|
|
95
95
|
yarn theme-bridge download -k <application-key> --theme-install-id <id> --theme-install-configuration-id <id> -o .env.development.json
|
|
96
96
|
```
|
|
97
97
|
|
|
98
|
+
> **Keep application keys out of your repository.** Provide the key on the command line only when you need it, rather than saving it in scripts or committed files. If you're concerned about security, or about accidentally storing a key with special access, create a new application key with no non-default permissions and delete it once you're finished.
|
|
99
|
+
|
|
98
100
|
Without `-o` the result is printed to stdout. Run with `--help` for all options. In this monorepo run it from a workspace that depends on `@repo/theme-bridge` (after `yarn install` and a build); outside it, `npx @spiffcommerce/theme-bridge` works without installing it first. `download` uses `@repo/core` (a peer dependency) to make the requests, so no extra GraphQL dependency is installed. Set `MOONLIGHT_GQL_URL` to override the server URL, e.g. to point at a local mock server that returns your own response when testing.
|
|
99
101
|
|
|
100
102
|
If your theme's schema has changed since the configuration was saved, keys that no longer exist are ignored with a console warning.
|
package/dist/bin.cjs
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
-
"use strict";var
|
|
2
|
+
"use strict";var w=Object.create;var u=Object.defineProperty;var v=Object.getOwnPropertyDescriptor;var k=Object.getOwnPropertyNames;var I=Object.getPrototypeOf,O=Object.prototype.hasOwnProperty;var L=(e,t,n,i)=>{if(t&&typeof t=="object"||typeof t=="function")for(let o of k(t))!O.call(e,o)&&o!==n&&u(e,o,{get:()=>t[o],enumerable:!(i=v(t,o))||i.enumerable});return e};var C=(e,t,n)=>(n=e!=null?w(I(e)):{},L(t||!e||!e.__esModule?u(n,"default",{value:e,enumerable:!0}):n,e));const d=require("node:util"),p=require("node:fs"),h=require("node:path"),r=require("./generateConfiguration-D0O62bWR.cjs"),l="theme-bridge",a=`Usage:
|
|
3
3
|
${l} download --application-key <key> [options]
|
|
4
4
|
${l} extract-overrides <file> [-o <file>]
|
|
5
5
|
|
|
@@ -17,6 +17,11 @@ Options:
|
|
|
17
17
|
-o, --out <file> File to write. Defaults to stdout.
|
|
18
18
|
-h, --help Show this help.
|
|
19
19
|
|
|
20
|
+
Application keys:
|
|
21
|
+
Don't keep application keys in your repository. Provide one on the command line only when you need it.
|
|
22
|
+
If you're concerned about security, or about accidentally storing a key with special access, create a new
|
|
23
|
+
application key with no non-default permissions for this, and delete it once you're finished.
|
|
24
|
+
|
|
20
25
|
Extract overrides:
|
|
21
26
|
Converts a local configuration file in the legacy format (a ThemeInstallConfigurationGraphQl, with flattened
|
|
22
27
|
fields marked "root") into an overrides file. Values that match the defaults of the schema in the file's
|
|
@@ -24,10 +29,10 @@ Extract overrides:
|
|
|
24
29
|
Writes to --out, or stdout when omitted. Use the same path for the input and --out to convert in place.
|
|
25
30
|
|
|
26
31
|
The MOONLIGHT_GQL_URL environment variable overrides the server URL. Set it when testing locally to point at a mock server that returns your own response.
|
|
27
|
-
`,x=()=>import("@spiffcommerce/core");function
|
|
32
|
+
`,x=()=>import("@spiffcommerce/core");function f(e,t,n){t?(p.writeFileSync(h.resolve(t),e+`
|
|
28
33
|
`),n.log(`Wrote ${t}`)):n.log(e)}async function G(e,t,n,i){const{values:o}=d.parseArgs({args:e,options:{"application-key":{type:"string",short:"k"},region:{type:"string",short:"r"},"activation-id":{type:"string"},"theme-install-id":{type:"string"},"theme-install-configuration-id":{type:"string"},out:{type:"string",short:"o"},help:{type:"boolean",short:"h"}}});if(o.help)return t.log(a),0;if(!o["application-key"])return t.error(`Missing required --application-key option.
|
|
29
34
|
|
|
30
|
-
${a}`),1;if(o.region&&!r.MOONLIGHT_REGIONS.includes(o.region))return t.error(`Invalid --region "${o.region}". Expected one of: ${r.MOONLIGHT_REGIONS.join(", ")}`),1;const s=console.log,g=console.info,y=console.warn;console.log=console.info=console.warn=(...m)=>console.error(...m);let c;try{c=await r.downloadThemeInstallConfiguration({applicationKey:o["application-key"],region:o.region,serverUrl:i.MOONLIGHT_GQL_URL,activationId:o["activation-id"],themeInstallId:o["theme-install-id"],themeInstallConfigurationId:o["theme-install-configuration-id"]},await n())}finally{console.log=s,console.info=g,console.warn=y}return
|
|
35
|
+
${a}`),1;if(o.region&&!r.MOONLIGHT_REGIONS.includes(o.region))return t.error(`Invalid --region "${o.region}". Expected one of: ${r.MOONLIGHT_REGIONS.join(", ")}`),1;const s=console.log,g=console.info,y=console.warn;console.log=console.info=console.warn=(...m)=>console.error(...m);let c;try{c=await r.downloadThemeInstallConfiguration({applicationKey:o["application-key"],region:o.region,serverUrl:i.MOONLIGHT_GQL_URL,activationId:o["activation-id"],themeInstallId:o["theme-install-id"],themeInstallConfigurationId:o["theme-install-configuration-id"]},await n())}finally{console.log=s,console.info=g,console.warn=y}return f(JSON.stringify(r.themeInstallConfigurationToOverrides(c),null,2),o.out,t),0}function N(e,t){const{values:n,positionals:i}=d.parseArgs({args:e,allowPositionals:!0,options:{out:{type:"string",short:"o"},help:{type:"boolean",short:"h"}}});if(n.help)return t.log(a),0;if(i.length!==1)return t.error(`extract-overrides expects exactly one input file.
|
|
31
36
|
|
|
32
|
-
${a}`),1;const o=i[0],s=JSON.parse(
|
|
37
|
+
${a}`),1;const o=i[0],s=JSON.parse(p.readFileSync(h.resolve(o),"utf-8"));if(!Array.isArray(s?.fields))throw new Error(`"${o}" isn't in the legacy format (expected a "fields" array). It may already be an overrides file.`);return f(JSON.stringify(r.themeInstallConfigurationGraphQlToOverrides(s),null,2),n.out,t),0}async function S(e,t={log:console.log,error:console.error},n=x,i=process.env){try{if(e[0]==="download")return await G(e.slice(1),t,n,i);if(e[0]==="extract-overrides")return N(e.slice(1),t);const o=e.length===0||e.includes("--help")||e.includes("-h");return(o?t.log:t.error)(a),o?0:1}catch(o){return t.error(`${l}: ${o.message}`),1}}S(process.argv.slice(2)).then(e=>{process.exitCode=e});
|
|
33
38
|
//# sourceMappingURL=bin.cjs.map
|
package/dist/bin.cjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"bin.cjs","sources":["../src/cli.ts","../src/bin.ts"],"sourcesContent":["import { parseArgs } from \"node:util\";\nimport { readFileSync, writeFileSync } from \"node:fs\";\nimport path from \"node:path\";\nimport {\n themeInstallConfigurationGraphQlToOverrides,\n themeInstallConfigurationToOverrides,\n} from \"./generateConfiguration\";\nimport { DownloadCore, MOONLIGHT_REGIONS, MoonlightRegion, downloadThemeInstallConfiguration } from \"./download\";\n\nexport const CLI_NAME = \"theme-bridge\";\n\nexport const HELP = `Usage:\n ${CLI_NAME} download --application-key <key> [options]\n ${CLI_NAME} extract-overrides <file> [-o <file>]\n\nDownload:\n Downloads a theme install configuration from Spiff Commerce and saves it as an overrides file for local theme\n development. Only the field values and page settings that differ from your theme's defaults are written.\n Without other options, this is the configuration of the current integration for the application key.\n\nOptions:\n -k, --application-key <key> Application key. (required)\n -r, --region <au|us> Region to download from. Defaults to \"au\".\n --activation-id <id> Download the configuration linked to an activation.\n --theme-install-id <id> Download a specific install. Requires --theme-install-configuration-id.\n --theme-install-configuration-id <id> Download a specific configuration.\n -o, --out <file> File to write. Defaults to stdout.\n -h, --help Show this help.\n\nExtract overrides:\n Converts a local configuration file in the legacy format (a ThemeInstallConfigurationGraphQl, with flattened\n fields marked \"root\") into an overrides file. Values that match the defaults of the schema in the file's\n themeVersion are dropped; without a schema, every value is kept.\n Writes to --out, or stdout when omitted. Use the same path for the input and --out to convert in place.\n\nThe MOONLIGHT_GQL_URL environment variable overrides the server URL. Set it when testing locally to point at a mock server that returns your own response.\n`;\n\n/** Loads the module used to talk to Spiff Commerce. Injectable for tests. */\nexport type LoadCore = () => Promise<DownloadCore>;\n\nconst defaultLoadCore: LoadCore = () => import(\"@repo/core\") as unknown as Promise<DownloadCore>;\n\ninterface CliIo {\n log: (s: string) => void;\n error: (s: string) => void;\n}\n\nfunction writeOutput(json: string, out: string | undefined, io: CliIo) {\n if (out) {\n writeFileSync(path.resolve(out), json + \"\\n\");\n io.log(`Wrote ${out}`);\n } else {\n io.log(json);\n }\n}\n\nasync function runDownload(argv: string[], io: CliIo, loadCore: LoadCore, env: NodeJS.ProcessEnv): Promise<number> {\n const { values: opts } = parseArgs({\n args: argv,\n options: {\n \"application-key\": { type: \"string\", short: \"k\" },\n region: { type: \"string\", short: \"r\" },\n \"activation-id\": { type: \"string\" },\n \"theme-install-id\": { type: \"string\" },\n \"theme-install-configuration-id\": { type: \"string\" },\n out: { type: \"string\", short: \"o\" },\n help: { type: \"boolean\", short: \"h\" },\n },\n });\n if (opts.help) {\n io.log(HELP);\n return 0;\n }\n if (!opts[\"application-key\"]) {\n io.error(`Missing required --application-key option.\\n\\n${HELP}`);\n return 1;\n }\n if (opts.region && !MOONLIGHT_REGIONS.includes(opts.region as MoonlightRegion)) {\n io.error(`Invalid --region \"${opts.region}\". Expected one of: ${MOONLIGHT_REGIONS.join(\", \")}`);\n return 1;\n }\n // @repo/core logs diagnostics to stdout. Send them to stderr so piped output stays valid JSON.\n const originalLog = console.log;\n const originalInfo = console.info;\n const originalWarn = console.warn;\n console.log = console.info = console.warn = (...args: unknown[]) => console.error(...args);\n let config;\n try {\n config = await downloadThemeInstallConfiguration(\n {\n applicationKey: opts[\"application-key\"],\n region: opts.region as MoonlightRegion | undefined,\n serverUrl: env.MOONLIGHT_GQL_URL,\n activationId: opts[\"activation-id\"],\n themeInstallId: opts[\"theme-install-id\"],\n themeInstallConfigurationId: opts[\"theme-install-configuration-id\"],\n },\n await loadCore(),\n );\n } finally {\n console.log = originalLog;\n console.info = originalInfo;\n console.warn = originalWarn;\n }\n writeOutput(JSON.stringify(themeInstallConfigurationToOverrides(config), null, 2), opts.out, io);\n return 0;\n}\n\nfunction runExtractOverrides(argv: string[], io: CliIo): number {\n const { values: opts, positionals } = parseArgs({\n args: argv,\n allowPositionals: true,\n options: {\n out: { type: \"string\", short: \"o\" },\n help: { type: \"boolean\", short: \"h\" },\n },\n });\n if (opts.help) {\n io.log(HELP);\n return 0;\n }\n if (positionals.length !== 1) {\n io.error(`extract-overrides expects exactly one input file.\\n\\n${HELP}`);\n return 1;\n }\n const input = positionals[0];\n const gql = JSON.parse(readFileSync(path.resolve(input), \"utf-8\"));\n if (!Array.isArray(gql?.fields)) {\n throw new Error(\n `\"${input}\" isn't in the legacy format (expected a \"fields\" array). It may already be an overrides file.`,\n );\n }\n writeOutput(JSON.stringify(themeInstallConfigurationGraphQlToOverrides(gql), null, 2), opts.out, io);\n return 0;\n}\n\n/** Runs the CLI. Returns the process exit code. */\nexport async function runCli(\n argv: string[],\n io: CliIo = { log: console.log, error: console.error },\n loadCore: LoadCore = defaultLoadCore,\n env: NodeJS.ProcessEnv = process.env,\n): Promise<number> {\n try {\n // Each subcommand handler receives only the arguments after its name.\n if (argv[0] === \"download\") {\n return await runDownload(argv.slice(1), io, loadCore, env);\n }\n if (argv[0] === \"extract-overrides\") {\n return runExtractOverrides(argv.slice(1), io);\n }\n const asked = argv.length === 0 || argv.includes(\"--help\") || argv.includes(\"-h\");\n (asked ? io.log : io.error)(HELP);\n return asked ? 0 : 1;\n } catch (e) {\n io.error(`${CLI_NAME}: ${(e as Error).message}`);\n return 1;\n }\n}\n","#!/usr/bin/env node\nimport { runCli } from \"./cli\";\n\n// Executable entry point for the `theme-bridge` command (see \"bin\" in package.json).\n// Kept separate from cli.ts so the command logic can be imported and tested without running it.\n\n// process.argv is [node path, script path, ...user arguments], so skip the first two.\nrunCli(process.argv.slice(2)).then((code) => {\n process.exitCode = code;\n});\n"],"names":["CLI_NAME","HELP","defaultLoadCore","writeOutput","json","out","io","writeFileSync","path","runDownload","argv","loadCore","env","opts","parseArgs","MOONLIGHT_REGIONS","originalLog","originalInfo","originalWarn","args","config","downloadThemeInstallConfiguration","themeInstallConfigurationToOverrides","runExtractOverrides","positionals","input","gql","readFileSync","themeInstallConfigurationGraphQlToOverrides","runCli","asked","e","code"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"bin.cjs","sources":["../src/cli.ts","../src/bin.ts"],"sourcesContent":["import { parseArgs } from \"node:util\";\nimport { readFileSync, writeFileSync } from \"node:fs\";\nimport path from \"node:path\";\nimport {\n themeInstallConfigurationGraphQlToOverrides,\n themeInstallConfigurationToOverrides,\n} from \"./generateConfiguration\";\nimport { DownloadCore, MOONLIGHT_REGIONS, MoonlightRegion, downloadThemeInstallConfiguration } from \"./download\";\n\nexport const CLI_NAME = \"theme-bridge\";\n\nexport const HELP = `Usage:\n ${CLI_NAME} download --application-key <key> [options]\n ${CLI_NAME} extract-overrides <file> [-o <file>]\n\nDownload:\n Downloads a theme install configuration from Spiff Commerce and saves it as an overrides file for local theme\n development. Only the field values and page settings that differ from your theme's defaults are written.\n Without other options, this is the configuration of the current integration for the application key.\n\nOptions:\n -k, --application-key <key> Application key. (required)\n -r, --region <au|us> Region to download from. Defaults to \"au\".\n --activation-id <id> Download the configuration linked to an activation.\n --theme-install-id <id> Download a specific install. Requires --theme-install-configuration-id.\n --theme-install-configuration-id <id> Download a specific configuration.\n -o, --out <file> File to write. Defaults to stdout.\n -h, --help Show this help.\n\nApplication keys:\n Don't keep application keys in your repository. Provide one on the command line only when you need it.\n If you're concerned about security, or about accidentally storing a key with special access, create a new\n application key with no non-default permissions for this, and delete it once you're finished.\n\nExtract overrides:\n Converts a local configuration file in the legacy format (a ThemeInstallConfigurationGraphQl, with flattened\n fields marked \"root\") into an overrides file. Values that match the defaults of the schema in the file's\n themeVersion are dropped; without a schema, every value is kept.\n Writes to --out, or stdout when omitted. Use the same path for the input and --out to convert in place.\n\nThe MOONLIGHT_GQL_URL environment variable overrides the server URL. Set it when testing locally to point at a mock server that returns your own response.\n`;\n\n/** Loads the module used to talk to Spiff Commerce. Injectable for tests. */\nexport type LoadCore = () => Promise<DownloadCore>;\n\nconst defaultLoadCore: LoadCore = () => import(\"@repo/core\") as unknown as Promise<DownloadCore>;\n\ninterface CliIo {\n log: (s: string) => void;\n error: (s: string) => void;\n}\n\nfunction writeOutput(json: string, out: string | undefined, io: CliIo) {\n if (out) {\n writeFileSync(path.resolve(out), json + \"\\n\");\n io.log(`Wrote ${out}`);\n } else {\n io.log(json);\n }\n}\n\nasync function runDownload(argv: string[], io: CliIo, loadCore: LoadCore, env: NodeJS.ProcessEnv): Promise<number> {\n // Application keys shouldn't be stored in repositories (including scripts and env files that get committed),\n // so the key is only ever accepted as a command line argument. Developers who are concerned can create a\n // throwaway application key with no non-default permissions, and delete it once they're finished.\n const { values: opts } = parseArgs({\n args: argv,\n options: {\n \"application-key\": { type: \"string\", short: \"k\" },\n region: { type: \"string\", short: \"r\" },\n \"activation-id\": { type: \"string\" },\n \"theme-install-id\": { type: \"string\" },\n \"theme-install-configuration-id\": { type: \"string\" },\n out: { type: \"string\", short: \"o\" },\n help: { type: \"boolean\", short: \"h\" },\n },\n });\n if (opts.help) {\n io.log(HELP);\n return 0;\n }\n if (!opts[\"application-key\"]) {\n io.error(`Missing required --application-key option.\\n\\n${HELP}`);\n return 1;\n }\n if (opts.region && !MOONLIGHT_REGIONS.includes(opts.region as MoonlightRegion)) {\n io.error(`Invalid --region \"${opts.region}\". Expected one of: ${MOONLIGHT_REGIONS.join(\", \")}`);\n return 1;\n }\n // @repo/core logs diagnostics to stdout. Send them to stderr so piped output stays valid JSON.\n const originalLog = console.log;\n const originalInfo = console.info;\n const originalWarn = console.warn;\n console.log = console.info = console.warn = (...args: unknown[]) => console.error(...args);\n let config;\n try {\n config = await downloadThemeInstallConfiguration(\n {\n applicationKey: opts[\"application-key\"],\n region: opts.region as MoonlightRegion | undefined,\n serverUrl: env.MOONLIGHT_GQL_URL,\n activationId: opts[\"activation-id\"],\n themeInstallId: opts[\"theme-install-id\"],\n themeInstallConfigurationId: opts[\"theme-install-configuration-id\"],\n },\n await loadCore(),\n );\n } finally {\n console.log = originalLog;\n console.info = originalInfo;\n console.warn = originalWarn;\n }\n writeOutput(JSON.stringify(themeInstallConfigurationToOverrides(config), null, 2), opts.out, io);\n return 0;\n}\n\nfunction runExtractOverrides(argv: string[], io: CliIo): number {\n const { values: opts, positionals } = parseArgs({\n args: argv,\n allowPositionals: true,\n options: {\n out: { type: \"string\", short: \"o\" },\n help: { type: \"boolean\", short: \"h\" },\n },\n });\n if (opts.help) {\n io.log(HELP);\n return 0;\n }\n if (positionals.length !== 1) {\n io.error(`extract-overrides expects exactly one input file.\\n\\n${HELP}`);\n return 1;\n }\n const input = positionals[0];\n const gql = JSON.parse(readFileSync(path.resolve(input), \"utf-8\"));\n if (!Array.isArray(gql?.fields)) {\n throw new Error(\n `\"${input}\" isn't in the legacy format (expected a \"fields\" array). It may already be an overrides file.`,\n );\n }\n writeOutput(JSON.stringify(themeInstallConfigurationGraphQlToOverrides(gql), null, 2), opts.out, io);\n return 0;\n}\n\n/** Runs the CLI. Returns the process exit code. */\nexport async function runCli(\n argv: string[],\n io: CliIo = { log: console.log, error: console.error },\n loadCore: LoadCore = defaultLoadCore,\n env: NodeJS.ProcessEnv = process.env,\n): Promise<number> {\n try {\n // Each subcommand handler receives only the arguments after its name.\n if (argv[0] === \"download\") {\n return await runDownload(argv.slice(1), io, loadCore, env);\n }\n if (argv[0] === \"extract-overrides\") {\n return runExtractOverrides(argv.slice(1), io);\n }\n const asked = argv.length === 0 || argv.includes(\"--help\") || argv.includes(\"-h\");\n (asked ? io.log : io.error)(HELP);\n return asked ? 0 : 1;\n } catch (e) {\n io.error(`${CLI_NAME}: ${(e as Error).message}`);\n return 1;\n }\n}\n","#!/usr/bin/env node\nimport { runCli } from \"./cli\";\n\n// Executable entry point for the `theme-bridge` command (see \"bin\" in package.json).\n// Kept separate from cli.ts so the command logic can be imported and tested without running it.\n\n// process.argv is [node path, script path, ...user arguments], so skip the first two.\nrunCli(process.argv.slice(2)).then((code) => {\n process.exitCode = code;\n});\n"],"names":["CLI_NAME","HELP","defaultLoadCore","writeOutput","json","out","io","writeFileSync","path","runDownload","argv","loadCore","env","opts","parseArgs","MOONLIGHT_REGIONS","originalLog","originalInfo","originalWarn","args","config","downloadThemeInstallConfiguration","themeInstallConfigurationToOverrides","runExtractOverrides","positionals","input","gql","readFileSync","themeInstallConfigurationGraphQlToOverrides","runCli","asked","e","code"],"mappings":"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"}
|
package/dist/bin.js
CHANGED
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
import { parseArgs as d } from "node:util";
|
|
3
|
-
import { readFileSync as
|
|
4
|
-
import
|
|
5
|
-
import { M as c, d as
|
|
6
|
-
const
|
|
7
|
-
${
|
|
8
|
-
${
|
|
3
|
+
import { readFileSync as y, writeFileSync as m } from "node:fs";
|
|
4
|
+
import p from "node:path";
|
|
5
|
+
import { M as c, d as w, t as v, a as k } from "./generateConfiguration-hQnHNgMM.js";
|
|
6
|
+
const s = "theme-bridge", r = `Usage:
|
|
7
|
+
${s} download --application-key <key> [options]
|
|
8
|
+
${s} extract-overrides <file> [-o <file>]
|
|
9
9
|
|
|
10
10
|
Download:
|
|
11
11
|
Downloads a theme install configuration from Spiff Commerce and saves it as an overrides file for local theme
|
|
@@ -21,6 +21,11 @@ Options:
|
|
|
21
21
|
-o, --out <file> File to write. Defaults to stdout.
|
|
22
22
|
-h, --help Show this help.
|
|
23
23
|
|
|
24
|
+
Application keys:
|
|
25
|
+
Don't keep application keys in your repository. Provide one on the command line only when you need it.
|
|
26
|
+
If you're concerned about security, or about accidentally storing a key with special access, create a new
|
|
27
|
+
application key with no non-default permissions for this, and delete it once you're finished.
|
|
28
|
+
|
|
24
29
|
Extract overrides:
|
|
25
30
|
Converts a local configuration file in the legacy format (a ThemeInstallConfigurationGraphQl, with flattened
|
|
26
31
|
fields marked "root") into an overrides file. Values that match the defaults of the schema in the file's
|
|
@@ -29,13 +34,13 @@ Extract overrides:
|
|
|
29
34
|
|
|
30
35
|
The MOONLIGHT_GQL_URL environment variable overrides the server URL. Set it when testing locally to point at a mock server that returns your own response.
|
|
31
36
|
`, I = () => import("@spiffcommerce/core");
|
|
32
|
-
function
|
|
33
|
-
|
|
34
|
-
`), i.log(`Wrote ${
|
|
37
|
+
function u(t, o, i) {
|
|
38
|
+
o ? (m(p.resolve(o), t + `
|
|
39
|
+
`), i.log(`Wrote ${o}`)) : i.log(t);
|
|
35
40
|
}
|
|
36
|
-
async function O(
|
|
41
|
+
async function O(t, o, i, n) {
|
|
37
42
|
const { values: e } = d({
|
|
38
|
-
args:
|
|
43
|
+
args: t,
|
|
39
44
|
options: {
|
|
40
45
|
"application-key": { type: "string", short: "k" },
|
|
41
46
|
region: { type: "string", short: "r" },
|
|
@@ -47,18 +52,18 @@ async function O(o, t, i, n) {
|
|
|
47
52
|
}
|
|
48
53
|
});
|
|
49
54
|
if (e.help)
|
|
50
|
-
return
|
|
55
|
+
return o.log(r), 0;
|
|
51
56
|
if (!e["application-key"])
|
|
52
|
-
return
|
|
57
|
+
return o.error(`Missing required --application-key option.
|
|
53
58
|
|
|
54
59
|
${r}`), 1;
|
|
55
60
|
if (e.region && !c.includes(e.region))
|
|
56
|
-
return
|
|
57
|
-
const a = console.log,
|
|
61
|
+
return o.error(`Invalid --region "${e.region}". Expected one of: ${c.join(", ")}`), 1;
|
|
62
|
+
const a = console.log, f = console.info, h = console.warn;
|
|
58
63
|
console.log = console.info = console.warn = (...g) => console.error(...g);
|
|
59
|
-
let
|
|
64
|
+
let l;
|
|
60
65
|
try {
|
|
61
|
-
|
|
66
|
+
l = await w(
|
|
62
67
|
{
|
|
63
68
|
applicationKey: e["application-key"],
|
|
64
69
|
region: e.region,
|
|
@@ -70,13 +75,13 @@ ${r}`), 1;
|
|
|
70
75
|
await i()
|
|
71
76
|
);
|
|
72
77
|
} finally {
|
|
73
|
-
console.log = a, console.info =
|
|
78
|
+
console.log = a, console.info = f, console.warn = h;
|
|
74
79
|
}
|
|
75
|
-
return
|
|
80
|
+
return u(JSON.stringify(v(l), null, 2), e.out, o), 0;
|
|
76
81
|
}
|
|
77
|
-
function L(
|
|
82
|
+
function L(t, o) {
|
|
78
83
|
const { values: i, positionals: n } = d({
|
|
79
|
-
args:
|
|
84
|
+
args: t,
|
|
80
85
|
allowPositionals: !0,
|
|
81
86
|
options: {
|
|
82
87
|
out: { type: "string", short: "o" },
|
|
@@ -84,31 +89,31 @@ function L(o, t) {
|
|
|
84
89
|
}
|
|
85
90
|
});
|
|
86
91
|
if (i.help)
|
|
87
|
-
return
|
|
92
|
+
return o.log(r), 0;
|
|
88
93
|
if (n.length !== 1)
|
|
89
|
-
return
|
|
94
|
+
return o.error(`extract-overrides expects exactly one input file.
|
|
90
95
|
|
|
91
96
|
${r}`), 1;
|
|
92
|
-
const e = n[0], a = JSON.parse(
|
|
97
|
+
const e = n[0], a = JSON.parse(y(p.resolve(e), "utf-8"));
|
|
93
98
|
if (!Array.isArray(a?.fields))
|
|
94
99
|
throw new Error(
|
|
95
100
|
`"${e}" isn't in the legacy format (expected a "fields" array). It may already be an overrides file.`
|
|
96
101
|
);
|
|
97
|
-
return
|
|
102
|
+
return u(JSON.stringify(k(a), null, 2), i.out, o), 0;
|
|
98
103
|
}
|
|
99
|
-
async function C(
|
|
104
|
+
async function C(t, o = { log: console.log, error: console.error }, i = I, n = process.env) {
|
|
100
105
|
try {
|
|
101
|
-
if (
|
|
102
|
-
return await O(
|
|
103
|
-
if (
|
|
104
|
-
return L(
|
|
105
|
-
const e =
|
|
106
|
-
return (e ?
|
|
106
|
+
if (t[0] === "download")
|
|
107
|
+
return await O(t.slice(1), o, i, n);
|
|
108
|
+
if (t[0] === "extract-overrides")
|
|
109
|
+
return L(t.slice(1), o);
|
|
110
|
+
const e = t.length === 0 || t.includes("--help") || t.includes("-h");
|
|
111
|
+
return (e ? o.log : o.error)(r), e ? 0 : 1;
|
|
107
112
|
} catch (e) {
|
|
108
|
-
return
|
|
113
|
+
return o.error(`${s}: ${e.message}`), 1;
|
|
109
114
|
}
|
|
110
115
|
}
|
|
111
|
-
C(process.argv.slice(2)).then((
|
|
112
|
-
process.exitCode =
|
|
116
|
+
C(process.argv.slice(2)).then((t) => {
|
|
117
|
+
process.exitCode = t;
|
|
113
118
|
});
|
|
114
119
|
//# sourceMappingURL=bin.js.map
|
package/dist/bin.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"bin.js","sources":["../src/cli.ts","../src/bin.ts"],"sourcesContent":["import { parseArgs } from \"node:util\";\nimport { readFileSync, writeFileSync } from \"node:fs\";\nimport path from \"node:path\";\nimport {\n themeInstallConfigurationGraphQlToOverrides,\n themeInstallConfigurationToOverrides,\n} from \"./generateConfiguration\";\nimport { DownloadCore, MOONLIGHT_REGIONS, MoonlightRegion, downloadThemeInstallConfiguration } from \"./download\";\n\nexport const CLI_NAME = \"theme-bridge\";\n\nexport const HELP = `Usage:\n ${CLI_NAME} download --application-key <key> [options]\n ${CLI_NAME} extract-overrides <file> [-o <file>]\n\nDownload:\n Downloads a theme install configuration from Spiff Commerce and saves it as an overrides file for local theme\n development. Only the field values and page settings that differ from your theme's defaults are written.\n Without other options, this is the configuration of the current integration for the application key.\n\nOptions:\n -k, --application-key <key> Application key. (required)\n -r, --region <au|us> Region to download from. Defaults to \"au\".\n --activation-id <id> Download the configuration linked to an activation.\n --theme-install-id <id> Download a specific install. Requires --theme-install-configuration-id.\n --theme-install-configuration-id <id> Download a specific configuration.\n -o, --out <file> File to write. Defaults to stdout.\n -h, --help Show this help.\n\nExtract overrides:\n Converts a local configuration file in the legacy format (a ThemeInstallConfigurationGraphQl, with flattened\n fields marked \"root\") into an overrides file. Values that match the defaults of the schema in the file's\n themeVersion are dropped; without a schema, every value is kept.\n Writes to --out, or stdout when omitted. Use the same path for the input and --out to convert in place.\n\nThe MOONLIGHT_GQL_URL environment variable overrides the server URL. Set it when testing locally to point at a mock server that returns your own response.\n`;\n\n/** Loads the module used to talk to Spiff Commerce. Injectable for tests. */\nexport type LoadCore = () => Promise<DownloadCore>;\n\nconst defaultLoadCore: LoadCore = () => import(\"@repo/core\") as unknown as Promise<DownloadCore>;\n\ninterface CliIo {\n log: (s: string) => void;\n error: (s: string) => void;\n}\n\nfunction writeOutput(json: string, out: string | undefined, io: CliIo) {\n if (out) {\n writeFileSync(path.resolve(out), json + \"\\n\");\n io.log(`Wrote ${out}`);\n } else {\n io.log(json);\n }\n}\n\nasync function runDownload(argv: string[], io: CliIo, loadCore: LoadCore, env: NodeJS.ProcessEnv): Promise<number> {\n const { values: opts } = parseArgs({\n args: argv,\n options: {\n \"application-key\": { type: \"string\", short: \"k\" },\n region: { type: \"string\", short: \"r\" },\n \"activation-id\": { type: \"string\" },\n \"theme-install-id\": { type: \"string\" },\n \"theme-install-configuration-id\": { type: \"string\" },\n out: { type: \"string\", short: \"o\" },\n help: { type: \"boolean\", short: \"h\" },\n },\n });\n if (opts.help) {\n io.log(HELP);\n return 0;\n }\n if (!opts[\"application-key\"]) {\n io.error(`Missing required --application-key option.\\n\\n${HELP}`);\n return 1;\n }\n if (opts.region && !MOONLIGHT_REGIONS.includes(opts.region as MoonlightRegion)) {\n io.error(`Invalid --region \"${opts.region}\". Expected one of: ${MOONLIGHT_REGIONS.join(\", \")}`);\n return 1;\n }\n // @repo/core logs diagnostics to stdout. Send them to stderr so piped output stays valid JSON.\n const originalLog = console.log;\n const originalInfo = console.info;\n const originalWarn = console.warn;\n console.log = console.info = console.warn = (...args: unknown[]) => console.error(...args);\n let config;\n try {\n config = await downloadThemeInstallConfiguration(\n {\n applicationKey: opts[\"application-key\"],\n region: opts.region as MoonlightRegion | undefined,\n serverUrl: env.MOONLIGHT_GQL_URL,\n activationId: opts[\"activation-id\"],\n themeInstallId: opts[\"theme-install-id\"],\n themeInstallConfigurationId: opts[\"theme-install-configuration-id\"],\n },\n await loadCore(),\n );\n } finally {\n console.log = originalLog;\n console.info = originalInfo;\n console.warn = originalWarn;\n }\n writeOutput(JSON.stringify(themeInstallConfigurationToOverrides(config), null, 2), opts.out, io);\n return 0;\n}\n\nfunction runExtractOverrides(argv: string[], io: CliIo): number {\n const { values: opts, positionals } = parseArgs({\n args: argv,\n allowPositionals: true,\n options: {\n out: { type: \"string\", short: \"o\" },\n help: { type: \"boolean\", short: \"h\" },\n },\n });\n if (opts.help) {\n io.log(HELP);\n return 0;\n }\n if (positionals.length !== 1) {\n io.error(`extract-overrides expects exactly one input file.\\n\\n${HELP}`);\n return 1;\n }\n const input = positionals[0];\n const gql = JSON.parse(readFileSync(path.resolve(input), \"utf-8\"));\n if (!Array.isArray(gql?.fields)) {\n throw new Error(\n `\"${input}\" isn't in the legacy format (expected a \"fields\" array). It may already be an overrides file.`,\n );\n }\n writeOutput(JSON.stringify(themeInstallConfigurationGraphQlToOverrides(gql), null, 2), opts.out, io);\n return 0;\n}\n\n/** Runs the CLI. Returns the process exit code. */\nexport async function runCli(\n argv: string[],\n io: CliIo = { log: console.log, error: console.error },\n loadCore: LoadCore = defaultLoadCore,\n env: NodeJS.ProcessEnv = process.env,\n): Promise<number> {\n try {\n // Each subcommand handler receives only the arguments after its name.\n if (argv[0] === \"download\") {\n return await runDownload(argv.slice(1), io, loadCore, env);\n }\n if (argv[0] === \"extract-overrides\") {\n return runExtractOverrides(argv.slice(1), io);\n }\n const asked = argv.length === 0 || argv.includes(\"--help\") || argv.includes(\"-h\");\n (asked ? io.log : io.error)(HELP);\n return asked ? 0 : 1;\n } catch (e) {\n io.error(`${CLI_NAME}: ${(e as Error).message}`);\n return 1;\n }\n}\n","#!/usr/bin/env node\nimport { runCli } from \"./cli\";\n\n// Executable entry point for the `theme-bridge` command (see \"bin\" in package.json).\n// Kept separate from cli.ts so the command logic can be imported and tested without running it.\n\n// process.argv is [node path, script path, ...user arguments], so skip the first two.\nrunCli(process.argv.slice(2)).then((code) => {\n process.exitCode = code;\n});\n"],"names":["CLI_NAME","HELP","defaultLoadCore","writeOutput","json","out","io","writeFileSync","path","runDownload","argv","loadCore","env","opts","parseArgs","MOONLIGHT_REGIONS","originalLog","originalInfo","originalWarn","args","config","downloadThemeInstallConfiguration","themeInstallConfigurationToOverrides","runExtractOverrides","positionals","input","gql","readFileSync","themeInstallConfigurationGraphQlToOverrides","runCli","asked","code"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"bin.js","sources":["../src/cli.ts","../src/bin.ts"],"sourcesContent":["import { parseArgs } from \"node:util\";\nimport { readFileSync, writeFileSync } from \"node:fs\";\nimport path from \"node:path\";\nimport {\n themeInstallConfigurationGraphQlToOverrides,\n themeInstallConfigurationToOverrides,\n} from \"./generateConfiguration\";\nimport { DownloadCore, MOONLIGHT_REGIONS, MoonlightRegion, downloadThemeInstallConfiguration } from \"./download\";\n\nexport const CLI_NAME = \"theme-bridge\";\n\nexport const HELP = `Usage:\n ${CLI_NAME} download --application-key <key> [options]\n ${CLI_NAME} extract-overrides <file> [-o <file>]\n\nDownload:\n Downloads a theme install configuration from Spiff Commerce and saves it as an overrides file for local theme\n development. Only the field values and page settings that differ from your theme's defaults are written.\n Without other options, this is the configuration of the current integration for the application key.\n\nOptions:\n -k, --application-key <key> Application key. (required)\n -r, --region <au|us> Region to download from. Defaults to \"au\".\n --activation-id <id> Download the configuration linked to an activation.\n --theme-install-id <id> Download a specific install. Requires --theme-install-configuration-id.\n --theme-install-configuration-id <id> Download a specific configuration.\n -o, --out <file> File to write. Defaults to stdout.\n -h, --help Show this help.\n\nApplication keys:\n Don't keep application keys in your repository. Provide one on the command line only when you need it.\n If you're concerned about security, or about accidentally storing a key with special access, create a new\n application key with no non-default permissions for this, and delete it once you're finished.\n\nExtract overrides:\n Converts a local configuration file in the legacy format (a ThemeInstallConfigurationGraphQl, with flattened\n fields marked \"root\") into an overrides file. Values that match the defaults of the schema in the file's\n themeVersion are dropped; without a schema, every value is kept.\n Writes to --out, or stdout when omitted. Use the same path for the input and --out to convert in place.\n\nThe MOONLIGHT_GQL_URL environment variable overrides the server URL. Set it when testing locally to point at a mock server that returns your own response.\n`;\n\n/** Loads the module used to talk to Spiff Commerce. Injectable for tests. */\nexport type LoadCore = () => Promise<DownloadCore>;\n\nconst defaultLoadCore: LoadCore = () => import(\"@repo/core\") as unknown as Promise<DownloadCore>;\n\ninterface CliIo {\n log: (s: string) => void;\n error: (s: string) => void;\n}\n\nfunction writeOutput(json: string, out: string | undefined, io: CliIo) {\n if (out) {\n writeFileSync(path.resolve(out), json + \"\\n\");\n io.log(`Wrote ${out}`);\n } else {\n io.log(json);\n }\n}\n\nasync function runDownload(argv: string[], io: CliIo, loadCore: LoadCore, env: NodeJS.ProcessEnv): Promise<number> {\n // Application keys shouldn't be stored in repositories (including scripts and env files that get committed),\n // so the key is only ever accepted as a command line argument. Developers who are concerned can create a\n // throwaway application key with no non-default permissions, and delete it once they're finished.\n const { values: opts } = parseArgs({\n args: argv,\n options: {\n \"application-key\": { type: \"string\", short: \"k\" },\n region: { type: \"string\", short: \"r\" },\n \"activation-id\": { type: \"string\" },\n \"theme-install-id\": { type: \"string\" },\n \"theme-install-configuration-id\": { type: \"string\" },\n out: { type: \"string\", short: \"o\" },\n help: { type: \"boolean\", short: \"h\" },\n },\n });\n if (opts.help) {\n io.log(HELP);\n return 0;\n }\n if (!opts[\"application-key\"]) {\n io.error(`Missing required --application-key option.\\n\\n${HELP}`);\n return 1;\n }\n if (opts.region && !MOONLIGHT_REGIONS.includes(opts.region as MoonlightRegion)) {\n io.error(`Invalid --region \"${opts.region}\". Expected one of: ${MOONLIGHT_REGIONS.join(\", \")}`);\n return 1;\n }\n // @repo/core logs diagnostics to stdout. Send them to stderr so piped output stays valid JSON.\n const originalLog = console.log;\n const originalInfo = console.info;\n const originalWarn = console.warn;\n console.log = console.info = console.warn = (...args: unknown[]) => console.error(...args);\n let config;\n try {\n config = await downloadThemeInstallConfiguration(\n {\n applicationKey: opts[\"application-key\"],\n region: opts.region as MoonlightRegion | undefined,\n serverUrl: env.MOONLIGHT_GQL_URL,\n activationId: opts[\"activation-id\"],\n themeInstallId: opts[\"theme-install-id\"],\n themeInstallConfigurationId: opts[\"theme-install-configuration-id\"],\n },\n await loadCore(),\n );\n } finally {\n console.log = originalLog;\n console.info = originalInfo;\n console.warn = originalWarn;\n }\n writeOutput(JSON.stringify(themeInstallConfigurationToOverrides(config), null, 2), opts.out, io);\n return 0;\n}\n\nfunction runExtractOverrides(argv: string[], io: CliIo): number {\n const { values: opts, positionals } = parseArgs({\n args: argv,\n allowPositionals: true,\n options: {\n out: { type: \"string\", short: \"o\" },\n help: { type: \"boolean\", short: \"h\" },\n },\n });\n if (opts.help) {\n io.log(HELP);\n return 0;\n }\n if (positionals.length !== 1) {\n io.error(`extract-overrides expects exactly one input file.\\n\\n${HELP}`);\n return 1;\n }\n const input = positionals[0];\n const gql = JSON.parse(readFileSync(path.resolve(input), \"utf-8\"));\n if (!Array.isArray(gql?.fields)) {\n throw new Error(\n `\"${input}\" isn't in the legacy format (expected a \"fields\" array). It may already be an overrides file.`,\n );\n }\n writeOutput(JSON.stringify(themeInstallConfigurationGraphQlToOverrides(gql), null, 2), opts.out, io);\n return 0;\n}\n\n/** Runs the CLI. Returns the process exit code. */\nexport async function runCli(\n argv: string[],\n io: CliIo = { log: console.log, error: console.error },\n loadCore: LoadCore = defaultLoadCore,\n env: NodeJS.ProcessEnv = process.env,\n): Promise<number> {\n try {\n // Each subcommand handler receives only the arguments after its name.\n if (argv[0] === \"download\") {\n return await runDownload(argv.slice(1), io, loadCore, env);\n }\n if (argv[0] === \"extract-overrides\") {\n return runExtractOverrides(argv.slice(1), io);\n }\n const asked = argv.length === 0 || argv.includes(\"--help\") || argv.includes(\"-h\");\n (asked ? io.log : io.error)(HELP);\n return asked ? 0 : 1;\n } catch (e) {\n io.error(`${CLI_NAME}: ${(e as Error).message}`);\n return 1;\n }\n}\n","#!/usr/bin/env node\nimport { runCli } from \"./cli\";\n\n// Executable entry point for the `theme-bridge` command (see \"bin\" in package.json).\n// Kept separate from cli.ts so the command logic can be imported and tested without running it.\n\n// process.argv is [node path, script path, ...user arguments], so skip the first two.\nrunCli(process.argv.slice(2)).then((code) => {\n process.exitCode = code;\n});\n"],"names":["CLI_NAME","HELP","defaultLoadCore","writeOutput","json","out","io","writeFileSync","path","runDownload","argv","loadCore","env","opts","parseArgs","MOONLIGHT_REGIONS","originalLog","originalInfo","originalWarn","args","config","downloadThemeInstallConfiguration","themeInstallConfigurationToOverrides","runExtractOverrides","positionals","input","gql","readFileSync","themeInstallConfigurationGraphQlToOverrides","runCli","asked","code"],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"generateConfiguration-D0O62bWR.cjs","sources":["../src/graphql.ts","../src/download.ts","../src/generateConfiguration.ts"],"sourcesContent":["import {\n ThemeConfigurationSchemaCustomSchemaResource,\n ThemeConfigurationSchemaFieldResource,\n ThemeConfigurationSchemaResource,\n ThemeInstallConfigurationFieldResource,\n ThemeInstallConfigurationResource,\n ThemeVersionResource,\n} from \"./resourceTypes\";\nimport type { ThemeInstallConfigurationGraphQl } from \"@repo/types\";\n\nexport type ThemeVersionGraphQl = Omit<ThemeVersionResource, \"configurationSchema\"> & {\n configurationSchema: ThemeConfigurationSchemaGraphQl;\n};\n\nexport type ThemeConfigurationSchemaGraphQl = Omit<ThemeConfigurationSchemaResource, \"fields\" | \"customSchemas\"> & {\n fields: ThemeConfigurationSchemaFieldGraphQl[];\n customSchemas?: ThemeConfigurationSchemaCustomSchemaGraphQl[] | null;\n};\n\nexport type ThemeConfigurationSchemaCustomSchemaGraphQl = Omit<\n ThemeConfigurationSchemaCustomSchemaResource,\n \"fields\"\n> & {\n fields?: number[] | null;\n};\n\nexport type ThemeConfigurationSchemaFieldGraphQl = Omit<ThemeConfigurationSchemaFieldResource, \"items\" | \"fields\"> & {\n /** When this field is type `List`, this is the index of the schema for the entries. */\n items?: number | null;\n /** When this field is type `Object`, this array contains the indices of the schemas for the sub-fields. */\n fields?: number[] | null;\n /** Whether this field is on the root. Otherwise this is a child. */\n root?: boolean | null;\n};\n\nexport type { ThemeInstallConfigurationGraphQl };\n\nexport type ThemeInstallConfigurationFieldGraphQl = Omit<\n ThemeInstallConfigurationFieldResource,\n \"listValues\" | \"objectValues\"\n> & {\n /** When the type is `List`, this will be the indices of the configured values */\n listValues?: number[] | null;\n /** When the type is `Object`, this will be the indices of the configured field values */\n objectValues?: number[] | null;\n /** Whether this field is on the root. Otherwise this is a child. */\n root?: boolean | null;\n};\n\nfunction themeVersionFieldToResource(\n field: ThemeConfigurationSchemaFieldGraphQl,\n allFields: ThemeConfigurationSchemaFieldGraphQl[],\n): ThemeConfigurationSchemaFieldResource {\n const resource: ThemeConfigurationSchemaFieldResource = {\n ...field,\n items: undefined,\n fields: undefined,\n };\n if (field.items !== undefined && field.items !== null) {\n resource.items = themeVersionFieldToResource(allFields[field.items], allFields);\n }\n if (field.fields !== undefined && field.fields !== null) {\n resource.fields = field.fields.map((idx) => themeVersionFieldToResource(allFields[idx], allFields));\n }\n return resource;\n}\n\nexport function themeVersionConfigurationGraphQlToResource(\n gql: ThemeConfigurationSchemaGraphQl,\n): ThemeConfigurationSchemaResource {\n const resource: ThemeConfigurationSchemaResource = {\n ...gql,\n fields: [],\n customSchemas: gql.customSchemas?.map((schema) => ({\n ...schema,\n fields: schema.fields?.map((fieldIdx) => themeVersionFieldToResource(gql.fields[fieldIdx], gql.fields)),\n })),\n };\n const resourceFields: ThemeConfigurationSchemaFieldResource[] = [];\n gql.fields.forEach((field) => {\n if (!field.root) {\n return;\n }\n resourceFields.push(themeVersionFieldToResource(field, gql.fields));\n });\n if (gql.fields.length > 0 && resourceFields.length === 0) {\n throw new Error(\n \"Failed to map ThemeVersionConfiguration GraphQL type to Resource type. Please ensure you've selected the `root` field on ThemeConfigurationSchemaField\",\n );\n }\n resource.fields = resourceFields;\n return resource;\n}\n\nexport function themeVersionGraphQlToResource(gql: ThemeVersionGraphQl): ThemeVersionResource {\n return {\n ...gql,\n configurationSchema: themeVersionConfigurationGraphQlToResource(gql.configurationSchema),\n };\n}\n\nfunction themeInstallFieldToResource(\n field: ThemeInstallConfigurationFieldGraphQl,\n allFields: ThemeInstallConfigurationFieldGraphQl[],\n): ThemeInstallConfigurationFieldResource {\n const resource: ThemeInstallConfigurationFieldResource = {\n ...field,\n listValues: undefined,\n objectValues: undefined,\n };\n if (field.listValues !== undefined && field.listValues !== null) {\n resource.listValues = field.listValues.map((idx) => themeInstallFieldToResource(allFields[idx], allFields));\n }\n if (field.objectValues !== undefined && field.objectValues !== null) {\n resource.objectValues = field.objectValues.map((idx) => themeInstallFieldToResource(allFields[idx], allFields));\n }\n return resource;\n}\n\nexport function themeInstallConfigurationGraphQlToResource(\n gql: ThemeInstallConfigurationGraphQl,\n): ThemeInstallConfigurationResource {\n const resource: ThemeInstallConfigurationResource = {\n ...gql,\n name: gql.name ?? \"\",\n fields: [],\n };\n const resourceFields: ThemeInstallConfigurationFieldResource[] = [];\n gql.fields.forEach((field: ThemeInstallConfigurationFieldGraphQl) => {\n if (!field.root) {\n return;\n }\n resourceFields.push(themeInstallFieldToResource(field, gql.fields));\n });\n if (gql.fields.length > 0 && resourceFields.length === 0) {\n throw new Error(\n \"Failed to map ThemeInstallConfiguration GraphQL type to Resource type. Please ensure you've selected the `root` field on ThemeInstallConfigurationField\",\n );\n }\n resource.fields = resourceFields;\n return resource;\n}\n","import type { ThemeInstallConfigurationResource } from \"./resourceTypes\";\nimport { themeInstallConfigurationGraphQlToResource, themeVersionGraphQlToResource } from \"./graphql\";\n\nexport type MoonlightRegion = \"au\" | \"us\";\nexport const MOONLIGHT_REGIONS: MoonlightRegion[] = [\"au\", \"us\"];\n\n/** The subset of `@repo/core` used to talk to Moonlight. */\nexport interface DownloadCore {\n spiffCoreConfiguration: { setServerUrl(url: string): void };\n setApplicationKey(key: string): void;\n getIntegration(applicationKey: string, themeConfigurationId?: string): Promise<any>;\n getActivation(activationId: string): Promise<any>;\n getOverrideThemeConfiguration(themeConfigurationId: string, themeInstallId: string): Promise<any>;\n}\n\nexport interface DownloadThemeInstallConfigurationOptions {\n /** The application key identifying the integration. Required for every request. */\n applicationKey: string;\n /** Selects `https://moonlight.<region>.spiffcommerce.com`. Defaults to `au`. Ignored when `serverUrl` is set. */\n region?: MoonlightRegion;\n /** Overrides the Moonlight URL entirely. Useful when testing locally against a mock server that returns your own response. */\n serverUrl?: string;\n /** Download via an activation. Cannot be combined with the theme install ids. */\n activationId?: string;\n /** Download a specific install. Must be combined with `themeInstallConfigurationId`. */\n themeInstallId?: string;\n /** Download a specific configuration. Without `themeInstallId` it is looked up on the current integration. */\n themeInstallConfigurationId?: string;\n}\n\n/** Recursively removes the `__typename` fields GraphQL adds to responses. */\nexport function stripTypenames<T>(value: T): T {\n if (Array.isArray(value)) {\n return value.map(stripTypenames) as T;\n }\n if (value && typeof value === \"object\") {\n return Object.fromEntries(\n Object.entries(value)\n .filter(([key]) => key !== \"__typename\")\n .map(([key, entry]) => [key, stripTypenames(entry)]),\n ) as T;\n }\n return value;\n}\n\n/**\n * Converts a `ThemeInstallConfigurationGraphQl` into a `ThemeInstallConfigurationResource`, removing `__typename`s.\n * Unlike `themeInstallConfigurationGraphQlToResource`, this also expands the theme version's flattened schema, when it has one.\n */\nexport function expandThemeInstallConfigurationGraphQl(gql: any): ThemeInstallConfigurationResource {\n const clean = stripTypenames(gql);\n const resource = themeInstallConfigurationGraphQlToResource(clean);\n return clean.themeVersion?.configurationSchema\n ? { ...resource, themeVersion: themeVersionGraphQlToResource(clean.themeVersion) }\n : resource;\n}\n\nexport function resolveMoonlightUrl(region: MoonlightRegion = \"au\", serverUrl?: string): string {\n if (serverUrl) return serverUrl;\n if (!MOONLIGHT_REGIONS.includes(region)) {\n throw new Error(`Unknown region \"${region}\". Expected one of: ${MOONLIGHT_REGIONS.join(\", \")}`);\n }\n return `https://moonlight.${region}.spiffcommerce.com`;\n}\n\n/**\n * Downloads a theme install configuration from Moonlight and returns it as a `ThemeInstallConfigurationResource`.\n *\n * The configuration is located in one of three ways:\n * - `themeInstallId` + `themeInstallConfigurationId`: directly.\n * - `activationId`: the configuration linked to the activation.\n * - Neither: the current integration, as identified by the application key\n * (optionally a specific `themeInstallConfigurationId` of it).\n */\nexport async function downloadThemeInstallConfiguration(\n options: DownloadThemeInstallConfigurationOptions,\n core: DownloadCore,\n): Promise<ThemeInstallConfigurationResource> {\n const { applicationKey, activationId, themeInstallId, themeInstallConfigurationId } = options;\n if (!applicationKey) {\n throw new Error(\"An application key is required\");\n }\n if (activationId && (themeInstallId || themeInstallConfigurationId)) {\n throw new Error(\"An activation id can't be combined with a theme install id or theme install configuration id\");\n }\n if (themeInstallId && !themeInstallConfigurationId) {\n throw new Error(\"A theme install id also requires a theme install configuration id\");\n }\n\n core.spiffCoreConfiguration.setServerUrl(resolveMoonlightUrl(options.region, options.serverUrl));\n core.setApplicationKey(applicationKey);\n\n let gql: any;\n let source: string;\n if (themeInstallId && themeInstallConfigurationId) {\n source = `theme install ${themeInstallId} configuration ${themeInstallConfigurationId}`;\n gql = await core.getOverrideThemeConfiguration(themeInstallConfigurationId, themeInstallId);\n } else if (activationId) {\n source = `activation ${activationId}`;\n gql = (await core.getActivation(activationId))?.marketplaceThemeInstallConfiguration;\n } else {\n source = themeInstallConfigurationId\n ? `configuration ${themeInstallConfigurationId} of the current integration`\n : \"the current integration\";\n gql = (await core.getIntegration(applicationKey, themeInstallConfigurationId))\n ?.marketplaceThemeInstallConfiguration;\n }\n if (!gql) {\n throw new Error(\n `Couldn't find a theme install configuration for ${source}. Check the ids, application key and region.`,\n );\n }\n return expandThemeInstallConfigurationGraphQl(gql);\n}\n","import {\n CustomSchemaType,\n FieldType,\n ThemeConfigurationPageSettings,\n ThemeConfigurationSchema,\n ThemeConfigurationSchemaCustomSchema,\n ThemeConfigurationSchemaField,\n} from \"./configurationTypes\";\nimport { expandThemeInstallConfigurationGraphQl } from \"./download\";\nimport {\n ThemeInstallConfigurationFieldResource,\n ThemeInstallConfigurationResource,\n ThemeInstallPageSettings,\n ThemeVersionResource,\n} from \"./resourceTypes\";\n\n/**\n * Values for the fields of a schema, keyed by field `key`.\n * This is the inverse of `themeInstallConfigurationToRecordObject`:\n * - Text, Color and Select: a string\n * - Number: a number (or numeric string)\n * - Boolean: a boolean\n * - DateRange: `{ start, end }` (Date or ISO date string)\n * - Asset, ConversionConfiguration, ProductCollection, MetafieldConfiguration: the resource object\n * - List: an array of values\n * - Object: a record of values. When the field references a `Union` schema, include `schema` to choose the variant.\n */\nexport type ThemeInstallConfigurationValues = Record<string, any>;\n\n/** Overrides for the user-configured state of the theme's pages. Anything not listed keeps its default. */\nexport interface ThemeInstallPageSettingsOverrides {\n /** Keyed by page key. */\n pages?: Record<string, { enabled?: boolean }>;\n /** Keyed by group key. */\n groups?: Record<string, { pageOrder?: string[] }>;\n}\n\n/**\n * The contents of a local development overrides file. Only list what you want to change;\n * everything else is defaulted from the theme's schema.\n */\nexport interface ThemeInstallConfigurationOverrides {\n /** Field values keyed by field `key`. See `ThemeInstallConfigurationValues` for the accepted formats. */\n fields?: ThemeInstallConfigurationValues;\n /** Overrides for page settings. */\n pageSettings?: ThemeInstallPageSettingsOverrides;\n}\n\ntype SchemaFields = ThemeConfigurationSchemaField[];\n\nfunction resolveSchemaFields(\n schemaName: string,\n chosen: string | undefined,\n customSchemas: ThemeConfigurationSchemaCustomSchema[],\n seen: string[] = [],\n): { name: string; fields: SchemaFields } {\n if (seen.includes(schemaName)) {\n throw new Error(`Circular schema reference: ${[...seen, schemaName].join(\" -> \")}`);\n }\n const schema = customSchemas.find((s) => s.name === schemaName);\n if (!schema) {\n throw new Error(`Unknown custom schema \"${schemaName}\"`);\n }\n if (schema.type === CustomSchemaType.Union) {\n if (!chosen || !schema.schemas.includes(chosen)) {\n throw new Error(\n `Union schema \"${schemaName}\" requires a value with \\`schema\\` set to one of: ${schema.schemas.join(\", \")}`,\n );\n }\n return resolveSchemaFields(chosen, undefined, customSchemas, [...seen, schemaName]);\n }\n const inherited = (schema.extends ?? []).flatMap(\n (parent) => resolveSchemaFields(parent, undefined, customSchemas, [...seen, schemaName]).fields,\n );\n return { name: schemaName, fields: [...inherited, ...schema.fields] };\n}\n\nfunction toDateString(value: unknown): string {\n if (value instanceof Date) {\n return value.toISOString().slice(0, 10);\n }\n return String(value);\n}\n\nfunction generateField(\n field: ThemeConfigurationSchemaField,\n value: any,\n customSchemas: ThemeConfigurationSchemaCustomSchema[],\n): ThemeInstallConfigurationFieldResource | undefined {\n if (field.type === FieldType.Heading) {\n return undefined;\n }\n const resource: ThemeInstallConfigurationFieldResource = {\n key: field.key,\n type: field.type,\n fallbackToDefaultConfiguration: false,\n };\n const defaultValue = (field as { defaultValue?: string }).defaultValue;\n const provided = value !== undefined && value !== null;\n\n switch (field.type) {\n case FieldType.Text:\n case FieldType.Color:\n case FieldType.Select:\n case FieldType.Number:\n case FieldType.Boolean:\n resource.value = provided ? String(value) : defaultValue;\n break;\n case FieldType.DateRange:\n resource.value = provided ? `${toDateString(value.start)},${toDateString(value.end)}` : defaultValue;\n break;\n case FieldType.Asset:\n resource.asset = provided ? value : undefined;\n break;\n case FieldType.ConversionConfiguration:\n resource.conversionConfiguration = provided ? value : undefined;\n break;\n case FieldType.ProductCollection:\n resource.productCollection = provided ? value : undefined;\n break;\n case FieldType.MetafieldConfiguration:\n resource.metafieldConfiguration = provided ? value : undefined;\n break;\n case FieldType.List:\n if (provided) {\n if (!Array.isArray(value)) {\n throw new Error(`Field \"${field.key}\" is a List and must be configured with an array`);\n }\n resource.listValues = value.map((entry) => {\n const item = generateField(\n { ...field.items, key: undefined, title: \"\" } as any,\n entry,\n customSchemas,\n );\n return item ?? { type: field.items.type };\n });\n }\n break;\n case FieldType.Object: {\n if (!provided) break;\n let fields: SchemaFields;\n if (field.schema) {\n const resolved = resolveSchemaFields(field.schema, value.schema, customSchemas);\n fields = resolved.fields;\n resource.schema = resolved.name;\n } else {\n fields = \"fields\" in field ? field.fields : [];\n }\n resource.objectValues = generateFields(fields, value, customSchemas);\n break;\n }\n }\n return resource;\n}\n\nfunction generateFields(\n fields: SchemaFields,\n values: ThemeInstallConfigurationValues,\n customSchemas: ThemeConfigurationSchemaCustomSchema[],\n): ThemeInstallConfigurationFieldResource[] {\n const result: ThemeInstallConfigurationFieldResource[] = [];\n for (const field of fields) {\n const resource = generateField(field, \"key\" in field ? values?.[field.key] : undefined, customSchemas);\n if (resource) {\n result.push(resource);\n }\n }\n return result;\n}\n\n/** Unknown keys usually mean a typo, or an overrides file saved from a different version of the theme. */\nfunction warnUnknownKeys(kind: string, provided: string[], known: string[]) {\n const unknown = provided.filter((key) => !known.includes(key));\n if (unknown.length > 0) {\n console.warn(\n `Ignoring unknown ${kind} ${unknown.map((k) => `\"${k}\"`).join(\", \")}. Expected one of: ${known.join(\", \")}`,\n );\n }\n}\n\nfunction generatePageSettings(\n settings: ThemeConfigurationPageSettings,\n overrides?: ThemeInstallPageSettingsOverrides,\n): ThemeInstallPageSettings {\n warnUnknownKeys(\n \"page\",\n Object.keys(overrides?.pages ?? {}),\n settings.pages.map((page) => page.key),\n );\n warnUnknownKeys(\n \"page group\",\n Object.keys(overrides?.groups ?? {}),\n settings.groups.map((group) => group.key),\n );\n return {\n groups: settings.groups.map((group) => {\n const pageOrder = overrides?.groups?.[group.key]?.pageOrder;\n return pageOrder ? { key: group.key, pageOrder } : { key: group.key };\n }),\n pages: settings.pages.map((page) => {\n const enabled = overrides?.pages?.[page.key]?.enabled;\n return enabled !== undefined ? { key: page.key, enabled } : { key: page.key };\n }),\n };\n}\n\nexport interface GenerateThemeInstallConfigurationFromOverridesOptions {\n /** The theme's configuration schema. */\n schema: ThemeConfigurationSchema;\n /** The theme's page settings definition, if it has one. */\n pageSettings?: ThemeConfigurationPageSettings;\n /** The contents of the overrides file. When omitted, the configuration is entirely defaults. */\n overrides?: ThemeInstallConfigurationOverrides;\n}\n\n/**\n * Generates a complete `ThemeInstallConfigurationResource` for local development, from the theme's schema and a\n * small overrides object (typically the contents of a JSON file) which lists only the field values and page\n * settings you want to change. Everything else is defaulted from the schema.\n *\n * Unknown field, page or group keys are ignored with a console warning.\n *\n * @example\n * // overrides.json: { \"fields\": { \"title\": \"Hello\" }, \"pageSettings\": { \"pages\": { \"faq\": { \"enabled\": false } } } }\n * const configuration = generateThemeInstallConfigurationFromOverrides({\n * schema: configurationSchema,\n * pageSettings,\n * overrides: JSON.parse(readFileSync(\"overrides.json\", \"utf-8\")),\n * });\n */\nexport function generateThemeInstallConfigurationFromOverrides(\n options: GenerateThemeInstallConfigurationFromOverridesOptions,\n): ThemeInstallConfigurationResource {\n const { schema, pageSettings, overrides } = options;\n warnUnknownKeys(\n \"field\",\n Object.keys(overrides?.fields ?? {}),\n schema.fields.flatMap((field) => (\"key\" in field ? [field.key] : [])),\n );\n const timestamp = \"2021-01-01T00:00:00Z\";\n const themeVersion: ThemeVersionResource = {\n id: \"local\",\n version: \"1.0.0\",\n createdAt: timestamp,\n updatedAt: timestamp,\n theme: { id: \"local\", name: \"Local Theme\", createdAt: timestamp, updatedAt: timestamp },\n launchData: { targetFiles: [] },\n configurationSchema: schema as unknown as ThemeVersionResource[\"configurationSchema\"],\n pageSettings,\n };\n return {\n id: \"local\",\n themeInstallId: \"local\",\n name: \"Local Configuration\",\n createdAt: timestamp,\n updatedAt: timestamp,\n themeVersion,\n fields: generateFields(schema.fields, overrides?.fields ?? {}, schema.customSchemas ?? []),\n pageSettings: pageSettings ? generatePageSettings(pageSettings, overrides?.pageSettings) : undefined,\n };\n}\n\n/** The inverse of `generateField`: turns an install field back into the value format used in overrides. */\nfunction fieldToValue(field: ThemeInstallConfigurationFieldResource): any {\n switch (field.type) {\n case FieldType.Asset:\n return field.asset ?? undefined;\n case FieldType.ConversionConfiguration:\n return field.conversionConfiguration ?? undefined;\n case FieldType.ProductCollection:\n return field.productCollection ?? undefined;\n case FieldType.MetafieldConfiguration:\n return field.metafieldConfiguration ?? undefined;\n case FieldType.DateRange: {\n const [start, end] = field.value?.split(\",\") ?? [];\n return start && end ? { start, end } : undefined;\n }\n case FieldType.List:\n return field.listValues?.map(fieldToValue);\n case FieldType.Object: {\n if (!field.objectValues) return undefined;\n const record = fieldsToRecord(field.objectValues);\n return field.schema ? { ...record, schema: field.schema } : record;\n }\n case FieldType.Number: {\n const number = Number.parseFloat(field.value ?? \"\");\n return Number.isNaN(number) ? undefined : number;\n }\n case FieldType.Boolean:\n return field.value === null || field.value === undefined ? undefined : field.value === \"true\";\n case FieldType.Heading:\n return undefined;\n default:\n return field.value ?? undefined;\n }\n}\n\nfunction fieldsToRecord(fields: ThemeInstallConfigurationFieldResource[]): ThemeInstallConfigurationValues {\n const record: ThemeInstallConfigurationValues = {};\n for (const field of fields) {\n if (!field.key) continue;\n const value = fieldToValue(field);\n if (value !== undefined) {\n record[field.key] = value;\n }\n }\n return record;\n}\n\n/** JSON.stringify with sorted keys, so structurally equal values compare equal. */\nfunction stableStringify(value: unknown): string {\n return JSON.stringify(value, (_key, v) =>\n v && typeof v === \"object\" && !Array.isArray(v)\n ? Object.fromEntries(Object.entries(v).sort(([a], [b]) => a.localeCompare(b)))\n : v,\n );\n}\n\n/**\n * The inverse of `generateThemeInstallConfigurationFromOverrides`: reduces a complete\n * `ThemeInstallConfigurationResource` (for example one downloaded from Spiff Commerce) to an overrides object that\n * lists only what differs from the defaults of its own schema.\n */\nexport function themeInstallConfigurationToOverrides(\n configuration: ThemeInstallConfigurationResource,\n): ThemeInstallConfigurationOverrides {\n // Without a schema there are no defaults to compare to, so every configured value is kept.\n const schema = (configuration.themeVersion?.configurationSchema ?? {\n fields: [],\n }) as unknown as ThemeConfigurationSchema;\n const customSchemas = schema.customSchemas ?? [];\n const defaults = fieldsToRecord(generateFields(schema.fields, {}, customSchemas));\n const fields: ThemeInstallConfigurationValues = {};\n for (const [key, value] of Object.entries(fieldsToRecord(configuration.fields))) {\n if (stableStringify(value) !== stableStringify(defaults[key])) {\n fields[key] = value;\n }\n }\n\n const pages: ThemeInstallPageSettingsOverrides[\"pages\"] = {};\n for (const page of configuration.pageSettings?.pages ?? []) {\n if (page.enabled !== undefined) pages[page.key] = { enabled: page.enabled };\n }\n const groups: ThemeInstallPageSettingsOverrides[\"groups\"] = {};\n for (const group of configuration.pageSettings?.groups ?? []) {\n if (group.pageOrder) groups[group.key] = { pageOrder: group.pageOrder };\n }\n\n const overrides: ThemeInstallConfigurationOverrides = {};\n if (Object.keys(fields).length > 0) overrides.fields = fields;\n if (Object.keys(pages).length > 0 || Object.keys(groups).length > 0) {\n overrides.pageSettings = {\n ...(Object.keys(pages).length > 0 && { pages }),\n ...(Object.keys(groups).length > 0 && { groups }),\n };\n }\n return overrides;\n}\n\n/**\n * Extracts overrides from a `ThemeInstallConfigurationGraphQl` (the flattened format that themes previously loaded\n * from a local JSON file, with fields marked `root`). If the object has no `themeVersion.configurationSchema`,\n * defaults can't be detected, so every configured value is kept.\n */\nexport function themeInstallConfigurationGraphQlToOverrides(gql: any): ThemeInstallConfigurationOverrides {\n return themeInstallConfigurationToOverrides(expandThemeInstallConfigurationGraphQl(gql));\n}\n"],"names":["themeVersionFieldToResource","field","allFields","resource","idx","themeVersionConfigurationGraphQlToResource","gql","schema","fieldIdx","resourceFields","themeVersionGraphQlToResource","themeInstallFieldToResource","themeInstallConfigurationGraphQlToResource","MOONLIGHT_REGIONS","stripTypenames","value","key","entry","expandThemeInstallConfigurationGraphQl","clean","resolveMoonlightUrl","region","serverUrl","downloadThemeInstallConfiguration","options","core","applicationKey","activationId","themeInstallId","themeInstallConfigurationId","source","resolveSchemaFields","schemaName","chosen","customSchemas","seen","s","CustomSchemaType","inherited","parent","toDateString","generateField","FieldType","defaultValue","provided","fields","resolved","generateFields","values","result","warnUnknownKeys","kind","known","unknown","k","generatePageSettings","settings","overrides","page","group","pageOrder","enabled","generateThemeInstallConfigurationFromOverrides","pageSettings","timestamp","fieldToValue","start","end","record","fieldsToRecord","number","stableStringify","_key","v","a","b","themeInstallConfigurationToOverrides","configuration","defaults","pages","groups","themeInstallConfigurationGraphQlToOverrides"],"mappings":"kEAiDA,SAASA,EACLC,EACAC,EACqC,CACrC,MAAMC,EAAkD,CACpD,GAAGF,EACH,MAAO,OACP,OAAQ,MAAA,EAEZ,OAAIA,EAAM,QAAU,QAAaA,EAAM,QAAU,OAC7CE,EAAS,MAAQH,EAA4BE,EAAUD,EAAM,KAAK,EAAGC,CAAS,GAE9ED,EAAM,SAAW,QAAaA,EAAM,SAAW,OAC/CE,EAAS,OAASF,EAAM,OAAO,IAAKG,GAAQJ,EAA4BE,EAAUE,CAAG,EAAGF,CAAS,CAAC,GAE/FC,CACX,CAEO,SAASE,EACZC,EACgC,CAChC,MAAMH,EAA6C,CAC/C,GAAGG,EACH,OAAQ,CAAA,EACR,cAAeA,EAAI,eAAe,IAAKC,IAAY,CAC/C,GAAGA,EACH,OAAQA,EAAO,QAAQ,IAAKC,GAAaR,EAA4BM,EAAI,OAAOE,CAAQ,EAAGF,EAAI,MAAM,CAAC,CAAA,EACxG,CAAA,EAEAG,EAA0D,CAAA,EAOhE,GANAH,EAAI,OAAO,QAASL,GAAU,CACrBA,EAAM,MAGXQ,EAAe,KAAKT,EAA4BC,EAAOK,EAAI,MAAM,CAAC,CACtE,CAAC,EACGA,EAAI,OAAO,OAAS,GAAKG,EAAe,SAAW,EACnD,MAAM,IAAI,MACN,wJAAA,EAGR,OAAAN,EAAS,OAASM,EACXN,CACX,CAEO,SAASO,EAA8BJ,EAAgD,CAC1F,MAAO,CACH,GAAGA,EACH,oBAAqBD,EAA2CC,EAAI,mBAAmB,CAAA,CAE/F,CAEA,SAASK,EACLV,EACAC,EACsC,CACtC,MAAMC,EAAmD,CACrD,GAAGF,EACH,WAAY,OACZ,aAAc,MAAA,EAElB,OAAIA,EAAM,aAAe,QAAaA,EAAM,aAAe,OACvDE,EAAS,WAAaF,EAAM,WAAW,IAAKG,GAAQO,EAA4BT,EAAUE,CAAG,EAAGF,CAAS,CAAC,GAE1GD,EAAM,eAAiB,QAAaA,EAAM,eAAiB,OAC3DE,EAAS,aAAeF,EAAM,aAAa,IAAKG,GAAQO,EAA4BT,EAAUE,CAAG,EAAGF,CAAS,CAAC,GAE3GC,CACX,CAEO,SAASS,EACZN,EACiC,CACjC,MAAMH,EAA8C,CAChD,GAAGG,EACH,KAAMA,EAAI,MAAQ,GAClB,OAAQ,CAAA,CAAC,EAEPG,EAA2D,CAAA,EAOjE,GANAH,EAAI,OAAO,QAASL,GAAiD,CAC5DA,EAAM,MAGXQ,EAAe,KAAKE,EAA4BV,EAAOK,EAAI,MAAM,CAAC,CACtE,CAAC,EACGA,EAAI,OAAO,OAAS,GAAKG,EAAe,SAAW,EACnD,MAAM,IAAI,MACN,yJAAA,EAGR,OAAAN,EAAS,OAASM,EACXN,CACX,CCzIO,MAAMU,EAAuC,CAAC,KAAM,IAAI,EA2BxD,SAASC,EAAkBC,EAAa,CAC3C,OAAI,MAAM,QAAQA,CAAK,EACZA,EAAM,IAAID,CAAc,EAE/BC,GAAS,OAAOA,GAAU,SACnB,OAAO,YACV,OAAO,QAAQA,CAAK,EACf,OAAO,CAAC,CAACC,CAAG,IAAMA,IAAQ,YAAY,EACtC,IAAI,CAAC,CAACA,EAAKC,CAAK,IAAM,CAACD,EAAKF,EAAeG,CAAK,CAAC,CAAC,CAAA,EAGxDF,CACX,CAMO,SAASG,EAAuCZ,EAA6C,CAChG,MAAMa,EAAQL,EAAeR,CAAG,EAC1BH,EAAWS,EAA2CO,CAAK,EACjE,OAAOA,EAAM,cAAc,oBACrB,CAAE,GAAGhB,EAAU,aAAcO,EAA8BS,EAAM,YAAY,CAAA,EAC7EhB,CACV,CAEO,SAASiB,EAAoBC,EAA0B,KAAMC,EAA4B,CAC5F,GAAIA,EAAW,OAAOA,EACtB,GAAI,CAACT,EAAkB,SAASQ,CAAM,EAClC,MAAM,IAAI,MAAM,mBAAmBA,CAAM,uBAAuBR,EAAkB,KAAK,IAAI,CAAC,EAAE,EAElG,MAAO,qBAAqBQ,CAAM,oBACtC,CAWA,eAAsBE,EAClBC,EACAC,EAC0C,CAC1C,KAAM,CAAE,eAAAC,EAAgB,aAAAC,EAAc,eAAAC,EAAgB,4BAAAC,GAAgCL,EACtF,GAAI,CAACE,EACD,MAAM,IAAI,MAAM,gCAAgC,EAEpD,GAAIC,IAAiBC,GAAkBC,GACnC,MAAM,IAAI,MAAM,8FAA8F,EAElH,GAAID,GAAkB,CAACC,EACnB,MAAM,IAAI,MAAM,mEAAmE,EAGvFJ,EAAK,uBAAuB,aAAaL,EAAoBI,EAAQ,OAAQA,EAAQ,SAAS,CAAC,EAC/FC,EAAK,kBAAkBC,CAAc,EAErC,IAAIpB,EACAwB,EAcJ,GAbIF,GAAkBC,GAClBC,EAAS,iBAAiBF,CAAc,kBAAkBC,CAA2B,GACrFvB,EAAM,MAAMmB,EAAK,8BAA8BI,EAA6BD,CAAc,GACnFD,GACPG,EAAS,cAAcH,CAAY,GACnCrB,GAAO,MAAMmB,EAAK,cAAcE,CAAY,IAAI,uCAEhDG,EAASD,EACH,iBAAiBA,CAA2B,8BAC5C,0BACNvB,GAAO,MAAMmB,EAAK,eAAeC,EAAgBG,CAA2B,IACtE,sCAEN,CAACvB,EACD,MAAM,IAAI,MACN,mDAAmDwB,CAAM,8CAAA,EAGjE,OAAOZ,EAAuCZ,CAAG,CACrD,CC/DA,SAASyB,EACLC,EACAC,EACAC,EACAC,EAAiB,CAAA,EACqB,CACtC,GAAIA,EAAK,SAASH,CAAU,EACxB,MAAM,IAAI,MAAM,8BAA8B,CAAC,GAAGG,EAAMH,CAAU,EAAE,KAAK,MAAM,CAAC,EAAE,EAEtF,MAAMzB,EAAS2B,EAAc,KAAME,GAAMA,EAAE,OAASJ,CAAU,EAC9D,GAAI,CAACzB,EACD,MAAM,IAAI,MAAM,0BAA0ByB,CAAU,GAAG,EAE3D,GAAIzB,EAAO,OAAS8B,EAAAA,iBAAiB,MAAO,CACxC,GAAI,CAACJ,GAAU,CAAC1B,EAAO,QAAQ,SAAS0B,CAAM,EAC1C,MAAM,IAAI,MACN,iBAAiBD,CAAU,qDAAqDzB,EAAO,QAAQ,KAAK,IAAI,CAAC,EAAA,EAGjH,OAAOwB,EAAoBE,EAAQ,OAAWC,EAAe,CAAC,GAAGC,EAAMH,CAAU,CAAC,CACtF,CACA,MAAMM,GAAa/B,EAAO,SAAW,CAAA,GAAI,QACpCgC,GAAWR,EAAoBQ,EAAQ,OAAWL,EAAe,CAAC,GAAGC,EAAMH,CAAU,CAAC,EAAE,MAAA,EAE7F,MAAO,CAAE,KAAMA,EAAY,OAAQ,CAAC,GAAGM,EAAW,GAAG/B,EAAO,MAAM,CAAA,CACtE,CAEA,SAASiC,EAAazB,EAAwB,CAC1C,OAAIA,aAAiB,KACVA,EAAM,YAAA,EAAc,MAAM,EAAG,EAAE,EAEnC,OAAOA,CAAK,CACvB,CAEA,SAAS0B,EACLxC,EACAc,EACAmB,EACkD,CAClD,GAAIjC,EAAM,OAASyC,EAAAA,UAAU,QACzB,OAEJ,MAAMvC,EAAmD,CACrD,IAAKF,EAAM,IACX,KAAMA,EAAM,KACZ,+BAAgC,EAAA,EAE9B0C,EAAgB1C,EAAoC,aACpD2C,EAAkC7B,GAAU,KAElD,OAAQd,EAAM,KAAA,CACV,KAAKyC,EAAAA,UAAU,KACf,KAAKA,EAAAA,UAAU,MACf,KAAKA,EAAAA,UAAU,OACf,KAAKA,EAAAA,UAAU,OACf,KAAKA,EAAAA,UAAU,QACXvC,EAAS,MAAQyC,EAAW,OAAO7B,CAAK,EAAI4B,EAC5C,MACJ,KAAKD,EAAAA,UAAU,UACXvC,EAAS,MAAQyC,EAAW,GAAGJ,EAAazB,EAAM,KAAK,CAAC,IAAIyB,EAAazB,EAAM,GAAG,CAAC,GAAK4B,EACxF,MACJ,KAAKD,EAAAA,UAAU,MACXvC,EAAS,MAAQyC,EAAW7B,EAAQ,OACpC,MACJ,KAAK2B,EAAAA,UAAU,wBACXvC,EAAS,wBAA0ByC,EAAW7B,EAAQ,OACtD,MACJ,KAAK2B,EAAAA,UAAU,kBACXvC,EAAS,kBAAoByC,EAAW7B,EAAQ,OAChD,MACJ,KAAK2B,EAAAA,UAAU,uBACXvC,EAAS,uBAAyByC,EAAW7B,EAAQ,OACrD,MACJ,KAAK2B,EAAAA,UAAU,KACX,GAAIE,EAAU,CACV,GAAI,CAAC,MAAM,QAAQ7B,CAAK,EACpB,MAAM,IAAI,MAAM,UAAUd,EAAM,GAAG,kDAAkD,EAEzFE,EAAS,WAAaY,EAAM,IAAKE,GAChBwB,EACT,CAAE,GAAGxC,EAAM,MAAO,IAAK,OAAW,MAAO,EAAA,EACzCgB,EACAiB,CAAA,GAEW,CAAE,KAAMjC,EAAM,MAAM,IAAA,CACtC,CACL,CACA,MACJ,KAAKyC,EAAAA,UAAU,OAAQ,CACnB,GAAI,CAACE,EAAU,MACf,IAAIC,EACJ,GAAI5C,EAAM,OAAQ,CACd,MAAM6C,EAAWf,EAAoB9B,EAAM,OAAQc,EAAM,OAAQmB,CAAa,EAC9EW,EAASC,EAAS,OAClB3C,EAAS,OAAS2C,EAAS,IAC/B,MACID,EAAS,WAAY5C,EAAQA,EAAM,OAAS,CAAA,EAEhDE,EAAS,aAAe4C,EAAeF,EAAQ9B,EAAOmB,CAAa,EACnE,KACJ,CAAA,CAEJ,OAAO/B,CACX,CAEA,SAAS4C,EACLF,EACAG,EACAd,EACwC,CACxC,MAAMe,EAAmD,CAAA,EACzD,UAAWhD,KAAS4C,EAAQ,CACxB,MAAM1C,EAAWsC,EAAcxC,EAAO,QAASA,EAAQ+C,IAAS/C,EAAM,GAAG,EAAI,OAAWiC,CAAa,EACjG/B,GACA8C,EAAO,KAAK9C,CAAQ,CAE5B,CACA,OAAO8C,CACX,CAGA,SAASC,EAAgBC,EAAcP,EAAoBQ,EAAiB,CACxE,MAAMC,EAAUT,EAAS,OAAQ5B,GAAQ,CAACoC,EAAM,SAASpC,CAAG,CAAC,EACzDqC,EAAQ,OAAS,GACjB,QAAQ,KACJ,oBAAoBF,CAAI,IAAIE,EAAQ,IAAKC,GAAM,IAAIA,CAAC,GAAG,EAAE,KAAK,IAAI,CAAC,sBAAsBF,EAAM,KAAK,IAAI,CAAC,EAAA,CAGrH,CAEA,SAASG,EACLC,EACAC,EACwB,CACxB,OAAAP,EACI,OACA,OAAO,KAAKO,GAAW,OAAS,CAAA,CAAE,EAClCD,EAAS,MAAM,IAAKE,GAASA,EAAK,GAAG,CAAA,EAEzCR,EACI,aACA,OAAO,KAAKO,GAAW,QAAU,CAAA,CAAE,EACnCD,EAAS,OAAO,IAAKG,GAAUA,EAAM,GAAG,CAAA,EAErC,CACH,OAAQH,EAAS,OAAO,IAAKG,GAAU,CACnC,MAAMC,EAAYH,GAAW,SAASE,EAAM,GAAG,GAAG,UAClD,OAAOC,EAAY,CAAE,IAAKD,EAAM,IAAK,UAAAC,GAAc,CAAE,IAAKD,EAAM,GAAA,CACpE,CAAC,EACD,MAAOH,EAAS,MAAM,IAAKE,GAAS,CAChC,MAAMG,EAAUJ,GAAW,QAAQC,EAAK,GAAG,GAAG,QAC9C,OAAOG,IAAY,OAAY,CAAE,IAAKH,EAAK,IAAK,QAAAG,GAAY,CAAE,IAAKH,EAAK,GAAA,CAC5E,CAAC,CAAA,CAET,CA0BO,SAASI,EACZtC,EACiC,CACjC,KAAM,CAAE,OAAAjB,EAAQ,aAAAwD,EAAc,UAAAN,CAAA,EAAcjC,EAC5C0B,EACI,QACA,OAAO,KAAKO,GAAW,QAAU,CAAA,CAAE,EACnClD,EAAO,OAAO,QAASN,GAAW,QAASA,EAAQ,CAACA,EAAM,GAAG,EAAI,CAAA,CAAG,CAAA,EAExE,MAAM+D,EAAY,uBAWlB,MAAO,CACH,GAAI,QACJ,eAAgB,QAChB,KAAM,sBACN,UAAWA,EACX,UAAWA,EACX,aAhBuC,CACvC,GAAI,QACJ,QAAS,QACT,UAAWA,EACX,UAAWA,EACX,MAAO,CAAE,GAAI,QAAS,KAAM,cAAe,UAAWA,EAAW,UAAWA,CAAA,EAC5E,WAAY,CAAE,YAAa,EAAC,EAC5B,oBAAqBzD,EACrB,aAAAwD,CAAA,EASA,OAAQhB,EAAexC,EAAO,OAAQkD,GAAW,QAAU,GAAIlD,EAAO,eAAiB,EAAE,EACzF,aAAcwD,EAAeR,EAAqBQ,EAAcN,GAAW,YAAY,EAAI,MAAA,CAEnG,CAGA,SAASQ,EAAahE,EAAoD,CACtE,OAAQA,EAAM,KAAA,CACV,KAAKyC,EAAAA,UAAU,MACX,OAAOzC,EAAM,OAAS,OAC1B,KAAKyC,EAAAA,UAAU,wBACX,OAAOzC,EAAM,yBAA2B,OAC5C,KAAKyC,EAAAA,UAAU,kBACX,OAAOzC,EAAM,mBAAqB,OACtC,KAAKyC,EAAAA,UAAU,uBACX,OAAOzC,EAAM,wBAA0B,OAC3C,KAAKyC,EAAAA,UAAU,UAAW,CACtB,KAAM,CAACwB,EAAOC,CAAG,EAAIlE,EAAM,OAAO,MAAM,GAAG,GAAK,CAAA,EAChD,OAAOiE,GAASC,EAAM,CAAE,MAAAD,EAAO,IAAAC,GAAQ,MAC3C,CACA,KAAKzB,EAAAA,UAAU,KACX,OAAOzC,EAAM,YAAY,IAAIgE,CAAY,EAC7C,KAAKvB,EAAAA,UAAU,OAAQ,CACnB,GAAI,CAACzC,EAAM,aAAc,OACzB,MAAMmE,EAASC,EAAepE,EAAM,YAAY,EAChD,OAAOA,EAAM,OAAS,CAAE,GAAGmE,EAAQ,OAAQnE,EAAM,QAAWmE,CAChE,CACA,KAAK1B,EAAAA,UAAU,OAAQ,CACnB,MAAM4B,EAAS,OAAO,WAAWrE,EAAM,OAAS,EAAE,EAClD,OAAO,OAAO,MAAMqE,CAAM,EAAI,OAAYA,CAC9C,CACA,KAAK5B,EAAAA,UAAU,QACX,OAAOzC,EAAM,QAAU,MAAQA,EAAM,QAAU,OAAY,OAAYA,EAAM,QAAU,OAC3F,KAAKyC,EAAAA,UAAU,QACX,OACJ,QACI,OAAOzC,EAAM,OAAS,MAAA,CAElC,CAEA,SAASoE,EAAexB,EAAmF,CACvG,MAAMuB,EAA0C,CAAA,EAChD,UAAWnE,KAAS4C,EAAQ,CACxB,GAAI,CAAC5C,EAAM,IAAK,SAChB,MAAMc,EAAQkD,EAAahE,CAAK,EAC5Bc,IAAU,SACVqD,EAAOnE,EAAM,GAAG,EAAIc,EAE5B,CACA,OAAOqD,CACX,CAGA,SAASG,EAAgBxD,EAAwB,CAC7C,OAAO,KAAK,UAAUA,EAAO,CAACyD,EAAMC,IAChCA,GAAK,OAAOA,GAAM,UAAY,CAAC,MAAM,QAAQA,CAAC,EACxC,OAAO,YAAY,OAAO,QAAQA,CAAC,EAAE,KAAK,CAAC,CAACC,CAAC,EAAG,CAACC,CAAC,IAAMD,EAAE,cAAcC,CAAC,CAAC,CAAC,EAC3EF,CAAA,CAEd,CAOO,SAASG,EACZC,EACkC,CAElC,MAAMtE,EAAUsE,EAAc,cAAc,qBAAuB,CAC/D,OAAQ,CAAA,CAAC,EAEP3C,EAAgB3B,EAAO,eAAiB,CAAA,EACxCuE,EAAWT,EAAetB,EAAexC,EAAO,OAAQ,CAAA,EAAI2B,CAAa,CAAC,EAC1EW,EAA0C,CAAA,EAChD,SAAW,CAAC7B,EAAKD,CAAK,IAAK,OAAO,QAAQsD,EAAeQ,EAAc,MAAM,CAAC,EACtEN,EAAgBxD,CAAK,IAAMwD,EAAgBO,EAAS9D,CAAG,CAAC,IACxD6B,EAAO7B,CAAG,EAAID,GAItB,MAAMgE,EAAoD,CAAA,EAC1D,UAAWrB,KAAQmB,EAAc,cAAc,OAAS,CAAA,EAChDnB,EAAK,UAAY,SAAWqB,EAAMrB,EAAK,GAAG,EAAI,CAAE,QAASA,EAAK,OAAA,GAEtE,MAAMsB,EAAsD,CAAA,EAC5D,UAAWrB,KAASkB,EAAc,cAAc,QAAU,CAAA,EAClDlB,EAAM,YAAWqB,EAAOrB,EAAM,GAAG,EAAI,CAAE,UAAWA,EAAM,SAAA,GAGhE,MAAMF,EAAgD,CAAA,EACtD,OAAI,OAAO,KAAKZ,CAAM,EAAE,OAAS,MAAa,OAASA,IACnD,OAAO,KAAKkC,CAAK,EAAE,OAAS,GAAK,OAAO,KAAKC,CAAM,EAAE,OAAS,KAC9DvB,EAAU,aAAe,CACrB,GAAI,OAAO,KAAKsB,CAAK,EAAE,OAAS,GAAK,CAAE,MAAAA,CAAA,EACvC,GAAI,OAAO,KAAKC,CAAM,EAAE,OAAS,GAAK,CAAE,OAAAA,CAAA,CAAO,GAGhDvB,CACX,CAOO,SAASwB,EAA4C3E,EAA8C,CACtG,OAAOsE,EAAqC1D,EAAuCZ,CAAG,CAAC,CAC3F"}
|
|
1
|
+
{"version":3,"file":"generateConfiguration-D0O62bWR.cjs","sources":["../src/graphql.ts","../src/download.ts","../src/generateConfiguration.ts"],"sourcesContent":["import {\n ThemeConfigurationSchemaCustomSchemaResource,\n ThemeConfigurationSchemaFieldResource,\n ThemeConfigurationSchemaResource,\n ThemeInstallConfigurationFieldResource,\n ThemeInstallConfigurationResource,\n ThemeVersionResource,\n} from \"./resourceTypes\";\nimport type { ThemeInstallConfigurationGraphQl } from \"@repo/types\";\n\nexport type ThemeVersionGraphQl = Omit<ThemeVersionResource, \"configurationSchema\"> & {\n configurationSchema: ThemeConfigurationSchemaGraphQl;\n};\n\nexport type ThemeConfigurationSchemaGraphQl = Omit<ThemeConfigurationSchemaResource, \"fields\" | \"customSchemas\"> & {\n fields: ThemeConfigurationSchemaFieldGraphQl[];\n customSchemas?: ThemeConfigurationSchemaCustomSchemaGraphQl[] | null;\n};\n\nexport type ThemeConfigurationSchemaCustomSchemaGraphQl = Omit<\n ThemeConfigurationSchemaCustomSchemaResource,\n \"fields\"\n> & {\n fields?: number[] | null;\n};\n\nexport type ThemeConfigurationSchemaFieldGraphQl = Omit<ThemeConfigurationSchemaFieldResource, \"items\" | \"fields\"> & {\n /** When this field is type `List`, this is the index of the schema for the entries. */\n items?: number | null;\n /** When this field is type `Object`, this array contains the indices of the schemas for the sub-fields. */\n fields?: number[] | null;\n /** Whether this field is on the root. Otherwise this is a child. */\n root?: boolean | null;\n};\n\nexport type { ThemeInstallConfigurationGraphQl };\n\nexport type ThemeInstallConfigurationFieldGraphQl = Omit<\n ThemeInstallConfigurationFieldResource,\n \"listValues\" | \"objectValues\"\n> & {\n /** When the type is `List`, this will be the indices of the configured values */\n listValues?: number[] | null;\n /** When the type is `Object`, this will be the indices of the configured field values */\n objectValues?: number[] | null;\n /** Whether this field is on the root. Otherwise this is a child. */\n root?: boolean | null;\n};\n\nfunction themeVersionFieldToResource(\n field: ThemeConfigurationSchemaFieldGraphQl,\n allFields: ThemeConfigurationSchemaFieldGraphQl[],\n): ThemeConfigurationSchemaFieldResource {\n const resource: ThemeConfigurationSchemaFieldResource = {\n ...field,\n items: undefined,\n fields: undefined,\n };\n if (field.items !== undefined && field.items !== null) {\n resource.items = themeVersionFieldToResource(allFields[field.items], allFields);\n }\n if (field.fields !== undefined && field.fields !== null) {\n resource.fields = field.fields.map((idx) => themeVersionFieldToResource(allFields[idx], allFields));\n }\n return resource;\n}\n\nexport function themeVersionConfigurationGraphQlToResource(\n gql: ThemeConfigurationSchemaGraphQl,\n): ThemeConfigurationSchemaResource {\n const resource: ThemeConfigurationSchemaResource = {\n ...gql,\n fields: [],\n customSchemas: gql.customSchemas?.map((schema) => ({\n ...schema,\n fields: schema.fields?.map((fieldIdx) => themeVersionFieldToResource(gql.fields[fieldIdx], gql.fields)),\n })),\n };\n const resourceFields: ThemeConfigurationSchemaFieldResource[] = [];\n gql.fields.forEach((field) => {\n if (!field.root) {\n return;\n }\n resourceFields.push(themeVersionFieldToResource(field, gql.fields));\n });\n if (gql.fields.length > 0 && resourceFields.length === 0) {\n throw new Error(\n \"Failed to map ThemeVersionConfiguration GraphQL type to Resource type. Please ensure you've selected the `root` field on ThemeConfigurationSchemaField\",\n );\n }\n resource.fields = resourceFields;\n return resource;\n}\n\nexport function themeVersionGraphQlToResource(gql: ThemeVersionGraphQl): ThemeVersionResource {\n return {\n ...gql,\n configurationSchema: themeVersionConfigurationGraphQlToResource(gql.configurationSchema),\n };\n}\n\nfunction themeInstallFieldToResource(\n field: ThemeInstallConfigurationFieldGraphQl,\n allFields: ThemeInstallConfigurationFieldGraphQl[],\n): ThemeInstallConfigurationFieldResource {\n const resource: ThemeInstallConfigurationFieldResource = {\n ...field,\n listValues: undefined,\n objectValues: undefined,\n };\n if (field.listValues !== undefined && field.listValues !== null) {\n resource.listValues = field.listValues.map((idx) => themeInstallFieldToResource(allFields[idx], allFields));\n }\n if (field.objectValues !== undefined && field.objectValues !== null) {\n resource.objectValues = field.objectValues.map((idx) => themeInstallFieldToResource(allFields[idx], allFields));\n }\n return resource;\n}\n\nexport function themeInstallConfigurationGraphQlToResource(\n gql: ThemeInstallConfigurationGraphQl,\n): ThemeInstallConfigurationResource {\n const resource: ThemeInstallConfigurationResource = {\n ...gql,\n name: gql.name ?? \"\",\n fields: [],\n };\n const resourceFields: ThemeInstallConfigurationFieldResource[] = [];\n gql.fields.forEach((field: ThemeInstallConfigurationFieldGraphQl) => {\n if (!field.root) {\n return;\n }\n resourceFields.push(themeInstallFieldToResource(field, gql.fields));\n });\n if (gql.fields.length > 0 && resourceFields.length === 0) {\n throw new Error(\n \"Failed to map ThemeInstallConfiguration GraphQL type to Resource type. Please ensure you've selected the `root` field on ThemeInstallConfigurationField\",\n );\n }\n resource.fields = resourceFields;\n return resource;\n}\n","import type { ThemeInstallConfigurationResource } from \"./resourceTypes\";\nimport { themeInstallConfigurationGraphQlToResource, themeVersionGraphQlToResource } from \"./graphql\";\n\nexport type MoonlightRegion = \"au\" | \"us\";\nexport const MOONLIGHT_REGIONS: MoonlightRegion[] = [\"au\", \"us\"];\n\n/** The subset of `@repo/core` used to talk to Moonlight. */\nexport interface DownloadCore {\n spiffCoreConfiguration: { setServerUrl(url: string): void };\n setApplicationKey(key: string): void;\n getIntegration(applicationKey: string, themeConfigurationId?: string): Promise<any>;\n getActivation(activationId: string): Promise<any>;\n getOverrideThemeConfiguration(themeConfigurationId: string, themeInstallId: string): Promise<any>;\n}\n\nexport interface DownloadThemeInstallConfigurationOptions {\n /**\n * The application key identifying the integration. Required for every request.\n * Don't store application keys in your repository; provide one only as needed. If you're concerned about\n * security, create a new application key with no non-default permissions and delete it when you're finished.\n */\n applicationKey: string;\n /** Selects `https://moonlight.<region>.spiffcommerce.com`. Defaults to `au`. Ignored when `serverUrl` is set. */\n region?: MoonlightRegion;\n /** Overrides the Moonlight URL entirely. Useful when testing locally against a mock server that returns your own response. */\n serverUrl?: string;\n /** Download via an activation. Cannot be combined with the theme install ids. */\n activationId?: string;\n /** Download a specific install. Must be combined with `themeInstallConfigurationId`. */\n themeInstallId?: string;\n /** Download a specific configuration. Without `themeInstallId` it is looked up on the current integration. */\n themeInstallConfigurationId?: string;\n}\n\n/** Recursively removes the `__typename` fields GraphQL adds to responses. */\nexport function stripTypenames<T>(value: T): T {\n if (Array.isArray(value)) {\n return value.map(stripTypenames) as T;\n }\n if (value && typeof value === \"object\") {\n return Object.fromEntries(\n Object.entries(value)\n .filter(([key]) => key !== \"__typename\")\n .map(([key, entry]) => [key, stripTypenames(entry)]),\n ) as T;\n }\n return value;\n}\n\n/**\n * Converts a `ThemeInstallConfigurationGraphQl` into a `ThemeInstallConfigurationResource`, removing `__typename`s.\n * Unlike `themeInstallConfigurationGraphQlToResource`, this also expands the theme version's flattened schema, when it has one.\n */\nexport function expandThemeInstallConfigurationGraphQl(gql: any): ThemeInstallConfigurationResource {\n const clean = stripTypenames(gql);\n const resource = themeInstallConfigurationGraphQlToResource(clean);\n return clean.themeVersion?.configurationSchema\n ? { ...resource, themeVersion: themeVersionGraphQlToResource(clean.themeVersion) }\n : resource;\n}\n\nexport function resolveMoonlightUrl(region: MoonlightRegion = \"au\", serverUrl?: string): string {\n if (serverUrl) return serverUrl;\n if (!MOONLIGHT_REGIONS.includes(region)) {\n throw new Error(`Unknown region \"${region}\". Expected one of: ${MOONLIGHT_REGIONS.join(\", \")}`);\n }\n return `https://moonlight.${region}.spiffcommerce.com`;\n}\n\n/**\n * Downloads a theme install configuration from Moonlight and returns it as a `ThemeInstallConfigurationResource`.\n *\n * The configuration is located in one of three ways:\n * - `themeInstallId` + `themeInstallConfigurationId`: directly.\n * - `activationId`: the configuration linked to the activation.\n * - Neither: the current integration, as identified by the application key\n * (optionally a specific `themeInstallConfigurationId` of it).\n */\nexport async function downloadThemeInstallConfiguration(\n options: DownloadThemeInstallConfigurationOptions,\n core: DownloadCore,\n): Promise<ThemeInstallConfigurationResource> {\n const { applicationKey, activationId, themeInstallId, themeInstallConfigurationId } = options;\n if (!applicationKey) {\n throw new Error(\"An application key is required\");\n }\n if (activationId && (themeInstallId || themeInstallConfigurationId)) {\n throw new Error(\"An activation id can't be combined with a theme install id or theme install configuration id\");\n }\n if (themeInstallId && !themeInstallConfigurationId) {\n throw new Error(\"A theme install id also requires a theme install configuration id\");\n }\n\n core.spiffCoreConfiguration.setServerUrl(resolveMoonlightUrl(options.region, options.serverUrl));\n core.setApplicationKey(applicationKey);\n\n let gql: any;\n let source: string;\n if (themeInstallId && themeInstallConfigurationId) {\n source = `theme install ${themeInstallId} configuration ${themeInstallConfigurationId}`;\n gql = await core.getOverrideThemeConfiguration(themeInstallConfigurationId, themeInstallId);\n } else if (activationId) {\n source = `activation ${activationId}`;\n gql = (await core.getActivation(activationId))?.marketplaceThemeInstallConfiguration;\n } else {\n source = themeInstallConfigurationId\n ? `configuration ${themeInstallConfigurationId} of the current integration`\n : \"the current integration\";\n gql = (await core.getIntegration(applicationKey, themeInstallConfigurationId))\n ?.marketplaceThemeInstallConfiguration;\n }\n if (!gql) {\n throw new Error(\n `Couldn't find a theme install configuration for ${source}. Check the ids, application key and region.`,\n );\n }\n return expandThemeInstallConfigurationGraphQl(gql);\n}\n","import {\n CustomSchemaType,\n FieldType,\n ThemeConfigurationPageSettings,\n ThemeConfigurationSchema,\n ThemeConfigurationSchemaCustomSchema,\n ThemeConfigurationSchemaField,\n} from \"./configurationTypes\";\nimport { expandThemeInstallConfigurationGraphQl } from \"./download\";\nimport {\n ThemeInstallConfigurationFieldResource,\n ThemeInstallConfigurationResource,\n ThemeInstallPageSettings,\n ThemeVersionResource,\n} from \"./resourceTypes\";\n\n/**\n * Values for the fields of a schema, keyed by field `key`.\n * This is the inverse of `themeInstallConfigurationToRecordObject`:\n * - Text, Color and Select: a string\n * - Number: a number (or numeric string)\n * - Boolean: a boolean\n * - DateRange: `{ start, end }` (Date or ISO date string)\n * - Asset, ConversionConfiguration, ProductCollection, MetafieldConfiguration: the resource object\n * - List: an array of values\n * - Object: a record of values. When the field references a `Union` schema, include `schema` to choose the variant.\n */\nexport type ThemeInstallConfigurationValues = Record<string, any>;\n\n/** Overrides for the user-configured state of the theme's pages. Anything not listed keeps its default. */\nexport interface ThemeInstallPageSettingsOverrides {\n /** Keyed by page key. */\n pages?: Record<string, { enabled?: boolean }>;\n /** Keyed by group key. */\n groups?: Record<string, { pageOrder?: string[] }>;\n}\n\n/**\n * The contents of a local development overrides file. Only list what you want to change;\n * everything else is defaulted from the theme's schema.\n */\nexport interface ThemeInstallConfigurationOverrides {\n /** Field values keyed by field `key`. See `ThemeInstallConfigurationValues` for the accepted formats. */\n fields?: ThemeInstallConfigurationValues;\n /** Overrides for page settings. */\n pageSettings?: ThemeInstallPageSettingsOverrides;\n}\n\ntype SchemaFields = ThemeConfigurationSchemaField[];\n\nfunction resolveSchemaFields(\n schemaName: string,\n chosen: string | undefined,\n customSchemas: ThemeConfigurationSchemaCustomSchema[],\n seen: string[] = [],\n): { name: string; fields: SchemaFields } {\n if (seen.includes(schemaName)) {\n throw new Error(`Circular schema reference: ${[...seen, schemaName].join(\" -> \")}`);\n }\n const schema = customSchemas.find((s) => s.name === schemaName);\n if (!schema) {\n throw new Error(`Unknown custom schema \"${schemaName}\"`);\n }\n if (schema.type === CustomSchemaType.Union) {\n if (!chosen || !schema.schemas.includes(chosen)) {\n throw new Error(\n `Union schema \"${schemaName}\" requires a value with \\`schema\\` set to one of: ${schema.schemas.join(\", \")}`,\n );\n }\n return resolveSchemaFields(chosen, undefined, customSchemas, [...seen, schemaName]);\n }\n const inherited = (schema.extends ?? []).flatMap(\n (parent) => resolveSchemaFields(parent, undefined, customSchemas, [...seen, schemaName]).fields,\n );\n return { name: schemaName, fields: [...inherited, ...schema.fields] };\n}\n\nfunction toDateString(value: unknown): string {\n if (value instanceof Date) {\n return value.toISOString().slice(0, 10);\n }\n return String(value);\n}\n\nfunction generateField(\n field: ThemeConfigurationSchemaField,\n value: any,\n customSchemas: ThemeConfigurationSchemaCustomSchema[],\n): ThemeInstallConfigurationFieldResource | undefined {\n if (field.type === FieldType.Heading) {\n return undefined;\n }\n const resource: ThemeInstallConfigurationFieldResource = {\n key: field.key,\n type: field.type,\n fallbackToDefaultConfiguration: false,\n };\n const defaultValue = (field as { defaultValue?: string }).defaultValue;\n const provided = value !== undefined && value !== null;\n\n switch (field.type) {\n case FieldType.Text:\n case FieldType.Color:\n case FieldType.Select:\n case FieldType.Number:\n case FieldType.Boolean:\n resource.value = provided ? String(value) : defaultValue;\n break;\n case FieldType.DateRange:\n resource.value = provided ? `${toDateString(value.start)},${toDateString(value.end)}` : defaultValue;\n break;\n case FieldType.Asset:\n resource.asset = provided ? value : undefined;\n break;\n case FieldType.ConversionConfiguration:\n resource.conversionConfiguration = provided ? value : undefined;\n break;\n case FieldType.ProductCollection:\n resource.productCollection = provided ? value : undefined;\n break;\n case FieldType.MetafieldConfiguration:\n resource.metafieldConfiguration = provided ? value : undefined;\n break;\n case FieldType.List:\n if (provided) {\n if (!Array.isArray(value)) {\n throw new Error(`Field \"${field.key}\" is a List and must be configured with an array`);\n }\n resource.listValues = value.map((entry) => {\n const item = generateField(\n { ...field.items, key: undefined, title: \"\" } as any,\n entry,\n customSchemas,\n );\n return item ?? { type: field.items.type };\n });\n }\n break;\n case FieldType.Object: {\n if (!provided) break;\n let fields: SchemaFields;\n if (field.schema) {\n const resolved = resolveSchemaFields(field.schema, value.schema, customSchemas);\n fields = resolved.fields;\n resource.schema = resolved.name;\n } else {\n fields = \"fields\" in field ? field.fields : [];\n }\n resource.objectValues = generateFields(fields, value, customSchemas);\n break;\n }\n }\n return resource;\n}\n\nfunction generateFields(\n fields: SchemaFields,\n values: ThemeInstallConfigurationValues,\n customSchemas: ThemeConfigurationSchemaCustomSchema[],\n): ThemeInstallConfigurationFieldResource[] {\n const result: ThemeInstallConfigurationFieldResource[] = [];\n for (const field of fields) {\n const resource = generateField(field, \"key\" in field ? values?.[field.key] : undefined, customSchemas);\n if (resource) {\n result.push(resource);\n }\n }\n return result;\n}\n\n/** Unknown keys usually mean a typo, or an overrides file saved from a different version of the theme. */\nfunction warnUnknownKeys(kind: string, provided: string[], known: string[]) {\n const unknown = provided.filter((key) => !known.includes(key));\n if (unknown.length > 0) {\n console.warn(\n `Ignoring unknown ${kind} ${unknown.map((k) => `\"${k}\"`).join(\", \")}. Expected one of: ${known.join(\", \")}`,\n );\n }\n}\n\nfunction generatePageSettings(\n settings: ThemeConfigurationPageSettings,\n overrides?: ThemeInstallPageSettingsOverrides,\n): ThemeInstallPageSettings {\n warnUnknownKeys(\n \"page\",\n Object.keys(overrides?.pages ?? {}),\n settings.pages.map((page) => page.key),\n );\n warnUnknownKeys(\n \"page group\",\n Object.keys(overrides?.groups ?? {}),\n settings.groups.map((group) => group.key),\n );\n return {\n groups: settings.groups.map((group) => {\n const pageOrder = overrides?.groups?.[group.key]?.pageOrder;\n return pageOrder ? { key: group.key, pageOrder } : { key: group.key };\n }),\n pages: settings.pages.map((page) => {\n const enabled = overrides?.pages?.[page.key]?.enabled;\n return enabled !== undefined ? { key: page.key, enabled } : { key: page.key };\n }),\n };\n}\n\nexport interface GenerateThemeInstallConfigurationFromOverridesOptions {\n /** The theme's configuration schema. */\n schema: ThemeConfigurationSchema;\n /** The theme's page settings definition, if it has one. */\n pageSettings?: ThemeConfigurationPageSettings;\n /** The contents of the overrides file. When omitted, the configuration is entirely defaults. */\n overrides?: ThemeInstallConfigurationOverrides;\n}\n\n/**\n * Generates a complete `ThemeInstallConfigurationResource` for local development, from the theme's schema and a\n * small overrides object (typically the contents of a JSON file) which lists only the field values and page\n * settings you want to change. Everything else is defaulted from the schema.\n *\n * Unknown field, page or group keys are ignored with a console warning.\n *\n * @example\n * // overrides.json: { \"fields\": { \"title\": \"Hello\" }, \"pageSettings\": { \"pages\": { \"faq\": { \"enabled\": false } } } }\n * const configuration = generateThemeInstallConfigurationFromOverrides({\n * schema: configurationSchema,\n * pageSettings,\n * overrides: JSON.parse(readFileSync(\"overrides.json\", \"utf-8\")),\n * });\n */\nexport function generateThemeInstallConfigurationFromOverrides(\n options: GenerateThemeInstallConfigurationFromOverridesOptions,\n): ThemeInstallConfigurationResource {\n const { schema, pageSettings, overrides } = options;\n warnUnknownKeys(\n \"field\",\n Object.keys(overrides?.fields ?? {}),\n schema.fields.flatMap((field) => (\"key\" in field ? [field.key] : [])),\n );\n const timestamp = \"2021-01-01T00:00:00Z\";\n const themeVersion: ThemeVersionResource = {\n id: \"local\",\n version: \"1.0.0\",\n createdAt: timestamp,\n updatedAt: timestamp,\n theme: { id: \"local\", name: \"Local Theme\", createdAt: timestamp, updatedAt: timestamp },\n launchData: { targetFiles: [] },\n configurationSchema: schema as unknown as ThemeVersionResource[\"configurationSchema\"],\n pageSettings,\n };\n return {\n id: \"local\",\n themeInstallId: \"local\",\n name: \"Local Configuration\",\n createdAt: timestamp,\n updatedAt: timestamp,\n themeVersion,\n fields: generateFields(schema.fields, overrides?.fields ?? {}, schema.customSchemas ?? []),\n pageSettings: pageSettings ? generatePageSettings(pageSettings, overrides?.pageSettings) : undefined,\n };\n}\n\n/** The inverse of `generateField`: turns an install field back into the value format used in overrides. */\nfunction fieldToValue(field: ThemeInstallConfigurationFieldResource): any {\n switch (field.type) {\n case FieldType.Asset:\n return field.asset ?? undefined;\n case FieldType.ConversionConfiguration:\n return field.conversionConfiguration ?? undefined;\n case FieldType.ProductCollection:\n return field.productCollection ?? undefined;\n case FieldType.MetafieldConfiguration:\n return field.metafieldConfiguration ?? undefined;\n case FieldType.DateRange: {\n const [start, end] = field.value?.split(\",\") ?? [];\n return start && end ? { start, end } : undefined;\n }\n case FieldType.List:\n return field.listValues?.map(fieldToValue);\n case FieldType.Object: {\n if (!field.objectValues) return undefined;\n const record = fieldsToRecord(field.objectValues);\n return field.schema ? { ...record, schema: field.schema } : record;\n }\n case FieldType.Number: {\n const number = Number.parseFloat(field.value ?? \"\");\n return Number.isNaN(number) ? undefined : number;\n }\n case FieldType.Boolean:\n return field.value === null || field.value === undefined ? undefined : field.value === \"true\";\n case FieldType.Heading:\n return undefined;\n default:\n return field.value ?? undefined;\n }\n}\n\nfunction fieldsToRecord(fields: ThemeInstallConfigurationFieldResource[]): ThemeInstallConfigurationValues {\n const record: ThemeInstallConfigurationValues = {};\n for (const field of fields) {\n if (!field.key) continue;\n const value = fieldToValue(field);\n if (value !== undefined) {\n record[field.key] = value;\n }\n }\n return record;\n}\n\n/** JSON.stringify with sorted keys, so structurally equal values compare equal. */\nfunction stableStringify(value: unknown): string {\n return JSON.stringify(value, (_key, v) =>\n v && typeof v === \"object\" && !Array.isArray(v)\n ? Object.fromEntries(Object.entries(v).sort(([a], [b]) => a.localeCompare(b)))\n : v,\n );\n}\n\n/**\n * The inverse of `generateThemeInstallConfigurationFromOverrides`: reduces a complete\n * `ThemeInstallConfigurationResource` (for example one downloaded from Spiff Commerce) to an overrides object that\n * lists only what differs from the defaults of its own schema.\n */\nexport function themeInstallConfigurationToOverrides(\n configuration: ThemeInstallConfigurationResource,\n): ThemeInstallConfigurationOverrides {\n // Without a schema there are no defaults to compare to, so every configured value is kept.\n const schema = (configuration.themeVersion?.configurationSchema ?? {\n fields: [],\n }) as unknown as ThemeConfigurationSchema;\n const customSchemas = schema.customSchemas ?? [];\n const defaults = fieldsToRecord(generateFields(schema.fields, {}, customSchemas));\n const fields: ThemeInstallConfigurationValues = {};\n for (const [key, value] of Object.entries(fieldsToRecord(configuration.fields))) {\n if (stableStringify(value) !== stableStringify(defaults[key])) {\n fields[key] = value;\n }\n }\n\n const pages: ThemeInstallPageSettingsOverrides[\"pages\"] = {};\n for (const page of configuration.pageSettings?.pages ?? []) {\n if (page.enabled !== undefined) pages[page.key] = { enabled: page.enabled };\n }\n const groups: ThemeInstallPageSettingsOverrides[\"groups\"] = {};\n for (const group of configuration.pageSettings?.groups ?? []) {\n if (group.pageOrder) groups[group.key] = { pageOrder: group.pageOrder };\n }\n\n const overrides: ThemeInstallConfigurationOverrides = {};\n if (Object.keys(fields).length > 0) overrides.fields = fields;\n if (Object.keys(pages).length > 0 || Object.keys(groups).length > 0) {\n overrides.pageSettings = {\n ...(Object.keys(pages).length > 0 && { pages }),\n ...(Object.keys(groups).length > 0 && { groups }),\n };\n }\n return overrides;\n}\n\n/**\n * Extracts overrides from a `ThemeInstallConfigurationGraphQl` (the flattened format that themes previously loaded\n * from a local JSON file, with fields marked `root`). If the object has no `themeVersion.configurationSchema`,\n * defaults can't be detected, so every configured value is kept.\n */\nexport function themeInstallConfigurationGraphQlToOverrides(gql: any): ThemeInstallConfigurationOverrides {\n return themeInstallConfigurationToOverrides(expandThemeInstallConfigurationGraphQl(gql));\n}\n"],"names":["themeVersionFieldToResource","field","allFields","resource","idx","themeVersionConfigurationGraphQlToResource","gql","schema","fieldIdx","resourceFields","themeVersionGraphQlToResource","themeInstallFieldToResource","themeInstallConfigurationGraphQlToResource","MOONLIGHT_REGIONS","stripTypenames","value","key","entry","expandThemeInstallConfigurationGraphQl","clean","resolveMoonlightUrl","region","serverUrl","downloadThemeInstallConfiguration","options","core","applicationKey","activationId","themeInstallId","themeInstallConfigurationId","source","resolveSchemaFields","schemaName","chosen","customSchemas","seen","s","CustomSchemaType","inherited","parent","toDateString","generateField","FieldType","defaultValue","provided","fields","resolved","generateFields","values","result","warnUnknownKeys","kind","known","unknown","k","generatePageSettings","settings","overrides","page","group","pageOrder","enabled","generateThemeInstallConfigurationFromOverrides","pageSettings","timestamp","fieldToValue","start","end","record","fieldsToRecord","number","stableStringify","_key","v","a","b","themeInstallConfigurationToOverrides","configuration","defaults","pages","groups","themeInstallConfigurationGraphQlToOverrides"],"mappings":"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"}
|