@buoy-gg/angular 0.0.0-stage → 7.0.64

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.
@@ -0,0 +1,68 @@
1
+ import{createRequire as y}from"node:module";import{existsSync as f}from"node:fs";import{join as i}from"node:path";export function autoModule(s,c,u={}){const e=new Set(c.map(r=>r.key));const g=y(i(s,"package.json"));const n=r=>{try{g.resolve(r);return true}catch{return false}};const d=i(u.sourceRoot||i(s,"src"),"environments/buoy.ts");const a=f(d);const o=e.has("route-events")&&n("@angular/router");const t=e.has("react-query")&&n("@tanstack/angular-query-experimental");const l=e.has("redux")&&n("@ngrx/store-devtools");const p=e.has("highlight-updates");return`import { inject, NgZone, DestroyRef, PLATFORM_ID, makeEnvironmentProviders, provideAppInitializer, isDevMode } from '@angular/core';
2
+ ${a?"import { BUOY_KEY } from '#buoy-angular-key';":""}
3
+ ${o?"import { Router } from '@angular/router';":""}
4
+ ${t?"import { QueryClient } from '@tanstack/angular-query-experimental';":""}
5
+ ${l?"import { REDUX_DEVTOOLS_EXTENSION } from '@ngrx/store-devtools'; import { createBuoyNgRxExtension } from '@buoy-gg/angular/ngrx';":""}
6
+ export function wrapBuoyInitializer(initializer, readOptions, manual) {
7
+ ${l?`if (!manual) return makeEnvironmentProviders([
8
+ { provide: REDUX_DEVTOOLS_EXTENSION, useFactory: () => {
9
+ if (inject(PLATFORM_ID) !== 'browser' || !isDevMode()) return null;
10
+ const pending = [];
11
+ let target, ready = false, stopped = false, owned = false;
12
+ const run = fn => { if (!stopped) { if (ready) fn(target); else pending.push(fn); } };
13
+ const extension = {
14
+ [Symbol.for('buoy.ngrx.extension')]: true,
15
+ [Symbol.for('buoy.ngrx.start')]() {
16
+ if (ready || stopped) return;
17
+ owned = readOptions().modules === undefined;
18
+ target = owned ? createBuoyNgRxExtension(() => import('@buoy-gg/redux/web'))
19
+ : inject(Symbol.for('buoy.ngrx.manual-extension'), { optional: true });
20
+ ready = true;
21
+ for (const fn of pending.splice(0)) fn(target);
22
+ },
23
+ connect(...args) {
24
+ let connection;
25
+ run(value => { connection = value?.connect(...args); });
26
+ return {
27
+ init(...args) { run(() => connection?.init(...args)); },
28
+ send(...args) { run(() => connection?.send(...args)); },
29
+ subscribe(listener) {
30
+ let stop, active = true;
31
+ run(() => { if (active) stop = connection?.subscribe(listener); });
32
+ return () => { active = false; stop?.(); };
33
+ },
34
+ unsubscribe() { run(() => connection?.unsubscribe()); },
35
+ };
36
+ },
37
+ send(...args) { run(value => value?.send(...args)); },
38
+ destroy() { if (stopped) return; stopped = true; pending.length = 0; if (owned) target?.destroy(); },
39
+ };
40
+ inject(DestroyRef).onDestroy(() => extension.destroy());
41
+ return extension;
42
+ } },
43
+ provideAppInitializer(() => {
44
+ if (inject(PLATFORM_ID) !== 'browser') return;
45
+ const extension = inject(REDUX_DEVTOOLS_EXTENSION, { optional: true });
46
+ extension?.[Symbol.for('buoy.ngrx.start')]?.();
47
+ if (readOptions().modules === undefined && isDevMode() && !extension?.[Symbol.for('buoy.ngrx.extension')]) console.warn('[Buoy] NgRx has no Buoy link. Move provideBuoy() last in providers.');
48
+ }),
49
+ initializer,
50
+ ]);`:""}
51
+ return initializer;
52
+ }
53
+ export function captureBuoyLinks() {
54
+ const zone = inject(NgZone);
55
+ ${o?"const router = inject(Router, { optional: true });":""}
56
+ ${t?"const queryClient = inject(QueryClient, { optional: true });":""}
57
+ return {
58
+ enableInRelease: ${Boolean(u.release)},
59
+ async load() {
60
+ const { installedTools: modules } = await import('@buoy-gg/core/web/installed-tools');
61
+ return { modules, ${a?"licenseKey: BUOY_KEY,":""} ${t?"...(queryClient ? { queryClient } : {}),":""} };
62
+ },
63
+ links: {
64
+ ${o?"...(router ? { 'route-events': async () => { const { connectBuoyRouter } = await import('@buoy-gg/angular/router'); return zone.runOutsideAngular(() => connectBuoyRouter(router, fn => zone.run(fn))); } } : {}),":""}
65
+ ${p?"'highlight-updates': async () => { const [{ installedTools: modules }, { connectBuoyHighlights }] = await Promise.all([import('@buoy-gg/core/web/installed-tools'), import('@buoy-gg/angular/highlights')]); return zone.runOutsideAngular(() => connectBuoyHighlights(modules['highlight-updates'].HighlightUpdatesController, fn => zone.runOutsideAngular(fn))); },":""}
66
+ },
67
+ };
68
+ }`}
@@ -0,0 +1,14 @@
1
+ {
2
+ "builders": {
3
+ "application": {
4
+ "implementation": "./application.cjs",
5
+ "schema": "./application.schema.json",
6
+ "description": "Build the app with Buoy."
7
+ },
8
+ "dev-server": {
9
+ "implementation": "./dev-server.cjs",
10
+ "schema": "./dev-server.schema.json",
11
+ "description": "Serve the app with Buoy."
12
+ }
13
+ }
14
+ }
@@ -0,0 +1 @@
1
+ const{architect,application,schemaOptions}=require("./runtime.cjs");module.exports=architect().createBuilder(async function*(g,e){const{targetFromTargetString:d}=architect();const{buildOptions:l,toolPlugin:p,prebundleOptions:b,warnReactVersions:y,watchTools:w}=await import("./plugin.mjs");const{buoy:T,buoyRelease:f,...m}=g;const a=await e.validateOptions(schemaOptions(e.workspaceRoot,"dev-server",m),"@angular/build:dev-server");const r=d(a.buildTarget);const{root:t,sourceRoot:v,api:O}=await application(e,r);const n=await e.getTargetOptions(r);const i=T?.release??f??n.buoy?.release??n.buoyRelease??false;const R=l({...n,buoy:{release:i}},r.configuration);const s=p(t,{disabled:R.disabled,release:i,sourceRoot:v});y(t,e.logger);e.logger.info("[Buoy] Tools: "+s.found.map(o=>o.key).join(", "));const u=w(t,e.logger);e.addTeardown(u);const B={...e,getBuilderNameForTarget:async o=>{const c=await e.getBuilderNameForTarget(o);return c==="@buoy-gg/angular:application"?"@angular/build:application":c},getTargetOptions:async o=>l({...await e.getTargetOptions(o),buoy:{release:i}},o.configuration).options};try{yield*O.executeDevServerBuilder({...a,prebundle:b(a.prebundle,s.found,t)},B,{buildPlugins:[s.plugin]})}finally{u()}});
@@ -0,0 +1,153 @@
1
+ {
2
+ "$schema": "http://json-schema.org/draft-07/schema",
3
+ "title": "Dev Server Target",
4
+ "description": "Dev Server target options for Build Facade.",
5
+ "type": "object",
6
+ "properties": {
7
+ "buildTarget": {
8
+ "type": "string",
9
+ "description": "A build builder target to serve in the format of `project:target[:configuration]`. You can also pass in more than one configuration name as a comma-separated list. Example: `project:target:production,staging`.",
10
+ "pattern": "^[^:\\s]*:[^:\\s]*(:[^\\s]+)?$"
11
+ },
12
+ "port": {
13
+ "type": "number",
14
+ "description": "Port to listen on."
15
+ },
16
+ "host": {
17
+ "type": "string",
18
+ "description": "Host to listen on."
19
+ },
20
+ "proxyConfig": {
21
+ "type": "string",
22
+ "description": "Proxy configuration file. For more information, see https://angular.dev/tools/cli/serve#proxying-to-a-backend-server."
23
+ },
24
+ "ssl": {
25
+ "type": "boolean",
26
+ "description": "Serve using HTTPS."
27
+ },
28
+ "sslKey": {
29
+ "type": "string",
30
+ "description": "SSL key to use for serving HTTPS."
31
+ },
32
+ "sslCert": {
33
+ "type": "string",
34
+ "description": "SSL certificate to use for serving HTTPS."
35
+ },
36
+ "allowedHosts": {
37
+ "description": "The hosts that the development server will respond to. This option sets the Vite option of the same name. For further details: https://vite.dev/config/server-options.html#server-allowedhosts",
38
+ "oneOf": [
39
+ {
40
+ "type": "array",
41
+ "description": "A list of hosts that the development server will respond to.",
42
+ "items": {
43
+ "type": "string"
44
+ }
45
+ },
46
+ {
47
+ "type": "boolean",
48
+ "description": "Indicates that all hosts are allowed. This is not recommended and a security risk."
49
+ }
50
+ ]
51
+ },
52
+ "define": {
53
+ "description": "Defines global identifiers that will be replaced with a specified constant value when found in any JavaScript or TypeScript code including libraries. The value will be used directly. String values must be put in quotes. Identifiers within Angular metadata such as Component Decorators will not be replaced.",
54
+ "type": "object",
55
+ "additionalProperties": {
56
+ "type": "string"
57
+ }
58
+ },
59
+ "headers": {
60
+ "type": "object",
61
+ "description": "Custom HTTP headers to be added to all responses.",
62
+ "propertyNames": {
63
+ "pattern": "^[-_A-Za-z0-9]+$"
64
+ },
65
+ "additionalProperties": {
66
+ "type": "string"
67
+ }
68
+ },
69
+ "open": {
70
+ "type": "boolean",
71
+ "description": "Opens the url in default browser.",
72
+ "alias": "o"
73
+ },
74
+ "verbose": {
75
+ "type": "boolean",
76
+ "description": "Adds more details to output logging."
77
+ },
78
+ "liveReload": {
79
+ "type": "boolean",
80
+ "description": "Whether to reload the page on change, using live-reload."
81
+ },
82
+ "servePath": {
83
+ "type": "string",
84
+ "description": "The pathname where the application will be served."
85
+ },
86
+ "hmr": {
87
+ "type": "boolean",
88
+ "description": "Enable hot module replacement. Defaults to the value of 'liveReload'. Currently, only global and component stylesheets are supported."
89
+ },
90
+ "watch": {
91
+ "type": "boolean",
92
+ "description": "Rebuild on change."
93
+ },
94
+ "poll": {
95
+ "type": "number",
96
+ "description": "Enable and define the file watching poll time period in milliseconds."
97
+ },
98
+ "inspect": {
99
+ "description": "Activate debugging inspector. This option only has an effect when 'SSR' or 'SSG' are enabled.",
100
+ "oneOf": [
101
+ {
102
+ "type": "string",
103
+ "description": "Activate the inspector on host and port in the format of `[[host:]port]`. See the security warning in https://nodejs.org/docs/latest-v22.x/api/cli.html#warning-binding-inspector-to-a-public-ipport-combination-is-insecure regarding the host parameter usage."
104
+ },
105
+ {
106
+ "type": "boolean"
107
+ }
108
+ ]
109
+ },
110
+ "prebundle": {
111
+ "description": "Enable and control the Vite-based development server's prebundling capabilities. To enable prebundling, the Angular CLI cache must also be enabled.",
112
+ "oneOf": [
113
+ {
114
+ "type": "boolean"
115
+ },
116
+ {
117
+ "type": "object",
118
+ "properties": {
119
+ "exclude": {
120
+ "description": "List of package imports that should not be prebundled by the development server. The packages will be bundled into the application code itself. Note: specifying `@foo/bar` marks all paths within the `@foo/bar` package as excluded, including sub-paths like `@foo/bar/baz`.",
121
+ "type": "array",
122
+ "items": {
123
+ "type": "string"
124
+ }
125
+ }
126
+ },
127
+ "additionalProperties": false,
128
+ "required": [
129
+ "exclude"
130
+ ]
131
+ }
132
+ ]
133
+ },
134
+ "buoy": {
135
+ "type": "object",
136
+ "additionalProperties": false,
137
+ "properties": {
138
+ "release": {
139
+ "type": "boolean",
140
+ "description": "Keep Buoy in this build for QA."
141
+ }
142
+ }
143
+ },
144
+ "buoyRelease": {
145
+ "type": "boolean",
146
+ "description": "Use buoy.release for new setups."
147
+ }
148
+ },
149
+ "additionalProperties": true,
150
+ "required": [
151
+ "buildTarget"
152
+ ]
153
+ }
@@ -0,0 +1 @@
1
+ import{autoModule as k}from"./auto-module.mjs";import{findInstalledTools as j,installedToolsModule as O}from"@buoy-gg/core/vite";import{createRequire as d}from"node:module";import{existsSync as v,readFileSync as g,watchFile as R,unwatchFile as S}from"node:fs";import{dirname as f,join as c}from"node:path";export const installedToolsId="@buoy-gg/core/web/installed-tools";export function toolPlugin(o,r={}){const{found:t,missingWeb:n}=j(o,r);return{found:t,missingWeb:n,plugin:{name:"buoy-angular-tools",setup(e){const l=r.disabled||e.initialOptions?.platform==="node"||e.initialOptions?.define?.ngServerMode==="true";const s=d(c(o,"package.json"));e.onResolve({filter:/^@buoy-gg\//},a=>{if(!l)return;const[u,m,...h]=a.path.split("/");let y;try{y=s.resolve(`${u}/${m}/package.json`)}catch{return}const p=JSON.parse(g(y,"utf8"));const b=p.exports?.[h.length?"./"+h.join("/"):"."];const w=b?.["buoy-disabled"];if(typeof w==="string")return{path:c(f(y),w)}});if(l)return;const i=c(r.sourceRoot||c(o,"src"),"environments/buoy.ts");e.onResolve({filter:/^#buoy-angular-key$/},()=>({path:i,namespace:"buoy-angular-key"}));e.onLoad({filter:/.*/,namespace:"buoy-angular-key"},()=>({contents:g(i,"utf8"),loader:"ts",resolveDir:f(i),watchFiles:[i]}));if(r.release){e.onResolve({filter:/^@buoy-gg\/angular\/register$/},()=>({path:"register",namespace:"buoy-release-hook"}));e.onLoad({filter:/.*/,namespace:"buoy-release-hook"},()=>({contents:"import { registerBrowserNetwork } from '@buoy-gg/core/web/register-network'; registerBrowserNetwork({enableInRelease:true});",loader:"js",resolveDir:o}))}e.onResolve({filter:/^#buoy-angular-auto$/},()=>({path:"auto",namespace:"buoy-angular-auto"}));e.onLoad({filter:/.*/,namespace:"buoy-angular-auto"},()=>({contents:k(o,t,r),loader:"js",resolveDir:o}));e.onResolve({filter:/^crypto$/},a=>a.importer.includes("/tweetnacl/")?{path:"crypto",namespace:"buoy-browser-empty"}:void 0);e.onLoad({filter:/.*/,namespace:"buoy-browser-empty"},()=>({contents:"export default {};",loader:"js"}));e.onResolve({filter:/^@buoy-gg\/core\/web\/installed-tools$/},()=>({path:installedToolsId,namespace:"buoy-angular"}));e.onLoad({filter:/.*/,namespace:"buoy-angular"},()=>({contents:O(t),loader:"js",resolveDir:o}))}}}}export function buildOptions(o,r=""){const{buoy:t,buoyRelease:n=false,...e}=o;const l=t?.release??n;const s=typeof e.optimization==="object"?e.optimization.scripts!==false:e.optimization!==false;const i=!l&&(s||r.split(",").includes("production"));const a=typeof e.polyfills==="string"?[e.polyfills]:e.polyfills??[];return{disabled:i,options:{...e,...!i?{polyfills:[...new Set(["@buoy-gg/angular/register",...a])]}:{}}}}export function watchTools(o,r){let t=o;while(!v(c(t,"package.json"))&&t!==f(t))t=f(t);const n=c(t,"package.json");const e=()=>{try{const a=JSON.parse(g(n,"utf8"));return JSON.stringify(Object.entries({...a.dependencies,...a.devDependencies}).filter(([u])=>u.startsWith("@buoy-gg/")).sort())}catch{return""}};const l=e();let s=false;const i=()=>{if(!s&&e()!==l){s=true;r.info("[Buoy] Tools changed. Restart ng serve to load the new list.")}};R(n,{persistent:false,interval:1e3},i);return()=>S(n,i)}export function hiddenDependencies(o,r){const t=d(c(o,"package.json"));const n=new Set;const e=new Set;function l(s,i){let a;try{a=i.resolve(s+"/package.json")}catch{try{let p=f(i.resolve(s));while(p!==f(p)){const b=c(p,"package.json");if(v(b)&&JSON.parse(g(b,"utf8")).name===s){a=b;break}p=f(p)}}catch{return}}if(!a||n.has(a))return;n.add(a);let u=o;let m=false;while(u!==f(u)){if(v(c(u,"node_modules",s))){m=true;break}u=f(u)}if(!m)e.add(s);const h=JSON.parse(g(a,"utf8"));const y=d(a);for(const p of Object.keys(h.dependencies??{}))l(p,y)}for(const s of r)l(s,t);return[...e]}export function prebundleOptions(o,r,t){if(o===false)return false;return{...typeof o==="object"?o:{},exclude:[...new Set([...o?.exclude??[],"@buoy-gg","@buoy-gg/angular","@buoy-gg/core",installedToolsId,...r.map(n=>n.id),...t?hiddenDependencies(t,["@buoy-gg/angular","@buoy-gg/core",...r.map(n=>n.id)]):[]])]}}export function warnReactVersions(o,r){const t=d(c(o,"package.json"));let n;try{n=d(t.resolve("@buoy-gg/angular/package.json"))}catch{n=t}try{const e=n.resolve("react-dom/package.json");const l=JSON.parse(g(e,"utf8")).version;const s=JSON.parse(g(d(e).resolve("react/package.json"),"utf8")).version;if(s!==l)r.warn(`[Buoy] React ${s} and React DOM ${l} do not match. Buoy may fail to load. Use the same version for both.`);return{react:s,reactDom:l}}catch{return void 0}}
@@ -0,0 +1 @@
1
+ const{createRequire}=require("node:module");const{join,resolve,dirname}=require("node:path");function architect(){const e=createRequire(join(process.cwd(),"package.json"));return createRequire(e.resolve("@angular/build"))("@angular-devkit/architect")}async function application(e,t=e.target){const r=t?.project?await e.getProjectMetadata(t.project):{};const o=resolve(e.workspaceRoot,String(r.root||"."));const n=createRequire(join(o,"package.json"));return{root:o,sourceRoot:resolve(e.workspaceRoot,String(r.sourceRoot||join(r.root||"","src"))),api:n("@angular/build")}}function withoutUndefined(e){if(Array.isArray(e))return e.map(withoutUndefined);if(e&&typeof e==="object")return Object.fromEntries(Object.entries(e).filter(([,t])=>t!==void 0).map(([t,r])=>[t,withoutUndefined(r)]));return e}function schemaOptions(e,t,r){const o=createRequire(join(e,"package.json"));const{readFileSync:n}=require("node:fs");const c=dirname(o.resolve("@angular/build/package.json"));const i=JSON.parse(n(join(c,"builders.json"),"utf8"));const u=JSON.parse(n(join(c,i.builders[t].schema),"utf8"));return Object.fromEntries(Object.entries(withoutUndefined(r)).filter(([s,a])=>{if(s in u.properties)return true;if(a==null||typeof a==="object"&&Object.keys(a).length===0)return false;throw new Error(`This Angular CLI does not support ${s}.`)}))}module.exports={architect,application,schemaOptions};
@@ -0,0 +1 @@
1
+ import{makeEnvironmentProviders as e}from"@angular/core";function n(o,r){return()=>{}}export{n as connectBuoyHighlights};
@@ -0,0 +1 @@
1
+ import{makeEnvironmentProviders as r}from"@angular/core";function o(e={}){return r([])}export{o as provideBuoy};
@@ -0,0 +1 @@
1
+ import{makeEnvironmentProviders as n}from"@angular/core";function e(){return n([])}function r(o){return{connect:()=>({init(){},send(){},subscribe:()=>()=>{},unsubscribe(){}}),send(){},destroy(){}}}export{r as createBuoyNgRxExtension,e as provideBuoyNgRx};
@@ -0,0 +1 @@
1
+ import{makeEnvironmentProviders as n}from"@angular/core";function t(){return n([])}function i(s,u,a){return{handle:(r,o,e)=>e(r,o),destroy(){}}}export{i as createBuoyNgxsPlugin,t as provideBuoyNgxs};
@@ -0,0 +1 @@
1
+ import{makeEnvironmentProviders as t}from"@angular/core";function r(e={}){return false}export{r as registerBrowserNetwork};
@@ -0,0 +1 @@
1
+ import{makeEnvironmentProviders as u}from"@angular/core";function t(n,o=""){return[]}function e(n,o=r=>r()){return()=>{}}export{t as angularRoutePaths,e as connectBuoyRouter};
@@ -0,0 +1,16 @@
1
+ import { type EnvironmentProviders } from '@angular/core';
2
+ import type { BuoyOptions } from './index';
3
+ /** The buoy-disabled build condition removes all runtime loaders. */
4
+ export declare function provideBuoy(_options?: BuoyOptions | (() => BuoyOptions)): EnvironmentProviders;
5
+ /** Keep the early entry inert when the build has disabled Buoy. */
6
+ export declare function registerBrowserNetwork(_options?: {
7
+ enableInRelease?: boolean;
8
+ }): boolean;
9
+ export declare function provideBuoyNgRx(): EnvironmentProviders;
10
+ /** No profiler hook or loader is kept in the disabled build. */
11
+ export declare function connectBuoyHighlights(_controller: import('./highlights').BuoyHighlightController, _runOutsideAngular: (fn: () => void) => void): () => void;
12
+ export declare function provideBuoyNgxs(): EnvironmentProviders;
13
+ export declare function createBuoyNgRxExtension(_load: Parameters<typeof import('./ngrx').createBuoyNgRxExtension>[0]): ReturnType<typeof import('./ngrx').createBuoyNgRxExtension>;
14
+ export declare function createBuoyNgxsPlugin(_getStore: Parameters<typeof import('./ngxs').createBuoyNgxsPlugin>[0], _load: Parameters<typeof import('./ngxs').createBuoyNgxsPlugin>[1], _runInAngular: Parameters<typeof import('./ngxs').createBuoyNgxsPlugin>[2]): ReturnType<typeof import('./ngxs').createBuoyNgxsPlugin>;
15
+ export declare function angularRoutePaths(_routes: Parameters<typeof import('./router').angularRoutePaths>[0], _parent?: string): string[];
16
+ export declare function connectBuoyRouter(_router: Parameters<typeof import('./router').connectBuoyRouter>[0], _runInAngular?: (fn: () => void) => void): () => void;
@@ -0,0 +1 @@
1
+ import{makeEnvironmentProviders as r}from"@angular/core";function i(n={}){return r([])}function c(n={}){return false}function a(){return r([])}function f(n,e){return()=>{}}function d(){return r([])}function g(n){return{connect:()=>({init(){},send(){},subscribe:()=>()=>{},unsubscribe(){}}),send(){},destroy(){}}}function y(n,e,t){return{handle:(o,u,s)=>s(o,u),destroy(){}}}function B(n,e=""){return[]}function x(n,e=t=>t()){return()=>{}}export{B as angularRoutePaths,f as connectBuoyHighlights,x as connectBuoyRouter,g as createBuoyNgRxExtension,y as createBuoyNgxsPlugin,i as provideBuoy,a as provideBuoyNgRx,d as provideBuoyNgxs,c as registerBrowserNetwork};
@@ -0,0 +1,14 @@
1
+ export interface AngularRenderBatch {
2
+ host: HTMLElement;
3
+ name: string;
4
+ count: number;
5
+ }
6
+ export interface BuoyHighlightController {
7
+ isEnabled(): boolean;
8
+ connectRenderSource(available: boolean): {
9
+ recordRenders(renders: AngularRenderBatch[]): void;
10
+ disconnect(): void;
11
+ };
12
+ }
13
+ /** Call in the dev loader. Pass NgZone.runOutsideAngular and keep the cleanup. */
14
+ export declare function connectBuoyHighlights(controller: BuoyHighlightController, runOutsideAngular: (fn: () => void) => void): () => void;
@@ -0,0 +1 @@
1
+ import{VERSION as l}from"@angular/core";var a=new WeakMap;function h(o,c){if(!(typeof ngDevMode>"u"||ngDevMode))return()=>{};let e=a.get(o);if(!e){let t=globalThis.ng,m=Number(l.major)>=20&&Number(l.major)<23&&!l.full.includes("-")&&typeof t?.\u0275setProfiler=="function"&&typeof t.getHostElement=="function"&&typeof t.getComponent=="function",d=o.connectRenderSource(m),r=new Map,s,u=false,p=m?t.\u0275setProfiler((v,i)=>{if(!(u||v!==3||!i||!o.isEnabled()))try{let n=t.getHostElement(i);if(!n?.isConnected||t.getComponent(n)!==i)return;let g=r.get(n);g?g.count++:r.set(n,{host:n,name:i.constructor.name.replace(/^_+/,"")||n.tagName.toLowerCase(),count:1}),s===void 0&&c(()=>{s=requestAnimationFrame(()=>{s=void 0;let y=Array.from(r.values());r.clear(),u||d.recordRenders(y)})})}catch{}}):void 0;e={users:0,stop:()=>{u=true,p?.(),s!==void 0&&cancelAnimationFrame(s),r.clear(),c(()=>d.disconnect())}},a.set(o,e)}e.users++;let f=false;return()=>{f||(f=true,--e.users===0&&(e.stop(),a.delete(o)))}}export{h as connectBuoyHighlights};
package/lib/index.d.ts ADDED
@@ -0,0 +1,18 @@
1
+ import { type EnvironmentProviders } from '@angular/core';
2
+ import type { MountBuoyOptions } from '@buoy-gg/core/web';
3
+ export interface BuoyOptions extends Omit<MountBuoyOptions, 'modules'> {
4
+ /** Start in a release build as well. App access rules still apply. */
5
+ enableInRelease?: boolean;
6
+ /** Load the tool modules after the first browser render. */
7
+ modules?: NonNullable<MountBuoyOptions['modules']> | (() => Promise<NonNullable<MountBuoyOptions['modules']>>);
8
+ /** Each app link replaces the default for that tool. Return its stop function. */
9
+ links?: Record<string, () => (() => void) | Promise<() => void>>;
10
+ /** Load app settings and tools together. */
11
+ load?: () => Promise<MountBuoyOptions>;
12
+ /** Remove any app hooks installed by the loader. */
13
+ onDestroy?: () => void;
14
+ /** Called once Buoy is mounted. The stop function is safe to call twice. */
15
+ onMount?: (stop: () => void) => void;
16
+ }
17
+ /** The factory can inject app services. Buoy starts after the first render. */
18
+ export declare function provideBuoy(options?: BuoyOptions | (() => BuoyOptions)): EnvironmentProviders;
package/lib/index.mjs ADDED
@@ -0,0 +1 @@
1
+ import{captureBuoyLinks as R,wrapBuoyInitializer as P}from"#buoy-angular-auto";import{isPlatformBrowser as D}from"@angular/common";import{afterNextRender as b,DestroyRef as j,ErrorHandler as x,inject as a,Injector as z,NgZone as E,PLATFORM_ID as h,provideAppInitializer as L}from"@angular/core";function N(u){let p=new WeakMap,y=()=>{let n=a(z),e=p.get(n);return e||(e=D(a(h))?(typeof u=="function"?u():u)??{}:{},p.set(n,e)),e};return P(L(()=>{if(!D(a(h)))return;let n=y(),e=n.modules===void 0?R():{},m={...e,...n},I={...e.links,...n.links},c=[];if(!(typeof ngDevMode>"u"||ngDevMode)&&!m.enableInRelease)return;let r=a(E),k=a(x),l=false,s,d=false,g=false,v=false,i=()=>{!d||v||(v=true,r.runOutsideAngular(()=>{try{n.onDestroy?.()}finally{try{for(let o of c.splice(0).reverse())o()}finally{e.onDestroy?.()}}}))},A=()=>{let o=s;s=void 0,o?.()};a(j).onDestroy(()=>{l=true,r.runOutsideAngular(()=>{A(),i()})}),b(()=>{l||r.runOutsideAngular(()=>{let{modules:o,load:O,links:W,onDestroy:_,onMount:B,enableInRelease:C,...w}=m,M=Promise.resolve().then(()=>r.runOutsideAngular(async()=>{if(o!==void 0)return O?O():{...w,modules:typeof o=="function"?await o():o};let t={...e.load?await e.load():{},...w,...await r.runOutsideAngular(()=>n.load?.())};for(let f of Object.values(I))c.push(await r.runOutsideAngular(f));return t})).then(t=>(d=true,(l||g)&&i(),t),t=>{throw d=true,i(),t});Promise.all([import("@buoy-gg/core/web"),M]).then(([{mountBuoy:t},f])=>r.runOutsideAngular(()=>{l||(s=t(f),B?.(s))})).catch(t=>{g=true,r.runOutsideAngular(()=>{A(),i()}),r.run(()=>k.handleError(t))})})})}),y,typeof u!="function"&&u?.modules!==void 0)}export{N as provideBuoy};
package/lib/ngrx.d.ts ADDED
@@ -0,0 +1,44 @@
1
+ import { type EnvironmentProviders } from '@angular/core';
2
+ type Action = Record<string, unknown> & {
3
+ type: string;
4
+ };
5
+ type Message = {
6
+ type: string;
7
+ payload?: unknown;
8
+ };
9
+ type LiftedState = {
10
+ computedStates: {
11
+ state: unknown;
12
+ }[];
13
+ currentStateIndex: number;
14
+ stagedActionIds: number[];
15
+ actionsById: Record<number, {
16
+ action: Action;
17
+ }>;
18
+ };
19
+ export interface NgRxBuoySink {
20
+ reduxActionStore: {
21
+ addAction(action: Record<string, unknown>, before: unknown, after: unknown): void;
22
+ };
23
+ connectReduxAdapter(store: {
24
+ getState(): unknown;
25
+ dispatch(action: Action): unknown;
26
+ }): () => void;
27
+ }
28
+ /** A private DevTools connection. It never reads or writes the browser global. */
29
+ export declare function createBuoyNgRxExtension(load: () => Promise<NgRxBuoySink>): {
30
+ connect(): {
31
+ init(): void;
32
+ send(action: {
33
+ action?: Action;
34
+ type: string;
35
+ }, state: unknown): void;
36
+ subscribe(listener: (message: Message) => void): () => void;
37
+ unsubscribe(): void;
38
+ };
39
+ send(action: null, state: LiftedState): void;
40
+ destroy(): void;
41
+ };
42
+ /** Put after provideStoreDevtools. NgRx receives Buoy through DI only. */
43
+ export declare function provideBuoyNgRx(): EnvironmentProviders;
44
+ export {};
package/lib/ngrx.mjs ADDED
@@ -0,0 +1 @@
1
+ import{inject as m,DestroyRef as g,isDevMode as A,makeEnvironmentProviders as b,PLATFORM_ID as I}from"@angular/core";import{isPlatformBrowser as T}from"@angular/common";import{REDUX_DEVTOOLS_EXTENSION as h}from"@ngrx/store-devtools";function S(r){let a=new Set,u=new WeakSet,n=[],c,s,l,i=false,f=e=>{for(let t of a)t(e)},x={getState:()=>c,dispatch(e){if(e.type==="@@buoy/JUMP_TO_STATE"){let t=e.payload;f({type:"DISPATCH",payload:{type:"IMPORT_STATE",nextLiftedState:{monitorState:null,actionsById:{0:{action:{type:"@ngrx/store/init"},timestamp:Date.now()}},nextActionId:1,stagedActionIds:[0],skippedActionIds:[],committedState:t,currentStateIndex:0,computedStates:[{state:t}],isLocked:false,isPaused:false}}})}else f({type:"ACTION",payload:e});return e}},p=(e,t,o)=>{if(i||u.has(e))return;u.add(e);let d=e.action??e;s?s.reduxActionStore.addAction(d,t,o):(n.push({action:d,before:t,after:o}),n.length>500&&n.shift())};r().then(e=>{if(!i){s=e,l=s.connectReduxAdapter(x);for(let t of n)s.reduxActionStore.addAction(t.action,t.before,t.after);n.length=0}}).catch(e=>{console.error("[Buoy] NgRx tools did not load.",e)});let y=()=>{a.clear()};return{connect:()=>({init(){},send(e,t){p(e,c,t),c=t},subscribe(e){return a.add(e),queueMicrotask(()=>{!i&&a.has(e)&&e({type:"START"})}),()=>a.delete(e)},unsubscribe:y}),send(e,t){for(let o=0;o<t.stagedActionIds.length;o++){let d=t.actionsById[t.stagedActionIds[o]];d&&p(d,t.computedStates[o-1]?.state,t.computedStates[o]?.state)}c=t.computedStates[t.currentStateIndex]?.state},destroy(){i||(i=true,y(),l?.(),n.length=0)}}}function E(){return b([{provide:h,useExisting:Symbol.for("buoy.ngrx.manual-extension")},{provide:Symbol.for("buoy.ngrx.manual-extension"),useFactory:()=>{if(!T(m(I))||!A())return null;let r=S(()=>import("@buoy-gg/redux/web"));return Object.defineProperty(r,Symbol.for("buoy.ngrx.extension"),{value:true}),m(g).onDestroy(()=>r.destroy()),r}}])}export{S as createBuoyNgRxExtension,E as provideBuoyNgRx};
package/lib/ngxs.d.ts ADDED
@@ -0,0 +1,14 @@
1
+ import { type EnvironmentProviders } from '@angular/core';
2
+ import { type NgxsPlugin } from '@ngxs/store/plugins';
3
+ import type { NgRxBuoySink } from './ngrx';
4
+ export interface BuoyNgxsStore {
5
+ snapshot(): unknown;
6
+ reset(state: unknown): void;
7
+ dispatch(action: Record<string, unknown>): unknown;
8
+ }
9
+ /** NGXS owns the stream. Buoy observes it without swallowing errors. */
10
+ export declare function createBuoyNgxsPlugin(getStore: () => BuoyNgxsStore, load: () => Promise<NgRxBuoySink>, runInAngular: <T>(fn: () => T) => T): NgxsPlugin & {
11
+ destroy(): void;
12
+ };
13
+ /** Use one Redux-tool bridge per app: NgRx, NGXS, or a Redux store. */
14
+ export declare function provideBuoyNgxs(): EnvironmentProviders;
package/lib/ngxs.mjs ADDED
@@ -0,0 +1 @@
1
+ import{DestroyRef as g,inject as c,Injector as A,isDevMode as S,makeEnvironmentProviders as x,NgZone as N,PLATFORM_ID as P}from"@angular/core";import{isPlatformBrowser as v}from"@angular/common";import{Store as T}from"@ngxs/store";import{NGXS_PLUGINS as B,getActionTypeFromInstance as D}from"@ngxs/store/plugins";import{tap as I}from"rxjs";function m(r,s,i){let o,p,n=false,a=[],d=(t,e,u)=>{n||(o?o.reduxActionStore.addAction(t,e,u):(a.push({action:t,before:e,after:u}),a.length>500&&a.shift()))};return s().then(t=>{if(!n){o=t,p=t.connectReduxAdapter({getState:()=>r().snapshot(),dispatch:e=>i(()=>e.type==="@@buoy/JUMP_TO_STATE"?r().reset(e.payload):r().dispatch(e))});for(let e of a)d(e.action,e.before,e.after);a.length=0}}).catch(t=>console.error("[Buoy] NGXS tools did not load.",t)),{handle(t,e,u){let h={...e,type:D(e)??"Unknown action"},f=false,l=y=>{f||(f=true,d(h,t,y))};return u(t,e).pipe(I({next:l,error:()=>l(r().snapshot())}))},destroy(){n||(n=true,p?.(),a.length=0)}}}function _(){return x([{provide:B,multi:true,useFactory:()=>{if(!v(c(P))||!S())return{handle:(o,p,n)=>n(o,p)};let r=c(A),s=c(N),i=m(()=>r.get(T),()=>s.runOutsideAngular(()=>import("@buoy-gg/redux/web")),o=>s.run(o));return c(g).onDestroy(()=>i.destroy()),i}}])}export{m as createBuoyNgxsPlugin,_ as provideBuoyNgxs};
@@ -0,0 +1 @@
1
+ export { registerBrowserNetwork } from '@buoy-gg/core/web/register-network';
@@ -0,0 +1 @@
1
+ import{registerBrowserNetwork as r}from"@buoy-gg/core/web/register-network";export{r as registerBrowserNetwork};
@@ -0,0 +1,5 @@
1
+ import { type Router, type Routes } from '@angular/router';
2
+ /** Convert Angular paths to the dynamic paths the Routes tool uses. */
3
+ export declare function angularRoutePaths(routes: Routes, parent?: string): string[];
4
+ /** Read the router's public snapshots. Call the result on app teardown. */
5
+ export declare function connectBuoyRouter(router: Router, runInAngular?: (fn: () => void) => void): () => void;
package/lib/router.mjs ADDED
@@ -0,0 +1 @@
1
+ import{ActivationEnd as R,NavigationEnd as w}from"@angular/router";import{claimBrowserRouteEvents as $,registerBrowserRoutes as h,routeObserver as E}from"@buoy-gg/route-events/web";import{registerBrowserRouter as S}from"@buoy-gg/shared-ui/web/utils";function l(t,u=""){return t.flatMap(e=>{if(e.redirectTo!==void 0||e.path==="**"||e.outlet&&e.outlet!=="primary")return[];let o=`${u}/${e.path??""}`.replace(/\/+/g,"/"),i=o.replace(/:([^/]+)/g,"[$1]");return[...e.component||e.loadComponent?[i]:[],...l(e.children??[],o)]})}function k(t,u=e=>e()){let e=$(),o=h(l(t.config)),i=new Set(l(t.config)),y=S({push:r=>u(()=>{t.navigateByUrl(r)}),replace:r=>u(()=>{t.navigateByUrl(r,{replaceUrl:true})}),back:()=>history.back()}),d,c;function g(){let r=[],s={},n,a=t.routerState.snapshot.root;for(;a;)a.routeConfig?.path&&r.push(a.routeConfig.path),Object.assign(s,a.queryParams,a.params),n=a.title??a.data.name??n,a=a.children.find(P=>P.outlet==="primary");let p="/"+r.join("/"),m=p.replace(/:([^/]+)/g,"[$1]");i.has(m)||(i.add(m),o(),o=h([...i]));let b=t.url.split(/[?#]/)[0],f=Date.now();E.emit({pathname:b,params:s,segments:m.split("/").filter(Boolean),routeName:n??p,matchedPath:p,previousPathname:d,timestamp:f,timeSincePrevious:c===void 0?void 0:f-c}),d=b,c=f}let B=t.events.subscribe(r=>{if(r instanceof R){let s=l(t.config);if(s.some(n=>!i.has(n))){for(let n of s)i.add(n);o(),o=h([...i])}}r instanceof w&&g()});g();let v=true;return()=>{v&&(v=false,B.unsubscribe(),o(),e(),y())}}export{l as angularRoutePaths,k as connectBuoyRouter};
@@ -0,0 +1,7 @@
1
+ {
2
+ "$schema": "http://json.schemastore.org/schematics",
3
+ "schematics": {
4
+ "ng-add": {"description":"Add Buoy to this app.","factory":"./ng-add/index.cjs#ngAdd","schema":"./ng-add/schema.json"},
5
+ "setup": {"description":"Pick and set up Buoy tools.","private":true,"factory":"./ng-add/index.cjs#setup","schema":"./ng-add/setup.schema.json"}
6
+ }
7
+ }
@@ -0,0 +1,8 @@
1
+ const{createRequire}=require("node:module");const appRequire=createRequire(require("node:path").join(process.cwd(),"package.json"));const ts=appRequire("typescript");const path=require("node:path").posix;const catalog=require("./tools.json");const read=(r,e)=>{const o=ts.parseConfigFileTextToJson(e,r.readText(e));if(o.error)throw new Error(`Cannot read ${e}. Fix its JSON, then run ng add again.`);return o.config};const write=(r,e,o)=>{const c=JSON.stringify(o,null,2)+"\n";if(!r.exists(e))r.create(e,c);else if(r.readText(e)!==c)r.overwrite(e,c)};function select(r,e){const o=read(r,"/angular.json");const c=Object.keys(o.projects).filter(s=>o.projects[s].projectType==="application");const n=e.project||o.defaultProject||(c.length===1?c[0]:void 0);if(!n||!c.includes(n))throw new Error("Choose an app with --project <name>.");return{workspace:o,name:n,project:o.projects[n]}}function defaults(r){const e={...r.dependencies,...r.devDependencies};const o=["network","console","storage","events","env"];if(e["@angular/router"])o.push("route-events");if(Object.keys(e).some(c=>c.startsWith("@tanstack/angular-query-")))o.push("react-query");if(e["@ngrx/store"]||e["@ngxs/store"])o.push("redux");if(Number((e["@angular/core"]||"").match(/\d+/)?.[0])>=20)o.push("highlight-updates");return o}function ngAdd(r){return(e,o)=>{const{name:c}=select(e,r);const n=read(e,"/package.json");if(n.buoy?.angular?.[c])return e;r={...r};if(!r.tools?.length)delete r.tools;const s=o.schematic.collection.createSchematic("setup",true);s.description.schemaJson=structuredClone(s.description.schemaJson);s.description.schemaJson.properties.tools.default=defaults(n);return s.call({...r,project:c},appRequire("rxjs").of(e),o)}}function source(r,e){return ts.createSourceFile(e,r.readText(e),ts.ScriptTarget.Latest,true)}function nodes(r,e){const o=[];const c=n=>{if(e(n))o.push(n);ts.forEachChild(n,c)};c(r);return o}function importName(r,e,o,c){const n=source(r,e);for(const l of n.statements)if(ts.isImportDeclaration(l)&&l.moduleSpecifier.text===o){const i=l.importClause?.namedBindings;if(i&&ts.isNamedImports(i)){for(const u of i.elements)if((u.propertyName||u.name).text===c)return u.name.text}}const s=new Set(nodes(n,ts.isIdentifier).map(l=>l.text));let t=c;while(s.has(t))t+="Buoy";r.overwrite(e,`import { ${c}${t!==c?" as "+t:""} } from '${o}';
2
+ `+r.readText(e));return t}function providerFile(r,e){const o=new Set;const c=n=>{if(o.has(n)||!r.exists(n))return;o.add(n);const s=source(r,n);if(nodes(s,t=>ts.isCallExpression(t)&&t.expression.getText(s)==="NgModule").length||nodes(s,t=>ts.isVariableDeclaration(t)&&t.name.getText(s)==="appConfig").length||nodes(s,t=>ts.isCallExpression(t)&&t.expression.getText(s)==="bootstrapApplication"&&t.arguments[1]&&ts.isObjectLiteralExpression(t.arguments[1])).length)return n;for(const t of s.statements)if(ts.isImportDeclaration(t)&&t.moduleSpecifier.text.startsWith(".")){const l=path.join(path.dirname(n),t.moduleSpecifier.text);for(const i of[l+".ts",path.join(l,"index.ts")]){const u=c(i);if(u)return u}}};return c(e)}function providers(r,e,o,c){const n=source(r,e);let s;const t=nodes(n,a=>ts.isCallExpression(a)&&a.expression.getText(n)==="NgModule")[0];if(t)s=t.arguments[0];else s=nodes(n,a=>ts.isVariableDeclaration(a)&&a.name.getText(n)==="appConfig")[0]?.initializer;if(!s)s=nodes(n,a=>ts.isCallExpression(a)&&a.expression.getText(n)==="bootstrapApplication")[0]?.arguments[1];if(!s||!ts.isObjectLiteralExpression(s))throw new Error(`Cannot find a provider list in ${e}. Add provideBuoy() last in your app's providers.`);const l=s.properties.find(a=>a.name?.getText(n)==="providers");const i=r.readText(e);if(!l){const a=s.getEnd()-1;r.overwrite(e,i.slice(0,a)+`${s.properties.length&&!s.properties.hasTrailingComma?",":""}
3
+ providers: [${o}]
4
+ `+i.slice(a));return}if(!ts.isArrayLiteralExpression(l.initializer))throw new Error(`The providers in ${e} use a shared value. Add provideBuoy() last in that list.`);const u=l.initializer;const d=u.elements.map(a=>a.getFullText(n).trim());const y=u.elements.findIndex(a=>nodes(a,v=>ts.isCallExpression(v)&&v.expression.getText(n)===c).length>0);const g=y<0?o:d.splice(y,1)[0];d.push(g);const x=i.includes("\r\n")?"\r\n":"\n";const p=a=>(i.slice(i.lastIndexOf("\n",a-1)+1,a).match(/^[ \t]*/)||[""])[0];const m=p(l.getStart(n));const b=u.elements[0];const h=b&&i.slice(u.getStart(n),b.getStart(n)).includes("\n")?p(b.getStart(n)):"";const $=(i.match(/^[ \t]+(?=\S)/m)||[" "])[0];const j=h||m+$;const T=u.elements.hasTrailingComma||/,\s*\n\s*[}\]]/.test(i);const k="["+x+d.map(a=>j+a).join(","+x)+(T?",":"")+x+m+"]";if(i.slice(u.getStart(n),u.getEnd())!==k)r.overwrite(e,i.slice(0,u.getStart(n))+k+i.slice(u.getEnd()))}function setup(r){return(e,o)=>{const{workspace:c,name:n,project:s}=select(e,r);const t=read(e,"/package.json");const l=[...new Set(r.tools??defaults(t))];for(const p of l)if(!catalog.some(m=>m.id===p))throw new Error(`Unknown Buoy tool: ${p}.`);const i=s.architect||s.targets;if(!i?.build)throw new Error("This app has no build target. Add Buoy by hand.");const u=["@angular/build:application","@buoy-gg/angular:application"].includes(i.build.builder)&&(!i.serve||["@angular/build:dev-server","@buoy-gg/angular:dev-server"].includes(i.serve.builder));const d=s.sourceRoot||path.join(s.root||"","src");const y=i.build.options?.browser||i.build.options?.main||path.join(d,"main.ts");const g=providerFile(e,y)||[path.join(d,"app/app.config.ts"),path.join(d,"app/app.module.ts"),path.join(d,"app/app-module.ts")].find(p=>e.exists(p));if(!g)throw new Error("Cannot find the app entry. Add provideBuoy() last in its providers.");const x=importName(e,g,"@buoy-gg/angular","provideBuoy");if(u){i.build.builder="@buoy-gg/angular:application";if(i.serve)i.serve.builder="@buoy-gg/angular:dev-server";providers(e,g,`${x}()`,x)}else{o.logger.warn(`[Buoy] Kept ${i.build.builder}. It is not an @angular/build builder. Added the manual setup instead.`);const p=path.join(d,"buoy.ts");const m=l.map((f,E)=>`'${f==="notifications"?"push-notifications":f}': await import('@buoy-gg/${f}/web')`).join(",\n ");const b=path.join(d,"environments/buoy.ts");if(!e.exists(b))e.create(b,"export const BUOY_KEY = '';\n");if(!e.exists(p))e.create(p,`import { BUOY_KEY } from './environments/buoy';
5
+ export const buoyOptions = { licenseKey: BUOY_KEY, modules: async () => ({
6
+ ${m}
7
+ }) };
8
+ `);let h=path.relative(path.dirname(g),p).replace(/\.ts$/,"");if(!h.startsWith("."))h="./"+h;const $=importName(e,g,h,"buoyOptions");let j=e.readText(g);if(!/declare\s+const\s+ngDevMode/.test(j))e.overwrite(g,"declare const ngDevMode: boolean | undefined;\n"+j);providers(e,g,`(typeof ngDevMode === 'undefined' || ngDevMode) ? ${x}(${$}) : []`,x);const T=e.readText(y);if(!T.includes("'@buoy-gg/angular/register'"))e.overwrite(y,"import '@buoy-gg/angular/register';\n"+T);const k=Number(({...t.dependencies,...t.devDependencies}["@angular/core"]||"").match(/\d+/)?.[0]);const a=(i.build.configurations??={}).production??={};const v=path.join(d,"buoy.prod.ts");if(!e.exists(v))e.create(v,"export const buoyOptions = {};\n");a.fileReplacements=[...(a.fileReplacements||[]).filter(f=>f.replace!==p),{replace:p,with:v}];if(k>=20&&!i.build.builder.endsWith(":browser"))a.conditions=[...new Set(["buoy-disabled",...a.conditions||["module","production"]])];else{const f=path.join(d,"buoy-entry.ts"),E=path.join(d,"buoy-entry.prod.ts");if(!e.exists(f))e.create(f,"import '@buoy-gg/angular/register';\nexport { provideBuoy } from '@buoy-gg/angular';\nexport { buoyOptions } from './buoy';\n");if(!e.exists(E))e.create(E,"import { makeEnvironmentProviders } from '@angular/core';\nexport const provideBuoy = (_options?: unknown) => makeEnvironmentProviders([]);\nexport const buoyOptions = {};\n");let w=path.relative(path.dirname(g),f).replace(/\.ts$/,"");if(!w.startsWith("."))w="./"+w;e.overwrite(g,e.readText(g).replace(/from '@buoy-gg\/angular'/,`from '${w}'`).replace(`from '${h}'`,`from '${w}'`));e.overwrite(y,e.readText(y).replace("import '@buoy-gg/angular/register';\n",""));a.fileReplacements=[...(a.fileReplacements||[]).filter(S=>S.replace!==f),{replace:f,with:E}]}}t.devDependencies??={};for(const p of["core",...l]){const m=catalog.find(h=>h.id===p);const b="@buoy-gg/"+p;if(!t.dependencies?.[b]&&!t.devDependencies[b])t.devDependencies[b]="^"+m.version}if(l.includes("react-query")&&!t.dependencies?.["@tanstack/react-query"]&&!t.devDependencies["@tanstack/react-query"]){const p=Object.entries({...t.dependencies,...t.devDependencies}).find(([m])=>m.startsWith("@tanstack/angular-query-"));t.devDependencies["@tanstack/react-query"]=p?.[1]||"^5.0.0"}t.buoy??={};t.buoy.angular??={};t.buoy.angular[n]={tools:l};write(e,"/angular.json",c);write(e,"/package.json",t);if(!r.skipInstall)o.addTask(new(createRequire(appRequire.resolve("@angular/cli/package.json"))("@angular-devkit/schematics/tasks")).NodePackageInstallTask);o.logger.info("[Buoy] Run npx buoy login to sign in.");return e}}module.exports={ngAdd,setup,defaults};
@@ -0,0 +1 @@
1
+ {"$schema":"http://json-schema.org/draft-07/schema","type":"object","additionalProperties":false,"properties":{"project":{"type":"string","description":"The app to set up."},"tools":{"type":"array","items":{"type":"string"}},"skipInstall":{"type":"boolean","default":false,"description":"Write files but do not install tools."}}}