praetom 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (102) hide show
  1. package/README.md +82 -0
  2. package/dist/_esm-loader.d.ts +49 -0
  3. package/dist/_esm-loader.d.ts.map +1 -0
  4. package/dist/_esm-loader.js +131 -0
  5. package/dist/_esm-loader.js.map +1 -0
  6. package/dist/_internal.d.ts +63 -0
  7. package/dist/_internal.d.ts.map +1 -0
  8. package/dist/_internal.js +357 -0
  9. package/dist/_internal.js.map +1 -0
  10. package/dist/browser.d.ts +90 -0
  11. package/dist/browser.d.ts.map +1 -0
  12. package/dist/browser.js +357 -0
  13. package/dist/browser.js.map +1 -0
  14. package/dist/cli/cli.d.ts +3 -0
  15. package/dist/cli/cli.d.ts.map +1 -0
  16. package/dist/cli/cli.js +97 -0
  17. package/dist/cli/cli.js.map +1 -0
  18. package/dist/cli/commands/discover.d.ts +3 -0
  19. package/dist/cli/commands/discover.d.ts.map +1 -0
  20. package/dist/cli/commands/discover.js +15 -0
  21. package/dist/cli/commands/discover.js.map +1 -0
  22. package/dist/cli/commands/features.d.ts +5 -0
  23. package/dist/cli/commands/features.d.ts.map +1 -0
  24. package/dist/cli/commands/features.js +83 -0
  25. package/dist/cli/commands/features.js.map +1 -0
  26. package/dist/cli/commands/init.d.ts +3 -0
  27. package/dist/cli/commands/init.d.ts.map +1 -0
  28. package/dist/cli/commands/init.js +52 -0
  29. package/dist/cli/commands/init.js.map +1 -0
  30. package/dist/cli/commands/login.d.ts +20 -0
  31. package/dist/cli/commands/login.d.ts.map +1 -0
  32. package/dist/cli/commands/login.js +138 -0
  33. package/dist/cli/commands/login.js.map +1 -0
  34. package/dist/cli/commands/logout.d.ts +3 -0
  35. package/dist/cli/commands/logout.d.ts.map +1 -0
  36. package/dist/cli/commands/logout.js +15 -0
  37. package/dist/cli/commands/logout.js.map +1 -0
  38. package/dist/cli/commands/rotate.d.ts +3 -0
  39. package/dist/cli/commands/rotate.d.ts.map +1 -0
  40. package/dist/cli/commands/rotate.js +33 -0
  41. package/dist/cli/commands/rotate.js.map +1 -0
  42. package/dist/cli/commands/status.d.ts +3 -0
  43. package/dist/cli/commands/status.d.ts.map +1 -0
  44. package/dist/cli/commands/status.js +54 -0
  45. package/dist/cli/commands/status.js.map +1 -0
  46. package/dist/cli/commands/uninstall.d.ts +3 -0
  47. package/dist/cli/commands/uninstall.d.ts.map +1 -0
  48. package/dist/cli/commands/uninstall.js +63 -0
  49. package/dist/cli/commands/uninstall.js.map +1 -0
  50. package/dist/cli/commands/usage.d.ts +3 -0
  51. package/dist/cli/commands/usage.d.ts.map +1 -0
  52. package/dist/cli/commands/usage.js +19 -0
  53. package/dist/cli/commands/usage.js.map +1 -0
  54. package/dist/cli/commands/whoami.d.ts +3 -0
  55. package/dist/cli/commands/whoami.d.ts.map +1 -0
  56. package/dist/cli/commands/whoami.js +37 -0
  57. package/dist/cli/commands/whoami.js.map +1 -0
  58. package/dist/cli/util/agent-env.d.ts +13 -0
  59. package/dist/cli/util/agent-env.d.ts.map +1 -0
  60. package/dist/cli/util/agent-env.js +28 -0
  61. package/dist/cli/util/agent-env.js.map +1 -0
  62. package/dist/cli/util/api.d.ts +36 -0
  63. package/dist/cli/util/api.d.ts.map +1 -0
  64. package/dist/cli/util/api.js +84 -0
  65. package/dist/cli/util/api.js.map +1 -0
  66. package/dist/cli/util/auth-file.d.ts +25 -0
  67. package/dist/cli/util/auth-file.d.ts.map +1 -0
  68. package/dist/cli/util/auth-file.js +74 -0
  69. package/dist/cli/util/auth-file.js.map +1 -0
  70. package/dist/cli/util/git.d.ts +28 -0
  71. package/dist/cli/util/git.d.ts.map +1 -0
  72. package/dist/cli/util/git.js +103 -0
  73. package/dist/cli/util/git.js.map +1 -0
  74. package/dist/cli/util/run.d.ts +26 -0
  75. package/dist/cli/util/run.d.ts.map +1 -0
  76. package/dist/cli/util/run.js +31 -0
  77. package/dist/cli/util/run.js.map +1 -0
  78. package/dist/edge.d.ts +34 -0
  79. package/dist/edge.d.ts.map +1 -0
  80. package/dist/edge.js +127 -0
  81. package/dist/edge.js.map +1 -0
  82. package/dist/server.d.ts +69 -0
  83. package/dist/server.d.ts.map +1 -0
  84. package/dist/server.js +193 -0
  85. package/dist/server.js.map +1 -0
  86. package/dist/vite/index.d.ts +48 -0
  87. package/dist/vite/index.d.ts.map +1 -0
  88. package/dist/vite/index.js +138 -0
  89. package/dist/vite/index.js.map +1 -0
  90. package/dist/webpack/index.d.ts +64 -0
  91. package/dist/webpack/index.d.ts.map +1 -0
  92. package/dist/webpack/index.js +106 -0
  93. package/dist/webpack/index.js.map +1 -0
  94. package/dist/webpack/loader.d.ts +27 -0
  95. package/dist/webpack/loader.d.ts.map +1 -0
  96. package/dist/webpack/loader.js +54 -0
  97. package/dist/webpack/loader.js.map +1 -0
  98. package/dist/webpack/shared.d.ts +25 -0
  99. package/dist/webpack/shared.d.ts.map +1 -0
  100. package/dist/webpack/shared.js +63 -0
  101. package/dist/webpack/shared.js.map +1 -0
  102. package/package.json +79 -0
@@ -0,0 +1,69 @@
1
+ /**
2
+ * praetom — the server-side customer API.
3
+ *
4
+ * Two exports, that's it:
5
+ * - register({ ingestId }) — call once at process start
6
+ * - emit(eventName, payload?) — fire a point-in-time event from
7
+ * inside business logic
8
+ *
9
+ * // In Next.js: apps/web/instrumentation.ts
10
+ * import { register } from "praetom";
11
+ * await register();
12
+ *
13
+ * // In Express / Fastify / raw Node: top of the entry point
14
+ * import { register } from "praetom";
15
+ * register();
16
+ *
17
+ * // Anywhere inside a feature's code, to mark a sub-event:
18
+ * import { emit } from "praetom";
19
+ * emit("checkout:stripe-charged", { amount });
20
+ *
21
+ * What register() does on boot:
22
+ * 1. Reads PRAETOM_INGEST_ID from env (or accepts via options). The
23
+ * token encodes both the workspace AND the repo it represents —
24
+ * same shape as a Sentry DSN.
25
+ * 2. Calls praetom.com/api/runtime/config; the server resolves the
26
+ * repo from the bearer token and returns its feature map.
27
+ * 3. Installs a Module._load hook (CJS) that wraps the entry_symbol
28
+ * of any file matching a feature's primary_path list.
29
+ *
30
+ * praetom's DB is the source of truth for what gets wrapped — there
31
+ * are NO feature(slug, fn) wraps in customer source code. Discovery
32
+ * defines features in praetom; the runtime applies them at boot.
33
+ *
34
+ * What's not yet covered by the runtime hooks alone:
35
+ * - Bundled apps (Next.js prod, Vite/Rollup builds, etc.) — files are
36
+ * concatenated into chunks, so neither Module._load nor the ESM
37
+ * loader sees them as individual modules. Use the bundler plugins
38
+ * (`praetom/vite`, `praetom/webpack`) for those — they wrap at
39
+ * build time.
40
+ * - Live map updates. v1 fetches once on boot. SSE subscription is
41
+ * a follow-up.
42
+ */
43
+ import { emit, wrapEntryPoint } from "./_internal";
44
+ export interface RegisterOptions {
45
+ /** Override the ingest token (defaults to PRAETOM_INGEST_ID env var). */
46
+ ingestId?: string;
47
+ /** Override the OTLP endpoint (defaults to praetom.com). */
48
+ endpoint?: string;
49
+ /** Override the config endpoint (defaults to praetom.com). */
50
+ configEndpoint?: string;
51
+ /** Suppress the boot-time console.warn lines (for tests). */
52
+ silent?: boolean;
53
+ }
54
+ export declare function register(opts?: RegisterOptions): Promise<void>;
55
+ export { emit };
56
+ /**
57
+ * Internal escape hatch for bundler-plugin-generated code. NOT a public
58
+ * customer API — the leading underscores signal "compile-time only;
59
+ * customers should never import this." The bundler plugin injects calls
60
+ * like `__praetomWrapEntryPoint("checkout", "POST", originalHandler)`
61
+ * into transformed source.
62
+ */
63
+ export declare const __praetomWrapEntryPoint: typeof wrapEntryPoint;
64
+ /**
65
+ * Test-only — clear the registered map between unit tests. Customers
66
+ * don't call this in production.
67
+ */
68
+ export declare function _resetForTests(): void;
69
+ //# sourceMappingURL=server.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"server.d.ts","sourceRoot":"","sources":["../src/server.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAyCG;AAKH,OAAO,EAAE,IAAI,EAAQ,cAAc,EAAE,MAAM,aAAa,CAAC;AAuBzD,MAAM,WAAW,eAAe;IAC9B,yEAAyE;IACzE,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,4DAA4D;IAC5D,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,8DAA8D;IAC9D,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,6DAA6D;IAC7D,MAAM,CAAC,EAAE,OAAO,CAAC;CAClB;AAID,wBAAsB,QAAQ,CAAC,IAAI,GAAE,eAAoB,GAAG,OAAO,CAAC,IAAI,CAAC,CAwDxE;AA4GD,OAAO,EAAE,IAAI,EAAE,CAAC;AAEhB;;;;;;GAMG;AACH,eAAO,MAAM,uBAAuB,uBAAiB,CAAC;AAEtD;;;GAGG;AACH,wBAAgB,cAAc,IAAI,IAAI,CAGrC"}
package/dist/server.js ADDED
@@ -0,0 +1,193 @@
1
+ /**
2
+ * praetom — the server-side customer API.
3
+ *
4
+ * Two exports, that's it:
5
+ * - register({ ingestId }) — call once at process start
6
+ * - emit(eventName, payload?) — fire a point-in-time event from
7
+ * inside business logic
8
+ *
9
+ * // In Next.js: apps/web/instrumentation.ts
10
+ * import { register } from "praetom";
11
+ * await register();
12
+ *
13
+ * // In Express / Fastify / raw Node: top of the entry point
14
+ * import { register } from "praetom";
15
+ * register();
16
+ *
17
+ * // Anywhere inside a feature's code, to mark a sub-event:
18
+ * import { emit } from "praetom";
19
+ * emit("checkout:stripe-charged", { amount });
20
+ *
21
+ * What register() does on boot:
22
+ * 1. Reads PRAETOM_INGEST_ID from env (or accepts via options). The
23
+ * token encodes both the workspace AND the repo it represents —
24
+ * same shape as a Sentry DSN.
25
+ * 2. Calls praetom.com/api/runtime/config; the server resolves the
26
+ * repo from the bearer token and returns its feature map.
27
+ * 3. Installs a Module._load hook (CJS) that wraps the entry_symbol
28
+ * of any file matching a feature's primary_path list.
29
+ *
30
+ * praetom's DB is the source of truth for what gets wrapped — there
31
+ * are NO feature(slug, fn) wraps in customer source code. Discovery
32
+ * defines features in praetom; the runtime applies them at boot.
33
+ *
34
+ * What's not yet covered by the runtime hooks alone:
35
+ * - Bundled apps (Next.js prod, Vite/Rollup builds, etc.) — files are
36
+ * concatenated into chunks, so neither Module._load nor the ESM
37
+ * loader sees them as individual modules. Use the bundler plugins
38
+ * (`praetom/vite`, `praetom/webpack`) for those — they wrap at
39
+ * build time.
40
+ * - Live map updates. v1 fetches once on boot. SSE subscription is
41
+ * a follow-up.
42
+ */
43
+ import Module from "node:module";
44
+ import { register as registerEsmLoader } from "node:module";
45
+ import { emit, init, wrapEntryPoint } from "./_internal";
46
+ const mapByPath = new Map();
47
+ let _hookInstalled = false;
48
+ const DEFAULT_CONFIG_ENDPOINT = "https://praetom.com/api/runtime/config";
49
+ export async function register(opts = {}) {
50
+ const ingestId = opts.ingestId ?? process.env.PRAETOM_INGEST_ID;
51
+ const warn = opts.silent
52
+ ? () => { }
53
+ : (msg) => {
54
+ // eslint-disable-next-line no-console
55
+ console.warn(`[praetom] ${msg}`);
56
+ };
57
+ if (!ingestId) {
58
+ warn("PRAETOM_INGEST_ID not set; instrumentation disabled");
59
+ return;
60
+ }
61
+ // The token encodes (workspace, repo) identity — no PRAETOM_REPO or
62
+ // deploy-provider env vars needed. Just call config; the server resolves
63
+ // the repo from the bearer token.
64
+ let config;
65
+ try {
66
+ const cfgUrl = opts.configEndpoint ?? DEFAULT_CONFIG_ENDPOINT;
67
+ const abort = new AbortController();
68
+ const timer = setTimeout(() => abort.abort(), 5_000);
69
+ const res = await fetch(cfgUrl, {
70
+ headers: { authorization: `Bearer ${ingestId}` },
71
+ signal: abort.signal,
72
+ }).finally(() => clearTimeout(timer));
73
+ if (!res.ok) {
74
+ warn(`runtime/config fetch failed: HTTP ${res.status}`);
75
+ return;
76
+ }
77
+ config = (await res.json());
78
+ }
79
+ catch (e) {
80
+ warn(`runtime/config fetch error: ${e.message}`);
81
+ return;
82
+ }
83
+ init({
84
+ token: ingestId,
85
+ endpoint: opts.endpoint,
86
+ serviceName: config.repo,
87
+ });
88
+ mapByPath.clear();
89
+ for (const f of config.features) {
90
+ for (const p of f.paths) {
91
+ mapByPath.set(p, { slug: f.slug, entrySymbol: f.entrySymbol, side: f.side });
92
+ }
93
+ }
94
+ if (mapByPath.size === 0) {
95
+ warn(`workspace ${config.workspaceSlug} has no features for ${config.repo}; instrumentation idle`);
96
+ return;
97
+ }
98
+ installRequireHook();
99
+ installEsmLoader(warn);
100
+ }
101
+ function installEsmLoader(warn) {
102
+ if (_esmLoaderInstalled)
103
+ return;
104
+ try {
105
+ const loaderUrl = new URL("./_esm-loader.js", import.meta.url);
106
+ registerEsmLoader(loaderUrl.href, import.meta.url, {
107
+ data: {
108
+ featureMap: [...mapByPath.entries()].map(([path, info]) => [
109
+ path,
110
+ { slug: info.slug, entrySymbol: info.entrySymbol },
111
+ ]),
112
+ },
113
+ });
114
+ _esmLoaderInstalled = true;
115
+ }
116
+ catch (e) {
117
+ warn(`ESM loader registration failed: ${e.message}`);
118
+ }
119
+ }
120
+ let _esmLoaderInstalled = false;
121
+ function installRequireHook() {
122
+ if (_hookInstalled)
123
+ return;
124
+ const mod = Module;
125
+ const originalLoad = mod._load;
126
+ mod._load = function patchedLoad(request, parent, isMain) {
127
+ const exported = originalLoad.call(this, request, parent, isMain);
128
+ if (!parent || typeof parent.filename !== "string")
129
+ return exported;
130
+ let resolved;
131
+ try {
132
+ resolved = mod._resolveFilename(request, parent, isMain);
133
+ }
134
+ catch {
135
+ return exported;
136
+ }
137
+ const match = matchFeatureForPath(resolved);
138
+ if (!match)
139
+ return exported;
140
+ return wrapModuleExports(exported, match);
141
+ };
142
+ _hookInstalled = true;
143
+ }
144
+ function matchFeatureForPath(absolutePath) {
145
+ for (const [featurePath, info] of mapByPath) {
146
+ if (absolutePath === featurePath ||
147
+ absolutePath.endsWith(`/${featurePath}`) ||
148
+ // Windows path support
149
+ absolutePath.replace(/\\/g, "/").endsWith(`/${featurePath}`)) {
150
+ return info;
151
+ }
152
+ }
153
+ return null;
154
+ }
155
+ function wrapModuleExports(exports, info) {
156
+ if (!exports || (typeof exports !== "object" && typeof exports !== "function")) {
157
+ return exports;
158
+ }
159
+ const e = exports;
160
+ if (info.entrySymbol && typeof e[info.entrySymbol] === "function") {
161
+ e[info.entrySymbol] = wrapEntryPoint(info.slug, info.entrySymbol, e[info.entrySymbol]);
162
+ return exports;
163
+ }
164
+ // No specific entry_symbol — wrap default export if function-shaped,
165
+ // plus any HTTP-method-named exports (Next.js App Router convention).
166
+ if (typeof e.default === "function") {
167
+ e.default = wrapEntryPoint(info.slug, "default", e.default);
168
+ }
169
+ for (const m of ["GET", "POST", "PUT", "PATCH", "DELETE", "OPTIONS", "HEAD"]) {
170
+ if (typeof e[m] === "function") {
171
+ e[m] = wrapEntryPoint(info.slug, m, e[m]);
172
+ }
173
+ }
174
+ return exports;
175
+ }
176
+ export { emit };
177
+ /**
178
+ * Internal escape hatch for bundler-plugin-generated code. NOT a public
179
+ * customer API — the leading underscores signal "compile-time only;
180
+ * customers should never import this." The bundler plugin injects calls
181
+ * like `__praetomWrapEntryPoint("checkout", "POST", originalHandler)`
182
+ * into transformed source.
183
+ */
184
+ export const __praetomWrapEntryPoint = wrapEntryPoint;
185
+ /**
186
+ * Test-only — clear the registered map between unit tests. Customers
187
+ * don't call this in production.
188
+ */
189
+ export function _resetForTests() {
190
+ mapByPath.clear();
191
+ _hookInstalled = false;
192
+ }
193
+ //# sourceMappingURL=server.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"server.js","sourceRoot":"","sources":["../src/server.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,48 @@
1
+ /**
2
+ * praetom/vite — Vite/Rollup plugin for praetom.
3
+ *
4
+ * On build start: fetches the workspace's feature map from praetom using
5
+ * the per-repo ingest token. On every file transformed by Vite, checks
6
+ * whether the file's path matches a feature's `paths` list — if so,
7
+ * rewrites the source to wrap each named export with
8
+ * `__praetomWrapEntryPoint(slug, name, original)` from the runtime SDK.
9
+ *
10
+ * Usage:
11
+ * // vite.config.ts
12
+ * import { defineConfig } from "vite";
13
+ * import praetom from "praetom/vite";
14
+ *
15
+ * export default defineConfig({
16
+ * plugins: [praetom()],
17
+ * });
18
+ *
19
+ * Auth: PRAETOM_INGEST_ID env var at build time (typical CI pattern),
20
+ * or pass `{ ingestId: "..." }` as plugin options.
21
+ *
22
+ * The transform is regex-level — same patterns as the runtime ESM
23
+ * loader hook in praetom. Same limitations: handles
24
+ * named-function-shaped exports, falls back to no-op + warning for
25
+ * shapes it doesn't recognize.
26
+ */
27
+ import type { Plugin } from "vite";
28
+ export interface PraetomViteOptions {
29
+ /**
30
+ * Per-repo ingest token used to fetch the feature map. Defaults to the
31
+ * PRAETOM_INGEST_ID env var. In CI, set the env var; locally, the
32
+ * dotenv loader (if any) feeds it in. As a last resort pass inline.
33
+ */
34
+ ingestId?: string;
35
+ /** Override the config endpoint. Defaults to https://praetom.com. */
36
+ configEndpoint?: string;
37
+ /**
38
+ * Project root for resolving feature paths. Feature paths come from
39
+ * praetom relative to the *repo* root; if your Vite build runs from
40
+ * inside a workspace package, set this so the plugin can translate.
41
+ * Defaults to the Vite-resolved project root.
42
+ */
43
+ projectRoot?: string;
44
+ /** Quiet mode — suppress [praetom] warns/info. */
45
+ silent?: boolean;
46
+ }
47
+ export default function praetom(opts?: PraetomViteOptions): Plugin;
48
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/vite/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;GAyBG;AAEH,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,MAAM,CAAC;AAenC,MAAM,WAAW,kBAAkB;IACjC;;;;OAIG;IACH,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,qEAAqE;IACrE,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB;;;;;OAKG;IACH,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,kDAAkD;IAClD,MAAM,CAAC,EAAE,OAAO,CAAC;CAClB;AAeD,MAAM,CAAC,OAAO,UAAU,OAAO,CAAC,IAAI,GAAE,kBAAuB,GAAG,MAAM,CA6ErE"}
@@ -0,0 +1,138 @@
1
+ /**
2
+ * praetom/vite — Vite/Rollup plugin for praetom.
3
+ *
4
+ * On build start: fetches the workspace's feature map from praetom using
5
+ * the per-repo ingest token. On every file transformed by Vite, checks
6
+ * whether the file's path matches a feature's `paths` list — if so,
7
+ * rewrites the source to wrap each named export with
8
+ * `__praetomWrapEntryPoint(slug, name, original)` from the runtime SDK.
9
+ *
10
+ * Usage:
11
+ * // vite.config.ts
12
+ * import { defineConfig } from "vite";
13
+ * import praetom from "praetom/vite";
14
+ *
15
+ * export default defineConfig({
16
+ * plugins: [praetom()],
17
+ * });
18
+ *
19
+ * Auth: PRAETOM_INGEST_ID env var at build time (typical CI pattern),
20
+ * or pass `{ ingestId: "..." }` as plugin options.
21
+ *
22
+ * The transform is regex-level — same patterns as the runtime ESM
23
+ * loader hook in praetom. Same limitations: handles
24
+ * named-function-shaped exports, falls back to no-op + warning for
25
+ * shapes it doesn't recognize.
26
+ */
27
+ const DEFAULT_CONFIG_ENDPOINT = "https://praetom.com/api/runtime/config";
28
+ const PRAETOM_IMPORT_MARKER = "__praetom_wrap_import__";
29
+ const HTTP_METHODS = new Set([
30
+ "GET",
31
+ "POST",
32
+ "PUT",
33
+ "PATCH",
34
+ "DELETE",
35
+ "OPTIONS",
36
+ "HEAD",
37
+ ]);
38
+ export default function praetom(opts = {}) {
39
+ let featureMap = [];
40
+ let projectRoot = "";
41
+ const log = opts.silent
42
+ ? () => { }
43
+ : // eslint-disable-next-line no-console
44
+ (msg) => console.warn(`[praetom] ${msg}`);
45
+ return {
46
+ name: "praetom/vite",
47
+ enforce: "pre",
48
+ async buildStart() {
49
+ const token = opts.ingestId ?? process.env.PRAETOM_INGEST_ID;
50
+ if (!token) {
51
+ log("PRAETOM_INGEST_ID not set and no ingestId option passed; build will not auto-wrap any features");
52
+ return;
53
+ }
54
+ const url = opts.configEndpoint ?? DEFAULT_CONFIG_ENDPOINT;
55
+ try {
56
+ const res = await fetch(url, {
57
+ headers: { authorization: `Bearer ${token}` },
58
+ });
59
+ if (!res.ok) {
60
+ throw new Error(`runtime/config returned HTTP ${res.status}`);
61
+ }
62
+ const config = (await res.json());
63
+ featureMap = config.features;
64
+ log(`loaded feature map: ${featureMap.length} features in ${config.repo}`);
65
+ }
66
+ catch (e) {
67
+ throw new Error(`[praetom] failed to fetch feature map from ${url}: ${e.message}. ` +
68
+ `Set PRAETOM_INGEST_ID to a valid per-repo token or pass { ingestId } to the plugin.`);
69
+ }
70
+ },
71
+ configResolved(resolvedConfig) {
72
+ projectRoot = opts.projectRoot ?? resolvedConfig.root;
73
+ },
74
+ transform(code, id) {
75
+ if (featureMap.length === 0)
76
+ return null;
77
+ if (id.includes("/node_modules/"))
78
+ return null;
79
+ if (id.startsWith("\0"))
80
+ return null; // virtual / rolled-up modules
81
+ const relPath = relativeToRoot(id, projectRoot);
82
+ const match = matchFeatureForPath(relPath);
83
+ if (!match)
84
+ return null;
85
+ const wrapped = wrapModuleSource(code, match.slug, match.entrySymbol);
86
+ if (!wrapped) {
87
+ log(`could not wrap ${relPath} (export shape not recognized; skipping)`);
88
+ return null;
89
+ }
90
+ return { code: wrapped, map: null };
91
+ },
92
+ };
93
+ function matchFeatureForPath(relPath) {
94
+ for (const feature of featureMap) {
95
+ if (feature.paths.some((p) => relPath === p || relPath.endsWith(`/${p}`))) {
96
+ return { slug: feature.slug, entrySymbol: feature.entrySymbol };
97
+ }
98
+ }
99
+ return null;
100
+ }
101
+ }
102
+ function relativeToRoot(id, root) {
103
+ const path = id.split("?")[0];
104
+ if (path.startsWith(root)) {
105
+ return path.slice(root.length).replace(/^\//, "");
106
+ }
107
+ return path;
108
+ }
109
+ function shouldWrap(name, entrySymbol) {
110
+ if (entrySymbol)
111
+ return name === entrySymbol;
112
+ return HTTP_METHODS.has(name) || name === "handler";
113
+ }
114
+ function wrapModuleSource(source, slug, entrySymbol) {
115
+ if (source.includes(PRAETOM_IMPORT_MARKER))
116
+ return null;
117
+ const targets = new Set();
118
+ let rewritten = source.replace(/^export\s+(async\s+)?function\s+([A-Za-z_$][\w$]*)\s*\(/gm, (_m, asyncKw, name) => {
119
+ if (!shouldWrap(name, entrySymbol))
120
+ return _m;
121
+ targets.add(name);
122
+ return `${asyncKw ?? ""}function __praetom_orig_${name}(`;
123
+ });
124
+ rewritten = rewritten.replace(/^export\s+const\s+([A-Za-z_$][\w$]*)\s*=/gm, (_m, name) => {
125
+ if (!shouldWrap(name, entrySymbol))
126
+ return _m;
127
+ targets.add(name);
128
+ return `const __praetom_orig_${name} =`;
129
+ });
130
+ if (targets.size === 0)
131
+ return null;
132
+ const importLine = `import { __praetomWrapEntryPoint as ${PRAETOM_IMPORT_MARKER} } from "praetom";\n`;
133
+ const wraps = [...targets]
134
+ .map((name) => `export const ${name} = ${PRAETOM_IMPORT_MARKER}(${JSON.stringify(slug)}, ${JSON.stringify(name)}, __praetom_orig_${name});`)
135
+ .join("\n");
136
+ return `${importLine}${rewritten}\n${wraps}\n`;
137
+ }
138
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/vite/index.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,64 @@
1
+ /**
2
+ * praetom/webpack — Webpack plugin for praetom.
3
+ *
4
+ * Usage (plain webpack):
5
+ * // webpack.config.js
6
+ * import praetom from "praetom/webpack";
7
+ *
8
+ * export default {
9
+ * plugins: [new praetom.PraetomPlugin()],
10
+ * // ...
11
+ * };
12
+ *
13
+ * Usage (Next.js):
14
+ * // next.config.ts
15
+ * import { PraetomPlugin } from "praetom/webpack";
16
+ *
17
+ * const nextConfig = {
18
+ * webpack(config) {
19
+ * config.plugins.push(new PraetomPlugin());
20
+ * return config;
21
+ * },
22
+ * };
23
+ * export default nextConfig;
24
+ *
25
+ * The plugin fetches the workspace's feature map at build start, then
26
+ * registers a loader rule so every JS/TS module webpack processes runs
27
+ * through the praetom loader. The loader checks each file's path
28
+ * against the feature map and rewrites named exports to call into the
29
+ * SDK's wrap helper.
30
+ *
31
+ * Auth: PRAETOM_INGEST_ID env var at build time, or pass
32
+ * `{ ingestId: "..." }` as constructor option.
33
+ */
34
+ export interface PraetomPluginOptions {
35
+ ingestId?: string;
36
+ configEndpoint?: string;
37
+ silent?: boolean;
38
+ }
39
+ interface CompilerHooks {
40
+ beforeRun: {
41
+ tapPromise: (name: string, fn: () => Promise<void>) => void;
42
+ };
43
+ watchRun: {
44
+ tapPromise: (name: string, fn: () => Promise<void>) => void;
45
+ };
46
+ }
47
+ interface Compiler {
48
+ options: {
49
+ module?: {
50
+ rules?: unknown[];
51
+ };
52
+ };
53
+ hooks: CompilerHooks;
54
+ }
55
+ export declare class PraetomPlugin {
56
+ private features;
57
+ private opts;
58
+ private log;
59
+ constructor(opts?: PraetomPluginOptions);
60
+ apply(compiler: Compiler): void;
61
+ private loadFeatureMap;
62
+ }
63
+ export default PraetomPlugin;
64
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/webpack/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAgCG;AAaH,MAAM,WAAW,oBAAoB;IACnC,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,MAAM,CAAC,EAAE,OAAO,CAAC;CAClB;AAKD,UAAU,aAAa;IACrB,SAAS,EAAE;QAAE,UAAU,EAAE,CAAC,IAAI,EAAE,MAAM,EAAE,EAAE,EAAE,MAAM,OAAO,CAAC,IAAI,CAAC,KAAK,IAAI,CAAA;KAAE,CAAC;IAC3E,QAAQ,EAAE;QAAE,UAAU,EAAE,CAAC,IAAI,EAAE,MAAM,EAAE,EAAE,EAAE,MAAM,OAAO,CAAC,IAAI,CAAC,KAAK,IAAI,CAAA;KAAE,CAAC;CAC3E;AAED,UAAU,QAAQ;IAChB,OAAO,EAAE;QACP,MAAM,CAAC,EAAE;YACP,KAAK,CAAC,EAAE,OAAO,EAAE,CAAC;SACnB,CAAC;KACH,CAAC;IACF,KAAK,EAAE,aAAa,CAAC;CACtB;AAED,qBAAa,aAAa;IACxB,OAAO,CAAC,QAAQ,CAAyB;IACzC,OAAO,CAAC,IAAI,CAAuB;IACnC,OAAO,CAAC,GAAG,CAAwB;gBAEvB,IAAI,GAAE,oBAAyB;IAQ3C,KAAK,CAAC,QAAQ,EAAE,QAAQ,GAAG,IAAI;YAiCjB,cAAc;CAyB7B;AAED,eAAe,aAAa,CAAC"}
@@ -0,0 +1,106 @@
1
+ /**
2
+ * praetom/webpack — Webpack plugin for praetom.
3
+ *
4
+ * Usage (plain webpack):
5
+ * // webpack.config.js
6
+ * import praetom from "praetom/webpack";
7
+ *
8
+ * export default {
9
+ * plugins: [new praetom.PraetomPlugin()],
10
+ * // ...
11
+ * };
12
+ *
13
+ * Usage (Next.js):
14
+ * // next.config.ts
15
+ * import { PraetomPlugin } from "praetom/webpack";
16
+ *
17
+ * const nextConfig = {
18
+ * webpack(config) {
19
+ * config.plugins.push(new PraetomPlugin());
20
+ * return config;
21
+ * },
22
+ * };
23
+ * export default nextConfig;
24
+ *
25
+ * The plugin fetches the workspace's feature map at build start, then
26
+ * registers a loader rule so every JS/TS module webpack processes runs
27
+ * through the praetom loader. The loader checks each file's path
28
+ * against the feature map and rewrites named exports to call into the
29
+ * SDK's wrap helper.
30
+ *
31
+ * Auth: PRAETOM_INGEST_ID env var at build time, or pass
32
+ * `{ ingestId: "..." }` as constructor option.
33
+ */
34
+ import { createRequire } from "node:module";
35
+ import { dirname, resolve } from "node:path";
36
+ import { fileURLToPath } from "node:url";
37
+ import { fetchFeatureMap } from "./shared.js";
38
+ const require_ = createRequire(import.meta.url);
39
+ const __filename_ = fileURLToPath(import.meta.url);
40
+ const __dirname_ = dirname(__filename_);
41
+ const DEFAULT_CONFIG_ENDPOINT = "https://praetom.com/api/runtime/config";
42
+ const PLUGIN_NAME = "PraetomPlugin";
43
+ export class PraetomPlugin {
44
+ features = [];
45
+ opts;
46
+ log;
47
+ constructor(opts = {}) {
48
+ this.opts = opts;
49
+ this.log = opts.silent
50
+ ? () => { }
51
+ : // eslint-disable-next-line no-console
52
+ (msg) => console.warn(`[praetom] ${msg}`);
53
+ }
54
+ apply(compiler) {
55
+ // Inject the loader as the first rule so it runs before everything else
56
+ // — we want to wrap before TypeScript/SWC strip types or transpile.
57
+ const moduleConfig = (compiler.options.module ??= {});
58
+ const rules = (moduleConfig.rules ??= []);
59
+ const loaderPath = resolve(__dirname_, "./loader.js");
60
+ rules.unshift({
61
+ test: /\.(ts|tsx|js|jsx|mjs|mts)$/,
62
+ exclude: /node_modules/,
63
+ enforce: "pre",
64
+ use: [
65
+ {
66
+ loader: loaderPath,
67
+ options: {
68
+ // Mutated below by the buildStart hook. Loader reads this on
69
+ // every transform call; mutating the same reference is the
70
+ // standard pattern for hot-reloading config from the plugin.
71
+ features: this.features,
72
+ },
73
+ },
74
+ ],
75
+ });
76
+ // Kick off the feature-map fetch immediately on apply(). The loader
77
+ // mutates the same `this.features` array reference, so even if a
78
+ // transform fires before the fetch completes, subsequent transforms
79
+ // will see the populated array. In practice the fetch takes <200ms
80
+ // and webpack's first transform fires seconds later, so this is fine
81
+ // for the typical case. Errors throw to surface broken builds early.
82
+ void this.loadFeatureMap();
83
+ }
84
+ async loadFeatureMap() {
85
+ const token = this.opts.ingestId ?? process.env.PRAETOM_INGEST_ID;
86
+ if (!token) {
87
+ this.log("PRAETOM_INGEST_ID not set and no ingestId option passed; build will not auto-wrap any features");
88
+ return;
89
+ }
90
+ const endpoint = this.opts.configEndpoint ?? DEFAULT_CONFIG_ENDPOINT;
91
+ try {
92
+ const config = await fetchFeatureMap(endpoint, token);
93
+ // Mutate in place so the loader's options.features reference
94
+ // updates without re-applying the rule.
95
+ this.features.length = 0;
96
+ this.features.push(...config.features);
97
+ this.log(`loaded feature map: ${this.features.length} features in ${config.repo}`);
98
+ }
99
+ catch (e) {
100
+ throw new Error(`[praetom] failed to fetch feature map from ${endpoint}: ${e.message}. ` +
101
+ `Set PRAETOM_INGEST_ID to a valid per-repo token or pass { ingestId } to the plugin constructor.`);
102
+ }
103
+ }
104
+ }
105
+ export default PraetomPlugin;
106
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/webpack/index.ts"],"names":[],"mappings":"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"}