@venizia/ardor 0.4.3 → 0.4.5

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 (44) hide show
  1. package/LICENSE.md +1 -7
  2. package/README.md +13 -0
  3. package/dist/presets/app/files/.configs/builders/vite.config.mts +3 -0
  4. package/dist/presets/app/files/src/application.test.ts +1 -1
  5. package/dist/presets/app/files/src/boot.test.ts +15 -0
  6. package/dist/presets/app/preset.json +9 -9
  7. package/dist/presets/lib/preset.json +3 -3
  8. package/dist/testing.d.ts +37 -0
  9. package/dist/testing.d.ts.map +1 -0
  10. package/dist/testing.js +69 -0
  11. package/dist/testing.js.map +1 -0
  12. package/dist/vite/common/constants.d.ts +10 -0
  13. package/dist/vite/common/constants.d.ts.map +1 -0
  14. package/dist/vite/common/constants.js +12 -0
  15. package/dist/vite/common/constants.js.map +1 -0
  16. package/dist/vite/common/index.d.ts +3 -0
  17. package/dist/vite/common/index.d.ts.map +1 -0
  18. package/dist/vite/common/index.js +3 -0
  19. package/dist/vite/common/index.js.map +1 -0
  20. package/dist/vite/common/types.d.ts +47 -0
  21. package/dist/vite/common/types.d.ts.map +1 -0
  22. package/dist/vite/common/types.js +2 -0
  23. package/dist/vite/common/types.js.map +1 -0
  24. package/dist/vite/index.d.ts +3 -0
  25. package/dist/vite/index.d.ts.map +1 -0
  26. package/dist/vite/index.js +3 -0
  27. package/dist/vite/index.js.map +1 -0
  28. package/dist/vite/plugin.d.ts +21 -0
  29. package/dist/vite/plugin.d.ts.map +1 -0
  30. package/dist/vite/plugin.js +108 -0
  31. package/dist/vite/plugin.js.map +1 -0
  32. package/dist/vite/quiet-logger.d.ts +3 -0
  33. package/dist/vite/quiet-logger.d.ts.map +1 -0
  34. package/dist/vite/quiet-logger.js +36 -0
  35. package/dist/vite/quiet-logger.js.map +1 -0
  36. package/dist/vite/resolver.d.ts +25 -0
  37. package/dist/vite/resolver.d.ts.map +1 -0
  38. package/dist/vite/resolver.js +62 -0
  39. package/dist/vite/resolver.js.map +1 -0
  40. package/dist/vite/sources.d.ts +22 -0
  41. package/dist/vite/sources.d.ts.map +1 -0
  42. package/dist/vite/sources.js +127 -0
  43. package/dist/vite/sources.js.map +1 -0
  44. package/package.json +51 -9
package/LICENSE.md CHANGED
@@ -5,7 +5,7 @@ ARDOR is a TypeScript frontend application framework built on [IGNIS](https://ig
5
5
 
6
6
  ## MIT License
7
7
 
8
- Copyright (c) 2025 VENIZIA Ltd. Co.
8
+ Copyright (c) 2025 Venizia Co., Ltd.
9
9
 
10
10
  Permission is hereby granted, free of charge, to any person obtaining a copy
11
11
  of this software and associated documentation files (the "Software"), to deal
@@ -62,8 +62,6 @@ these projects.
62
62
  | [React Redux](https://github.com/reduxjs/react-redux) | MIT | React bindings for Redux |
63
63
  | [TanStack Query](https://github.com/TanStack/query) | MIT | Asynchronous state management |
64
64
  | [React Router](https://github.com/remix-run/react-router) | MIT | Routing |
65
- | [Axios](https://github.com/axios/axios) | MIT | HTTP client |
66
- | [Socket.IO Client](https://github.com/socketio/socket.io) | MIT | Real-time bidirectional communication |
67
65
  | [Lodash](https://github.com/lodash/lodash) | MIT | Utility library |
68
66
  | [node-polyglot](https://github.com/airbnb/polyglot.js) (`ra-i18n-polyglot`) | BSD-2-Clause | Internationalisation |
69
67
 
@@ -72,9 +70,6 @@ these projects.
72
70
  | Library | License | Description |
73
71
  |---------|---------|-------------|
74
72
  | [Tailwind CSS](https://github.com/tailwindlabs/tailwindcss) | MIT | Utility-first CSS framework |
75
- | [Radix UI](https://github.com/radix-ui/primitives) | MIT | Unstyled, accessible component primitives |
76
- | [Lucide](https://github.com/lucide-icons/lucide) | ISC | Icon set |
77
- | [Day.js](https://github.com/iamkun/dayjs) | MIT | Date manipulation library |
78
73
 
79
74
  ---
80
75
 
@@ -84,7 +79,6 @@ ARDOR is inspired by and built upon the work of many open-source projects:
84
79
 
85
80
  - **[IGNIS](https://ignis.venizia.ai)** - The backend framework ARDOR is the frontend sibling of
86
81
  - **[react-admin](https://marmelab.com/react-admin/)** by Marmelab - The admin framework ARDOR adapts
87
- - **[LoopBack 4](https://loopback.io/)** by IBM/StrongLoop - Inspiration for the binding-key and provider patterns
88
82
  - **[shadcn/ui](https://ui.shadcn.com/)** - Inspiration and source for the UI kit component layer
89
83
 
90
84
  We thank all the maintainers and contributors of these projects for their excellent work.
package/README.md CHANGED
@@ -101,3 +101,16 @@ the move is four mechanical edits plus four symbol renames.
101
101
  ## License
102
102
 
103
103
  MIT - see [LICENSE.md](./LICENSE.md).
104
+
105
+ ---
106
+
107
+ <p align="center">
108
+ <a href="https://venizia.ai">
109
+ <picture>
110
+ <source media="(prefers-color-scheme: dark)" srcset="https://venizia.ai/assets/logo-white.svg">
111
+ <img src="https://venizia.ai/assets/logo.svg" alt="VENIZIA" height="28">
112
+ </picture>
113
+ </a>
114
+ <br>
115
+ <sub>ARDOR is built and maintained by <a href="https://venizia.ai">VENIZIA</a>.</sub>
116
+ </p>
@@ -27,6 +27,9 @@ export default defineConfig(({ mode }) => {
27
27
  emptyOutDir: true,
28
28
  rolldownOptions: {
29
29
  output: {
30
+ // Runs each module after the modules it imports: a split chunk can otherwise run a DI package
31
+ // before reflect-metadata (vitejs/vite#21866). It costs about 3% of the gzip size; keep it on.
32
+ strictExecutionOrder: true,
30
33
  // React, react-admin and the router weigh about 500 KB before any application code. Two
31
34
  // vendor chunks keep the application's own chunk small, cacheable across a deploy, and
32
35
  // under Vite's 500 KB warning.
@@ -12,7 +12,7 @@ import {
12
12
 
13
13
  import { AdminConfiguration } from '#src/configurations/admin.configuration';
14
14
 
15
- // The class list is given by hand: the one `application.ts` uses is built by Vite, not by Bun.
15
+ // The class list is given by hand, so this test names exactly what it binds; boot.test.ts boots the real Application.
16
16
  class TestApplication extends BaseArdorApplication {
17
17
  getAppInfo(): IApplicationInfo {
18
18
  return { name: 'test', version: '0.0.0', description: 'A test of the container' };
@@ -0,0 +1,15 @@
1
+ import 'reflect-metadata';
2
+
3
+ import { describe, test } from 'bun:test';
4
+
5
+ import { assertArdorApplicationBoots } from '@venizia/ardor/testing';
6
+
7
+ import { Application } from '#src/application';
8
+
9
+ // Fails the way opening the app would: a service whose injection nobody registered, a missing
10
+ // provider, a lazy locale that cannot load. No browser and no request: `fetch` is blocked for the run.
11
+ describe('Application', () => {
12
+ test('boots', async () => {
13
+ await assertArdorApplicationBoots(() => new Application());
14
+ });
15
+ });
@@ -13,12 +13,12 @@
13
13
  "dependencies": {
14
14
  "@reduxjs/toolkit": "^2.13.0",
15
15
  "@tanstack/react-query": "^5.104.5",
16
- "@venizia/ardor": "0.4.3",
17
- "@venizia/ignis-connectors": "0.4.3",
18
- "@venizia/ignis-filter": "0.4.3",
19
- "@venizia/ignis-helpers": "0.4.3",
20
- "@venizia/ignis-inversion": "0.4.3",
21
- "@venizia/ignis-kernel": "0.4.3",
16
+ "@venizia/ardor": "0.4.5",
17
+ "@venizia/ignis-connectors": "0.4.5",
18
+ "@venizia/ignis-filter": "0.4.4",
19
+ "@venizia/ignis-helpers": "0.4.5",
20
+ "@venizia/ignis-inversion": "0.4.4",
21
+ "@venizia/ignis-kernel": "0.4.5",
22
22
  "class-variance-authority": "^0.7.1",
23
23
  "clsx": "^2.1.1",
24
24
  "ra-core": "^5.15.5",
@@ -35,8 +35,8 @@
35
35
  "@types/bun": "^1.4.3",
36
36
  "@types/react": "^19",
37
37
  "@types/react-dom": "^19",
38
- "@venizia/dev-configs": "0.4.3",
39
- "@venizia/ignis-boot": "0.4.3",
38
+ "@venizia/dev-configs": "0.4.5",
39
+ "@venizia/ignis-boot": "0.4.5",
40
40
  "@vitejs/plugin-react": "^6.1.2",
41
41
  "eslint": "^10.13.0",
42
42
  "oxlint": "1.89.0",
@@ -50,7 +50,7 @@
50
50
  "@venizia/ignis-connectors": "^0.4.1",
51
51
  "@venizia/ignis-filter": "^0.4.1",
52
52
  "@venizia/ignis-helpers": "^0.4.1",
53
- "@venizia/ignis-inversion": "^0.4.1",
53
+ "@venizia/ignis-inversion": "^0.4.4",
54
54
  "@venizia/ignis-kernel": "^0.4.1"
55
55
  },
56
56
  "scripts": {
@@ -5,8 +5,8 @@
5
5
  "devDependencies": {
6
6
  "@types/bun": "^1.4.3",
7
7
  "@types/react": "^19",
8
- "@venizia/ardor": "^0.4.3",
9
- "@venizia/dev-configs": "0.4.3",
8
+ "@venizia/ardor": "^0.4.5",
9
+ "@venizia/dev-configs": "0.4.5",
10
10
  "eslint": "^10.13.0",
11
11
  "oxlint": "1.89.0",
12
12
  "oxlint-tsgolint": "7.0.2004",
@@ -17,7 +17,7 @@
17
17
  "typescript": "^6.0.3"
18
18
  },
19
19
  "peerDependencies": {
20
- "@venizia/ardor": "^0.4.3",
20
+ "@venizia/ardor": "^0.4.5",
21
21
  "react": "^19.3.1",
22
22
  "react-dom": "^19.3.1",
23
23
  "react-router-dom": "^7.18.4",
@@ -0,0 +1,37 @@
1
+ import * as inversion from '@venizia/ignis-inversion';
2
+ import { type BaseArdorApplication } from '@venizia/ardor-kernel';
3
+ /** A class (matched exactly), a class name, or a binding key; the shape the shared core takes. */
4
+ export type TBootSkip = inversion.TBindingSkip;
5
+ export interface IAssertArdorApplicationBootsOptions {
6
+ /**
7
+ * Bindings the check leaves unresolved, for the few that open a socket or read the page when
8
+ * they are built. A name that matches no binding rejects: a typo must not skip silently.
9
+ *
10
+ * It applies to the binding check only: the bindings of the five namespaces below. The provider
11
+ * step (data, auth, i18n) always builds what the application bound, and a provider key such as
12
+ * `CoreBindings.DEFAULT_AUTH_PROVIDER` is outside those namespaces, so naming it rejects as a
13
+ * skip that matched nothing. To leave a provider out, leave it unbound.
14
+ */
15
+ skipBindings?: Array<TBootSkip>;
16
+ /** The locale whose messages must load. Default: the i18n provider's initial one. */
17
+ locale?: string;
18
+ /**
19
+ * Default `false`: an application with no service, repository, datasource, component or
20
+ * configuration and no feature proves nothing (usually the artifact index was empty).
21
+ */
22
+ allowEmpty?: boolean;
23
+ }
24
+ /**
25
+ * Proves an ARDOR application boots, without a browser and without a network: it runs `start()`,
26
+ * resolves every service, repository, datasource, component and configuration the application
27
+ * bound, then resolves what opening the app resolves (the data, auth and i18n providers, the
28
+ * features, the messages of the first locale). It stops at the first failure, with the error the
29
+ * app would raise; the check over the bindings reports every failure at once and names who needs
30
+ * each missing key.
31
+ *
32
+ * `fetch` is replaced for the run by a function that rejects, so nothing leaves the process. The
33
+ * application stays started and is returned. A failed boot leaves a half-started instance, so
34
+ * build a new one (pass a factory) for each call.
35
+ */
36
+ export declare const assertArdorApplicationBoots: <Application extends BaseArdorApplication>(application: Application | (() => Application | Promise<Application>), options?: IAssertArdorApplicationBootsOptions) => Promise<Application>;
37
+ //# sourceMappingURL=testing.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"testing.d.ts","sourceRoot":"","sources":["../src/testing.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,SAAS,MAAM,0BAA0B,CAAC;AAGtD,OAAO,EAAgB,KAAK,oBAAoB,EAAE,MAAM,uBAAuB,CAAC;AAEhF,kGAAkG;AAClG,MAAM,MAAM,SAAS,GAAG,SAAS,CAAC,YAAY,CAAC;AAE/C,MAAM,WAAW,mCAAmC;IAClD;;;;;;;;OAQG;IACH,YAAY,CAAC,EAAE,KAAK,CAAC,SAAS,CAAC,CAAC;IAEhC,qFAAqF;IACrF,MAAM,CAAC,EAAE,MAAM,CAAC;IAEhB;;;OAGG;IACH,UAAU,CAAC,EAAE,OAAO,CAAC;CACtB;AAmBD;;;;;;;;;;;GAWG;AACH,eAAO,MAAM,2BAA2B,GAAU,WAAW,SAAS,oBAAoB,EACxF,aAAa,WAAW,GAAG,CAAC,MAAM,WAAW,GAAG,OAAO,CAAC,WAAW,CAAC,CAAC,EACrE,UAAS,mCAAwC,KAChD,OAAO,CAAC,WAAW,CA0DrB,CAAC"}
@@ -0,0 +1,69 @@
1
+ import * as inversion from '@venizia/ignis-inversion';
2
+ import { Features, loadFeatureMessages, resolveApplicationProviders } from '@venizia/ardor-admin';
3
+ import { CoreBindings } from '@venizia/ardor-kernel';
4
+ /** The namespaces ARDOR binds its stereotyped classes under; the check resolves each binding of them. */
5
+ const VERIFIED_NAMESPACES = [
6
+ 'services',
7
+ 'repositories',
8
+ 'datasources',
9
+ 'components',
10
+ 'configurations',
11
+ ];
12
+ const SCOPE = 'assertArdorApplicationBoots';
13
+ const bootedApplications = new WeakSet();
14
+ const fail = (message) => {
15
+ throw inversion.getError({ message: `[${SCOPE}] ${message}` });
16
+ };
17
+ /**
18
+ * Proves an ARDOR application boots, without a browser and without a network: it runs `start()`,
19
+ * resolves every service, repository, datasource, component and configuration the application
20
+ * bound, then resolves what opening the app resolves (the data, auth and i18n providers, the
21
+ * features, the messages of the first locale). It stops at the first failure, with the error the
22
+ * app would raise; the check over the bindings reports every failure at once and names who needs
23
+ * each missing key.
24
+ *
25
+ * `fetch` is replaced for the run by a function that rejects, so nothing leaves the process. The
26
+ * application stays started and is returned. A failed boot leaves a half-started instance, so
27
+ * build a new one (pass a factory) for each call.
28
+ */
29
+ export const assertArdorApplicationBoots = async (application, options = {}) => {
30
+ const { skipBindings, locale, allowEmpty = false } = options;
31
+ if (typeof inversion.assertBindingsResolve !== 'function') {
32
+ fail('The installed @venizia/ignis-inversion has no assertBindingsResolve | It arrived in 0.4.4: upgrade the peer to ^0.4.4, or this helper cannot check the bindings');
33
+ }
34
+ const target = typeof application === 'function' ? await application() : application;
35
+ if (bootedApplications.has(target) ||
36
+ target.isBound({ key: CoreBindings.APPLICATION_INSTANCE })) {
37
+ fail('This application instance was already started | A failed or finished start leaves registrations behind, so build a new instance (pass a factory) for each call');
38
+ }
39
+ bootedApplications.add(target);
40
+ const originalFetch = Reflect.get(globalThis, 'fetch');
41
+ Reflect.set(globalThis, 'fetch', () => {
42
+ return Promise.reject(inversion.getError({
43
+ message: `[${SCOPE}] A request was made during the boot check | The check never reaches the network: stub the service that sends it, or pass it in skipBindings`,
44
+ }));
45
+ });
46
+ try {
47
+ await target.start();
48
+ const verification = inversion.assertBindingsResolve({
49
+ container: target,
50
+ namespaces: VERIFIED_NAMESPACES,
51
+ skip: skipBindings,
52
+ scope: SCOPE,
53
+ });
54
+ const { i18nProvider } = resolveApplicationProviders({ container: target });
55
+ const features = Features.read({ container: target });
56
+ Features.mount({ features });
57
+ await loadFeatureMessages({ features, i18nProvider, locale });
58
+ // A skip that matched is a binding that exists: the core rejects one that matched nothing.
59
+ const hasBindings = verification.verified.length > 0 || (skipBindings?.length ?? 0) > 0;
60
+ if (!allowEmpty && !hasBindings && features.length === 0) {
61
+ fail('The application bound no service, repository, datasource, component, configuration or feature | Nothing was checked: the artifact index is probably empty. Pass { allowEmpty: true } if that is intended');
62
+ }
63
+ }
64
+ finally {
65
+ Reflect.set(globalThis, 'fetch', originalFetch);
66
+ }
67
+ return target;
68
+ };
69
+ //# sourceMappingURL=testing.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"testing.js","sourceRoot":"","sources":["../src/testing.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,10 @@
1
+ export declare const DEFAULT_BUILD_INFO_FILE_NAME = "build-info.json";
2
+ export declare const DEFAULT_FRAMEWORK_SCOPE = "@venizia/";
3
+ /** What to do when the commit is neither in the pipeline environment nor in git. */
4
+ export declare class UnresolvedPolicies {
5
+ static readonly ERROR = "error";
6
+ static readonly UNSPECIFIED = "unspecified";
7
+ static readonly SCHEME_SET: Set<string>;
8
+ static isValid(value: string): boolean;
9
+ }
10
+ //# sourceMappingURL=constants.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"constants.d.ts","sourceRoot":"","sources":["../../../src/vite/common/constants.ts"],"names":[],"mappings":"AAAA,eAAO,MAAM,4BAA4B,oBAAoB,CAAC;AAC9D,eAAO,MAAM,uBAAuB,cAAc,CAAC;AAEnD,oFAAoF;AACpF,qBAAa,kBAAkB;IAC7B,MAAM,CAAC,QAAQ,CAAC,KAAK,WAAW;IAChC,MAAM,CAAC,QAAQ,CAAC,WAAW,iBAAiB;IAE5C,MAAM,CAAC,QAAQ,CAAC,UAAU,cAA2C;IAErE,MAAM,CAAC,OAAO,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO;CAGvC"}
@@ -0,0 +1,12 @@
1
+ export const DEFAULT_BUILD_INFO_FILE_NAME = 'build-info.json';
2
+ export const DEFAULT_FRAMEWORK_SCOPE = '@venizia/';
3
+ /** What to do when the commit is neither in the pipeline environment nor in git. */
4
+ export class UnresolvedPolicies {
5
+ static { this.ERROR = 'error'; }
6
+ static { this.UNSPECIFIED = 'unspecified'; }
7
+ static { this.SCHEME_SET = new Set([this.ERROR, this.UNSPECIFIED]); }
8
+ static isValid(value) {
9
+ return this.SCHEME_SET.has(value);
10
+ }
11
+ }
12
+ //# sourceMappingURL=constants.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"constants.js","sourceRoot":"","sources":["../../../src/vite/common/constants.ts"],"names":[],"mappings":"AAAA,MAAM,CAAC,MAAM,4BAA4B,GAAG,iBAAiB,CAAC;AAC9D,MAAM,CAAC,MAAM,uBAAuB,GAAG,WAAW,CAAC;AAEnD,oFAAoF;AACpF,MAAM,OAAO,kBAAkB;aACb,UAAK,GAAG,OAAO,CAAC;aAChB,gBAAW,GAAG,aAAa,CAAC;aAE5B,eAAU,GAAG,IAAI,GAAG,CAAC,CAAC,IAAI,CAAC,KAAK,EAAE,IAAI,CAAC,WAAW,CAAC,CAAC,CAAC;IAErE,MAAM,CAAC,OAAO,CAAC,KAAa;QAC1B,OAAO,IAAI,CAAC,UAAU,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC;IACpC,CAAC"}
@@ -0,0 +1,3 @@
1
+ export * from './constants.js';
2
+ export * from './types.js';
3
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/vite/common/index.ts"],"names":[],"mappings":"AAAA,cAAc,aAAa,CAAC;AAC5B,cAAc,SAAS,CAAC"}
@@ -0,0 +1,3 @@
1
+ export * from './constants.js';
2
+ export * from './types.js';
3
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/vite/common/index.ts"],"names":[],"mappings":"AAAA,cAAc,aAAa,CAAC;AAC5B,cAAc,SAAS,CAAC"}
@@ -0,0 +1,47 @@
1
+ import type { IBuildInfoFile, TConstValue } from '@venizia/ardor-kernel';
2
+ import type { TBuildInfoRecord } from '@venizia/ignis-helpers/core';
3
+ import type { UnresolvedPolicies } from './constants.js';
4
+ export type TUnresolvedPolicy = TConstValue<typeof UnresolvedPolicies>;
5
+ export interface IBuildInfoFileOptions {
6
+ /** The app folder, where its package.json is. Default: the folder Vite runs in. */
7
+ root?: string;
8
+ /** The file's path under the output folder and under the dev server's base. Default: `build-info.json`. */
9
+ fileName?: string;
10
+ /** Dependencies whose name starts with this are listed under `frameworks`. Default: `@venizia/`. */
11
+ frameworkScope?: string;
12
+ /** What a build does when no commit can be found: `error` (default) or `unspecified`. The dev server always serves what it has and warns. */
13
+ onUnresolved?: TUnresolvedPolicy;
14
+ }
15
+ export type TGitReadResult = {
16
+ ok: true;
17
+ value: string;
18
+ } | {
19
+ ok: false;
20
+ reason: string;
21
+ };
22
+ export interface IFrameworkVersions {
23
+ versions: Record<string, string>;
24
+ /** Declared dependencies of the scope with no installed package.json: the install has not run. */
25
+ missing: string[];
26
+ /** Declared dependencies of the scope whose name is not a package name; they are never looked up. */
27
+ invalid: string[];
28
+ }
29
+ /** The effects of resolving the file; tests replace them, and the plugin passes the real ones. */
30
+ export interface IBuildInfoSources {
31
+ resolveRecord(opts: {
32
+ root: string;
33
+ }): Promise<TBuildInfoRecord>;
34
+ readGit(opts: {
35
+ root: string;
36
+ args: string[];
37
+ }): Promise<TGitReadResult>;
38
+ readFrameworkVersions(opts: {
39
+ root: string;
40
+ scope: string;
41
+ }): Promise<IFrameworkVersions>;
42
+ }
43
+ export interface IBuildInfoResolution {
44
+ info: IBuildInfoFile;
45
+ warnings: string[];
46
+ }
47
+ //# sourceMappingURL=types.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../../src/vite/common/types.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,cAAc,EAAE,WAAW,EAAE,MAAM,uBAAuB,CAAC;AACzE,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,6BAA6B,CAAC;AAEpE,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,aAAa,CAAC;AAEtD,MAAM,MAAM,iBAAiB,GAAG,WAAW,CAAC,OAAO,kBAAkB,CAAC,CAAC;AAEvE,MAAM,WAAW,qBAAqB;IACpC,mFAAmF;IACnF,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,2GAA2G;IAC3G,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,oGAAoG;IACpG,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,6IAA6I;IAC7I,YAAY,CAAC,EAAE,iBAAiB,CAAC;CAClC;AAED,MAAM,MAAM,cAAc,GAAG;IAAE,EAAE,EAAE,IAAI,CAAC;IAAC,KAAK,EAAE,MAAM,CAAA;CAAE,GAAG;IAAE,EAAE,EAAE,KAAK,CAAC;IAAC,MAAM,EAAE,MAAM,CAAA;CAAE,CAAC;AAEzF,MAAM,WAAW,kBAAkB;IACjC,QAAQ,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IACjC,kGAAkG;IAClG,OAAO,EAAE,MAAM,EAAE,CAAC;IAClB,qGAAqG;IACrG,OAAO,EAAE,MAAM,EAAE,CAAC;CACnB;AAED,kGAAkG;AAClG,MAAM,WAAW,iBAAiB;IAChC,aAAa,CAAC,IAAI,EAAE;QAAE,IAAI,EAAE,MAAM,CAAA;KAAE,GAAG,OAAO,CAAC,gBAAgB,CAAC,CAAC;IACjE,OAAO,CAAC,IAAI,EAAE;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,MAAM,EAAE,CAAA;KAAE,GAAG,OAAO,CAAC,cAAc,CAAC,CAAC;IACzE,qBAAqB,CAAC,IAAI,EAAE;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,KAAK,EAAE,MAAM,CAAA;KAAE,GAAG,OAAO,CAAC,kBAAkB,CAAC,CAAC;CAC3F;AAED,MAAM,WAAW,oBAAoB;IACnC,IAAI,EAAE,cAAc,CAAC;IACrB,QAAQ,EAAE,MAAM,EAAE,CAAC;CACpB"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=types.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.js","sourceRoot":"","sources":["../../../src/vite/common/types.ts"],"names":[],"mappings":""}
@@ -0,0 +1,3 @@
1
+ export { DEFAULT_BUILD_INFO_FILE_NAME, DEFAULT_FRAMEWORK_SCOPE, type IBuildInfoFileOptions, type TUnresolvedPolicy, UnresolvedPolicies, } from './common/index.js';
2
+ export { buildInfoFile } from './plugin.js';
3
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/vite/index.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,4BAA4B,EAC5B,uBAAuB,EACvB,KAAK,qBAAqB,EAC1B,KAAK,iBAAiB,EACtB,kBAAkB,GACnB,MAAM,UAAU,CAAC;AAClB,OAAO,EAAE,aAAa,EAAE,MAAM,UAAU,CAAC"}
@@ -0,0 +1,3 @@
1
+ export { DEFAULT_BUILD_INFO_FILE_NAME, DEFAULT_FRAMEWORK_SCOPE, UnresolvedPolicies, } from './common/index.js';
2
+ export { buildInfoFile } from './plugin.js';
3
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/vite/index.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,4BAA4B,EAC5B,uBAAuB,EAGvB,kBAAkB,GACnB,MAAM,UAAU,CAAC;AAClB,OAAO,EAAE,aAAa,EAAE,MAAM,UAAU,CAAC"}
@@ -0,0 +1,21 @@
1
+ import type { Plugin } from 'vite';
2
+ import { type IBuildInfoFileOptions, type IBuildInfoSources } from './common/index.js';
3
+ type TParsedOptions = Required<IBuildInfoFileOptions>;
4
+ export declare const parseBuildInfoFileOptions: (opts: IBuildInfoFileOptions) => TParsedOptions;
5
+ export declare const isBuildInfoRequest: (opts: {
6
+ url: string | undefined;
7
+ base: string;
8
+ fileName: string;
9
+ }) => boolean;
10
+ export declare const createBuildInfoFilePlugin: (opts: {
11
+ options: IBuildInfoFileOptions;
12
+ sources: IBuildInfoSources;
13
+ }) => Plugin;
14
+ /**
15
+ * Emits `build-info.json` into the build and serves it on the dev server: the commit, the branch and
16
+ * the build time from the pipeline or git, the app's name and version, and the installed versions of
17
+ * the framework packages it depends on. The shape is `IBuildInfoFile` of `@venizia/ardor`.
18
+ */
19
+ export declare const buildInfoFile: (opts?: IBuildInfoFileOptions) => Plugin;
20
+ export {};
21
+ //# sourceMappingURL=plugin.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"plugin.d.ts","sourceRoot":"","sources":["../../src/vite/plugin.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,MAAM,CAAC;AAEnC,OAAO,EAGL,KAAK,qBAAqB,EAC1B,KAAK,iBAAiB,EAGvB,MAAM,UAAU,CAAC;AAIlB,KAAK,cAAc,GAAG,QAAQ,CAAC,qBAAqB,CAAC,CAAC;AAItD,eAAO,MAAM,yBAAyB,GAAI,MAAM,qBAAqB,KAAG,cA4BvE,CAAC;AAEF,eAAO,MAAM,kBAAkB,GAAI,MAAM;IACvC,GAAG,EAAE,MAAM,GAAG,SAAS,CAAC;IACxB,IAAI,EAAE,MAAM,CAAC;IACb,QAAQ,EAAE,MAAM,CAAC;CAClB,KAAG,OAMH,CAAC;AAEF,eAAO,MAAM,yBAAyB,GAAI,MAAM;IAC9C,OAAO,EAAE,qBAAqB,CAAC;IAC/B,OAAO,EAAE,iBAAiB,CAAC;CAC5B,KAAG,MAwFH,CAAC;AAEF;;;;GAIG;AACH,eAAO,MAAM,aAAa,GAAI,OAAM,qBAA0B,KAAG,MACM,CAAC"}
@@ -0,0 +1,108 @@
1
+ import { getError } from '@venizia/ignis-inversion';
2
+ import { DEFAULT_BUILD_INFO_FILE_NAME, DEFAULT_FRAMEWORK_SCOPE, UnresolvedPolicies, } from './common/index.js';
3
+ import { serializeBuildInfoFile, resolveBuildInfo } from './resolver.js';
4
+ import { defaultSources } from './sources.js';
5
+ const FILE_NAME_PATTERN = /^[A-Za-z0-9._-]+(?:\/[A-Za-z0-9._-]+)*\.json$/;
6
+ export const parseBuildInfoFileOptions = (opts) => {
7
+ const { root = process.cwd(), fileName = DEFAULT_BUILD_INFO_FILE_NAME, frameworkScope = DEFAULT_FRAMEWORK_SCOPE, onUnresolved = UnresolvedPolicies.ERROR, } = opts;
8
+ // A folder outside the output folder, or one a request path could climb out of, is refused.
9
+ if (!FILE_NAME_PATTERN.test(fileName) || fileName.split('/').includes('..')) {
10
+ throw getError({
11
+ message: `[buildInfoFile] fileName '${fileName}' is not valid | Use a relative path of letters, digits, '.', '_' and '-' that ends in .json, like 'build-info.json'`,
12
+ });
13
+ }
14
+ if (frameworkScope === '') {
15
+ throw getError({
16
+ message: "[buildInfoFile] frameworkScope is empty | Use a scope like '@venizia/'",
17
+ });
18
+ }
19
+ if (!UnresolvedPolicies.isValid(onUnresolved)) {
20
+ throw getError({
21
+ message: `[buildInfoFile] onUnresolved '${onUnresolved}' is not valid | Use one of: ${[...UnresolvedPolicies.SCHEME_SET].join(', ')}`,
22
+ });
23
+ }
24
+ return { root, fileName, frameworkScope, onUnresolved };
25
+ };
26
+ export const isBuildInfoRequest = (opts) => {
27
+ if (opts.url === undefined) {
28
+ return false;
29
+ }
30
+ return opts.url.split('?')[0] === `${opts.base}${opts.fileName}`;
31
+ };
32
+ export const createBuildInfoFilePlugin = (opts) => {
33
+ const { options, sources } = opts;
34
+ const { root, fileName, frameworkScope, onUnresolved } = parseBuildInfoFileOptions(options);
35
+ let body;
36
+ // One resolution per process, so the dev server and the build both serve the same builtAt; a failed
37
+ // one is not kept, because the cause (a half-saved package.json) may be gone on the next request.
38
+ const loadBody = (load) => {
39
+ body ??= (async () => {
40
+ const { info, warnings } = await resolveBuildInfo({
41
+ root,
42
+ scope: frameworkScope,
43
+ policy: load.policy,
44
+ sources,
45
+ });
46
+ for (const warning of warnings) {
47
+ load.warn(warning);
48
+ }
49
+ return serializeBuildInfoFile({ info });
50
+ })().catch((error) => {
51
+ body = undefined;
52
+ throw error;
53
+ });
54
+ return body;
55
+ };
56
+ return {
57
+ name: 'ardor:build-info-file',
58
+ configureServer(server) {
59
+ server.middlewares.use(async (request, response, next) => {
60
+ if (!isBuildInfoRequest({ url: request.url, base: server.config.base, fileName })) {
61
+ next();
62
+ return;
63
+ }
64
+ if (request.method !== 'GET' && request.method !== 'HEAD') {
65
+ response.statusCode = 405;
66
+ response.setHeader('allow', 'GET, HEAD');
67
+ response.end();
68
+ return;
69
+ }
70
+ try {
71
+ const text = await loadBody({
72
+ warn: (message) => server.config.logger.warn(message),
73
+ policy: UnresolvedPolicies.UNSPECIFIED,
74
+ });
75
+ response.setHeader('content-type', 'application/json; charset=utf-8');
76
+ response.setHeader('content-length', Buffer.byteLength(text));
77
+ response.setHeader('cache-control', 'no-store');
78
+ response.end(request.method === 'HEAD' ? undefined : text);
79
+ }
80
+ catch (error) {
81
+ // The cause goes to the terminal of the developer; the response never carries a path or a stack.
82
+ server.config.logger.error(error instanceof Error ? error.message : String(error));
83
+ response.statusCode = 500;
84
+ response.setHeader('content-type', 'application/json; charset=utf-8');
85
+ response.setHeader('cache-control', 'no-store');
86
+ response.end(`${JSON.stringify({ error: `${fileName} is unavailable, see the dev server log` })}\n`);
87
+ }
88
+ });
89
+ },
90
+ async generateBundle() {
91
+ this.emitFile({
92
+ type: 'asset',
93
+ fileName,
94
+ source: await loadBody({
95
+ warn: (message) => this.warn(message),
96
+ policy: onUnresolved,
97
+ }),
98
+ });
99
+ },
100
+ };
101
+ };
102
+ /**
103
+ * Emits `build-info.json` into the build and serves it on the dev server: the commit, the branch and
104
+ * the build time from the pipeline or git, the app's name and version, and the installed versions of
105
+ * the framework packages it depends on. The shape is `IBuildInfoFile` of `@venizia/ardor`.
106
+ */
107
+ export const buildInfoFile = (opts = {}) => createBuildInfoFilePlugin({ options: opts, sources: defaultSources });
108
+ //# sourceMappingURL=plugin.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"plugin.js","sourceRoot":"","sources":["../../src/vite/plugin.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,3 @@
1
+ /** The default IGNIS logger needs winston, which a frontend app does not install. The provider is process-wide: it is the one of the Vite process that runs the build. */
2
+ export declare const useQuietConsoleLogger: () => void;
3
+ //# sourceMappingURL=quiet-logger.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"quiet-logger.d.ts","sourceRoot":"","sources":["../../src/vite/quiet-logger.ts"],"names":[],"mappings":"AAoCA,0KAA0K;AAC1K,eAAO,MAAM,qBAAqB,QAAO,IAIxC,CAAC"}
@@ -0,0 +1,36 @@
1
+ import { ConsoleLogger, LoggerFactory } from '@venizia/ignis-helpers';
2
+ import { LogLevels } from '@venizia/ignis-helpers/core';
3
+ /** IGNIS's resolver logs why git was unavailable at debug level; a Vite build has no use for those lines. */
4
+ class QuietDebugLogger {
5
+ constructor(inner) {
6
+ this.inner = inner;
7
+ }
8
+ debug() { }
9
+ info(message, ...args) {
10
+ this.inner.info(message, ...args);
11
+ }
12
+ warn(message, ...args) {
13
+ this.inner.warn(message, ...args);
14
+ }
15
+ error(message, ...args) {
16
+ this.inner.error(message, ...args);
17
+ }
18
+ emerg(message, ...args) {
19
+ this.inner.emerg(message, ...args);
20
+ }
21
+ log(level, message, ...args) {
22
+ if (level !== LogLevels.DEBUG) {
23
+ this.inner.log(level, message, ...args);
24
+ }
25
+ }
26
+ for(methodName) {
27
+ return new QuietDebugLogger(this.inner.for(methodName));
28
+ }
29
+ }
30
+ /** The default IGNIS logger needs winston, which a frontend app does not install. The provider is process-wide: it is the one of the Vite process that runs the build. */
31
+ export const useQuietConsoleLogger = () => {
32
+ LoggerFactory.use({
33
+ provider: { get: (scope) => new QuietDebugLogger(ConsoleLogger.get({ scope })) },
34
+ });
35
+ };
36
+ //# sourceMappingURL=quiet-logger.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"quiet-logger.js","sourceRoot":"","sources":["../../src/vite/quiet-logger.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,aAAa,EAAE,aAAa,EAAE,MAAM,wBAAwB,CAAC;AACtE,OAAO,EAAgB,SAAS,EAAkB,MAAM,6BAA6B,CAAC;AAEtF,6GAA6G;AAC7G,MAAM,gBAAgB;IACpB,YAA6B,KAAc;QAAd,UAAK,GAAL,KAAK,CAAS;IAAG,CAAC;IAE/C,KAAK,KAAU,CAAC;IAEhB,IAAI,CAAC,OAAe,EAAE,GAAG,IAAe;QACtC,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,OAAO,EAAE,GAAG,IAAI,CAAC,CAAC;IACpC,CAAC;IAED,IAAI,CAAC,OAAe,EAAE,GAAG,IAAe;QACtC,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,OAAO,EAAE,GAAG,IAAI,CAAC,CAAC;IACpC,CAAC;IAED,KAAK,CAAC,OAAe,EAAE,GAAG,IAAe;QACvC,IAAI,CAAC,KAAK,CAAC,KAAK,CAAC,OAAO,EAAE,GAAG,IAAI,CAAC,CAAC;IACrC,CAAC;IAED,KAAK,CAAC,OAAe,EAAE,GAAG,IAAe;QACvC,IAAI,CAAC,KAAK,CAAC,KAAK,CAAC,OAAO,EAAE,GAAG,IAAI,CAAC,CAAC;IACrC,CAAC;IAED,GAAG,CAAC,KAAgB,EAAE,OAAe,EAAE,GAAG,IAAe;QACvD,IAAI,KAAK,KAAK,SAAS,CAAC,KAAK,EAAE,CAAC;YAC9B,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,KAAK,EAAE,OAAO,EAAE,GAAG,IAAI,CAAC,CAAC;QAC1C,CAAC;IACH,CAAC;IAED,GAAG,CAAC,UAAkB;QACpB,OAAO,IAAI,gBAAgB,CAAC,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,UAAU,CAAC,CAAC,CAAC;IAC1D,CAAC;CACF;AAED,0KAA0K;AAC1K,MAAM,CAAC,MAAM,qBAAqB,GAAG,GAAS,EAAE;IAC9C,aAAa,CAAC,GAAG,CAAC;QAChB,QAAQ,EAAE,EAAE,GAAG,EAAE,CAAC,KAAK,EAAE,EAAE,CAAC,IAAI,gBAAgB,CAAC,aAAa,CAAC,GAAG,CAAC,EAAE,KAAK,EAAE,CAAC,CAAC,EAAE;KACjF,CAAC,CAAC;AACL,CAAC,CAAC"}
@@ -0,0 +1,25 @@
1
+ import type { IBuildInfoFile } from '@venizia/ardor-kernel';
2
+ import { type TBuildInfoRecord } from '@venizia/ignis-helpers/core';
3
+ import { type IBuildInfoResolution, type IBuildInfoSources, type TGitReadResult, type TUnresolvedPolicy } from './common/index.js';
4
+ export declare const completeFromGit: (opts: {
5
+ record: TBuildInfoRecord;
6
+ commit: TGitReadResult;
7
+ branch: TGitReadResult;
8
+ }) => TBuildInfoRecord;
9
+ /** The fields in the order the file writes them, the framework versions sorted by name. */
10
+ export declare const toBuildInfoFile: (opts: {
11
+ record: TBuildInfoRecord;
12
+ frameworks: Record<string, string>;
13
+ }) => IBuildInfoFile;
14
+ /** The same input is always the same text: the keys keep one order, and the file ends with a newline. */
15
+ export declare const serializeBuildInfoFile: (opts: {
16
+ info: IBuildInfoFile;
17
+ }) => string;
18
+ /** The stamp of IGNIS, with the commit and the branch from git when the pipeline gave none, and the framework versions. */
19
+ export declare const resolveBuildInfo: (opts: {
20
+ root: string;
21
+ scope: string;
22
+ policy: TUnresolvedPolicy;
23
+ sources: IBuildInfoSources;
24
+ }) => Promise<IBuildInfoResolution>;
25
+ //# sourceMappingURL=resolver.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"resolver.d.ts","sourceRoot":"","sources":["../../src/vite/resolver.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,uBAAuB,CAAC;AAC5D,OAAO,EAAqB,KAAK,gBAAgB,EAAE,MAAM,6BAA6B,CAAC;AAGvF,OAAO,EACL,KAAK,oBAAoB,EACzB,KAAK,iBAAiB,EACtB,KAAK,cAAc,EACnB,KAAK,iBAAiB,EAEvB,MAAM,UAAU,CAAC;AAOlB,eAAO,MAAM,eAAe,GAAI,MAAM;IACpC,MAAM,EAAE,gBAAgB,CAAC;IACzB,MAAM,EAAE,cAAc,CAAC;IACvB,MAAM,EAAE,cAAc,CAAC;CACxB,KAAG,gBAUH,CAAC;AAEF,2FAA2F;AAC3F,eAAO,MAAM,eAAe,GAAI,MAAM;IACpC,MAAM,EAAE,gBAAgB,CAAC;IACzB,UAAU,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;CACpC,KAAG,cASF,CAAC;AAEH,yGAAyG;AACzG,eAAO,MAAM,sBAAsB,GAAI,MAAM;IAAE,IAAI,EAAE,cAAc,CAAA;CAAE,KAAG,MAIvE,CAAC;AAEF,2HAA2H;AAC3H,eAAO,MAAM,gBAAgB,GAAU,MAAM;IAC3C,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,EAAE,MAAM,CAAC;IACd,MAAM,EAAE,iBAAiB,CAAC;IAC1B,OAAO,EAAE,iBAAiB,CAAC;CAC5B,KAAG,OAAO,CAAC,oBAAoB,CA0C/B,CAAC"}
@@ -0,0 +1,62 @@
1
+ import { BuildInfoRegistry } from '@venizia/ignis-helpers/core';
2
+ import { getError } from '@venizia/ignis-inversion';
3
+ import { UnresolvedPolicies, } from './common/index.js';
4
+ const COMMIT_LENGTH = 12;
5
+ // SHORTCUT: the commit and the branch are completed from git here, because the IGNIS resolver reads git
6
+ // through Bun and answers unspecified under Node; revisit when @venizia/ignis-boot reads git under Node
7
+ // (VENIZIA-AI/ignis#537), then delete this.
8
+ export const completeFromGit = (opts) => {
9
+ const { record, commit, branch } = opts;
10
+ return {
11
+ ...record,
12
+ commit: record.commit === BuildInfoRegistry.UNSPECIFIED && commit.ok ? commit.value : record.commit,
13
+ branch: record.branch === BuildInfoRegistry.UNSPECIFIED && branch.ok ? branch.value : record.branch,
14
+ };
15
+ };
16
+ /** The fields in the order the file writes them, the framework versions sorted by name. */
17
+ export const toBuildInfoFile = (opts) => ({
18
+ service: opts.record.service,
19
+ version: opts.record.version,
20
+ commit: opts.record.commit,
21
+ branch: opts.record.branch,
22
+ builtAt: opts.record.builtAt,
23
+ frameworks: Object.fromEntries(Object.entries(opts.frameworks).sort(([left], [right]) => left.localeCompare(right))),
24
+ });
25
+ /** The same input is always the same text: the keys keep one order, and the file ends with a newline. */
26
+ export const serializeBuildInfoFile = (opts) => {
27
+ const { service, version, commit, branch, builtAt, frameworks } = opts.info;
28
+ return `${JSON.stringify({ service, version, commit, branch, builtAt, frameworks }, null, 2)}\n`;
29
+ };
30
+ /** The stamp of IGNIS, with the commit and the branch from git when the pipeline gave none, and the framework versions. */
31
+ export const resolveBuildInfo = async (opts) => {
32
+ const { root, scope, policy, sources } = opts;
33
+ const warnings = [];
34
+ const stamp = await sources.resolveRecord({ root });
35
+ const [commit, branch, frameworks] = await Promise.all([
36
+ sources.readGit({ root, args: ['rev-parse', `--short=${COMMIT_LENGTH}`, 'HEAD'] }),
37
+ sources.readGit({ root, args: ['rev-parse', '--abbrev-ref', 'HEAD'] }),
38
+ sources.readFrameworkVersions({ root, scope }),
39
+ ]);
40
+ const record = completeFromGit({ record: stamp, commit, branch });
41
+ if (!commit.ok && record.commit === BuildInfoRegistry.UNSPECIFIED) {
42
+ const message = `[buildInfoFile] no commit | The pipeline gave none (APP_BUILD_COMMIT or the CI variable of your host) and ${commit.reason}. Build inside a git checkout, or set APP_BUILD_COMMIT`;
43
+ if (policy === UnresolvedPolicies.ERROR) {
44
+ throw getError({ message });
45
+ }
46
+ warnings.push(message);
47
+ }
48
+ if (!branch.ok && record.branch === BuildInfoRegistry.UNSPECIFIED) {
49
+ warnings.push(`[buildInfoFile] no branch | The pipeline gave none (APP_BUILD_BRANCH) and ${branch.reason}`);
50
+ }
51
+ for (const name of frameworks.missing) {
52
+ warnings.push(`[buildInfoFile] ${name} is a dependency with no installed package.json | Run the install`);
53
+ }
54
+ for (const name of frameworks.invalid) {
55
+ warnings.push(`[buildInfoFile] '${name}' is not a package name | It is left out of frameworks`);
56
+ }
57
+ return {
58
+ info: toBuildInfoFile({ record, frameworks: frameworks.versions }),
59
+ warnings,
60
+ };
61
+ };
62
+ //# sourceMappingURL=resolver.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"resolver.js","sourceRoot":"","sources":["../../src/vite/resolver.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,22 @@
1
+ import type { IBuildInfoSources, IFrameworkVersions, TGitReadResult } from './common/index.js';
2
+ /** `undefined` only when the file does not exist; an unreadable or malformed file is an error naming it. */
3
+ export declare const readJsonFile: (opts: {
4
+ path: string;
5
+ }) => Promise<unknown>;
6
+ /** The version of the package as Node would find it: the nearest `node_modules` upward from the app. */
7
+ export declare const findInstalledVersion: (opts: {
8
+ root: string;
9
+ name: string;
10
+ }) => Promise<string | undefined>;
11
+ /** The installed version of every dependency of the app whose name starts with the scope, by name. */
12
+ export declare const readFrameworkVersions: (opts: {
13
+ root: string;
14
+ scope: string;
15
+ }) => Promise<IFrameworkVersions>;
16
+ /** Runs git without a shell, so no argument is ever interpreted. */
17
+ export declare const readGit: (opts: {
18
+ root: string;
19
+ args: string[];
20
+ }) => Promise<TGitReadResult>;
21
+ export declare const defaultSources: IBuildInfoSources;
22
+ //# sourceMappingURL=sources.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"sources.d.ts","sourceRoot":"","sources":["../../src/vite/sources.ts"],"names":[],"mappings":"AAQA,OAAO,KAAK,EAAE,iBAAiB,EAAE,kBAAkB,EAAE,cAAc,EAAE,MAAM,UAAU,CAAC;AAoCtF,4GAA4G;AAC5G,eAAO,MAAM,YAAY,GAAU,MAAM;IAAE,IAAI,EAAE,MAAM,CAAA;CAAE,KAAG,OAAO,CAAC,OAAO,CAsB1E,CAAC;AAEF,wGAAwG;AACxG,eAAO,MAAM,oBAAoB,GAAU,MAAM;IAC/C,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;CACd,KAAG,OAAO,CAAC,MAAM,GAAG,SAAS,CAoB7B,CAAC;AAEF,sGAAsG;AACtG,eAAO,MAAM,qBAAqB,GAAU,MAAM;IAChD,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,EAAE,MAAM,CAAC;CACf,KAAG,OAAO,CAAC,kBAAkB,CAoC7B,CAAC;AAEF,oEAAoE;AACpE,eAAO,MAAM,OAAO,GAAU,MAAM;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,MAAM,EAAE,CAAA;CAAE,KAAG,OAAO,CAAC,cAAc,CAe5F,CAAC;AAEF,eAAO,MAAM,cAAc,EAAE,iBAQ5B,CAAC"}
@@ -0,0 +1,127 @@
1
+ import { execFile } from 'node:child_process';
2
+ import { readFile } from 'node:fs/promises';
3
+ import { dirname, join } from 'node:path';
4
+ import { promisify } from 'node:util';
5
+ import { BuildInfoResolver } from '@venizia/ignis-boot/build-info';
6
+ import { getError } from '@venizia/ignis-inversion';
7
+ import { useQuietConsoleLogger } from './quiet-logger.js';
8
+ const runFile = promisify(execFile);
9
+ const GIT_TIMEOUT_MS = 5_000;
10
+ const MANIFEST_FILE = 'package.json';
11
+ const PACKAGE_NAME = /^(?:@[a-z0-9][a-z0-9._-]*\/)?[a-z0-9][a-z0-9._-]*$/;
12
+ // A type guard takes its argument as it is: that is what it narrows.
13
+ const isRecord = (value) => typeof value === 'object' && value !== null && !Array.isArray(value);
14
+ const getString = (opts) => {
15
+ const value = opts.record[opts.key];
16
+ return typeof value === 'string' ? value : undefined;
17
+ };
18
+ const getKeys = (opts) => {
19
+ const value = opts.record[opts.key];
20
+ return typeof value === 'object' && value !== null ? Object.keys(value) : [];
21
+ };
22
+ /** The error code or name only: a message can quote the content of a file that was never meant to be read. */
23
+ const describeError = (opts) => {
24
+ const { error } = opts;
25
+ if (!(error instanceof Error)) {
26
+ return 'unknown error';
27
+ }
28
+ return 'code' in error && typeof error.code === 'string' ? error.code : error.name;
29
+ };
30
+ /** `undefined` only when the file does not exist; an unreadable or malformed file is an error naming it. */
31
+ export const readJsonFile = async (opts) => {
32
+ let text;
33
+ try {
34
+ text = await readFile(opts.path, 'utf8');
35
+ }
36
+ catch (error) {
37
+ if (error instanceof Error && 'code' in error && error.code === 'ENOENT') {
38
+ return undefined;
39
+ }
40
+ throw getError({
41
+ message: `[buildInfoFile] cannot read ${opts.path} | ${describeError({ error })}`,
42
+ });
43
+ }
44
+ try {
45
+ return JSON.parse(text);
46
+ }
47
+ catch (error) {
48
+ throw getError({
49
+ message: `[buildInfoFile] ${opts.path} is not valid JSON | ${describeError({ error })}`,
50
+ });
51
+ }
52
+ };
53
+ /** The version of the package as Node would find it: the nearest `node_modules` upward from the app. */
54
+ export const findInstalledVersion = async (opts) => {
55
+ let directory = opts.root;
56
+ for (;;) {
57
+ const manifest = await readJsonFile({
58
+ path: join(directory, 'node_modules', opts.name, MANIFEST_FILE),
59
+ });
60
+ if (isRecord(manifest)) {
61
+ return getString({ record: manifest, key: 'version' });
62
+ }
63
+ const parent = dirname(directory);
64
+ if (parent === directory) {
65
+ return undefined;
66
+ }
67
+ directory = parent;
68
+ }
69
+ };
70
+ /** The installed version of every dependency of the app whose name starts with the scope, by name. */
71
+ export const readFrameworkVersions = async (opts) => {
72
+ const { root, scope } = opts;
73
+ const manifest = await readJsonFile({ path: join(root, MANIFEST_FILE) });
74
+ if (!isRecord(manifest)) {
75
+ throw getError({
76
+ message: `[buildInfoFile] no ${MANIFEST_FILE} in ${root} | Pass the app folder as the root option`,
77
+ });
78
+ }
79
+ const names = [
80
+ ...getKeys({ record: manifest, key: 'dependencies' }),
81
+ ...getKeys({ record: manifest, key: 'devDependencies' }),
82
+ ].filter((name) => name.startsWith(scope));
83
+ const versions = {};
84
+ const missing = [];
85
+ const invalid = [];
86
+ for (const name of [...new Set(names)].sort()) {
87
+ // The name becomes a path: only a real package name may be looked up.
88
+ if (!PACKAGE_NAME.test(name)) {
89
+ invalid.push(name);
90
+ continue;
91
+ }
92
+ const version = await findInstalledVersion({ root, name });
93
+ if (version === undefined) {
94
+ missing.push(name);
95
+ }
96
+ else {
97
+ versions[name] = version;
98
+ }
99
+ }
100
+ return { versions, missing, invalid };
101
+ };
102
+ /** Runs git without a shell, so no argument is ever interpreted. */
103
+ export const readGit = async (opts) => {
104
+ try {
105
+ const { stdout } = await runFile('git', opts.args, {
106
+ cwd: opts.root,
107
+ timeout: GIT_TIMEOUT_MS,
108
+ windowsHide: true,
109
+ });
110
+ const value = stdout.trim();
111
+ return value === ''
112
+ ? { ok: false, reason: `git ${opts.args.join(' ')} printed nothing` }
113
+ : { ok: true, value };
114
+ }
115
+ catch (error) {
116
+ return { ok: false, reason: `git ${opts.args.join(' ')} failed | ${String(error)}` };
117
+ }
118
+ };
119
+ export const defaultSources = {
120
+ resolveRecord: (opts) => {
121
+ useQuietConsoleLogger();
122
+ return BuildInfoResolver.getInstance().resolve({ root: opts.root });
123
+ },
124
+ readGit,
125
+ readFrameworkVersions,
126
+ };
127
+ //# sourceMappingURL=sources.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"sources.js","sourceRoot":"","sources":["../../src/vite/sources.ts"],"names":[],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@venizia/ardor",
3
- "version": "0.4.3",
3
+ "version": "0.4.5",
4
4
  "description": "ARDOR - frontend application framework for the VENIZIA family. One entry point over ardor-kernel, ardor-react and ardor-admin: IGNIS inversion of control, a REST data layer, auth and i18n providers, and the React bindings for a react-admin application.",
5
5
  "keywords": [
6
6
  "ardor",
@@ -55,7 +55,17 @@
55
55
  "import": "./dist/repository.js",
56
56
  "default": "./dist/repository.js"
57
57
  },
58
- "./package.json": "./package.json"
58
+ "./testing": {
59
+ "types": "./dist/testing.d.ts",
60
+ "import": "./dist/testing.js",
61
+ "default": "./dist/testing.js"
62
+ },
63
+ "./package.json": "./package.json",
64
+ "./vite": {
65
+ "types": "./dist/vite/index.d.ts",
66
+ "import": "./dist/vite/index.js",
67
+ "default": "./dist/vite/index.js"
68
+ }
59
69
  },
60
70
  "publishConfig": {
61
71
  "access": "public"
@@ -65,27 +75,32 @@
65
75
  "prepublishOnly": "make rebuild"
66
76
  },
67
77
  "dependencies": {
68
- "@venizia/ardor-admin": "0.4.3",
69
- "@venizia/ardor-kernel": "0.4.3",
70
- "@venizia/ardor-react": "0.4.3"
78
+ "@venizia/ardor-admin": "0.4.5",
79
+ "@venizia/ardor-kernel": "0.4.5",
80
+ "@venizia/ardor-react": "0.4.5"
71
81
  },
72
82
  "devDependencies": {
73
83
  "@size-limit/preset-small-lib": "^14.2.0",
74
- "@venizia/dev-configs": "^0.4.3",
84
+ "@types/bun": "^1.4.3",
85
+ "@types/node": "^25.0.10",
86
+ "@venizia/dev-configs": "^0.4.5",
87
+ "@venizia/ignis-boot": "^0.4.5",
75
88
  "eslint": "^10.13.0",
76
89
  "oxlint": "1.89.0",
77
90
  "oxlint-tsgolint": "7.0.2004",
78
91
  "size-limit": "^14.2.0",
79
92
  "tsc-alias": "~1.8.17",
80
- "typescript": "^6.0.3"
93
+ "typescript": "^6.0.3",
94
+ "vite": "^8.3.5"
81
95
  },
82
96
  "peerDependencies": {
83
97
  "@reduxjs/toolkit": ">=2.13.0",
84
98
  "@tanstack/react-query": ">=5.104.5",
99
+ "@venizia/ignis-boot": "^0.4.1",
85
100
  "@venizia/ignis-connectors": "^0.4.1",
86
101
  "@venizia/ignis-filter": "^0.4.1",
87
102
  "@venizia/ignis-helpers": "^0.4.1",
88
- "@venizia/ignis-inversion": "^0.4.1",
103
+ "@venizia/ignis-inversion": "^0.4.4",
89
104
  "@venizia/ignis-kernel": "^0.4.1",
90
105
  "ra-core": ">=5.15.5",
91
106
  "ra-i18n-polyglot": ">=5.15.5",
@@ -93,11 +108,18 @@
93
108
  "react-dom": ">=19.3.1",
94
109
  "react-redux": ">=9.3.0",
95
110
  "react-router-dom": ">=7.18.4",
96
- "reflect-metadata": ">=0.2.2"
111
+ "reflect-metadata": ">=0.2.2",
112
+ "vite": ">=8.3.5"
97
113
  },
98
114
  "peerDependenciesMeta": {
115
+ "@venizia/ignis-boot": {
116
+ "optional": true
117
+ },
99
118
  "@venizia/ignis-connectors": {
100
119
  "optional": true
120
+ },
121
+ "vite": {
122
+ "optional": true
101
123
  }
102
124
  },
103
125
  "size-limit": [
@@ -120,6 +142,26 @@
120
142
  "reflect-metadata"
121
143
  ],
122
144
  "limit": "350 B"
145
+ },
146
+ {
147
+ "path": "dist/testing.js",
148
+ "import": "*",
149
+ "ignore": [
150
+ "@reduxjs/toolkit",
151
+ "@tanstack/react-query",
152
+ "@venizia/ardor-admin",
153
+ "@venizia/ardor-kernel",
154
+ "@venizia/ardor-react",
155
+ "@venizia/ignis-filter",
156
+ "@venizia/ignis-inversion",
157
+ "ra-core",
158
+ "react",
159
+ "react-dom",
160
+ "react-redux",
161
+ "react-router-dom",
162
+ "reflect-metadata"
163
+ ],
164
+ "limit": "900 B"
123
165
  }
124
166
  ],
125
167
  "engines": {