@junejs/server 1.0.0-dev.19 → 1.0.0-dev.24

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (43) hide show
  1. package/dist/adapter-DcZ-W1-7.d.ts +62 -0
  2. package/dist/adapter.d.ts +1 -61
  3. package/dist/agent-durable.js +1 -43
  4. package/dist/agent-native.d.ts +15 -5
  5. package/dist/agent-native.js +85 -16
  6. package/dist/app.js +2 -7
  7. package/dist/build.d.ts +5 -26
  8. package/dist/build.js +10 -276
  9. package/dist/config-freeze-DwI-Rmvq.d.ts +17 -0
  10. package/dist/config-freeze.d.ts +2 -0
  11. package/dist/config-freeze.js +51 -0
  12. package/dist/connection-auth.d.ts +39 -0
  13. package/dist/connection-auth.js +31 -0
  14. package/dist/content-freeze-CyiW2fRK.d.ts +4 -0
  15. package/dist/content-freeze.d.ts +2 -0
  16. package/dist/content-freeze.js +83 -0
  17. package/dist/core-version.js +1 -1
  18. package/dist/index.d.ts +9 -4
  19. package/dist/index.js +7 -2
  20. package/dist/manifest-gcNWqWoI.d.ts +11 -0
  21. package/dist/manifest.d.ts +2 -0
  22. package/dist/manifest.js +111 -0
  23. package/dist/route-scan-DMlwoESy.d.ts +13 -0
  24. package/dist/route-scan.d.ts +2 -0
  25. package/dist/route-scan.js +55 -0
  26. package/dist/turn-events.d.ts +5 -0
  27. package/dist/turn-events.js +46 -0
  28. package/dist/worker-BkFHGtxp.d.ts +61 -0
  29. package/dist/worker.d.ts +1 -60
  30. package/package.json +2 -2
  31. package/src/agent-discover.ts +10 -7
  32. package/src/agent-durable.ts +1 -39
  33. package/src/agent-native.ts +133 -21
  34. package/src/app.ts +4 -6
  35. package/src/build.ts +26 -440
  36. package/src/config-freeze.ts +104 -0
  37. package/src/connection-auth.ts +101 -0
  38. package/src/content-freeze.ts +151 -0
  39. package/src/core-version.ts +1 -1
  40. package/src/index.ts +14 -0
  41. package/src/manifest.ts +128 -0
  42. package/src/route-scan.ts +84 -0
  43. package/src/turn-events.ts +43 -0
package/dist/build.js CHANGED
@@ -1,289 +1,27 @@
1
1
  import { jsxTransform } from "./tsconfig-jsx.js";
2
- import { deno, staticSite, vercel, workers } from "./adapter.js";
3
2
  import { generateAgentModule } from "./agent-compile.js";
4
3
  import { findMiddlewareFile } from "./router.js";
5
4
  import { resolveBoundary } from "./segment.js";
6
5
  import { buildModuleCss, registerCssModules, rolldownCssModulesPlugin } from "./css-modules.js";
7
- import { CLIENT_SCRIPT_URL, bundleClientToFile, findClientEntry } from "./client-bundle.js";
6
+ import { bundleClientToFile, findClientEntry } from "./client-bundle.js";
8
7
  import { generateIslandRegistry } from "./island-registry.js";
9
- import { STYLES_URL, cssTargets, findGlobalCss, globalCssUsesTailwind, minifyCss, processCss } from "./css.js";
8
+ import { cssTargets, minifyCss, processCss } from "./css.js";
10
9
  import { RESERVED_PREFIX } from "./static-files.js";
11
- import { findJuneConfigPath, loadJuneConfig } from "./config-loader.js";
12
- import { generateContentModule } from "./content.js";
10
+ import { loadJuneConfig } from "./config-loader.js";
11
+ import { freezeConfig, normalizeBase, resolveDeployAdapter, workerName } from "./config-freeze.js";
12
+ import { generateContent } from "./content-freeze.js";
13
13
  import { createWorker } from "./worker.js";
14
+ import { scanAppRoutes, scanRoutes } from "./route-scan.js";
15
+ import { buildManifest, importLayout } from "./manifest.js";
14
16
  import { buildRsc, findRscRoutes } from "./rsc-build.js";
15
17
  import { existsSync, lstatSync } from "node:fs";
16
- import { copyFile, mkdir, readFile, readdir, rm, writeFile } from "node:fs/promises";
18
+ import { copyFile, mkdir, readdir, rm, writeFile } from "node:fs/promises";
17
19
  import { basename, dirname, join, relative, resolve, sep } from "node:path";
18
- import { pathToFileURL } from "node:url";
19
- import { routeFromModule } from "@junejs/core/route";
20
- import { resolveAgent, resolveClientRouter, resolveSpeculationRules } from "@junejs/core/config";
21
20
  import { buildLinkHeader } from "@junejs/core/discovery";
22
21
  import { localeHref } from "@junejs/core/i18n";
23
22
  import { createHash } from "node:crypto";
24
- import { execFileSync } from "node:child_process";
25
23
  //#region src/build.ts
26
- const PAGE_BASENAMES = /* @__PURE__ */ new Set(["page", "index"]);
27
- const ROUTE_EXTS = [
28
- ".tsx",
29
- ".jsx",
30
- ".ts",
31
- ".js"
32
- ];
33
- const isRouteGroup = (name) => /^\(.+\)$/.test(name);
34
24
  const isBunSpecifier = (id) => id === "bun" || id.startsWith("bun:");
35
- function resolveDeployAdapter(deploy) {
36
- if (deploy?.adapter) return deploy.adapter;
37
- switch (deploy?.target) {
38
- case "static": return staticSite();
39
- case "vercel": return vercel();
40
- case "deno": return deno();
41
- default: return workers({
42
- name: deploy?.name,
43
- domain: deploy?.domain
44
- });
45
- }
46
- }
47
- function segmentFile(dir, base) {
48
- return ROUTE_EXTS.map((e) => join(dir, `${base}${e}`)).find(existsSync);
49
- }
50
- async function scanRoutes(appDir, dir = appDir, layouts = [], out = [], loading) {
51
- const ownLayout = segmentFile(dir, "layout");
52
- const chain = ownLayout ? [...layouts, ownLayout] : layouts;
53
- const nearestLoading = segmentFile(dir, "loading") ?? loading;
54
- const entries = await readdir(dir, { withFileTypes: true }).catch(() => []);
55
- for (const e of entries) {
56
- if (e.name.startsWith("_") || e.name.startsWith(".")) continue;
57
- const full = join(dir, e.name);
58
- if (e.isDirectory()) {
59
- await scanRoutes(appDir, full, chain, out, nearestLoading);
60
- continue;
61
- }
62
- const ext = e.name.match(/\.[^.]+$/)?.[0] ?? "";
63
- if (!ROUTE_EXTS.includes(ext)) continue;
64
- const base = basename(e.name, ext);
65
- const resource = base === "route";
66
- if (!PAGE_BASENAMES.has(base) && !resource) continue;
67
- const relDir = relative(appDir, dir);
68
- const path = "/" + (relDir === "" ? [] : relDir.split(sep).filter((s) => !isRouteGroup(s))).join("/");
69
- out.push({
70
- path: path === "/" ? "/" : path,
71
- file: full,
72
- dynamic: /\[.+\]/.test(path),
73
- resource,
74
- layouts: chain,
75
- loading: nearestLoading
76
- });
77
- }
78
- return out;
79
- }
80
- async function generateContent(appRoot) {
81
- const contentDir = join(appRoot, "content");
82
- await mkdir(join(appRoot, "app"), { recursive: true });
83
- const emit = async (sources, knownLocales) => {
84
- const { code, names } = generateContentModule(contentDir, knownLocales, sources);
85
- await writeFile(join(appRoot, "app", "_content.ts"), code);
86
- return names;
87
- };
88
- const resolveSources = (sources) => sources.map((s) => ({
89
- ...s,
90
- dir: resolve(appRoot, s.dir)
91
- }));
92
- const declaredLocales = (config) => config.i18n ? [.../* @__PURE__ */ new Set([config.i18n.defaultLocale, ...Object.keys(config.i18n.locales)])] : [];
93
- let config = null;
94
- try {
95
- config = await loadJuneConfig(appRoot);
96
- } catch {}
97
- if (config) return emit(resolveSources(config.content?.sources ?? []), declaredLocales(config));
98
- const names = await emit([], void 0);
99
- await seedContentImports(appRoot);
100
- const probed = probeConfigFresh(appRoot);
101
- if (probed === null) {
102
- console.warn("[june gen] june.config.ts failed to load — content.sources/i18n locales (if any) not applied");
103
- return names;
104
- }
105
- return emit(resolveSources(probed.sources), probed.locales);
106
- }
107
- async function seedContentImports(appRoot) {
108
- const cfgPath = findJuneConfigPath(appRoot);
109
- if (!cfgPath) return;
110
- const contentFile = join(appRoot, "app", "_content.ts");
111
- const current = existsSync(contentFile) ? await readFile(contentFile, "utf8") : "";
112
- const cfgSrc = await readFile(cfgPath, "utf8");
113
- const isIdent = (s) => /^[A-Za-z_$][A-Za-z0-9_$]*$/.test(s);
114
- const seen = /* @__PURE__ */ new Set();
115
- const stubs = [];
116
- for (const m of cfgSrc.matchAll(/import\s*(?:type\s+)?\{([^}]*)\}\s*from\s*["'][^"']*app\/_content(?:\.\w+)?["']/g)) {
117
- const inner = (m[1] ?? "").replace(/\/\*[\s\S]*?\*\//g, "").replace(/\/\/[^\n]*/g, "");
118
- for (const part of inner.split(",")) {
119
- const name = part.replace(/\btype\b/g, "").split(/\s+as\s+/).pop()?.trim();
120
- if (!name || !isIdent(name) || seen.has(name)) continue;
121
- seen.add(name);
122
- const reName = name.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
123
- if (!new RegExp(`export (?:const|function|type) ${reName}\\b`).test(current)) stubs.push(`export const ${name}: ContentEntry[] = [];`);
124
- }
125
- }
126
- if (stubs.length) await writeFile(contentFile, current + stubs.join("\n") + "\n");
127
- }
128
- function probeConfigFresh(appRoot) {
129
- const path = findJuneConfigPath(appRoot);
130
- if (!path) return {
131
- sources: [],
132
- locales: []
133
- };
134
- const code = `import(${JSON.stringify(pathToFileURL(path).href)}).then((m) => { const c = m.default ?? {}; process.stdout.write("\\n__JUNE_CONTENT__" + JSON.stringify({ sources: c.content?.sources ?? [], locales: c.i18n ? [...new Set([c.i18n.defaultLocale, ...Object.keys(c.i18n.locales ?? {})])] : [] }) + "__END__"); }, () => process.exit(42));`;
135
- try {
136
- const m = execFileSync(process.execPath, [
137
- ...process.execArgv,
138
- "-e",
139
- code
140
- ], {
141
- encoding: "utf8",
142
- stdio: [
143
- "ignore",
144
- "pipe",
145
- "ignore"
146
- ]
147
- }).match(/__JUNE_CONTENT__(.*?)__END__/s);
148
- return m ? JSON.parse(m[1]) : null;
149
- } catch {
150
- return null;
151
- }
152
- }
153
- async function freezeConfig(appRoot) {
154
- const cfg = await loadJuneConfig(appRoot);
155
- const hasClient = findClientEntry(join(appRoot, "app")) !== void 0 || findClientEntry(join(appRoot, ".june", "routes")) !== void 0;
156
- const hasCss = findGlobalCss(join(appRoot, "app")) !== null;
157
- return {
158
- document: {
159
- site: cfg.site ?? {},
160
- speculationRules: resolveSpeculationRules(cfg.speculation ?? void 0),
161
- speculationDelivery: "inline",
162
- viewTransitions: cfg.viewTransitions ?? true,
163
- cssReset: cfg.cssReset ?? !globalCssUsesTailwind(join(appRoot, "app")),
164
- clientRouter: resolveClientRouter(cfg.clientRouter),
165
- clientScript: hasClient ? CLIENT_SCRIPT_URL : null,
166
- styles: hasCss ? STYLES_URL : null,
167
- basePath: normalizeBase(cfg.basePath)
168
- },
169
- agent: resolveAgent(cfg.agent),
170
- i18n: cfg.i18n,
171
- earlyHints: cfg.earlyHints ?? [],
172
- buildExternal: cfg.build?.external ?? []
173
- };
174
- }
175
- function normalizeBase(base) {
176
- if (!base) return "";
177
- const b = base.startsWith("/") ? base : `/${base}`;
178
- return b.endsWith("/") ? b.slice(0, -1) : b;
179
- }
180
- async function importLayout(file) {
181
- const mod = await import(pathToFileURL(file).href);
182
- return typeof mod.default === "function" ? {
183
- component: mod.default,
184
- boundary: mod.segmentBoundary === true
185
- } : null;
186
- }
187
- function workerName(raw) {
188
- return raw.replace(/^@[^/]+\//, "").toLowerCase().replace(/[^a-z0-9-]+/g, "-").replace(/^-+|-+$/g, "") || "app";
189
- }
190
- async function buildManifest(appRoot) {
191
- const appDir = join(appRoot, "app");
192
- const juneRoutesDir = join(appRoot, ".june", "routes");
193
- const frozen = await freezeConfig(appRoot);
194
- const appRoutes = await scanRoutes(appDir);
195
- const frameworkRoutes = existsSync(juneRoutesDir) ? await scanRoutes(juneRoutesDir) : [];
196
- const appPaths = new Set(appRoutes.map((r) => r.path));
197
- const scanned = [...appRoutes, ...frameworkRoutes.filter((r) => !appPaths.has(r.path))].sort((a, b) => a.path.localeCompare(b.path));
198
- const layoutCache = /* @__PURE__ */ new Map();
199
- const loadCached = async (f) => {
200
- if (!layoutCache.has(f)) layoutCache.set(f, await importLayout(f));
201
- return layoutCache.get(f) ?? null;
202
- };
203
- const componentsFor = async (files) => {
204
- const items = [];
205
- for (const f of files) {
206
- const c = await loadCached(f);
207
- items.push({
208
- file: f,
209
- entry: c?.component ?? null,
210
- boundary: !!c?.boundary
211
- });
212
- }
213
- return resolveBoundary(items);
214
- };
215
- const loadingCache = /* @__PURE__ */ new Map();
216
- const loadingFor = async (file) => {
217
- if (!file) return void 0;
218
- if (!loadingCache.has(file)) {
219
- const loaded = await importLayout(file);
220
- loadingCache.set(file, loaded ? loaded.component : null);
221
- }
222
- return loadingCache.get(file) ?? void 0;
223
- };
224
- const routes = {};
225
- const dynamicRoutes = [];
226
- const resourceRoutes = [];
227
- const layoutChains = {};
228
- const layoutBoundaries = {};
229
- const loadings = {};
230
- for (const r of scanned) {
231
- const mod = await import(pathToFileURL(r.file).href);
232
- if (r.resource) {
233
- const handler = mod.default;
234
- if (typeof handler === "function") resourceRoutes.push({
235
- pattern: r.path,
236
- handler
237
- });
238
- continue;
239
- }
240
- const def = routeFromModule(mod);
241
- if (!def) continue;
242
- const { chain, boundaryIndex, key } = await componentsFor(r.layouts);
243
- const loading = await loadingFor(r.loading);
244
- if (r.dynamic) {
245
- dynamicRoutes.push({
246
- pattern: r.path,
247
- def
248
- });
249
- layoutChains[r.path] = chain;
250
- } else {
251
- routes[r.path] = def;
252
- layoutChains[r.path] = chain;
253
- }
254
- if (boundaryIndex !== null && key !== null) layoutBoundaries[r.path] = {
255
- index: boundaryIndex,
256
- key
257
- };
258
- if (loading) loadings[r.path] = loading;
259
- }
260
- let extra;
261
- const extraFile = findMiddlewareFile(appDir);
262
- if (extraFile) {
263
- const mod = await import(pathToFileURL(extraFile).href);
264
- if (typeof mod.default === "function") extra = mod.default;
265
- }
266
- let agentName;
267
- const agentDir = join(appDir, frozen.agent.runtime.dir);
268
- if (frozen.agent.runtime.enabled && existsSync(agentDir)) {
269
- const cfgFile = join(agentDir, "agent.ts");
270
- agentName = (existsSync(cfgFile) ? (await import(pathToFileURL(cfgFile).href)).default : void 0)?.name ?? basename(agentDir);
271
- }
272
- return {
273
- routes,
274
- dynamicRoutes,
275
- resourceRoutes,
276
- layoutChains,
277
- layoutBoundaries,
278
- loadings,
279
- document: frozen.document,
280
- agent: frozen.agent,
281
- agentName,
282
- i18n: frozen.i18n,
283
- earlyHints: frozen.earlyHints,
284
- extra
285
- };
286
- }
287
25
  function importPath(fromDir, file) {
288
26
  const p = relative(fromDir, file).split(sep).join("/").replace(/\.[^.]+$/, "");
289
27
  return p.startsWith(".") ? p : `./${p}`;
@@ -308,11 +46,7 @@ async function juneBuild(appRoot, options = {}) {
308
46
  force: true
309
47
  });
310
48
  const contentCollections = await generateContent(appRoot);
311
- const juneRoutesDir2 = join(appRoot, ".june", "routes");
312
- const appRoutes2 = await scanRoutes(appDir);
313
- const frameworkRoutes2 = existsSync(juneRoutesDir2) ? await scanRoutes(juneRoutesDir2) : [];
314
- const appPaths2 = new Set(appRoutes2.map((r) => r.path));
315
- const routes = [...appRoutes2, ...frameworkRoutes2.filter((r) => !appPaths2.has(r.path))].sort((a, b) => a.path.localeCompare(b.path));
49
+ const routes = await scanAppRoutes(appRoot);
316
50
  if (routes.length === 0) throw new Error(`no page.* routes found under ${appDir} or .june/routes/`);
317
51
  const frozen = await freezeConfig(appRoot);
318
52
  if (frozen.i18n?.resolveLocale) console.warn("[june build] i18n.resolveLocale is not yet wired into the built worker (URL-pinned + built-in negotiation work; the hook runs in dev only).");
@@ -650,4 +384,4 @@ ${doClass}`;
650
384
  };
651
385
  }
652
386
  //#endregion
653
- export { buildManifest, freezeConfig, generateContent, isBunSpecifier, juneBuild, normalizeBase, resolveDeployAdapter, scanRoutes, workerName };
387
+ export { buildManifest, freezeConfig, generateContent, isBunSpecifier, juneBuild, normalizeBase, resolveDeployAdapter, scanAppRoutes, scanRoutes, workerName };
@@ -0,0 +1,17 @@
1
+ import { i as JuneAdapter } from "./adapter-DcZ-W1-7.js";
2
+ import { n as WorkerManifest } from "./worker-BkFHGtxp.js";
3
+ import { JuneConfig } from "@junejs/core/config";
4
+ import { DocumentConfig } from "@junejs/core/document";
5
+ //#region src/config-freeze.d.ts
6
+ declare function resolveDeployAdapter(deploy: JuneConfig["deploy"]): JuneAdapter;
7
+ declare function freezeConfig(appRoot: string): Promise<{
8
+ document: DocumentConfig;
9
+ agent: WorkerManifest["agent"];
10
+ i18n: WorkerManifest["i18n"];
11
+ earlyHints: string[];
12
+ buildExternal: string[];
13
+ }>;
14
+ declare function normalizeBase(base?: string): string;
15
+ declare function workerName(raw: string): string;
16
+ //#endregion
17
+ export { workerName as i, normalizeBase as n, resolveDeployAdapter as r, freezeConfig as t };
@@ -0,0 +1,2 @@
1
+ import { i as workerName, n as normalizeBase, r as resolveDeployAdapter, t as freezeConfig } from "./config-freeze-DwI-Rmvq.js";
2
+ export { freezeConfig, normalizeBase, resolveDeployAdapter, workerName };
@@ -0,0 +1,51 @@
1
+ import { deno, staticSite, vercel, workers } from "./adapter.js";
2
+ import { CLIENT_SCRIPT_URL, findClientEntry } from "./client-bundle.js";
3
+ import { STYLES_URL, findGlobalCss, globalCssUsesTailwind } from "./css.js";
4
+ import { loadJuneConfig } from "./config-loader.js";
5
+ import { join } from "node:path";
6
+ import { resolveAgent, resolveClientRouter, resolveSpeculationRules } from "@junejs/core/config";
7
+ //#region src/config-freeze.ts
8
+ function resolveDeployAdapter(deploy) {
9
+ if (deploy?.adapter) return deploy.adapter;
10
+ switch (deploy?.target) {
11
+ case "static": return staticSite();
12
+ case "vercel": return vercel();
13
+ case "deno": return deno();
14
+ default: return workers({
15
+ name: deploy?.name,
16
+ domain: deploy?.domain
17
+ });
18
+ }
19
+ }
20
+ async function freezeConfig(appRoot) {
21
+ const cfg = await loadJuneConfig(appRoot);
22
+ const hasClient = findClientEntry(join(appRoot, "app")) !== void 0 || findClientEntry(join(appRoot, ".june", "routes")) !== void 0;
23
+ const hasCss = findGlobalCss(join(appRoot, "app")) !== null;
24
+ return {
25
+ document: {
26
+ site: cfg.site ?? {},
27
+ speculationRules: resolveSpeculationRules(cfg.speculation ?? void 0),
28
+ speculationDelivery: "inline",
29
+ viewTransitions: cfg.viewTransitions ?? true,
30
+ cssReset: cfg.cssReset ?? !globalCssUsesTailwind(join(appRoot, "app")),
31
+ clientRouter: resolveClientRouter(cfg.clientRouter),
32
+ clientScript: hasClient ? CLIENT_SCRIPT_URL : null,
33
+ styles: hasCss ? STYLES_URL : null,
34
+ basePath: normalizeBase(cfg.basePath)
35
+ },
36
+ agent: resolveAgent(cfg.agent),
37
+ i18n: cfg.i18n,
38
+ earlyHints: cfg.earlyHints ?? [],
39
+ buildExternal: cfg.build?.external ?? []
40
+ };
41
+ }
42
+ function normalizeBase(base) {
43
+ if (!base) return "";
44
+ const b = base.startsWith("/") ? base : `/${base}`;
45
+ return b.endsWith("/") ? b.slice(0, -1) : b;
46
+ }
47
+ function workerName(raw) {
48
+ return raw.replace(/^@[^/]+\//, "").toLowerCase().replace(/[^a-z0-9-]+/g, "-").replace(/^-+|-+$/g, "") || "app";
49
+ }
50
+ //#endregion
51
+ export { freezeConfig, normalizeBase, resolveDeployAdapter, workerName };
@@ -0,0 +1,39 @@
1
+ import { ActionContext } from "@junejs/core/context";
2
+ //#region src/connection-auth.d.ts
3
+ type AccountTokenStore = (args: {
4
+ userId: string;
5
+ providerId: string;
6
+ }) => Promise<{
7
+ accessToken: string;
8
+ } | null> | {
9
+ accessToken: string;
10
+ } | null;
11
+ type LinkedAccountAuthOptions = {
12
+ providerId: string;
13
+ store: AccountTokenStore;
14
+ };
15
+ type ConnectionAuth = (ctx?: ActionContext) => Promise<{
16
+ token: string;
17
+ }>;
18
+ declare function linkedAccountAuth(opts: LinkedAccountAuthOptions): ConnectionAuth;
19
+ type BetterAuthLike = {
20
+ api: {
21
+ getAccessToken: (input: {
22
+ body: {
23
+ providerId: string;
24
+ userId?: string;
25
+ accountId?: string;
26
+ };
27
+ headers?: HeadersInit;
28
+ }) => Promise<{
29
+ accessToken?: string;
30
+ token?: string;
31
+ } | null | undefined>;
32
+ };
33
+ };
34
+ declare function betterAuthAccountTokenStore(auth: BetterAuthLike): AccountTokenStore;
35
+ declare function betterAuthAccessToken(auth: BetterAuthLike, opts: {
36
+ providerId: string;
37
+ }): ConnectionAuth;
38
+ //#endregion
39
+ export { AccountTokenStore, BetterAuthLike, ConnectionAuth, LinkedAccountAuthOptions, betterAuthAccessToken, betterAuthAccountTokenStore, linkedAccountAuth };
@@ -0,0 +1,31 @@
1
+ //#region src/connection-auth.ts
2
+ function linkedAccountAuth(opts) {
3
+ return async (ctx) => {
4
+ const userId = ctx?.user?.id;
5
+ if (!userId) throw new Error(`connection auth (${opts.providerId}): no authenticated principal — set requiresPrincipal and resolve identity on the surface`);
6
+ const record = await opts.store({
7
+ userId,
8
+ providerId: opts.providerId
9
+ });
10
+ if (!record?.accessToken) throw new Error(`connection auth (${opts.providerId}): user "${userId}" has no linked "${opts.providerId}" account`);
11
+ return { token: record.accessToken };
12
+ };
13
+ }
14
+ function betterAuthAccountTokenStore(auth) {
15
+ return async ({ userId, providerId }) => {
16
+ const res = await auth.api.getAccessToken({ body: {
17
+ providerId,
18
+ userId
19
+ } });
20
+ const accessToken = res?.accessToken ?? res?.token;
21
+ return accessToken ? { accessToken } : null;
22
+ };
23
+ }
24
+ function betterAuthAccessToken(auth, opts) {
25
+ return linkedAccountAuth({
26
+ providerId: opts.providerId,
27
+ store: betterAuthAccountTokenStore(auth)
28
+ });
29
+ }
30
+ //#endregion
31
+ export { betterAuthAccessToken, betterAuthAccountTokenStore, linkedAccountAuth };
@@ -0,0 +1,4 @@
1
+ //#region src/content-freeze.d.ts
2
+ declare function generateContent(appRoot: string): Promise<string[]>;
3
+ //#endregion
4
+ export { generateContent as t };
@@ -0,0 +1,2 @@
1
+ import { t as generateContent } from "./content-freeze-CyiW2fRK.js";
2
+ export { generateContent };
@@ -0,0 +1,83 @@
1
+ import { findJuneConfigPath, loadJuneConfig } from "./config-loader.js";
2
+ import { generateContentModule } from "./content.js";
3
+ import { existsSync } from "node:fs";
4
+ import { mkdir, readFile, writeFile } from "node:fs/promises";
5
+ import { join, resolve } from "node:path";
6
+ import { pathToFileURL } from "node:url";
7
+ import { execFileSync } from "node:child_process";
8
+ //#region src/content-freeze.ts
9
+ async function generateContent(appRoot) {
10
+ const contentDir = join(appRoot, "content");
11
+ await mkdir(join(appRoot, "app"), { recursive: true });
12
+ const emit = async (sources, knownLocales) => {
13
+ const { code, names } = generateContentModule(contentDir, knownLocales, sources);
14
+ await writeFile(join(appRoot, "app", "_content.ts"), code);
15
+ return names;
16
+ };
17
+ const resolveSources = (sources) => sources.map((s) => ({
18
+ ...s,
19
+ dir: resolve(appRoot, s.dir)
20
+ }));
21
+ const declaredLocales = (config) => config.i18n ? [.../* @__PURE__ */ new Set([config.i18n.defaultLocale, ...Object.keys(config.i18n.locales)])] : [];
22
+ let config = null;
23
+ try {
24
+ config = await loadJuneConfig(appRoot);
25
+ } catch {}
26
+ if (config) return emit(resolveSources(config.content?.sources ?? []), declaredLocales(config));
27
+ const names = await emit([], void 0);
28
+ await seedContentImports(appRoot);
29
+ const probed = probeConfigFresh(appRoot);
30
+ if (probed === null) {
31
+ console.warn("[june gen] june.config.ts failed to load — content.sources/i18n locales (if any) not applied");
32
+ return names;
33
+ }
34
+ return emit(resolveSources(probed.sources), probed.locales);
35
+ }
36
+ async function seedContentImports(appRoot) {
37
+ const cfgPath = findJuneConfigPath(appRoot);
38
+ if (!cfgPath) return;
39
+ const contentFile = join(appRoot, "app", "_content.ts");
40
+ const current = existsSync(contentFile) ? await readFile(contentFile, "utf8") : "";
41
+ const cfgSrc = await readFile(cfgPath, "utf8");
42
+ const isIdent = (s) => /^[A-Za-z_$][A-Za-z0-9_$]*$/.test(s);
43
+ const seen = /* @__PURE__ */ new Set();
44
+ const stubs = [];
45
+ for (const m of cfgSrc.matchAll(/import\s*(?:type\s+)?\{([^}]*)\}\s*from\s*["'][^"']*app\/_content(?:\.\w+)?["']/g)) {
46
+ const inner = (m[1] ?? "").replace(/\/\*[\s\S]*?\*\//g, "").replace(/\/\/[^\n]*/g, "");
47
+ for (const part of inner.split(",")) {
48
+ const name = part.replace(/\btype\b/g, "").split(/\s+as\s+/).pop()?.trim();
49
+ if (!name || !isIdent(name) || seen.has(name)) continue;
50
+ seen.add(name);
51
+ const reName = name.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
52
+ if (!new RegExp(`export (?:const|function|type) ${reName}\\b`).test(current)) stubs.push(`export const ${name}: ContentEntry[] = [];`);
53
+ }
54
+ }
55
+ if (stubs.length) await writeFile(contentFile, current + stubs.join("\n") + "\n");
56
+ }
57
+ function probeConfigFresh(appRoot) {
58
+ const path = findJuneConfigPath(appRoot);
59
+ if (!path) return {
60
+ sources: [],
61
+ locales: []
62
+ };
63
+ const code = `import(${JSON.stringify(pathToFileURL(path).href)}).then((m) => { const c = m.default ?? {}; process.stdout.write("\\n__JUNE_CONTENT__" + JSON.stringify({ sources: c.content?.sources ?? [], locales: c.i18n ? [...new Set([c.i18n.defaultLocale, ...Object.keys(c.i18n.locales ?? {})])] : [] }) + "__END__"); }, () => process.exit(42));`;
64
+ try {
65
+ const m = execFileSync(process.execPath, [
66
+ ...process.execArgv,
67
+ "-e",
68
+ code
69
+ ], {
70
+ encoding: "utf8",
71
+ stdio: [
72
+ "ignore",
73
+ "pipe",
74
+ "ignore"
75
+ ]
76
+ }).match(/__JUNE_CONTENT__(.*?)__END__/s);
77
+ return m ? JSON.parse(m[1]) : null;
78
+ } catch {
79
+ return null;
80
+ }
81
+ }
82
+ //#endregion
83
+ export { generateContent };
@@ -1,6 +1,6 @@
1
1
  import * as coreRuntime from "@junejs/core/agent-runtime";
2
2
  //#region src/core-version.ts
3
- const EXPECTED_CORE_RUNTIME_API = 1;
3
+ const EXPECTED_CORE_RUNTIME_API = 2;
4
4
  function assertCoreRuntimeVersion(surface) {
5
5
  checkCoreRuntimeVersion(surface, coreRuntime.RUNTIME_API_VERSION);
6
6
  }
package/dist/index.d.ts CHANGED
@@ -1,11 +1,16 @@
1
- import { AdapterCapabilities, AdapterEmitContext, AdapterEntry, JuneAdapter, ResourcePlan, deno, staticSite, vercel, workers } from "./adapter.js";
1
+ import { a as ResourcePlan, c as staticSite, i as JuneAdapter, l as vercel, n as AdapterEmitContext, o as deno, r as AdapterEntry, t as AdapterCapabilities, u as workers } from "./adapter-DcZ-W1-7.js";
2
2
  import { AGENT_MODULE_FILE, AgentDirScan, emitAgentModule, findAgentDir, generateAgentModule, scanAgentDir } from "./agent-compile.js";
3
3
  import { CreateAppOptions, JuneApp, createApp } from "./app.js";
4
4
  import { R2Bucket, localBlob, r2 } from "./blob.js";
5
+ import { r as scanRoutes } from "./route-scan-DMlwoESy.js";
6
+ import { t as generateContent } from "./content-freeze-CyiW2fRK.js";
5
7
  import { a as Pipeline, d as createPipeline, n as LayoutComponent, o as PipelineConfig, s as Resolved, u as RouteResolver } from "./pipeline-cCR6MGNK.js";
6
- import { WorkerManifest, createWorker } from "./worker.js";
7
- import { BuildResult, buildManifest, freezeConfig, generateContent, juneBuild, scanRoutes } from "./build.js";
8
+ import { n as WorkerManifest, r as createWorker } from "./worker-BkFHGtxp.js";
9
+ import { t as freezeConfig } from "./config-freeze-DwI-Rmvq.js";
10
+ import { n as buildManifest } from "./manifest-gcNWqWoI.js";
11
+ import { BuildResult, juneBuild } from "./build.js";
8
12
  import { loadJuneConfig } from "./config-loader.js";
13
+ import { AccountTokenStore, BetterAuthLike, ConnectionAuth, LinkedAccountAuthOptions, betterAuthAccessToken, betterAuthAccountTokenStore, linkedAccountAuth } from "./connection-auth.js";
9
14
  import { ContentEntry, collection, entry } from "./content.js";
10
15
  import { a as blockedMessage, c as migrateApp, l as readMigrations, n as MigrateResult, o as classify, r as Migration, s as migrate, u as typesApp } from "./migrate-BbWt-PuB.js";
11
16
  import { D1Exec, migrateD1, resolveD1Database, wranglerD1 } from "./d1-migrate.js";
@@ -25,4 +30,4 @@ import { Negotiated, negotiate } from "./negotiate.js";
25
30
  import { blob, currentServices, db, kv } from "@junejs/db";
26
31
  import { ServicesConfig, defineServices } from "@junejs/core/config";
27
32
  import { I18nConfig, LOCALE_COOKIE, LocaleConfig, LocaleMatch, dirForLang, localeDir, localeHref, matchPinnedLocale, negotiateLocale, parseAcceptLanguage, resolveRequestLocale } from "@junejs/core/i18n";
28
- export { AGENT_MODULE_FILE, type AdapterCapabilities, type AdapterEmitContext, type AdapterEntry, type AgentDirScan, type BuildResult, type ContentEntry, type CreateAppOptions, type D1Database, type D1Exec, type DeployResult, type DevServer, type DevServerOptions, type I18nConfig, type JuneAdapter, type JuneApp, type JuneDb, type JuneHost, LOCALE_COOKIE, type LayoutComponent, type LocaleConfig, type LocaleMatch, type MatchOptions, type MigrateResult, type Migration, type Negotiated, type Pipeline, type PipelineConfig, type R2Bucket, type Resolved, type ResourceFlags, type ResourcePlan, type RouteMatch, type RouteResolver, type RouteTreeMatch, type RunResult, type SegmentMatch, type ServeHandle, type ServicesConfig, type SpawnedModule, type WorkerEnv, type WorkerManifest, bindWorkerResources, blob, blockedMessage, buildManifest, classify, collection, createApp, createPipeline, createWorker, currentServices, d1, db, defineServices, deno, dirForLang, emitAgentModule, entry, findAgentDir, freezeConfig, generateAgentModule, generateContent, host, installAsyncContext, juneBuild, juneDeploy, kv, listRoutes, loadJuneConfig, localBlob, localeDir, localeHref, matchPinnedLocale, matchRoute, matchRouteTree, memoizeResources, memoryKv, migrate, migrateApp, migrateD1, mysql, negotiate, negotiateLocale, parseAcceptLanguage, postgres, r2, readMigrations, redisKv, resolveD1Database, resolveNotFound, resolveRequestLocale, scanAgentDir, scanRoutes, sqlite, startDevServer, staticSite, turso, typesApp, vercel, workers, wranglerD1 };
33
+ export { AGENT_MODULE_FILE, type AccountTokenStore, type AdapterCapabilities, type AdapterEmitContext, type AdapterEntry, type AgentDirScan, type BetterAuthLike, type BuildResult, type ConnectionAuth, type ContentEntry, type CreateAppOptions, type D1Database, type D1Exec, type DeployResult, type DevServer, type DevServerOptions, type I18nConfig, type JuneAdapter, type JuneApp, type JuneDb, type JuneHost, LOCALE_COOKIE, type LayoutComponent, type LinkedAccountAuthOptions, type LocaleConfig, type LocaleMatch, type MatchOptions, type MigrateResult, type Migration, type Negotiated, type Pipeline, type PipelineConfig, type R2Bucket, type Resolved, type ResourceFlags, type ResourcePlan, type RouteMatch, type RouteResolver, type RouteTreeMatch, type RunResult, type SegmentMatch, type ServeHandle, type ServicesConfig, type SpawnedModule, type WorkerEnv, type WorkerManifest, betterAuthAccessToken, betterAuthAccountTokenStore, bindWorkerResources, blob, blockedMessage, buildManifest, classify, collection, createApp, createPipeline, createWorker, currentServices, d1, db, defineServices, deno, dirForLang, emitAgentModule, entry, findAgentDir, freezeConfig, generateAgentModule, generateContent, host, installAsyncContext, juneBuild, juneDeploy, kv, linkedAccountAuth, listRoutes, loadJuneConfig, localBlob, localeDir, localeHref, matchPinnedLocale, matchRoute, matchRouteTree, memoizeResources, memoryKv, migrate, migrateApp, migrateD1, mysql, negotiate, negotiateLocale, parseAcceptLanguage, postgres, r2, readMigrations, redisKv, resolveD1Database, resolveNotFound, resolveRequestLocale, scanAgentDir, scanRoutes, sqlite, startDevServer, staticSite, turso, typesApp, vercel, workers, wranglerD1 };
package/dist/index.js CHANGED
@@ -8,9 +8,14 @@ import { bindWorkerResources, memoizeResources } from "./resources.js";
8
8
  import { createApp } from "./app.js";
9
9
  import { localBlob, r2 } from "./blob.js";
10
10
  import { loadJuneConfig } from "./config-loader.js";
11
+ import { freezeConfig } from "./config-freeze.js";
11
12
  import { collection, entry } from "./content.js";
13
+ import { generateContent } from "./content-freeze.js";
12
14
  import { createWorker } from "./worker.js";
13
- import { buildManifest, freezeConfig, generateContent, juneBuild, scanRoutes } from "./build.js";
15
+ import { scanRoutes } from "./route-scan.js";
16
+ import { buildManifest } from "./manifest.js";
17
+ import { juneBuild } from "./build.js";
18
+ import { betterAuthAccessToken, betterAuthAccountTokenStore, linkedAccountAuth } from "./connection-auth.js";
14
19
  import { blockedMessage, classify, migrate, migrateApp, readMigrations, typesApp } from "./migrate.js";
15
20
  import { migrateD1, resolveD1Database, wranglerD1 } from "./d1-migrate.js";
16
21
  import { postgres } from "./postgres-driver.js";
@@ -25,4 +30,4 @@ import { memoryKv, redisKv } from "./kv.js";
25
30
  import { blob, currentServices, db, kv } from "@junejs/db";
26
31
  import { defineServices } from "@junejs/core/config";
27
32
  import { LOCALE_COOKIE, dirForLang, localeDir, localeHref, matchPinnedLocale, negotiateLocale, parseAcceptLanguage, resolveRequestLocale } from "@junejs/core/i18n";
28
- export { AGENT_MODULE_FILE, LOCALE_COOKIE, bindWorkerResources, blob, blockedMessage, buildManifest, classify, collection, createApp, createPipeline, createWorker, currentServices, d1, db, defineServices, deno, dirForLang, emitAgentModule, entry, findAgentDir, freezeConfig, generateAgentModule, generateContent, host, installAsyncContext, juneBuild, juneDeploy, kv, listRoutes, loadJuneConfig, localBlob, localeDir, localeHref, matchPinnedLocale, matchRoute, matchRouteTree, memoizeResources, memoryKv, migrate, migrateApp, migrateD1, mysql, negotiate, negotiateLocale, parseAcceptLanguage, postgres, r2, readMigrations, redisKv, resolveD1Database, resolveNotFound, resolveRequestLocale, scanAgentDir, scanRoutes, sqlite, startDevServer, staticSite, turso, typesApp, vercel, workers, wranglerD1 };
33
+ export { AGENT_MODULE_FILE, LOCALE_COOKIE, betterAuthAccessToken, betterAuthAccountTokenStore, bindWorkerResources, blob, blockedMessage, buildManifest, classify, collection, createApp, createPipeline, createWorker, currentServices, d1, db, defineServices, deno, dirForLang, emitAgentModule, entry, findAgentDir, freezeConfig, generateAgentModule, generateContent, host, installAsyncContext, juneBuild, juneDeploy, kv, linkedAccountAuth, listRoutes, loadJuneConfig, localBlob, localeDir, localeHref, matchPinnedLocale, matchRoute, matchRouteTree, memoizeResources, memoryKv, migrate, migrateApp, migrateD1, mysql, negotiate, negotiateLocale, parseAcceptLanguage, postgres, r2, readMigrations, redisKv, resolveD1Database, resolveNotFound, resolveRequestLocale, scanAgentDir, scanRoutes, sqlite, startDevServer, staticSite, turso, typesApp, vercel, workers, wranglerD1 };
@@ -0,0 +1,11 @@
1
+ import { n as LayoutComponent } from "./pipeline-cCR6MGNK.js";
2
+ import { n as WorkerManifest } from "./worker-BkFHGtxp.js";
3
+ //#region src/manifest.d.ts
4
+ type ImportedLayout = {
5
+ component: LayoutComponent;
6
+ boundary: boolean;
7
+ };
8
+ declare function importLayout(file: string): Promise<ImportedLayout | null>;
9
+ declare function buildManifest(appRoot: string): Promise<WorkerManifest>;
10
+ //#endregion
11
+ export { buildManifest as n, importLayout as r, ImportedLayout as t };
@@ -0,0 +1,2 @@
1
+ import { n as buildManifest, r as importLayout, t as ImportedLayout } from "./manifest-gcNWqWoI.js";
2
+ export { ImportedLayout, buildManifest, importLayout };