primitive-app 3.2.0-alpha.7 → 3.2.0-alpha.9
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.
|
@@ -28,18 +28,23 @@ export declare const PROJECT_CONFIG_FILENAME = "config.json";
|
|
|
28
28
|
export declare const LOCAL_STATE_FILENAME = "local.json";
|
|
29
29
|
export declare const PROJECT_CONFIG_DISPLAY_NAME = "primitive/config.json";
|
|
30
30
|
export declare const LOCAL_STATE_DISPLAY_NAME = ".primitive/local.json";
|
|
31
|
-
/** The docs-site slug of the migration procedure (#3155 publishes the page). */
|
|
32
|
-
export declare const MIGRATION_GUIDE_SLUG = "getting-started/cli-project-migration";
|
|
33
31
|
/**
|
|
34
|
-
* The one refusal for a project
|
|
32
|
+
* The one refusal for a project that never migrated off the pre-#3153 layout:
|
|
33
|
+
* a `.primitive/config.json` with no `primitive/config.json` beside it.
|
|
35
34
|
*
|
|
36
|
-
*
|
|
37
|
-
* the
|
|
38
|
-
*
|
|
39
|
-
*
|
|
40
|
-
*
|
|
35
|
+
* That shape is refused rather than walked past because the walk's next stop
|
|
36
|
+
* is the parent directory, and in a nested checkout the parent may be a
|
|
37
|
+
* DIFFERENT project — a command run in the unmigrated one would silently act
|
|
38
|
+
* on the other's app. Nothing else is refused (#3392): anything left under
|
|
39
|
+
* `.primitive/` beside a migrated tree is machine-local junk, not signal.
|
|
40
|
+
*
|
|
41
|
+
* One sentence, naming both halves — the file that was found and the file
|
|
42
|
+
* that is expected — and no document. The migration page this once pointed
|
|
43
|
+
* at was never published (#3155, won't-fix), and every reader that shares
|
|
44
|
+
* this refusal — this core, the generated Vite-plugin copy, the Swift
|
|
45
|
+
* pre-build script, the Vue template's deploy script — says the same thing.
|
|
41
46
|
*/
|
|
42
|
-
export declare function
|
|
47
|
+
export declare function unmigratedProjectMessage(found: string, expected: string): string;
|
|
43
48
|
/**
|
|
44
49
|
* The one refusal for a command run outside a Primitive project (#3154,
|
|
45
50
|
* intent criterion 5).
|
|
@@ -177,14 +182,14 @@ export declare function deriveWsUrl(apiUrl: string): string;
|
|
|
177
182
|
*
|
|
178
183
|
* The override is checked for provenance BEFORE the file is read (#3153, F2):
|
|
179
184
|
* it bypasses the walk, so without this an old-layout config could be handed
|
|
180
|
-
* straight to a reader and defeat the cutover.
|
|
181
|
-
*
|
|
182
|
-
*
|
|
183
|
-
*
|
|
184
|
-
*
|
|
185
|
-
*
|
|
186
|
-
* never call `resolvePrimitiveEnv` would
|
|
187
|
-
*
|
|
185
|
+
* straight to a reader and defeat the cutover. An override that points inside
|
|
186
|
+
* a `.primitive/` directory IS the old layout, named explicitly.
|
|
187
|
+
*
|
|
188
|
+
* This is the one function every reader goes through — `resolvePrimitiveEnv`
|
|
189
|
+
* and the CLI's own `loadProjectConfig`/`findProjectRoot` alike — so the
|
|
190
|
+
* unmigrated-project refusal lives HERE, in the walk, or the commands that
|
|
191
|
+
* never call `resolvePrimitiveEnv` would walk past the old anchor into the
|
|
192
|
+
* parent directory's project.
|
|
188
193
|
*/
|
|
189
194
|
export declare function findPrimitiveConfigPath(options?: {
|
|
190
195
|
cwd?: string;
|
|
@@ -65,6 +65,6 @@ const observer = new MutationObserver(async (mutations, obs) => {
|
|
|
65
65
|
});
|
|
66
66
|
|
|
67
67
|
observer.observe(document.body, { childList: true, subtree: true });
|
|
68
|
-
`},transformIndexHtml(e){if(!h||!d)return e;let t=`<style data-primitive-devtools-sonner>${g}</style>`;return e.replace(`</body>`,`${t}\n<script type="module" src="/@id/__x00__virtual:primitive-devtools-init"><\/script>\n</body>`)},hotUpdate({file:e,server:t}){if(e.endsWith(`.primitive-test.ts`)){let e=t.moduleGraph.getModuleById(c);e&&(t.moduleGraph.invalidateModule(e),t.ws.send({type:`full-reload`}))}}}}var f=`primitive`,p=`.primitive`,m=`config.json`,h=`local.json`,g=`primitive/config.json`,_=`.primitive/local.json
|
|
69
|
-
`)}function
|
|
70
|
-
`)}function
|
|
68
|
+
`},transformIndexHtml(e){if(!h||!d)return e;let t=`<style data-primitive-devtools-sonner>${g}</style>`;return e.replace(`</body>`,`${t}\n<script type="module" src="/@id/__x00__virtual:primitive-devtools-init"><\/script>\n</body>`)},hotUpdate({file:e,server:t}){if(e.endsWith(`.primitive-test.ts`)){let e=t.moduleGraph.getModuleById(c);e&&(t.moduleGraph.invalidateModule(e),t.ws.send({type:`full-reload`}))}}}}var f=`primitive`,p=`.primitive`,m=`config.json`,h=`local.json`,g=`primitive/config.json`,_=`.primitive/local.json`;function v(e,t){return`Found ${e} but no ${t}: this project still uses the retired layout under ${p}/, which is never read.`}function y(e){return`No ${g} found in ${e} or any parent directory. Primitive commands run inside a Primitive project: it is where the CLI reads the environment, the app that environment names, and the configuration tree from. Run 'primitive init' to create one.`}var b=class extends Error{kind;path;constructor(e,t,n){super(t),this.name=`PrimitiveEnvError`,this.kind=e,this.path=n}};function x(e){if(typeof e!=`string`)return;let t=e.trim();if(!t)return;let n;try{n=new URL(t)}catch{return}if(!(n.protocol!==`https:`&&n.protocol!==`http:`)&&!(n.protocol===`http:`&&n.hostname!==`localhost`&&n.hostname!==`127.0.0.1`)&&!(n.username||n.password)&&!(n.pathname!==`/`&&n.pathname!==``)&&!(n.search||n.hash))return n.origin}function S(e,t){return`Environment "${e}" in ${t?`${g} (${t})`:g} has no "appId". Every environment names exactly one app — add "appId": "<app-id>" to that environment in ${g}. Find the app id in the Primitive admin UI, with 'primitive apps list' run from another Primitive project, or as the residual "currentAppId" in .primitive/credentials.json if this environment was ever pointed at an app by the retired per-machine app selection.`}function C(e){if(typeof e==`string`)return e.trim()||void 0}function w(e){return e.startsWith(`https://`)?`wss://`+e.slice(8):e.startsWith(`http://`)?`ws://`+e.slice(7):e}function T(e={}){let n=(e.env??process.env).PRIMITIVE_PROJECT_CONFIG;if(n){let e=(0,a.resolve)(n);if((0,a.basename)((0,a.dirname)(e))===`.primitive`)throw new b(`stale-layout`,v(e,(0,a.join)((0,a.dirname)((0,a.dirname)(e)),f,m)),e);return(0,t.existsSync)(e)?e:null}let r=(0,a.resolve)(e.cwd??process.cwd());for(;;){let e=(0,a.join)(r,f,m);if((0,t.existsSync)(e))return e;let n=(0,a.join)(r,p,m);if((0,t.existsSync)(n))throw new b(`stale-layout`,v(n,e),n);let i=(0,a.dirname)(r);if(i===r)return null;r=i}}function E(e){let t=(0,a.dirname)(e);return(0,a.basename)(t)===`primitive`?(0,a.dirname)(t):t}function D(e){return(0,a.join)(E(e),p,h)}function O(e){if(!(0,t.existsSync)(e))throw new b(`missing-config`,y((0,a.dirname)(e)),e);let n;try{n=(0,t.readFileSync)(e,`utf-8`)}catch(t){throw new b(`malformed-config`,`Failed to read ${g} (${e}): ${t.message}`,e)}let r;try{r=JSON.parse(n)}catch(t){throw new b(`malformed-config`,`Failed to parse ${g} (${e}): ${t.message}`,e)}if(!r||typeof r!=`object`||Array.isArray(r))throw new b(`malformed-config`,`${g} (${e}) must contain a JSON object at the top level.`,e);let i=r;if(typeof i.version!=`number`||!Number.isInteger(i.version))throw new b(`malformed-config`,`${g} (${e}) is missing required integer field "version".`,e);if(i.version!==1)throw new b(`unsupported-version`,`${g} (${e}) has version ${i.version}, but this tool understands version 1.`,e);if(!i.environments||typeof i.environments!=`object`||Array.isArray(i.environments))throw new b(`malformed-config`,`${g} (${e}) is missing required "environments" object.`,e);let o={};for(let[t,n]of Object.entries(i.environments)){if(!n||typeof n!=`object`||Array.isArray(n))throw new b(`malformed-config`,`Environment "${t}" must be an object in ${g} (${e}).`,e);let r=n;if(typeof r.apiUrl!=`string`||!r.apiUrl)throw new b(`malformed-config`,`Environment "${t}" must have a non-empty "apiUrl" string in ${g} (${e}).`,e);let i=C(r.appId);if(!i)throw new b(`missing-app-id`,S(t,e),e);o[t]={apiUrl:r.apiUrl.replace(/\/$/,``),appId:i,appName:typeof r.appName==`string`?r.appName:void 0,webUrl:x(r.webUrl),description:typeof r.description==`string`?r.description:void 0}}return{version:i.version,defaultEnvironment:typeof i.defaultEnvironment==`string`&&i.defaultEnvironment?i.defaultEnvironment:void 0,environments:o}}function k(e){let n=D(e);if(!(0,t.existsSync)(n))return null;let r=e=>{throw new b(`corrupt-local-state`,`${_} (${n}) is unreadable: ${e}. Delete the file or re-run 'primitive env use <name>'.`,n)},i;try{i=JSON.parse((0,t.readFileSync)(n,`utf-8`))}catch(e){return r(e.message)}if(!i||typeof i!=`object`||Array.isArray(i))return r(`expected a JSON object`);let a=i.selectedEnvironment;return a==null||a===``?null:typeof a==`string`?a:r(`"selectedEnvironment" must be a string`)}function A(e,t){let n=Object.keys(e.environments),r=n.join(`, `)||`(none)`,i=t.configPath?`${g} (${t.configPath})`:g,a=(n,a,o)=>{if(!e.environments[n])throw new b(`unknown-environment`,`Environment "${n}" is not defined in ${i} (selected ${o}). Available: ${r}`,t.configPath);return{name:n,source:a}};if(t.explicitEnvName)return a(t.explicitEnvName,`explicit`,`explicitly`);if(t.envVarName)return a(t.envVarName,`env-var`,`via PRIMITIVE_ENV`);if(t.localSelection)return a(t.localSelection,`local`,`in ${_}`);if(e.defaultEnvironment)return a(e.defaultEnvironment,`default`,`as "defaultEnvironment"`);if(n.length===1)return{name:n[0],source:`sole`};throw n.length===0?new b(`no-selection`,`${i} has no environments defined. Run 'primitive env add <name>' or 'primitive init'.`,t.configPath):new b(`no-selection`,`No environment selected. Run 'primitive env use <name>', set "defaultEnvironment" in ${i}, or export PRIMITIVE_ENV. Available: ${r}`,t.configPath)}function j(e={}){let t=e.env??process.env,n=e.configPath??T({cwd:e.cwd,env:t});if(!n)throw new b(`missing-config`,y(e.cwd??process.cwd()));let r=E(n),i=O(n),{name:a,source:o}=A(i,{explicitEnvName:e.explicitEnvName||null,envVarName:t.PRIMITIVE_ENV||null,localSelection:k(n),configPath:n}),s=i.environments[a];return{name:a,apiUrl:s.apiUrl,wsUrl:w(s.apiUrl),appId:s.appId,appName:s.appName,webUrl:s.webUrl,description:s.description,source:o,configPath:n,localStatePath:D(n),projectRoot:r}}var M=[`VITE_APP_ID`,`VITE_API_URL`,`VITE_WS_URL`,`VITE_APP_NAME`],N=`VITE_EXPECTED_PRIMITIVE_ENV`,P=new Map;function F(e,t){let n=process.env[e];n!==void 0&&n!==``&&P.get(e)!==n||(process.env[e]=t,P.set(e,t))}function I(e={}){return j({cwd:e.root,env:e.env,explicitEnvName:e.primitiveEnv??null})}function L(e,t,n){let r=e=>n.includes(e)?` (overridden)`:``,i=[`[primitive-env] Primitive environment: ${e.name} (selected: ${e.source})`,`[primitive-env] apiUrl: ${t.apiUrl}${r(`VITE_API_URL`)}`,`[primitive-env] wsUrl: ${t.wsUrl}${r(`VITE_WS_URL`)}`,`[primitive-env] appId: ${t.appId??`(unset)`}${r(`VITE_APP_ID`)}`,`[primitive-env] appName: ${t.appName??`(unset)`}${r(`VITE_APP_NAME`)}`,`[primitive-env] config: ${e.configPath}`];return n.length>0&&i.push(`[primitive-env] overridden by the environment: ${n.join(`, `)}`),i.join(`
|
|
69
|
+
`)}function R(e,t){let n=e?.envDir;return n===!1?null:typeof n==`string`&&n!==``?(0,a.resolve)(t,n):t}function z(e,t){let n=process.env[N];if(n!==void 0&&n!==``)return{value:n,where:`the process environment`};if(t===null)return null;for(let n of[`.env.${e}.local`,`.env.${e}`,`.env.local`,`.env`]){let e=W((0,a.join)(t,n))[N];if(e!==void 0)return{value:e,where:n}}return null}function B(e,t,n){return[`[primitive-env] Wrong pair: vite mode "${e}" is declared to run against Primitive environment "${t.value}", but "${n.name}" resolved.`,`[primitive-env] expected: ${t.value} (${N} in ${t.where})`,`[primitive-env] resolved: ${n.name} (selected: ${n.source})`,`[primitive-env] config: ${n.configPath}`,``,`Run the pair you meant — PRIMITIVE_ENV=${t.value} <command> --mode ${e}, or 'primitive env use ${t.value}' — or change/remove ${N} in ${t.where}.`,``,`A mode declares this when its .env.${e} carries values coupled to one backend, so continuing would run this environment's identity with another's configuration.`].join(`
|
|
70
|
+
`)}function V(e,t,n){let r=z(e,t);if(r&&r.value!==``&&r.value!==n.name)throw Error(B(e,r,n))}function H(e={}){let t=null,n=null,r,i=[],a=!1,o=null;return{name:`primitive-env`,enforce:`pre`,config(s,c){a=c?.command===`serve`,o=null;let l=s?.root??process.cwd(),u=c?.mode??`development`,d=U(u,l),f={};for(let e of M){let t=process.env[e],n=t!==void 0&&P.get(e)!==t?t:d[e];n!==void 0&&n!==``&&(f[e]=n)}let p;try{p=j({cwd:l,explicitEnvName:e.primitiveEnv??null})}catch(e){if(e instanceof b&&e.kind===`missing-config`&&f.VITE_APP_ID&&f.VITE_API_URL)return console.warn(`[primitive-env] No primitive/config.json found; using VITE_APP_ID / VITE_API_URL from the environment. Run 'primitive init' to make the project the source of truth.`),r=f.VITE_APP_NAME,{};throw e}if(!(f.VITE_APP_ID&&f.VITE_API_URL)){let e=R(s,l);V(u,e,p),o={root:l,mode:u,dir:e}}t=p,r=f.VITE_APP_NAME??p.appName;let m={VITE_APP_ID:p.appId,VITE_API_URL:p.apiUrl,VITE_WS_URL:p.wsUrl,VITE_APP_NAME:p.appName},h={"import.meta.env.VITE_PRIMITIVE_ENV":JSON.stringify(p.name)},g=[];for(let e of M){if(f[e]!==void 0){g.push(e);continue}let t=m[e];t!==void 0&&(h[`import.meta.env.${e}`]=JSON.stringify(t),F(e,t))}return F(`VITE_PRIMITIVE_ENV`,p.name),i=g,n={apiUrl:f.VITE_API_URL??p.apiUrl,wsUrl:f.VITE_WS_URL??p.wsUrl,appId:f.VITE_APP_ID??p.appId,appName:r},e.logResolved!==!1&&console.log(L(p,n,g)),g.length>0&&console.warn(`[primitive-env] Overridden by an explicit value in .env or the shell: ${g.join(`, `)}. Remove it to use primitive/config.json (deploys reject these outright).`),{define:h}},configResolved(e){if(!o||!t)return;let n=R(e,o.root),r=e?.mode??o.mode;n===o.dir&&r===o.mode||(V(r,n,t),o={root:o.root,mode:r,dir:n})},transformIndexHtml(){if(!a||!t||!n)return[];let e=`%c[primitive] env=${t.name} api=${n.apiUrl} app=${n.appId??`(unset)`} (${t.configPath})`+(i.length>0?` overridden: ${i.join(`, `)}`:``);return[{tag:`script`,injectTo:`head`,children:`console.info(${JSON.stringify(e)}, "color:#888");`}]},appName(){return r},resolved(){return t}}}function U(e,t){let n=[`.env`,`.env.local`,`.env.${e}`,`.env.${e}.local`],r={};for(let e of n)Object.assign(r,W((0,a.join)(t,e)));return r}function W(e){if(!(0,t.existsSync)(e))return{};let n={};for(let r of(0,t.readFileSync)(e,`utf-8`).split(/\r?\n/)){let e=r.trim();if(!e||e.startsWith(`#`))continue;let t=e.match(/^(?:export\s+)?([A-Za-z_][A-Za-z0-9_]*)\s*=\s*(.*)$/);if(!t)continue;let i=t[2].trim(),a=i[0],o=a===`"`||a===`'`||a==="`"?i.indexOf(a,1):-1;n[t[1]]=o===-1?i.replace(/\s+#.*$/,``).trim():i.slice(1,o)}return n}exports.PrimitiveEnvError=b,exports.primitiveDevTools=d,exports.primitiveEnv=H,exports.resolvePrimitiveEnv=I;
|
|
@@ -63,21 +63,21 @@ export const keyboardShortcut = ${JSON.stringify(s)};
|
|
|
63
63
|
}
|
|
64
64
|
};
|
|
65
65
|
}
|
|
66
|
-
var h = "primitive", g = ".primitive", _ = "config.json", v = "local.json", y = "primitive/config.json", b = ".primitive/local.json"
|
|
67
|
-
function
|
|
68
|
-
return
|
|
66
|
+
var h = "primitive", g = ".primitive", _ = "config.json", v = "local.json", y = "primitive/config.json", b = ".primitive/local.json";
|
|
67
|
+
function x(e, t) {
|
|
68
|
+
return `Found ${e} but no ${t}: this project still uses the retired layout under ${g}/, which is never read.`;
|
|
69
69
|
}
|
|
70
|
-
function
|
|
70
|
+
function S(e) {
|
|
71
71
|
return `No ${y} found in ${e} or any parent directory. Primitive commands run inside a Primitive project: it is where the CLI reads the environment, the app that environment names, and the configuration tree from. Run 'primitive init' to create one.`;
|
|
72
72
|
}
|
|
73
|
-
var
|
|
73
|
+
var C = class extends Error {
|
|
74
74
|
kind;
|
|
75
75
|
path;
|
|
76
76
|
constructor(e, t, n) {
|
|
77
77
|
super(t), this.name = "PrimitiveEnvError", this.kind = e, this.path = n;
|
|
78
78
|
}
|
|
79
79
|
};
|
|
80
|
-
function
|
|
80
|
+
function w(e) {
|
|
81
81
|
if (typeof e != "string") return;
|
|
82
82
|
let t = e.trim();
|
|
83
83
|
if (!t) return;
|
|
@@ -89,75 +89,71 @@ function T(e) {
|
|
|
89
89
|
}
|
|
90
90
|
if (!(n.protocol !== "https:" && n.protocol !== "http:") && !(n.protocol === "http:" && n.hostname !== "localhost" && n.hostname !== "127.0.0.1") && !(n.username || n.password) && !(n.pathname !== "/" && n.pathname !== "") && !(n.search || n.hash)) return n.origin;
|
|
91
91
|
}
|
|
92
|
-
function
|
|
92
|
+
function T(e, t) {
|
|
93
93
|
return `Environment "${e}" in ${t ? `${y} (${t})` : y} has no "appId". Every environment names exactly one app — add "appId": "<app-id>" to that environment in ${y}. Find the app id in the Primitive admin UI, with 'primitive apps list' run from another Primitive project, or as the residual "currentAppId" in .primitive/credentials.json if this environment was ever pointed at an app by the retired per-machine app selection.`;
|
|
94
94
|
}
|
|
95
|
-
function
|
|
95
|
+
function E(e) {
|
|
96
96
|
if (typeof e == "string") return e.trim() || void 0;
|
|
97
97
|
}
|
|
98
|
-
function
|
|
98
|
+
function D(e) {
|
|
99
99
|
return e.startsWith("https://") ? "wss://" + e.slice(8) : e.startsWith("http://") ? "ws://" + e.slice(7) : e;
|
|
100
100
|
}
|
|
101
|
-
function
|
|
102
|
-
let n = s(t, g, _);
|
|
103
|
-
if (e(n)) throw new w("stale-layout", S(`${n} still exists.`), n);
|
|
104
|
-
let r = s(t, g, "sync");
|
|
105
|
-
if (e(r)) throw new w("stale-layout", S(`${r} still exists.`), r);
|
|
106
|
-
}
|
|
107
|
-
function A(t = {}) {
|
|
101
|
+
function O(t = {}) {
|
|
108
102
|
let n = (t.env ?? process.env).PRIMITIVE_PROJECT_CONFIG;
|
|
109
103
|
if (n) {
|
|
110
104
|
let t = c(n);
|
|
111
|
-
if (a(o(t)) === ".primitive") throw new
|
|
112
|
-
return e(t) ?
|
|
105
|
+
if (a(o(t)) === ".primitive") throw new C("stale-layout", x(t, s(o(o(t)), h, _)), t);
|
|
106
|
+
return e(t) ? t : null;
|
|
113
107
|
}
|
|
114
108
|
let r = c(t.cwd ?? process.cwd());
|
|
115
109
|
for (;;) {
|
|
116
110
|
let t = s(r, h, _);
|
|
117
|
-
if (
|
|
118
|
-
let n =
|
|
119
|
-
if (n
|
|
120
|
-
|
|
111
|
+
if (e(t)) return t;
|
|
112
|
+
let n = s(r, g, _);
|
|
113
|
+
if (e(n)) throw new C("stale-layout", x(n, t), n);
|
|
114
|
+
let i = o(r);
|
|
115
|
+
if (i === r) return null;
|
|
116
|
+
r = i;
|
|
121
117
|
}
|
|
122
118
|
}
|
|
123
|
-
function
|
|
119
|
+
function k(e) {
|
|
124
120
|
let t = o(e);
|
|
125
121
|
return a(t) === "primitive" ? o(t) : t;
|
|
126
122
|
}
|
|
127
|
-
function
|
|
128
|
-
return s(
|
|
123
|
+
function A(e) {
|
|
124
|
+
return s(k(e), g, v);
|
|
129
125
|
}
|
|
130
|
-
function
|
|
131
|
-
if (!e(n)) throw new
|
|
126
|
+
function j(n) {
|
|
127
|
+
if (!e(n)) throw new C("missing-config", S(o(n)), n);
|
|
132
128
|
let r;
|
|
133
129
|
try {
|
|
134
130
|
r = t(n, "utf-8");
|
|
135
131
|
} catch (e) {
|
|
136
|
-
throw new
|
|
132
|
+
throw new C("malformed-config", `Failed to read ${y} (${n}): ${e.message}`, n);
|
|
137
133
|
}
|
|
138
134
|
let i;
|
|
139
135
|
try {
|
|
140
136
|
i = JSON.parse(r);
|
|
141
137
|
} catch (e) {
|
|
142
|
-
throw new
|
|
138
|
+
throw new C("malformed-config", `Failed to parse ${y} (${n}): ${e.message}`, n);
|
|
143
139
|
}
|
|
144
|
-
if (!i || typeof i != "object" || Array.isArray(i)) throw new
|
|
140
|
+
if (!i || typeof i != "object" || Array.isArray(i)) throw new C("malformed-config", `${y} (${n}) must contain a JSON object at the top level.`, n);
|
|
145
141
|
let a = i;
|
|
146
|
-
if (typeof a.version != "number" || !Number.isInteger(a.version)) throw new
|
|
147
|
-
if (a.version !== 1) throw new
|
|
148
|
-
if (!a.environments || typeof a.environments != "object" || Array.isArray(a.environments)) throw new
|
|
142
|
+
if (typeof a.version != "number" || !Number.isInteger(a.version)) throw new C("malformed-config", `${y} (${n}) is missing required integer field "version".`, n);
|
|
143
|
+
if (a.version !== 1) throw new C("unsupported-version", `${y} (${n}) has version ${a.version}, but this tool understands version 1.`, n);
|
|
144
|
+
if (!a.environments || typeof a.environments != "object" || Array.isArray(a.environments)) throw new C("malformed-config", `${y} (${n}) is missing required "environments" object.`, n);
|
|
149
145
|
let s = {};
|
|
150
146
|
for (let [e, t] of Object.entries(a.environments)) {
|
|
151
|
-
if (!t || typeof t != "object" || Array.isArray(t)) throw new
|
|
147
|
+
if (!t || typeof t != "object" || Array.isArray(t)) throw new C("malformed-config", `Environment "${e}" must be an object in ${y} (${n}).`, n);
|
|
152
148
|
let r = t;
|
|
153
|
-
if (typeof r.apiUrl != "string" || !r.apiUrl) throw new
|
|
154
|
-
let i =
|
|
155
|
-
if (!i) throw new
|
|
149
|
+
if (typeof r.apiUrl != "string" || !r.apiUrl) throw new C("malformed-config", `Environment "${e}" must have a non-empty "apiUrl" string in ${y} (${n}).`, n);
|
|
150
|
+
let i = E(r.appId);
|
|
151
|
+
if (!i) throw new C("missing-app-id", T(e, n), n);
|
|
156
152
|
s[e] = {
|
|
157
153
|
apiUrl: r.apiUrl.replace(/\/$/, ""),
|
|
158
154
|
appId: i,
|
|
159
155
|
appName: typeof r.appName == "string" ? r.appName : void 0,
|
|
160
|
-
webUrl:
|
|
156
|
+
webUrl: w(r.webUrl),
|
|
161
157
|
description: typeof r.description == "string" ? r.description : void 0
|
|
162
158
|
};
|
|
163
159
|
}
|
|
@@ -167,11 +163,11 @@ function N(n) {
|
|
|
167
163
|
environments: s
|
|
168
164
|
};
|
|
169
165
|
}
|
|
170
|
-
function
|
|
171
|
-
let r =
|
|
166
|
+
function M(n) {
|
|
167
|
+
let r = A(n);
|
|
172
168
|
if (!e(r)) return null;
|
|
173
169
|
let i = (e) => {
|
|
174
|
-
throw new
|
|
170
|
+
throw new C("corrupt-local-state", `${b} (${r}) is unreadable: ${e}. Delete the file or re-run 'primitive env use <name>'.`, r);
|
|
175
171
|
}, a;
|
|
176
172
|
try {
|
|
177
173
|
a = JSON.parse(t(r, "utf-8"));
|
|
@@ -182,9 +178,9 @@ function P(n) {
|
|
|
182
178
|
let o = a.selectedEnvironment;
|
|
183
179
|
return o == null || o === "" ? null : typeof o == "string" ? o : i("\"selectedEnvironment\" must be a string");
|
|
184
180
|
}
|
|
185
|
-
function
|
|
181
|
+
function N(e, t) {
|
|
186
182
|
let n = Object.keys(e.environments), r = n.join(", ") || "(none)", i = t.configPath ? `${y} (${t.configPath})` : y, a = (n, a, o) => {
|
|
187
|
-
if (!e.environments[n]) throw new
|
|
183
|
+
if (!e.environments[n]) throw new C("unknown-environment", `Environment "${n}" is not defined in ${i} (selected ${o}). Available: ${r}`, t.configPath);
|
|
188
184
|
return {
|
|
189
185
|
name: n,
|
|
190
186
|
source: a
|
|
@@ -198,56 +194,54 @@ function F(e, t) {
|
|
|
198
194
|
name: n[0],
|
|
199
195
|
source: "sole"
|
|
200
196
|
};
|
|
201
|
-
throw n.length === 0 ? new
|
|
197
|
+
throw n.length === 0 ? new C("no-selection", `${i} has no environments defined. Run 'primitive env add <name>' or 'primitive init'.`, t.configPath) : new C("no-selection", `No environment selected. Run 'primitive env use <name>', set "defaultEnvironment" in ${i}, or export PRIMITIVE_ENV. Available: ${r}`, t.configPath);
|
|
202
198
|
}
|
|
203
|
-
function
|
|
204
|
-
let t = e.env ?? process.env, n = e.configPath ??
|
|
199
|
+
function P(e = {}) {
|
|
200
|
+
let t = e.env ?? process.env, n = e.configPath ?? O({
|
|
205
201
|
cwd: e.cwd,
|
|
206
202
|
env: t
|
|
207
203
|
});
|
|
208
|
-
if (!n) throw new
|
|
209
|
-
let r = j(n)
|
|
210
|
-
k(r);
|
|
211
|
-
let i = N(n), { name: a, source: o } = F(i, {
|
|
204
|
+
if (!n) throw new C("missing-config", S(e.cwd ?? process.cwd()));
|
|
205
|
+
let r = k(n), i = j(n), { name: a, source: o } = N(i, {
|
|
212
206
|
explicitEnvName: e.explicitEnvName || null,
|
|
213
207
|
envVarName: t.PRIMITIVE_ENV || null,
|
|
214
|
-
localSelection:
|
|
208
|
+
localSelection: M(n),
|
|
215
209
|
configPath: n
|
|
216
210
|
}), s = i.environments[a];
|
|
217
211
|
return {
|
|
218
212
|
name: a,
|
|
219
213
|
apiUrl: s.apiUrl,
|
|
220
|
-
wsUrl:
|
|
214
|
+
wsUrl: D(s.apiUrl),
|
|
221
215
|
appId: s.appId,
|
|
222
216
|
appName: s.appName,
|
|
223
217
|
webUrl: s.webUrl,
|
|
224
218
|
description: s.description,
|
|
225
219
|
source: o,
|
|
226
220
|
configPath: n,
|
|
227
|
-
localStatePath:
|
|
221
|
+
localStatePath: A(n),
|
|
228
222
|
projectRoot: r
|
|
229
223
|
};
|
|
230
224
|
}
|
|
231
225
|
//#endregion
|
|
232
226
|
//#region src/dev-tools/vite-plugin/primitive-env.ts
|
|
233
|
-
var
|
|
227
|
+
var F = [
|
|
234
228
|
"VITE_APP_ID",
|
|
235
229
|
"VITE_API_URL",
|
|
236
230
|
"VITE_WS_URL",
|
|
237
231
|
"VITE_APP_NAME"
|
|
238
|
-
],
|
|
239
|
-
function
|
|
232
|
+
], I = "VITE_EXPECTED_PRIMITIVE_ENV", L = /* @__PURE__ */ new Map();
|
|
233
|
+
function R(e, t) {
|
|
240
234
|
let n = process.env[e];
|
|
241
|
-
n !== void 0 && n !== "" &&
|
|
235
|
+
n !== void 0 && n !== "" && L.get(e) !== n || (process.env[e] = t, L.set(e, t));
|
|
242
236
|
}
|
|
243
|
-
function
|
|
244
|
-
return
|
|
237
|
+
function z(e = {}) {
|
|
238
|
+
return P({
|
|
245
239
|
cwd: e.root,
|
|
246
240
|
env: e.env,
|
|
247
241
|
explicitEnvName: e.primitiveEnv ?? null
|
|
248
242
|
});
|
|
249
243
|
}
|
|
250
|
-
function
|
|
244
|
+
function B(e, t, n) {
|
|
251
245
|
let r = (e) => n.includes(e) ? " (overridden)" : "", i = [
|
|
252
246
|
`[primitive-env] Primitive environment: ${e.name} (selected: ${e.source})`,
|
|
253
247
|
`[primitive-env] apiUrl: ${t.apiUrl}${r("VITE_API_URL")}`,
|
|
@@ -258,12 +252,12 @@ function H(e, t, n) {
|
|
|
258
252
|
];
|
|
259
253
|
return n.length > 0 && i.push(`[primitive-env] overridden by the environment: ${n.join(", ")}`), i.join("\n");
|
|
260
254
|
}
|
|
261
|
-
function
|
|
255
|
+
function V(e, t) {
|
|
262
256
|
let n = e?.envDir;
|
|
263
257
|
return n === !1 ? null : typeof n == "string" && n !== "" ? c(t, n) : t;
|
|
264
258
|
}
|
|
265
|
-
function
|
|
266
|
-
let n = process.env[
|
|
259
|
+
function H(e, t) {
|
|
260
|
+
let n = process.env[I];
|
|
267
261
|
if (n !== void 0 && n !== "") return {
|
|
268
262
|
value: n,
|
|
269
263
|
where: "the process environment"
|
|
@@ -275,7 +269,7 @@ function W(e, t) {
|
|
|
275
269
|
".env.local",
|
|
276
270
|
".env"
|
|
277
271
|
]) {
|
|
278
|
-
let e =
|
|
272
|
+
let e = q(s(t, n))[I];
|
|
279
273
|
if (e !== void 0) return {
|
|
280
274
|
value: e,
|
|
281
275
|
where: n
|
|
@@ -283,47 +277,47 @@ function W(e, t) {
|
|
|
283
277
|
}
|
|
284
278
|
return null;
|
|
285
279
|
}
|
|
286
|
-
function
|
|
280
|
+
function U(e, t, n) {
|
|
287
281
|
return [
|
|
288
282
|
`[primitive-env] Wrong pair: vite mode "${e}" is declared to run against Primitive environment "${t.value}", but "${n.name}" resolved.`,
|
|
289
|
-
`[primitive-env] expected: ${t.value} (${
|
|
283
|
+
`[primitive-env] expected: ${t.value} (${I} in ${t.where})`,
|
|
290
284
|
`[primitive-env] resolved: ${n.name} (selected: ${n.source})`,
|
|
291
285
|
`[primitive-env] config: ${n.configPath}`,
|
|
292
286
|
"",
|
|
293
|
-
`Run the pair you meant — PRIMITIVE_ENV=${t.value} <command> --mode ${e}, or 'primitive env use ${t.value}' — or change/remove ${
|
|
287
|
+
`Run the pair you meant — PRIMITIVE_ENV=${t.value} <command> --mode ${e}, or 'primitive env use ${t.value}' — or change/remove ${I} in ${t.where}.`,
|
|
294
288
|
"",
|
|
295
289
|
`A mode declares this when its .env.${e} carries values coupled to one backend, so continuing would run this environment's identity with another's configuration.`
|
|
296
290
|
].join("\n");
|
|
297
291
|
}
|
|
298
|
-
function
|
|
299
|
-
let r =
|
|
300
|
-
if (r && r.value !== "" && r.value !== n.name) throw Error(
|
|
292
|
+
function W(e, t, n) {
|
|
293
|
+
let r = H(e, t);
|
|
294
|
+
if (r && r.value !== "" && r.value !== n.name) throw Error(U(e, r, n));
|
|
301
295
|
}
|
|
302
|
-
function
|
|
296
|
+
function G(e = {}) {
|
|
303
297
|
let t = null, n = null, r, i = [], a = !1, o = null;
|
|
304
298
|
return {
|
|
305
299
|
name: "primitive-env",
|
|
306
300
|
enforce: "pre",
|
|
307
301
|
config(s, c) {
|
|
308
302
|
a = c?.command === "serve", o = null;
|
|
309
|
-
let l = s?.root ?? process.cwd(), u = c?.mode ?? "development", d =
|
|
310
|
-
for (let e of
|
|
311
|
-
let t = process.env[e], n = t !== void 0 &&
|
|
303
|
+
let l = s?.root ?? process.cwd(), u = c?.mode ?? "development", d = K(u, l), f = {};
|
|
304
|
+
for (let e of F) {
|
|
305
|
+
let t = process.env[e], n = t !== void 0 && L.get(e) !== t ? t : d[e];
|
|
312
306
|
n !== void 0 && n !== "" && (f[e] = n);
|
|
313
307
|
}
|
|
314
308
|
let p;
|
|
315
309
|
try {
|
|
316
|
-
p =
|
|
310
|
+
p = P({
|
|
317
311
|
cwd: l,
|
|
318
312
|
explicitEnvName: e.primitiveEnv ?? null
|
|
319
313
|
});
|
|
320
314
|
} catch (e) {
|
|
321
|
-
if (e instanceof
|
|
315
|
+
if (e instanceof C && e.kind === "missing-config" && f.VITE_APP_ID && f.VITE_API_URL) return console.warn("[primitive-env] No primitive/config.json found; using VITE_APP_ID / VITE_API_URL from the environment. Run 'primitive init' to make the project the source of truth."), r = f.VITE_APP_NAME, {};
|
|
322
316
|
throw e;
|
|
323
317
|
}
|
|
324
318
|
if (!(f.VITE_APP_ID && f.VITE_API_URL)) {
|
|
325
|
-
let e =
|
|
326
|
-
|
|
319
|
+
let e = V(s, l);
|
|
320
|
+
W(u, e, p), o = {
|
|
327
321
|
root: l,
|
|
328
322
|
mode: u,
|
|
329
323
|
dir: e
|
|
@@ -336,25 +330,25 @@ function q(e = {}) {
|
|
|
336
330
|
VITE_WS_URL: p.wsUrl,
|
|
337
331
|
VITE_APP_NAME: p.appName
|
|
338
332
|
}, h = { "import.meta.env.VITE_PRIMITIVE_ENV": JSON.stringify(p.name) }, g = [];
|
|
339
|
-
for (let e of
|
|
333
|
+
for (let e of F) {
|
|
340
334
|
if (f[e] !== void 0) {
|
|
341
335
|
g.push(e);
|
|
342
336
|
continue;
|
|
343
337
|
}
|
|
344
338
|
let t = m[e];
|
|
345
|
-
t !== void 0 && (h[`import.meta.env.${e}`] = JSON.stringify(t),
|
|
339
|
+
t !== void 0 && (h[`import.meta.env.${e}`] = JSON.stringify(t), R(e, t));
|
|
346
340
|
}
|
|
347
|
-
return
|
|
341
|
+
return R("VITE_PRIMITIVE_ENV", p.name), i = g, n = {
|
|
348
342
|
apiUrl: f.VITE_API_URL ?? p.apiUrl,
|
|
349
343
|
wsUrl: f.VITE_WS_URL ?? p.wsUrl,
|
|
350
344
|
appId: f.VITE_APP_ID ?? p.appId,
|
|
351
345
|
appName: r
|
|
352
|
-
}, e.logResolved !== !1 && console.log(
|
|
346
|
+
}, e.logResolved !== !1 && console.log(B(p, n, g)), g.length > 0 && console.warn(`[primitive-env] Overridden by an explicit value in .env or the shell: ${g.join(", ")}. Remove it to use primitive/config.json (deploys reject these outright).`), { define: h };
|
|
353
347
|
},
|
|
354
348
|
configResolved(e) {
|
|
355
349
|
if (!o || !t) return;
|
|
356
|
-
let n =
|
|
357
|
-
n === o.dir && r === o.mode || (
|
|
350
|
+
let n = V(e, o.root), r = e?.mode ?? o.mode;
|
|
351
|
+
n === o.dir && r === o.mode || (W(r, n, t), o = {
|
|
358
352
|
root: o.root,
|
|
359
353
|
mode: r,
|
|
360
354
|
dir: n
|
|
@@ -377,17 +371,17 @@ function q(e = {}) {
|
|
|
377
371
|
}
|
|
378
372
|
};
|
|
379
373
|
}
|
|
380
|
-
function
|
|
374
|
+
function K(e, t) {
|
|
381
375
|
let n = [
|
|
382
376
|
".env",
|
|
383
377
|
".env.local",
|
|
384
378
|
`.env.${e}`,
|
|
385
379
|
`.env.${e}.local`
|
|
386
380
|
], r = {};
|
|
387
|
-
for (let e of n) Object.assign(r,
|
|
381
|
+
for (let e of n) Object.assign(r, q(s(t, e)));
|
|
388
382
|
return r;
|
|
389
383
|
}
|
|
390
|
-
function
|
|
384
|
+
function q(n) {
|
|
391
385
|
if (!e(n)) return {};
|
|
392
386
|
let r = {};
|
|
393
387
|
for (let e of t(n, "utf-8").split(/\r?\n/)) {
|
|
@@ -401,4 +395,4 @@ function Y(n) {
|
|
|
401
395
|
return r;
|
|
402
396
|
}
|
|
403
397
|
//#endregion
|
|
404
|
-
export {
|
|
398
|
+
export { C as PrimitiveEnvError, m as primitiveDevTools, G as primitiveEnv, z as resolvePrimitiveEnv };
|