primitive-app 3.2.0-alpha.0 → 3.2.0-alpha.2
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.
|
@@ -33,7 +33,12 @@ export declare class PrimitiveEnvError extends Error {
|
|
|
33
33
|
}
|
|
34
34
|
export interface CoreEnvironmentEntry {
|
|
35
35
|
apiUrl: string;
|
|
36
|
-
|
|
36
|
+
/**
|
|
37
|
+
* The one app this environment names (#3152). Required: selecting an
|
|
38
|
+
* environment selects exactly one app, so there is no per-machine "current
|
|
39
|
+
* app" for a second reader to disagree with.
|
|
40
|
+
*/
|
|
41
|
+
appId: string;
|
|
37
42
|
appName?: string;
|
|
38
43
|
/**
|
|
39
44
|
* The app's web counterpart for this environment, as a normalized origin
|
|
@@ -75,6 +80,21 @@ export interface CoreEnvironmentEntry {
|
|
|
75
80
|
* two agree.
|
|
76
81
|
*/
|
|
77
82
|
export declare function normalizeWebOrigin(value: unknown): string | undefined;
|
|
83
|
+
/**
|
|
84
|
+
* The one remedy for an environment that names no app (#3152), shared by every
|
|
85
|
+
* reader that can hit it: this core, the CLI's `validateProjectConfig`, the
|
|
86
|
+
* Swift template's pre-build script, and the Vue template's cf-deploy.
|
|
87
|
+
*
|
|
88
|
+
* Two constraints on the wording, both test-asserted:
|
|
89
|
+
*
|
|
90
|
+
* - it never says `primitive env add <name>`, which REFUSES an environment
|
|
91
|
+
* name that already exists — the shape this error is always about;
|
|
92
|
+
* - it names no command the failure itself blocks. The CLI validates the
|
|
93
|
+
* project config before any command parses, so every `primitive` command
|
|
94
|
+
* run inside the broken project fails with this same error. The only
|
|
95
|
+
* invocation it may offer is one it says out loud to run elsewhere.
|
|
96
|
+
*/
|
|
97
|
+
export declare function missingAppIdMessage(name: string, configPath?: string): string;
|
|
78
98
|
export interface CoreProjectConfig {
|
|
79
99
|
version: number;
|
|
80
100
|
defaultEnvironment?: string;
|
|
@@ -87,7 +107,8 @@ export interface ResolvedPrimitiveEnv {
|
|
|
87
107
|
apiUrl: string;
|
|
88
108
|
/** Derived from apiUrl by scheme swap — never authored separately. */
|
|
89
109
|
wsUrl: string;
|
|
90
|
-
|
|
110
|
+
/** The app this environment names. Always present — see #3152. */
|
|
111
|
+
appId: string;
|
|
91
112
|
appName?: string;
|
|
92
113
|
/** The app's web counterpart for the SELECTED environment, if it has one. */
|
|
93
114
|
webUrl?: string;
|
|
@@ -106,11 +127,6 @@ export interface ResolveOptions {
|
|
|
106
127
|
explicitEnvName?: string | null;
|
|
107
128
|
/** Use this config file instead of discovering one. */
|
|
108
129
|
configPath?: string;
|
|
109
|
-
/**
|
|
110
|
-
* Identity consumers (the Vite plugin, cf-deploy, the Swift script) cannot
|
|
111
|
-
* work without an app ID; plain CLI resolution can, and always could.
|
|
112
|
-
*/
|
|
113
|
-
requireAppId?: boolean;
|
|
114
130
|
}
|
|
115
131
|
/**
|
|
116
132
|
* Derives the WebSocket URL from the API URL. Every apiUrl/wsUrl pair in
|
|
@@ -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=`config.json`,m=`local.json`,h=`.primitive/config.json`,g=`.primitive/local.json`,_=class extends Error{kind;path;constructor(e,t,n){super(t),this.name=`PrimitiveEnvError`,this.kind=e,this.path=n}};function v(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 y(e){return e.startsWith(`https://`)?`wss://`+e.slice(8):e.startsWith(`http://`)?`ws://`+e.slice(7):e}function
|
|
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=`config.json`,m=`local.json`,h=`.primitive/config.json`,g=`.primitive/local.json`,_=class extends Error{kind;path;constructor(e,t,n){super(t),this.name=`PrimitiveEnvError`,this.kind=e,this.path=n}};function v(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 y(e,t){return`Environment "${e}" in ${t?`${h} (${t})`:h} has no "appId". Every environment names exactly one app — add "appId": "<app-id>" to that environment in ${h}. Find the app id in the Primitive admin UI, with 'primitive apps list' run from a directory outside this 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 b(e){if(typeof e==`string`)return e.trim()||void 0}function x(e){return e.startsWith(`https://`)?`wss://`+e.slice(8):e.startsWith(`http://`)?`ws://`+e.slice(7):e}function S(e={}){let n=(e.env??process.env).PRIMITIVE_PROJECT_CONFIG;if(n){let e=(0,a.resolve)(n);return(0,t.existsSync)(e)?e:null}let r=(0,a.resolve)(e.cwd??process.cwd());for(;;){let e=(0,a.join)(r,f,p);if((0,t.existsSync)(e))return e;let n=(0,a.dirname)(r);if(n===r)return null;r=n}}function C(e){let t=(0,a.dirname)(e);return(0,a.basename)(t)===`.primitive`?(0,a.dirname)(t):t}function w(e){return(0,a.join)((0,a.dirname)(e),m)}function T(e){if(!(0,t.existsSync)(e))throw new _(`missing-config`,`No ${h} found at ${e}. Run 'primitive init' to create one.`,e);let n;try{n=(0,t.readFileSync)(e,`utf-8`)}catch(t){throw new _(`malformed-config`,`Failed to read ${h} (${e}): ${t.message}`,e)}let r;try{r=JSON.parse(n)}catch(t){throw new _(`malformed-config`,`Failed to parse ${h} (${e}): ${t.message}`,e)}if(!r||typeof r!=`object`||Array.isArray(r))throw new _(`malformed-config`,`${h} (${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 _(`malformed-config`,`${h} (${e}) is missing required integer field "version".`,e);if(i.version!==1)throw new _(`unsupported-version`,`${h} (${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 _(`malformed-config`,`${h} (${e}) is missing required "environments" object.`,e);let a={};for(let[t,n]of Object.entries(i.environments)){if(!n||typeof n!=`object`||Array.isArray(n))throw new _(`malformed-config`,`Environment "${t}" must be an object in ${h} (${e}).`,e);let r=n;if(typeof r.apiUrl!=`string`||!r.apiUrl)throw new _(`malformed-config`,`Environment "${t}" must have a non-empty "apiUrl" string in ${h} (${e}).`,e);let i=b(r.appId);if(!i)throw new _(`missing-app-id`,y(t,e),e);a[t]={apiUrl:r.apiUrl.replace(/\/$/,``),appId:i,appName:typeof r.appName==`string`?r.appName:void 0,webUrl:v(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:a}}function E(e){let n=w(e);if(!(0,t.existsSync)(n))return null;let r=e=>{throw new _(`corrupt-local-state`,`${g} (${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 D(e,t){let n=Object.keys(e.environments),r=n.join(`, `)||`(none)`,i=t.configPath?`${h} (${t.configPath})`:h,a=(n,a,o)=>{if(!e.environments[n])throw new _(`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 ${g}`);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 _(`no-selection`,`${i} has no environments defined. Run 'primitive env add <name>' or 'primitive init'.`,t.configPath):new _(`no-selection`,`No environment selected. Run 'primitive env use <name>', set "defaultEnvironment" in ${i}, or export PRIMITIVE_ENV. Available: ${r}`,t.configPath)}function O(e={}){let t=e.env??process.env,n=e.configPath??S({cwd:e.cwd,env:t});if(!n)throw new _(`missing-config`,`No ${h} found in ${e.cwd??process.cwd()} or any parent directory. Run 'primitive init' to create one, or 'primitive env add <name>' to add an environment.`);let r=T(n),{name:i,source:a}=D(r,{explicitEnvName:e.explicitEnvName||null,envVarName:t.PRIMITIVE_ENV||null,localSelection:E(n),configPath:n}),o=r.environments[i];return{name:i,apiUrl:o.apiUrl,wsUrl:x(o.apiUrl),appId:o.appId,appName:o.appName,webUrl:o.webUrl,description:o.description,source:a,configPath:n,localStatePath:w(n),projectRoot:C(n)}}var k=[`VITE_APP_ID`,`VITE_API_URL`,`VITE_WS_URL`,`VITE_APP_NAME`],A=`VITE_EXPECTED_PRIMITIVE_ENV`,j=new Map;function M(e,t){let n=process.env[e];n!==void 0&&n!==``&&j.get(e)!==n||(process.env[e]=t,j.set(e,t))}function N(e={}){return O({cwd:e.root,env:e.env,explicitEnvName:e.primitiveEnv??null})}function P(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 F(e,t){let n=e?.envDir;return n===!1?null:typeof n==`string`&&n!==``?(0,a.resolve)(t,n):t}function I(e,t){let n=process.env[A];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=V((0,a.join)(t,n))[A];if(e!==void 0)return{value:e,where:n}}return null}function L(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} (${A} 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 ${A} 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 R(e,t,n){let r=I(e,t);if(r&&r.value!==``&&r.value!==n.name)throw Error(L(e,r,n))}function z(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=B(u,l),f={};for(let e of k){let t=process.env[e],n=t!==void 0&&j.get(e)!==t?t:d[e];n!==void 0&&n!==``&&(f[e]=n)}let p;try{p=O({cwd:l,explicitEnvName:e.primitiveEnv??null})}catch(e){if(e instanceof _&&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=F(s,l);R(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 k){if(f[e]!==void 0){g.push(e);continue}let t=m[e];t!==void 0&&(h[`import.meta.env.${e}`]=JSON.stringify(t),M(e,t))}return M(`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(P(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=F(e,o.root),r=e?.mode??o.mode;n===o.dir&&r===o.mode||(R(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 B(e,t){let n=[`.env`,`.env.local`,`.env.${e}`,`.env.${e}.local`],r={};for(let e of n)Object.assign(r,V((0,a.join)(t,e)));return r}function V(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=_,exports.primitiveDevTools=d,exports.primitiveEnv=z,exports.resolvePrimitiveEnv=N;
|
|
@@ -82,10 +82,16 @@ function x(e) {
|
|
|
82
82
|
}
|
|
83
83
|
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;
|
|
84
84
|
}
|
|
85
|
-
function S(e) {
|
|
85
|
+
function S(e, t) {
|
|
86
|
+
return `Environment "${e}" in ${t ? `${v} (${t})` : v} has no "appId". Every environment names exactly one app — add "appId": "<app-id>" to that environment in ${v}. Find the app id in the Primitive admin UI, with 'primitive apps list' run from a directory outside this 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.`;
|
|
87
|
+
}
|
|
88
|
+
function C(e) {
|
|
89
|
+
if (typeof e == "string") return e.trim() || void 0;
|
|
90
|
+
}
|
|
91
|
+
function w(e) {
|
|
86
92
|
return e.startsWith("https://") ? "wss://" + e.slice(8) : e.startsWith("http://") ? "ws://" + e.slice(7) : e;
|
|
87
93
|
}
|
|
88
|
-
function
|
|
94
|
+
function T(t = {}) {
|
|
89
95
|
let n = (t.env ?? process.env).PRIMITIVE_PROJECT_CONFIG;
|
|
90
96
|
if (n) {
|
|
91
97
|
let t = c(n);
|
|
@@ -100,14 +106,14 @@ function C(t = {}) {
|
|
|
100
106
|
r = n;
|
|
101
107
|
}
|
|
102
108
|
}
|
|
103
|
-
function
|
|
109
|
+
function E(e) {
|
|
104
110
|
let t = o(e);
|
|
105
111
|
return a(t) === ".primitive" ? o(t) : t;
|
|
106
112
|
}
|
|
107
|
-
function
|
|
113
|
+
function D(e) {
|
|
108
114
|
return s(o(e), _);
|
|
109
115
|
}
|
|
110
|
-
function
|
|
116
|
+
function O(n) {
|
|
111
117
|
if (!e(n)) throw new b("missing-config", `No ${v} found at ${n}. Run 'primitive init' to create one.`, n);
|
|
112
118
|
let r;
|
|
113
119
|
try {
|
|
@@ -131,9 +137,11 @@ function E(n) {
|
|
|
131
137
|
if (!t || typeof t != "object" || Array.isArray(t)) throw new b("malformed-config", `Environment "${e}" must be an object in ${v} (${n}).`, n);
|
|
132
138
|
let r = t;
|
|
133
139
|
if (typeof r.apiUrl != "string" || !r.apiUrl) throw new b("malformed-config", `Environment "${e}" must have a non-empty "apiUrl" string in ${v} (${n}).`, n);
|
|
140
|
+
let i = C(r.appId);
|
|
141
|
+
if (!i) throw new b("missing-app-id", S(e, n), n);
|
|
134
142
|
o[e] = {
|
|
135
143
|
apiUrl: r.apiUrl.replace(/\/$/, ""),
|
|
136
|
-
appId:
|
|
144
|
+
appId: i,
|
|
137
145
|
appName: typeof r.appName == "string" ? r.appName : void 0,
|
|
138
146
|
webUrl: x(r.webUrl),
|
|
139
147
|
description: typeof r.description == "string" ? r.description : void 0
|
|
@@ -145,8 +153,8 @@ function E(n) {
|
|
|
145
153
|
environments: o
|
|
146
154
|
};
|
|
147
155
|
}
|
|
148
|
-
function
|
|
149
|
-
let r =
|
|
156
|
+
function k(n) {
|
|
157
|
+
let r = D(n);
|
|
150
158
|
if (!e(r)) return null;
|
|
151
159
|
let i = (e) => {
|
|
152
160
|
throw new b("corrupt-local-state", `${y} (${r}) is unreadable: ${e}. Delete the file or re-run 'primitive env use <name>'.`, r);
|
|
@@ -160,7 +168,7 @@ function D(n) {
|
|
|
160
168
|
let o = a.selectedEnvironment;
|
|
161
169
|
return o == null || o === "" ? null : typeof o == "string" ? o : i("\"selectedEnvironment\" must be a string");
|
|
162
170
|
}
|
|
163
|
-
function
|
|
171
|
+
function A(e, t) {
|
|
164
172
|
let n = Object.keys(e.environments), r = n.join(", ") || "(none)", i = t.configPath ? `${v} (${t.configPath})` : v, a = (n, a, o) => {
|
|
165
173
|
if (!e.environments[n]) throw new b("unknown-environment", `Environment "${n}" is not defined in ${i} (selected ${o}). Available: ${r}`, t.configPath);
|
|
166
174
|
return {
|
|
@@ -178,54 +186,52 @@ function O(e, t) {
|
|
|
178
186
|
};
|
|
179
187
|
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);
|
|
180
188
|
}
|
|
181
|
-
function
|
|
182
|
-
let t = e.env ?? process.env, n = e.configPath ??
|
|
189
|
+
function j(e = {}) {
|
|
190
|
+
let t = e.env ?? process.env, n = e.configPath ?? T({
|
|
183
191
|
cwd: e.cwd,
|
|
184
192
|
env: t
|
|
185
193
|
});
|
|
186
194
|
if (!n) throw new b("missing-config", `No ${v} found in ${e.cwd ?? process.cwd()} or any parent directory. Run 'primitive init' to create one, or 'primitive env add <name>' to add an environment.`);
|
|
187
|
-
let r =
|
|
195
|
+
let r = O(n), { name: i, source: a } = A(r, {
|
|
188
196
|
explicitEnvName: e.explicitEnvName || null,
|
|
189
197
|
envVarName: t.PRIMITIVE_ENV || null,
|
|
190
|
-
localSelection:
|
|
198
|
+
localSelection: k(n),
|
|
191
199
|
configPath: n
|
|
192
200
|
}), o = r.environments[i];
|
|
193
|
-
if (e.requireAppId && !o.appId) throw new b("missing-app-id", `Environment "${i}" in ${v} (${n}) has no "appId", which this build needs. Add one with 'primitive env add ${i} --api-url ${o.apiUrl} --app-id <id>' or edit the config.`, n);
|
|
194
201
|
return {
|
|
195
202
|
name: i,
|
|
196
203
|
apiUrl: o.apiUrl,
|
|
197
|
-
wsUrl:
|
|
204
|
+
wsUrl: w(o.apiUrl),
|
|
198
205
|
appId: o.appId,
|
|
199
206
|
appName: o.appName,
|
|
200
207
|
webUrl: o.webUrl,
|
|
201
208
|
description: o.description,
|
|
202
209
|
source: a,
|
|
203
210
|
configPath: n,
|
|
204
|
-
localStatePath:
|
|
205
|
-
projectRoot:
|
|
211
|
+
localStatePath: D(n),
|
|
212
|
+
projectRoot: E(n)
|
|
206
213
|
};
|
|
207
214
|
}
|
|
208
215
|
//#endregion
|
|
209
216
|
//#region src/dev-tools/vite-plugin/primitive-env.ts
|
|
210
|
-
var
|
|
217
|
+
var M = [
|
|
211
218
|
"VITE_APP_ID",
|
|
212
219
|
"VITE_API_URL",
|
|
213
220
|
"VITE_WS_URL",
|
|
214
221
|
"VITE_APP_NAME"
|
|
215
|
-
],
|
|
216
|
-
function
|
|
222
|
+
], N = "VITE_EXPECTED_PRIMITIVE_ENV", P = /* @__PURE__ */ new Map();
|
|
223
|
+
function F(e, t) {
|
|
217
224
|
let n = process.env[e];
|
|
218
|
-
n !== void 0 && n !== "" &&
|
|
225
|
+
n !== void 0 && n !== "" && P.get(e) !== n || (process.env[e] = t, P.set(e, t));
|
|
219
226
|
}
|
|
220
|
-
function
|
|
221
|
-
return
|
|
227
|
+
function I(e = {}) {
|
|
228
|
+
return j({
|
|
222
229
|
cwd: e.root,
|
|
223
230
|
env: e.env,
|
|
224
|
-
explicitEnvName: e.primitiveEnv ?? null
|
|
225
|
-
requireAppId: e.requireAppId
|
|
231
|
+
explicitEnvName: e.primitiveEnv ?? null
|
|
226
232
|
});
|
|
227
233
|
}
|
|
228
|
-
function
|
|
234
|
+
function L(e, t, n) {
|
|
229
235
|
let r = (e) => n.includes(e) ? " (overridden)" : "", i = [
|
|
230
236
|
`[primitive-env] Primitive environment: ${e.name} (selected: ${e.source})`,
|
|
231
237
|
`[primitive-env] apiUrl: ${t.apiUrl}${r("VITE_API_URL")}`,
|
|
@@ -236,12 +242,12 @@ function F(e, t, n) {
|
|
|
236
242
|
];
|
|
237
243
|
return n.length > 0 && i.push(`[primitive-env] overridden by the environment: ${n.join(", ")}`), i.join("\n");
|
|
238
244
|
}
|
|
239
|
-
function
|
|
245
|
+
function R(e, t) {
|
|
240
246
|
let n = e?.envDir;
|
|
241
247
|
return n === !1 ? null : typeof n == "string" && n !== "" ? c(t, n) : t;
|
|
242
248
|
}
|
|
243
|
-
function
|
|
244
|
-
let n = process.env[
|
|
249
|
+
function z(e, t) {
|
|
250
|
+
let n = process.env[N];
|
|
245
251
|
if (n !== void 0 && n !== "") return {
|
|
246
252
|
value: n,
|
|
247
253
|
where: "the process environment"
|
|
@@ -253,7 +259,7 @@ function L(e, t) {
|
|
|
253
259
|
".env.local",
|
|
254
260
|
".env"
|
|
255
261
|
]) {
|
|
256
|
-
let e =
|
|
262
|
+
let e = W(s(t, n))[N];
|
|
257
263
|
if (e !== void 0) return {
|
|
258
264
|
value: e,
|
|
259
265
|
where: n
|
|
@@ -261,48 +267,47 @@ function L(e, t) {
|
|
|
261
267
|
}
|
|
262
268
|
return null;
|
|
263
269
|
}
|
|
264
|
-
function
|
|
270
|
+
function B(e, t, n) {
|
|
265
271
|
return [
|
|
266
272
|
`[primitive-env] Wrong pair: vite mode "${e}" is declared to run against Primitive environment "${t.value}", but "${n.name}" resolved.`,
|
|
267
|
-
`[primitive-env] expected: ${t.value} (${
|
|
273
|
+
`[primitive-env] expected: ${t.value} (${N} in ${t.where})`,
|
|
268
274
|
`[primitive-env] resolved: ${n.name} (selected: ${n.source})`,
|
|
269
275
|
`[primitive-env] config: ${n.configPath}`,
|
|
270
276
|
"",
|
|
271
|
-
`Run the pair you meant — PRIMITIVE_ENV=${t.value} <command> --mode ${e}, or 'primitive env use ${t.value}' — or change/remove ${
|
|
277
|
+
`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}.`,
|
|
272
278
|
"",
|
|
273
279
|
`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.`
|
|
274
280
|
].join("\n");
|
|
275
281
|
}
|
|
276
|
-
function
|
|
277
|
-
let r =
|
|
278
|
-
if (r && r.value !== "" && r.value !== n.name) throw Error(
|
|
282
|
+
function V(e, t, n) {
|
|
283
|
+
let r = z(e, t);
|
|
284
|
+
if (r && r.value !== "" && r.value !== n.name) throw Error(B(e, r, n));
|
|
279
285
|
}
|
|
280
|
-
function
|
|
286
|
+
function H(e = {}) {
|
|
281
287
|
let t = null, n = null, r, i = [], a = !1, o = null;
|
|
282
288
|
return {
|
|
283
289
|
name: "primitive-env",
|
|
284
290
|
enforce: "pre",
|
|
285
291
|
config(s, c) {
|
|
286
292
|
a = c?.command === "serve", o = null;
|
|
287
|
-
let l = s?.root ?? process.cwd(), u = c?.mode ?? "development", d =
|
|
288
|
-
for (let e of
|
|
289
|
-
let t = process.env[e], n = t !== void 0 &&
|
|
293
|
+
let l = s?.root ?? process.cwd(), u = c?.mode ?? "development", d = U(u, l), f = {};
|
|
294
|
+
for (let e of M) {
|
|
295
|
+
let t = process.env[e], n = t !== void 0 && P.get(e) !== t ? t : d[e];
|
|
290
296
|
n !== void 0 && n !== "" && (f[e] = n);
|
|
291
297
|
}
|
|
292
298
|
let p;
|
|
293
299
|
try {
|
|
294
|
-
p =
|
|
300
|
+
p = j({
|
|
295
301
|
cwd: l,
|
|
296
|
-
explicitEnvName: e.primitiveEnv ?? null
|
|
297
|
-
requireAppId: !f.VITE_APP_ID
|
|
302
|
+
explicitEnvName: e.primitiveEnv ?? null
|
|
298
303
|
});
|
|
299
304
|
} catch (e) {
|
|
300
305
|
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, {};
|
|
301
306
|
throw e;
|
|
302
307
|
}
|
|
303
308
|
if (!(f.VITE_APP_ID && f.VITE_API_URL)) {
|
|
304
|
-
let e =
|
|
305
|
-
|
|
309
|
+
let e = R(s, l);
|
|
310
|
+
V(u, e, p), o = {
|
|
306
311
|
root: l,
|
|
307
312
|
mode: u,
|
|
308
313
|
dir: e
|
|
@@ -315,25 +320,25 @@ function B(e = {}) {
|
|
|
315
320
|
VITE_WS_URL: p.wsUrl,
|
|
316
321
|
VITE_APP_NAME: p.appName
|
|
317
322
|
}, h = { "import.meta.env.VITE_PRIMITIVE_ENV": JSON.stringify(p.name) }, g = [];
|
|
318
|
-
for (let e of
|
|
323
|
+
for (let e of M) {
|
|
319
324
|
if (f[e] !== void 0) {
|
|
320
325
|
g.push(e);
|
|
321
326
|
continue;
|
|
322
327
|
}
|
|
323
328
|
let t = m[e];
|
|
324
|
-
t !== void 0 && (h[`import.meta.env.${e}`] = JSON.stringify(t),
|
|
329
|
+
t !== void 0 && (h[`import.meta.env.${e}`] = JSON.stringify(t), F(e, t));
|
|
325
330
|
}
|
|
326
|
-
return
|
|
331
|
+
return F("VITE_PRIMITIVE_ENV", p.name), i = g, n = {
|
|
327
332
|
apiUrl: f.VITE_API_URL ?? p.apiUrl,
|
|
328
333
|
wsUrl: f.VITE_WS_URL ?? p.wsUrl,
|
|
329
334
|
appId: f.VITE_APP_ID ?? p.appId,
|
|
330
335
|
appName: r
|
|
331
|
-
}, e.logResolved !== !1 && console.log(
|
|
336
|
+
}, 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 };
|
|
332
337
|
},
|
|
333
338
|
configResolved(e) {
|
|
334
339
|
if (!o || !t) return;
|
|
335
|
-
let n =
|
|
336
|
-
n === o.dir && r === o.mode || (
|
|
340
|
+
let n = R(e, o.root), r = e?.mode ?? o.mode;
|
|
341
|
+
n === o.dir && r === o.mode || (V(r, n, t), o = {
|
|
337
342
|
root: o.root,
|
|
338
343
|
mode: r,
|
|
339
344
|
dir: n
|
|
@@ -356,17 +361,17 @@ function B(e = {}) {
|
|
|
356
361
|
}
|
|
357
362
|
};
|
|
358
363
|
}
|
|
359
|
-
function
|
|
364
|
+
function U(e, t) {
|
|
360
365
|
let n = [
|
|
361
366
|
".env",
|
|
362
367
|
".env.local",
|
|
363
368
|
`.env.${e}`,
|
|
364
369
|
`.env.${e}.local`
|
|
365
370
|
], r = {};
|
|
366
|
-
for (let e of n) Object.assign(r,
|
|
371
|
+
for (let e of n) Object.assign(r, W(s(t, e)));
|
|
367
372
|
return r;
|
|
368
373
|
}
|
|
369
|
-
function
|
|
374
|
+
function W(n) {
|
|
370
375
|
if (!e(n)) return {};
|
|
371
376
|
let r = {};
|
|
372
377
|
for (let e of t(n, "utf-8").split(/\r?\n/)) {
|
|
@@ -380,4 +385,4 @@ function H(n) {
|
|
|
380
385
|
return r;
|
|
381
386
|
}
|
|
382
387
|
//#endregion
|
|
383
|
-
export { b as PrimitiveEnvError, m as primitiveDevTools,
|
|
388
|
+
export { b as PrimitiveEnvError, m as primitiveDevTools, H as primitiveEnv, I as resolvePrimitiveEnv };
|
|
@@ -45,8 +45,6 @@ export interface ResolvePrimitiveEnvOptions {
|
|
|
45
45
|
env?: Record<string, string | undefined>;
|
|
46
46
|
/** An explicit environment name (e.g. from `--primitive-env`). */
|
|
47
47
|
primitiveEnv?: string | null;
|
|
48
|
-
/** Fail when the resolved environment has no `appId`. */
|
|
49
|
-
requireAppId?: boolean;
|
|
50
48
|
}
|
|
51
49
|
/**
|
|
52
50
|
* Resolves the Primitive environment for a project. A thin wrapper over the
|