@memberjunction/ng-forms 0.0.1 → 5.13.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.
- package/dist/lib/dynamic-form/dynamic-form.component.d.ts +116 -0
- package/dist/lib/dynamic-form/dynamic-form.component.d.ts.map +1 -0
- package/dist/lib/dynamic-form/dynamic-form.component.js +258 -0
- package/dist/lib/dynamic-form/dynamic-form.component.js.map +1 -0
- package/dist/lib/dynamic-form-field/dynamic-form-field.component.d.ts +111 -0
- package/dist/lib/dynamic-form-field/dynamic-form-field.component.d.ts.map +1 -0
- package/dist/lib/dynamic-form-field/dynamic-form-field.component.js +240 -0
- package/dist/lib/dynamic-form-field/dynamic-form-field.component.js.map +1 -0
- package/dist/lib/dynamic-form-response/dynamic-form-response.component.d.ts +43 -0
- package/dist/lib/dynamic-form-response/dynamic-form-response.component.d.ts.map +1 -0
- package/dist/lib/dynamic-form-response/dynamic-form-response.component.js +129 -0
- package/dist/lib/dynamic-form-response/dynamic-form-response.component.js.map +1 -0
- package/dist/lib/dynamic-form-response/form-response-utils.d.ts +74 -0
- package/dist/lib/dynamic-form-response/form-response-utils.d.ts.map +1 -0
- package/dist/lib/dynamic-form-response/form-response-utils.js +147 -0
- package/dist/lib/dynamic-form-response/form-response-utils.js.map +1 -0
- package/dist/lib/forms.module.d.ts +15 -0
- package/dist/lib/forms.module.d.ts.map +1 -0
- package/dist/lib/forms.module.js +97 -0
- package/dist/lib/forms.module.js.map +1 -0
- package/dist/public-api.d.ts +52 -0
- package/dist/public-api.d.ts.map +1 -0
- package/dist/public-api.js +54 -0
- package/dist/public-api.js.map +1 -0
- package/package.json +43 -6
- package/README.md +0 -45
|
@@ -0,0 +1,74 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @fileoverview Shared utilities for formatting form response values.
|
|
3
|
+
*
|
|
4
|
+
* Used by both `DynamicFormResponseComponent` (Angular component rendering)
|
|
5
|
+
* and the conversations package (inline HTML rendering via markdown).
|
|
6
|
+
*
|
|
7
|
+
* @module @memberjunction/ng-forms
|
|
8
|
+
*/
|
|
9
|
+
import { FormQuestion } from '@memberjunction/ai-core-plus';
|
|
10
|
+
/**
|
|
11
|
+
* Represents a resolved form response field ready for display.
|
|
12
|
+
*/
|
|
13
|
+
export interface FormResponseField {
|
|
14
|
+
/** Question ID or key name */
|
|
15
|
+
key: string;
|
|
16
|
+
/** Human-readable label */
|
|
17
|
+
label: string;
|
|
18
|
+
/** Raw value from the response */
|
|
19
|
+
value: unknown;
|
|
20
|
+
/** Display-friendly formatted value */
|
|
21
|
+
displayValue: string;
|
|
22
|
+
/** Field type from the schema (for type-aware formatting) */
|
|
23
|
+
type: string | null;
|
|
24
|
+
}
|
|
25
|
+
/**
|
|
26
|
+
* Static utility class for form response value formatting and resolution.
|
|
27
|
+
*
|
|
28
|
+
* Provides type-aware formatting for all supported field types:
|
|
29
|
+
* date, datetime, time, daterange, slider, buttongroup, radio, dropdown, checkbox.
|
|
30
|
+
*/
|
|
31
|
+
export declare class FormResponseUtils {
|
|
32
|
+
/**
|
|
33
|
+
* Format a value for display, using schema info when available.
|
|
34
|
+
* Resolves choice labels and applies type-specific formatting.
|
|
35
|
+
*/
|
|
36
|
+
static FormatValue(value: unknown, question: FormQuestion | null, type: string | null): string;
|
|
37
|
+
/**
|
|
38
|
+
* Resolve a raw value to its display label from form options.
|
|
39
|
+
*/
|
|
40
|
+
static ResolveOptionLabel(question: FormQuestion, value: unknown): string | null;
|
|
41
|
+
/**
|
|
42
|
+
* Format a date string for display.
|
|
43
|
+
* @param value ISO date string
|
|
44
|
+
* @param includeTime Whether to include time in the output
|
|
45
|
+
*/
|
|
46
|
+
static FormatDate(value: string, includeTime: boolean): string;
|
|
47
|
+
/**
|
|
48
|
+
* Format a time string (HH:mm or HH:mm:ss) for display.
|
|
49
|
+
*/
|
|
50
|
+
static FormatTime(value: string): string;
|
|
51
|
+
/**
|
|
52
|
+
* Format a date range object for display.
|
|
53
|
+
* @param value Object with `start` and `end` date strings, or any fallback value
|
|
54
|
+
*/
|
|
55
|
+
static FormatDateRange(value: unknown): string;
|
|
56
|
+
/**
|
|
57
|
+
* Convert a camelCase/snake_case key to a human-readable label.
|
|
58
|
+
*/
|
|
59
|
+
static HumanizeKey(key: string): string;
|
|
60
|
+
/**
|
|
61
|
+
* Escape HTML special characters to prevent XSS.
|
|
62
|
+
*/
|
|
63
|
+
static EscapeHtml(text: string): string;
|
|
64
|
+
/**
|
|
65
|
+
* Format a value for display with HTML escaping applied.
|
|
66
|
+
* Convenience wrapper combining FormatValue + EscapeHtml.
|
|
67
|
+
*/
|
|
68
|
+
static FormatValueHtml(value: unknown, question: FormQuestion | null, type: string | null): string;
|
|
69
|
+
/**
|
|
70
|
+
* Get the type string from a FormQuestion.
|
|
71
|
+
*/
|
|
72
|
+
static GetQuestionTypeString(question: FormQuestion): string;
|
|
73
|
+
}
|
|
74
|
+
//# sourceMappingURL=form-response-utils.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"form-response-utils.d.ts","sourceRoot":"","sources":["../../../src/lib/dynamic-form-response/form-response-utils.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH,OAAO,EAAE,YAAY,EAAc,MAAM,8BAA8B,CAAC;AAExE;;GAEG;AACH,MAAM,WAAW,iBAAiB;IAC9B,8BAA8B;IAC9B,GAAG,EAAE,MAAM,CAAC;IACZ,2BAA2B;IAC3B,KAAK,EAAE,MAAM,CAAC;IACd,kCAAkC;IAClC,KAAK,EAAE,OAAO,CAAC;IACf,uCAAuC;IACvC,YAAY,EAAE,MAAM,CAAC;IACrB,6DAA6D;IAC7D,IAAI,EAAE,MAAM,GAAG,IAAI,CAAC;CACvB;AAED;;;;;GAKG;AACH,qBAAa,iBAAiB;IAC1B;;;OAGG;IACH,MAAM,CAAC,WAAW,CAAC,KAAK,EAAE,OAAO,EAAE,QAAQ,EAAE,YAAY,GAAG,IAAI,EAAE,IAAI,EAAE,MAAM,GAAG,IAAI,GAAG,MAAM;IA+B9F;;OAEG;IACH,MAAM,CAAC,kBAAkB,CAAC,QAAQ,EAAE,YAAY,EAAE,KAAK,EAAE,OAAO,GAAG,MAAM,GAAG,IAAI;IAOhF;;;;OAIG;IACH,MAAM,CAAC,UAAU,CAAC,KAAK,EAAE,MAAM,EAAE,WAAW,EAAE,OAAO,GAAG,MAAM;IAmB9D;;OAEG;IACH,MAAM,CAAC,UAAU,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM;IAaxC;;;OAGG;IACH,MAAM,CAAC,eAAe,CAAC,KAAK,EAAE,OAAO,GAAG,MAAM;IAU9C;;OAEG;IACH,MAAM,CAAC,WAAW,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM;IAQvC;;OAEG;IACH,MAAM,CAAC,UAAU,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM;IASvC;;;OAGG;IACH,MAAM,CAAC,eAAe,CAAC,KAAK,EAAE,OAAO,EAAE,QAAQ,EAAE,YAAY,GAAG,IAAI,EAAE,IAAI,EAAE,MAAM,GAAG,IAAI,GAAG,MAAM;IAIlG;;OAEG;IACH,MAAM,CAAC,qBAAqB,CAAC,QAAQ,EAAE,YAAY,GAAG,MAAM;CAG/D"}
|
|
@@ -0,0 +1,147 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @fileoverview Shared utilities for formatting form response values.
|
|
3
|
+
*
|
|
4
|
+
* Used by both `DynamicFormResponseComponent` (Angular component rendering)
|
|
5
|
+
* and the conversations package (inline HTML rendering via markdown).
|
|
6
|
+
*
|
|
7
|
+
* @module @memberjunction/ng-forms
|
|
8
|
+
*/
|
|
9
|
+
/**
|
|
10
|
+
* Static utility class for form response value formatting and resolution.
|
|
11
|
+
*
|
|
12
|
+
* Provides type-aware formatting for all supported field types:
|
|
13
|
+
* date, datetime, time, daterange, slider, buttongroup, radio, dropdown, checkbox.
|
|
14
|
+
*/
|
|
15
|
+
export class FormResponseUtils {
|
|
16
|
+
/**
|
|
17
|
+
* Format a value for display, using schema info when available.
|
|
18
|
+
* Resolves choice labels and applies type-specific formatting.
|
|
19
|
+
*/
|
|
20
|
+
static FormatValue(value, question, type) {
|
|
21
|
+
if (value == null)
|
|
22
|
+
return '';
|
|
23
|
+
// For choice types, resolve the option label
|
|
24
|
+
if (question && type && ['buttongroup', 'radio', 'dropdown', 'checkbox'].includes(type)) {
|
|
25
|
+
const optionLabel = FormResponseUtils.ResolveOptionLabel(question, value);
|
|
26
|
+
if (optionLabel)
|
|
27
|
+
return optionLabel;
|
|
28
|
+
}
|
|
29
|
+
const stringValue = String(value);
|
|
30
|
+
switch (type) {
|
|
31
|
+
case 'date':
|
|
32
|
+
return FormResponseUtils.FormatDate(stringValue, false);
|
|
33
|
+
case 'datetime':
|
|
34
|
+
return FormResponseUtils.FormatDate(stringValue, true);
|
|
35
|
+
case 'time':
|
|
36
|
+
return FormResponseUtils.FormatTime(stringValue);
|
|
37
|
+
case 'daterange':
|
|
38
|
+
return FormResponseUtils.FormatDateRange(value);
|
|
39
|
+
default:
|
|
40
|
+
// Auto-detect ISO dates for backward compatibility
|
|
41
|
+
if (stringValue.match(/^\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}/)) {
|
|
42
|
+
const date = new Date(stringValue);
|
|
43
|
+
const hasMidnight = date.getUTCHours() === 0 && date.getUTCMinutes() === 0 && date.getUTCSeconds() === 0;
|
|
44
|
+
return FormResponseUtils.FormatDate(stringValue, !hasMidnight);
|
|
45
|
+
}
|
|
46
|
+
return stringValue;
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
/**
|
|
50
|
+
* Resolve a raw value to its display label from form options.
|
|
51
|
+
*/
|
|
52
|
+
static ResolveOptionLabel(question, value) {
|
|
53
|
+
if (typeof question.type !== 'object' || !('options' in question.type))
|
|
54
|
+
return null;
|
|
55
|
+
const options = question.type.options;
|
|
56
|
+
const match = options.find(o => String(o.value) === String(value));
|
|
57
|
+
return match ? match.label : null;
|
|
58
|
+
}
|
|
59
|
+
/**
|
|
60
|
+
* Format a date string for display.
|
|
61
|
+
* @param value ISO date string
|
|
62
|
+
* @param includeTime Whether to include time in the output
|
|
63
|
+
*/
|
|
64
|
+
static FormatDate(value, includeTime) {
|
|
65
|
+
try {
|
|
66
|
+
const date = new Date(value);
|
|
67
|
+
if (isNaN(date.getTime()))
|
|
68
|
+
return value;
|
|
69
|
+
if (includeTime) {
|
|
70
|
+
return date.toLocaleString('en-US', {
|
|
71
|
+
month: 'short', day: 'numeric', year: 'numeric',
|
|
72
|
+
hour: 'numeric', minute: '2-digit', hour12: true
|
|
73
|
+
});
|
|
74
|
+
}
|
|
75
|
+
return date.toLocaleDateString('en-US', {
|
|
76
|
+
month: 'short', day: 'numeric', year: 'numeric'
|
|
77
|
+
});
|
|
78
|
+
}
|
|
79
|
+
catch {
|
|
80
|
+
return value;
|
|
81
|
+
}
|
|
82
|
+
}
|
|
83
|
+
/**
|
|
84
|
+
* Format a time string (HH:mm or HH:mm:ss) for display.
|
|
85
|
+
*/
|
|
86
|
+
static FormatTime(value) {
|
|
87
|
+
try {
|
|
88
|
+
const [hours, minutes] = value.split(':').map(Number);
|
|
89
|
+
const date = new Date();
|
|
90
|
+
date.setHours(hours, minutes, 0);
|
|
91
|
+
return date.toLocaleTimeString('en-US', {
|
|
92
|
+
hour: 'numeric', minute: '2-digit', hour12: true
|
|
93
|
+
});
|
|
94
|
+
}
|
|
95
|
+
catch {
|
|
96
|
+
return value;
|
|
97
|
+
}
|
|
98
|
+
}
|
|
99
|
+
/**
|
|
100
|
+
* Format a date range object for display.
|
|
101
|
+
* @param value Object with `start` and `end` date strings, or any fallback value
|
|
102
|
+
*/
|
|
103
|
+
static FormatDateRange(value) {
|
|
104
|
+
if (typeof value === 'object' && value !== null && 'start' in value && 'end' in value) {
|
|
105
|
+
const rangeValue = value;
|
|
106
|
+
const start = FormResponseUtils.FormatDate(rangeValue.start, false);
|
|
107
|
+
const end = FormResponseUtils.FormatDate(rangeValue.end, false);
|
|
108
|
+
return `${start} to ${end}`;
|
|
109
|
+
}
|
|
110
|
+
return JSON.stringify(value);
|
|
111
|
+
}
|
|
112
|
+
/**
|
|
113
|
+
* Convert a camelCase/snake_case key to a human-readable label.
|
|
114
|
+
*/
|
|
115
|
+
static HumanizeKey(key) {
|
|
116
|
+
return key
|
|
117
|
+
.replace(/([A-Z])/g, ' $1')
|
|
118
|
+
.replace(/[_-]/g, ' ')
|
|
119
|
+
.replace(/^\s+/, '')
|
|
120
|
+
.replace(/\b\w/g, c => c.toUpperCase());
|
|
121
|
+
}
|
|
122
|
+
/**
|
|
123
|
+
* Escape HTML special characters to prevent XSS.
|
|
124
|
+
*/
|
|
125
|
+
static EscapeHtml(text) {
|
|
126
|
+
return text
|
|
127
|
+
.replace(/&/g, '&')
|
|
128
|
+
.replace(/</g, '<')
|
|
129
|
+
.replace(/>/g, '>')
|
|
130
|
+
.replace(/"/g, '"')
|
|
131
|
+
.replace(/'/g, ''');
|
|
132
|
+
}
|
|
133
|
+
/**
|
|
134
|
+
* Format a value for display with HTML escaping applied.
|
|
135
|
+
* Convenience wrapper combining FormatValue + EscapeHtml.
|
|
136
|
+
*/
|
|
137
|
+
static FormatValueHtml(value, question, type) {
|
|
138
|
+
return FormResponseUtils.EscapeHtml(FormResponseUtils.FormatValue(value, question, type));
|
|
139
|
+
}
|
|
140
|
+
/**
|
|
141
|
+
* Get the type string from a FormQuestion.
|
|
142
|
+
*/
|
|
143
|
+
static GetQuestionTypeString(question) {
|
|
144
|
+
return typeof question.type === 'string' ? question.type : question.type.type;
|
|
145
|
+
}
|
|
146
|
+
}
|
|
147
|
+
//# sourceMappingURL=form-response-utils.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"form-response-utils.js","sourceRoot":"","sources":["../../../src/lib/dynamic-form-response/form-response-utils.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * @fileoverview Shared utilities for formatting form response values.\n *\n * Used by both `DynamicFormResponseComponent` (Angular component rendering)\n * and the conversations package (inline HTML rendering via markdown).\n *\n * @module @memberjunction/ng-forms\n */\n\nimport { FormQuestion, FormOption } from '@memberjunction/ai-core-plus';\n\n/**\n * Represents a resolved form response field ready for display.\n */\nexport interface FormResponseField {\n /** Question ID or key name */\n key: string;\n /** Human-readable label */\n label: string;\n /** Raw value from the response */\n value: unknown;\n /** Display-friendly formatted value */\n displayValue: string;\n /** Field type from the schema (for type-aware formatting) */\n type: string | null;\n}\n\n/**\n * Static utility class for form response value formatting and resolution.\n *\n * Provides type-aware formatting for all supported field types:\n * date, datetime, time, daterange, slider, buttongroup, radio, dropdown, checkbox.\n */\nexport class FormResponseUtils {\n /**\n * Format a value for display, using schema info when available.\n * Resolves choice labels and applies type-specific formatting.\n */\n static FormatValue(value: unknown, question: FormQuestion | null, type: string | null): string {\n if (value == null) return '';\n\n // For choice types, resolve the option label\n if (question && type && ['buttongroup', 'radio', 'dropdown', 'checkbox'].includes(type)) {\n const optionLabel = FormResponseUtils.ResolveOptionLabel(question, value);\n if (optionLabel) return optionLabel;\n }\n\n const stringValue = String(value);\n\n switch (type) {\n case 'date':\n return FormResponseUtils.FormatDate(stringValue, false);\n case 'datetime':\n return FormResponseUtils.FormatDate(stringValue, true);\n case 'time':\n return FormResponseUtils.FormatTime(stringValue);\n case 'daterange':\n return FormResponseUtils.FormatDateRange(value);\n default:\n // Auto-detect ISO dates for backward compatibility\n if (stringValue.match(/^\\d{4}-\\d{2}-\\d{2}T\\d{2}:\\d{2}:\\d{2}/)) {\n const date = new Date(stringValue);\n const hasMidnight = date.getUTCHours() === 0 && date.getUTCMinutes() === 0 && date.getUTCSeconds() === 0;\n return FormResponseUtils.FormatDate(stringValue, !hasMidnight);\n }\n return stringValue;\n }\n }\n\n /**\n * Resolve a raw value to its display label from form options.\n */\n static ResolveOptionLabel(question: FormQuestion, value: unknown): string | null {\n if (typeof question.type !== 'object' || !('options' in question.type)) return null;\n const options = question.type.options as FormOption[];\n const match = options.find(o => String(o.value) === String(value));\n return match ? match.label : null;\n }\n\n /**\n * Format a date string for display.\n * @param value ISO date string\n * @param includeTime Whether to include time in the output\n */\n static FormatDate(value: string, includeTime: boolean): string {\n try {\n const date = new Date(value);\n if (isNaN(date.getTime())) return value;\n\n if (includeTime) {\n return date.toLocaleString('en-US', {\n month: 'short', day: 'numeric', year: 'numeric',\n hour: 'numeric', minute: '2-digit', hour12: true\n });\n }\n return date.toLocaleDateString('en-US', {\n month: 'short', day: 'numeric', year: 'numeric'\n });\n } catch {\n return value;\n }\n }\n\n /**\n * Format a time string (HH:mm or HH:mm:ss) for display.\n */\n static FormatTime(value: string): string {\n try {\n const [hours, minutes] = value.split(':').map(Number);\n const date = new Date();\n date.setHours(hours, minutes, 0);\n return date.toLocaleTimeString('en-US', {\n hour: 'numeric', minute: '2-digit', hour12: true\n });\n } catch {\n return value;\n }\n }\n\n /**\n * Format a date range object for display.\n * @param value Object with `start` and `end` date strings, or any fallback value\n */\n static FormatDateRange(value: unknown): string {\n if (typeof value === 'object' && value !== null && 'start' in value && 'end' in value) {\n const rangeValue = value as { start: string; end: string };\n const start = FormResponseUtils.FormatDate(rangeValue.start, false);\n const end = FormResponseUtils.FormatDate(rangeValue.end, false);\n return `${start} to ${end}`;\n }\n return JSON.stringify(value);\n }\n\n /**\n * Convert a camelCase/snake_case key to a human-readable label.\n */\n static HumanizeKey(key: string): string {\n return key\n .replace(/([A-Z])/g, ' $1')\n .replace(/[_-]/g, ' ')\n .replace(/^\\s+/, '')\n .replace(/\\b\\w/g, c => c.toUpperCase());\n }\n\n /**\n * Escape HTML special characters to prevent XSS.\n */\n static EscapeHtml(text: string): string {\n return text\n .replace(/&/g, '&')\n .replace(/</g, '<')\n .replace(/>/g, '>')\n .replace(/\"/g, '"')\n .replace(/'/g, ''');\n }\n\n /**\n * Format a value for display with HTML escaping applied.\n * Convenience wrapper combining FormatValue + EscapeHtml.\n */\n static FormatValueHtml(value: unknown, question: FormQuestion | null, type: string | null): string {\n return FormResponseUtils.EscapeHtml(FormResponseUtils.FormatValue(value, question, type));\n }\n\n /**\n * Get the type string from a FormQuestion.\n */\n static GetQuestionTypeString(question: FormQuestion): string {\n return typeof question.type === 'string' ? question.type : question.type.type;\n }\n}\n"]}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import * as i0 from "@angular/core";
|
|
2
|
+
import * as i1 from "./dynamic-form/dynamic-form.component";
|
|
3
|
+
import * as i2 from "./dynamic-form-field/dynamic-form-field.component";
|
|
4
|
+
import * as i3 from "./dynamic-form-response/dynamic-form-response.component";
|
|
5
|
+
import * as i4 from "@angular/common";
|
|
6
|
+
import * as i5 from "@angular/forms";
|
|
7
|
+
import * as i6 from "@progress/kendo-angular-buttons";
|
|
8
|
+
import * as i7 from "@progress/kendo-angular-inputs";
|
|
9
|
+
import * as i8 from "@progress/kendo-angular-dateinputs";
|
|
10
|
+
export declare class DynamicFormsModule {
|
|
11
|
+
static ɵfac: i0.ɵɵFactoryDeclaration<DynamicFormsModule, never>;
|
|
12
|
+
static ɵmod: i0.ɵɵNgModuleDeclaration<DynamicFormsModule, [typeof i1.DynamicFormComponent, typeof i2.DynamicFormFieldComponent, typeof i3.DynamicFormResponseComponent], [typeof i4.CommonModule, typeof i5.FormsModule, typeof i5.ReactiveFormsModule, typeof i6.ButtonsModule, typeof i7.InputsModule, typeof i8.DateInputsModule], [typeof i1.DynamicFormComponent, typeof i2.DynamicFormFieldComponent, typeof i3.DynamicFormResponseComponent]>;
|
|
13
|
+
static ɵinj: i0.ɵɵInjectorDeclaration<DynamicFormsModule>;
|
|
14
|
+
}
|
|
15
|
+
//# sourceMappingURL=forms.module.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"forms.module.d.ts","sourceRoot":"","sources":["../../src/lib/forms.module.ts"],"names":[],"mappings":";;;;;;;;;AAyDA,qBAoBa,kBAAkB;yCAAlB,kBAAkB;0CAAlB,kBAAkB;0CAAlB,kBAAkB;CAAI"}
|
|
@@ -0,0 +1,97 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @fileoverview MJ Dynamic Forms Module
|
|
3
|
+
*
|
|
4
|
+
* Provides reusable dynamic form components that render structured forms from
|
|
5
|
+
* `AgentResponseForm` JSON schemas. Supports 14+ input types with built-in
|
|
6
|
+
* validation, responsive layout, and intelligent field sizing.
|
|
7
|
+
*
|
|
8
|
+
* ## Usage
|
|
9
|
+
*
|
|
10
|
+
* Import `DynamicFormsModule` into your feature module:
|
|
11
|
+
*
|
|
12
|
+
* ```typescript
|
|
13
|
+
* import { DynamicFormsModule } from '@memberjunction/ng-forms';
|
|
14
|
+
*
|
|
15
|
+
* @NgModule({
|
|
16
|
+
* imports: [DynamicFormsModule]
|
|
17
|
+
* })
|
|
18
|
+
* export class MyFeatureModule { }
|
|
19
|
+
* ```
|
|
20
|
+
*
|
|
21
|
+
* Then use in templates:
|
|
22
|
+
*
|
|
23
|
+
* ```html
|
|
24
|
+
* <mj-dynamic-form
|
|
25
|
+
* [FormDefinition]="myFormSchema"
|
|
26
|
+
* [Disabled]="isSaving"
|
|
27
|
+
* (FormSubmitted)="onSubmit($event)">
|
|
28
|
+
* </mj-dynamic-form>
|
|
29
|
+
* ```
|
|
30
|
+
*
|
|
31
|
+
* Or use the field component individually within your own reactive forms:
|
|
32
|
+
*
|
|
33
|
+
* ```html
|
|
34
|
+
* <mj-dynamic-form-field
|
|
35
|
+
* [Question]="question"
|
|
36
|
+
* [Control]="myFormGroup.get(question.id)"
|
|
37
|
+
* [formControlName]="question.id">
|
|
38
|
+
* </mj-dynamic-form-field>
|
|
39
|
+
* ```
|
|
40
|
+
*
|
|
41
|
+
* @module @memberjunction/ng-forms
|
|
42
|
+
*/
|
|
43
|
+
import { NgModule } from '@angular/core';
|
|
44
|
+
import { CommonModule } from '@angular/common';
|
|
45
|
+
import { FormsModule, ReactiveFormsModule } from '@angular/forms';
|
|
46
|
+
// Kendo UI modules
|
|
47
|
+
import { ButtonsModule } from '@progress/kendo-angular-buttons';
|
|
48
|
+
import { InputsModule } from '@progress/kendo-angular-inputs';
|
|
49
|
+
import { DateInputsModule } from '@progress/kendo-angular-dateinputs';
|
|
50
|
+
// Components
|
|
51
|
+
import { DynamicFormComponent } from './dynamic-form/dynamic-form.component';
|
|
52
|
+
import { DynamicFormFieldComponent } from './dynamic-form-field/dynamic-form-field.component';
|
|
53
|
+
import { DynamicFormResponseComponent } from './dynamic-form-response/dynamic-form-response.component';
|
|
54
|
+
import * as i0 from "@angular/core";
|
|
55
|
+
export class DynamicFormsModule {
|
|
56
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.1.3", ngImport: i0, type: DynamicFormsModule, deps: [], target: i0.ɵɵFactoryTarget.NgModule });
|
|
57
|
+
static ɵmod = i0.ɵɵngDeclareNgModule({ minVersion: "14.0.0", version: "21.1.3", ngImport: i0, type: DynamicFormsModule, declarations: [DynamicFormComponent,
|
|
58
|
+
DynamicFormFieldComponent,
|
|
59
|
+
DynamicFormResponseComponent], imports: [CommonModule,
|
|
60
|
+
FormsModule,
|
|
61
|
+
ReactiveFormsModule,
|
|
62
|
+
ButtonsModule,
|
|
63
|
+
InputsModule,
|
|
64
|
+
DateInputsModule], exports: [DynamicFormComponent,
|
|
65
|
+
DynamicFormFieldComponent,
|
|
66
|
+
DynamicFormResponseComponent] });
|
|
67
|
+
static ɵinj = i0.ɵɵngDeclareInjector({ minVersion: "12.0.0", version: "21.1.3", ngImport: i0, type: DynamicFormsModule, imports: [CommonModule,
|
|
68
|
+
FormsModule,
|
|
69
|
+
ReactiveFormsModule,
|
|
70
|
+
ButtonsModule,
|
|
71
|
+
InputsModule,
|
|
72
|
+
DateInputsModule] });
|
|
73
|
+
}
|
|
74
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.3", ngImport: i0, type: DynamicFormsModule, decorators: [{
|
|
75
|
+
type: NgModule,
|
|
76
|
+
args: [{
|
|
77
|
+
declarations: [
|
|
78
|
+
DynamicFormComponent,
|
|
79
|
+
DynamicFormFieldComponent,
|
|
80
|
+
DynamicFormResponseComponent
|
|
81
|
+
],
|
|
82
|
+
imports: [
|
|
83
|
+
CommonModule,
|
|
84
|
+
FormsModule,
|
|
85
|
+
ReactiveFormsModule,
|
|
86
|
+
ButtonsModule,
|
|
87
|
+
InputsModule,
|
|
88
|
+
DateInputsModule
|
|
89
|
+
],
|
|
90
|
+
exports: [
|
|
91
|
+
DynamicFormComponent,
|
|
92
|
+
DynamicFormFieldComponent,
|
|
93
|
+
DynamicFormResponseComponent
|
|
94
|
+
]
|
|
95
|
+
}]
|
|
96
|
+
}] });
|
|
97
|
+
//# sourceMappingURL=forms.module.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"forms.module.js","sourceRoot":"","sources":["../../src/lib/forms.module.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAyCG;AAEH,OAAO,EAAE,QAAQ,EAAE,MAAM,eAAe,CAAC;AACzC,OAAO,EAAE,YAAY,EAAE,MAAM,iBAAiB,CAAC;AAC/C,OAAO,EAAE,WAAW,EAAE,mBAAmB,EAAE,MAAM,gBAAgB,CAAC;AAElE,mBAAmB;AACnB,OAAO,EAAE,aAAa,EAAE,MAAM,iCAAiC,CAAC;AAChE,OAAO,EAAE,YAAY,EAAE,MAAM,gCAAgC,CAAC;AAC9D,OAAO,EAAE,gBAAgB,EAAE,MAAM,oCAAoC,CAAC;AAEtE,aAAa;AACb,OAAO,EAAE,oBAAoB,EAAE,MAAM,uCAAuC,CAAC;AAC7E,OAAO,EAAE,yBAAyB,EAAE,MAAM,mDAAmD,CAAC;AAC9F,OAAO,EAAE,4BAA4B,EAAE,MAAM,yDAAyD,CAAC;;AAsBvG,MAAM,OAAO,kBAAkB;uGAAlB,kBAAkB;wGAAlB,kBAAkB,iBAlBvB,oBAAoB;YACpB,yBAAyB;YACzB,4BAA4B,aAG5B,YAAY;YACZ,WAAW;YACX,mBAAmB;YACnB,aAAa;YACb,YAAY;YACZ,gBAAgB,aAGhB,oBAAoB;YACpB,yBAAyB;YACzB,4BAA4B;wGAGvB,kBAAkB,YAbvB,YAAY;YACZ,WAAW;YACX,mBAAmB;YACnB,aAAa;YACb,YAAY;YACZ,gBAAgB;;2FAQX,kBAAkB;kBApB9B,QAAQ;mBAAC;oBACN,YAAY,EAAE;wBACV,oBAAoB;wBACpB,yBAAyB;wBACzB,4BAA4B;qBAC/B;oBACD,OAAO,EAAE;wBACL,YAAY;wBACZ,WAAW;wBACX,mBAAmB;wBACnB,aAAa;wBACb,YAAY;wBACZ,gBAAgB;qBACnB;oBACD,OAAO,EAAE;wBACL,oBAAoB;wBACpB,yBAAyB;wBACzB,4BAA4B;qBAC/B;iBACJ","sourcesContent":["/**\n * @fileoverview MJ Dynamic Forms Module\n *\n * Provides reusable dynamic form components that render structured forms from\n * `AgentResponseForm` JSON schemas. Supports 14+ input types with built-in\n * validation, responsive layout, and intelligent field sizing.\n *\n * ## Usage\n *\n * Import `DynamicFormsModule` into your feature module:\n *\n * ```typescript\n * import { DynamicFormsModule } from '@memberjunction/ng-forms';\n *\n * @NgModule({\n * imports: [DynamicFormsModule]\n * })\n * export class MyFeatureModule { }\n * ```\n *\n * Then use in templates:\n *\n * ```html\n * <mj-dynamic-form\n * [FormDefinition]=\"myFormSchema\"\n * [Disabled]=\"isSaving\"\n * (FormSubmitted)=\"onSubmit($event)\">\n * </mj-dynamic-form>\n * ```\n *\n * Or use the field component individually within your own reactive forms:\n *\n * ```html\n * <mj-dynamic-form-field\n * [Question]=\"question\"\n * [Control]=\"myFormGroup.get(question.id)\"\n * [formControlName]=\"question.id\">\n * </mj-dynamic-form-field>\n * ```\n *\n * @module @memberjunction/ng-forms\n */\n\nimport { NgModule } from '@angular/core';\nimport { CommonModule } from '@angular/common';\nimport { FormsModule, ReactiveFormsModule } from '@angular/forms';\n\n// Kendo UI modules\nimport { ButtonsModule } from '@progress/kendo-angular-buttons';\nimport { InputsModule } from '@progress/kendo-angular-inputs';\nimport { DateInputsModule } from '@progress/kendo-angular-dateinputs';\n\n// Components\nimport { DynamicFormComponent } from './dynamic-form/dynamic-form.component';\nimport { DynamicFormFieldComponent } from './dynamic-form-field/dynamic-form-field.component';\nimport { DynamicFormResponseComponent } from './dynamic-form-response/dynamic-form-response.component';\n\n@NgModule({\n declarations: [\n DynamicFormComponent,\n DynamicFormFieldComponent,\n DynamicFormResponseComponent\n ],\n imports: [\n CommonModule,\n FormsModule,\n ReactiveFormsModule,\n ButtonsModule,\n InputsModule,\n DateInputsModule\n ],\n exports: [\n DynamicFormComponent,\n DynamicFormFieldComponent,\n DynamicFormResponseComponent\n ]\n})\nexport class DynamicFormsModule { }\n"]}
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Public API Surface for @memberjunction/ng-forms
|
|
3
|
+
*
|
|
4
|
+
* Generic dynamic form rendering from JSON schemas. Renders structured forms
|
|
5
|
+
* with 14+ field types, built-in validation, responsive layout, and intelligent
|
|
6
|
+
* field sizing. Schema types are defined in `@memberjunction/ai-core-plus`.
|
|
7
|
+
*
|
|
8
|
+
* ## Quick Start
|
|
9
|
+
*
|
|
10
|
+
* 1. Import the module:
|
|
11
|
+
* ```typescript
|
|
12
|
+
* import { DynamicFormsModule } from '@memberjunction/ng-forms';
|
|
13
|
+
* ```
|
|
14
|
+
*
|
|
15
|
+
* 2. Add to your NgModule imports:
|
|
16
|
+
* ```typescript
|
|
17
|
+
* @NgModule({ imports: [DynamicFormsModule] })
|
|
18
|
+
* ```
|
|
19
|
+
*
|
|
20
|
+
* 3. Use in your template:
|
|
21
|
+
* ```html
|
|
22
|
+
* <mj-dynamic-form
|
|
23
|
+
* [FormDefinition]="formSchema"
|
|
24
|
+
* (FormSubmitted)="onSubmit($event)">
|
|
25
|
+
* </mj-dynamic-form>
|
|
26
|
+
* ```
|
|
27
|
+
*
|
|
28
|
+
* ## Components
|
|
29
|
+
*
|
|
30
|
+
* - **`<mj-dynamic-form>`** — Full form container: title bar, description,
|
|
31
|
+
* questions, validation, and submit/choice buttons.
|
|
32
|
+
* - **`<mj-dynamic-form-field>`** — Individual field renderer with
|
|
33
|
+
* `ControlValueAccessor` for use inside your own reactive forms.
|
|
34
|
+
*
|
|
35
|
+
* ## Supported Field Types
|
|
36
|
+
*
|
|
37
|
+
* text, textarea, email, number, currency, date, datetime, time,
|
|
38
|
+
* daterange, buttongroup, radio, dropdown, checkbox, slider
|
|
39
|
+
*
|
|
40
|
+
* ## Schema Types (from @memberjunction/ai-core-plus)
|
|
41
|
+
*
|
|
42
|
+
* - `AgentResponseForm` — Top-level form definition
|
|
43
|
+
* - `FormQuestion` — Individual field definition
|
|
44
|
+
* - `FormQuestionType` — Union of all field type configurations
|
|
45
|
+
* - `FormOption` — Option in a choice field
|
|
46
|
+
*/
|
|
47
|
+
export * from './lib/forms.module';
|
|
48
|
+
export * from './lib/dynamic-form/dynamic-form.component';
|
|
49
|
+
export * from './lib/dynamic-form-field/dynamic-form-field.component';
|
|
50
|
+
export * from './lib/dynamic-form-response/dynamic-form-response.component';
|
|
51
|
+
export * from './lib/dynamic-form-response/form-response-utils';
|
|
52
|
+
//# sourceMappingURL=public-api.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"public-api.d.ts","sourceRoot":"","sources":["../src/public-api.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA6CG;AAGH,cAAc,oBAAoB,CAAC;AAGnC,cAAc,2CAA2C,CAAC;AAC1D,cAAc,uDAAuD,CAAC;AACtE,cAAc,6DAA6D,CAAC;AAC5E,cAAc,iDAAiD,CAAC"}
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Public API Surface for @memberjunction/ng-forms
|
|
3
|
+
*
|
|
4
|
+
* Generic dynamic form rendering from JSON schemas. Renders structured forms
|
|
5
|
+
* with 14+ field types, built-in validation, responsive layout, and intelligent
|
|
6
|
+
* field sizing. Schema types are defined in `@memberjunction/ai-core-plus`.
|
|
7
|
+
*
|
|
8
|
+
* ## Quick Start
|
|
9
|
+
*
|
|
10
|
+
* 1. Import the module:
|
|
11
|
+
* ```typescript
|
|
12
|
+
* import { DynamicFormsModule } from '@memberjunction/ng-forms';
|
|
13
|
+
* ```
|
|
14
|
+
*
|
|
15
|
+
* 2. Add to your NgModule imports:
|
|
16
|
+
* ```typescript
|
|
17
|
+
* @NgModule({ imports: [DynamicFormsModule] })
|
|
18
|
+
* ```
|
|
19
|
+
*
|
|
20
|
+
* 3. Use in your template:
|
|
21
|
+
* ```html
|
|
22
|
+
* <mj-dynamic-form
|
|
23
|
+
* [FormDefinition]="formSchema"
|
|
24
|
+
* (FormSubmitted)="onSubmit($event)">
|
|
25
|
+
* </mj-dynamic-form>
|
|
26
|
+
* ```
|
|
27
|
+
*
|
|
28
|
+
* ## Components
|
|
29
|
+
*
|
|
30
|
+
* - **`<mj-dynamic-form>`** — Full form container: title bar, description,
|
|
31
|
+
* questions, validation, and submit/choice buttons.
|
|
32
|
+
* - **`<mj-dynamic-form-field>`** — Individual field renderer with
|
|
33
|
+
* `ControlValueAccessor` for use inside your own reactive forms.
|
|
34
|
+
*
|
|
35
|
+
* ## Supported Field Types
|
|
36
|
+
*
|
|
37
|
+
* text, textarea, email, number, currency, date, datetime, time,
|
|
38
|
+
* daterange, buttongroup, radio, dropdown, checkbox, slider
|
|
39
|
+
*
|
|
40
|
+
* ## Schema Types (from @memberjunction/ai-core-plus)
|
|
41
|
+
*
|
|
42
|
+
* - `AgentResponseForm` — Top-level form definition
|
|
43
|
+
* - `FormQuestion` — Individual field definition
|
|
44
|
+
* - `FormQuestionType` — Union of all field type configurations
|
|
45
|
+
* - `FormOption` — Option in a choice field
|
|
46
|
+
*/
|
|
47
|
+
// Module
|
|
48
|
+
export * from './lib/forms.module';
|
|
49
|
+
// Components
|
|
50
|
+
export * from './lib/dynamic-form/dynamic-form.component';
|
|
51
|
+
export * from './lib/dynamic-form-field/dynamic-form-field.component';
|
|
52
|
+
export * from './lib/dynamic-form-response/dynamic-form-response.component';
|
|
53
|
+
export * from './lib/dynamic-form-response/form-response-utils';
|
|
54
|
+
//# sourceMappingURL=public-api.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"public-api.js","sourceRoot":"","sources":["../src/public-api.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA6CG;AAEH,SAAS;AACT,cAAc,oBAAoB,CAAC;AAEnC,aAAa;AACb,cAAc,2CAA2C,CAAC;AAC1D,cAAc,uDAAuD,CAAC;AACtE,cAAc,6DAA6D,CAAC;AAC5E,cAAc,iDAAiD,CAAC","sourcesContent":["/**\n * Public API Surface for @memberjunction/ng-forms\n *\n * Generic dynamic form rendering from JSON schemas. Renders structured forms\n * with 14+ field types, built-in validation, responsive layout, and intelligent\n * field sizing. Schema types are defined in `@memberjunction/ai-core-plus`.\n *\n * ## Quick Start\n *\n * 1. Import the module:\n * ```typescript\n * import { DynamicFormsModule } from '@memberjunction/ng-forms';\n * ```\n *\n * 2. Add to your NgModule imports:\n * ```typescript\n * @NgModule({ imports: [DynamicFormsModule] })\n * ```\n *\n * 3. Use in your template:\n * ```html\n * <mj-dynamic-form\n * [FormDefinition]=\"formSchema\"\n * (FormSubmitted)=\"onSubmit($event)\">\n * </mj-dynamic-form>\n * ```\n *\n * ## Components\n *\n * - **`<mj-dynamic-form>`** — Full form container: title bar, description,\n * questions, validation, and submit/choice buttons.\n * - **`<mj-dynamic-form-field>`** — Individual field renderer with\n * `ControlValueAccessor` for use inside your own reactive forms.\n *\n * ## Supported Field Types\n *\n * text, textarea, email, number, currency, date, datetime, time,\n * daterange, buttongroup, radio, dropdown, checkbox, slider\n *\n * ## Schema Types (from @memberjunction/ai-core-plus)\n *\n * - `AgentResponseForm` — Top-level form definition\n * - `FormQuestion` — Individual field definition\n * - `FormQuestionType` — Union of all field type configurations\n * - `FormOption` — Option in a choice field\n */\n\n// Module\nexport * from './lib/forms.module';\n\n// Components\nexport * from './lib/dynamic-form/dynamic-form.component';\nexport * from './lib/dynamic-form-field/dynamic-form-field.component';\nexport * from './lib/dynamic-form-response/dynamic-form-response.component';\nexport * from './lib/dynamic-form-response/form-response-utils';\n"]}
|
package/package.json
CHANGED
|
@@ -1,10 +1,47 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@memberjunction/ng-forms",
|
|
3
|
-
"version": "
|
|
4
|
-
"description": "
|
|
3
|
+
"version": "5.13.0",
|
|
4
|
+
"description": "MemberJunction: Generic dynamic form rendering from JSON schemas. Renders structured forms with 14+ field types (text, textarea, number, currency, date, daterange, time, checkbox, radio, dropdown, buttongroup, slider, email) with built-in validation, responsive layout, and intelligent field sizing.",
|
|
5
|
+
"main": "./dist/public-api.js",
|
|
6
|
+
"typings": "./dist/public-api.d.ts",
|
|
7
|
+
"files": [
|
|
8
|
+
"/dist"
|
|
9
|
+
],
|
|
10
|
+
"scripts": {
|
|
11
|
+
"test": "echo \"No tests configured yet\"",
|
|
12
|
+
"build": "ngc",
|
|
13
|
+
"test:watch": "vitest"
|
|
14
|
+
},
|
|
5
15
|
"keywords": [
|
|
6
|
-
"
|
|
7
|
-
"
|
|
8
|
-
"
|
|
9
|
-
|
|
16
|
+
"memberjunction",
|
|
17
|
+
"angular",
|
|
18
|
+
"forms",
|
|
19
|
+
"dynamic-forms",
|
|
20
|
+
"json-schema",
|
|
21
|
+
"agent-response"
|
|
22
|
+
],
|
|
23
|
+
"author": "",
|
|
24
|
+
"license": "ISC",
|
|
25
|
+
"devDependencies": {
|
|
26
|
+
"@angular/compiler": "21.1.3",
|
|
27
|
+
"@angular/compiler-cli": "21.1.3",
|
|
28
|
+
"vitest": "^4.0.18"
|
|
29
|
+
},
|
|
30
|
+
"peerDependencies": {
|
|
31
|
+
"@angular/common": "21.1.3",
|
|
32
|
+
"@angular/core": "21.1.3",
|
|
33
|
+
"@angular/forms": "21.1.3"
|
|
34
|
+
},
|
|
35
|
+
"dependencies": {
|
|
36
|
+
"@memberjunction/ai-core-plus": "5.13.0",
|
|
37
|
+
"@progress/kendo-angular-buttons": "22.0.1",
|
|
38
|
+
"@progress/kendo-angular-dateinputs": "22.0.1",
|
|
39
|
+
"@progress/kendo-angular-inputs": "22.0.1",
|
|
40
|
+
"tslib": "^2.8.1"
|
|
41
|
+
},
|
|
42
|
+
"sideEffects": false,
|
|
43
|
+
"repository": {
|
|
44
|
+
"type": "git",
|
|
45
|
+
"url": "https://github.com/MemberJunction/MJ"
|
|
46
|
+
}
|
|
10
47
|
}
|
package/README.md
DELETED
|
@@ -1,45 +0,0 @@
|
|
|
1
|
-
# @memberjunction/ng-forms
|
|
2
|
-
|
|
3
|
-
## ⚠️ IMPORTANT NOTICE ⚠️
|
|
4
|
-
|
|
5
|
-
**This package is created solely for the purpose of setting up OIDC (OpenID Connect) trusted publishing with npm.**
|
|
6
|
-
|
|
7
|
-
This is **NOT** a functional package and contains **NO** code or functionality beyond the OIDC setup configuration.
|
|
8
|
-
|
|
9
|
-
## Purpose
|
|
10
|
-
|
|
11
|
-
This package exists to:
|
|
12
|
-
1. Configure OIDC trusted publishing for the package name `@memberjunction/ng-forms`
|
|
13
|
-
2. Enable secure, token-less publishing from CI/CD workflows
|
|
14
|
-
3. Establish provenance for packages published under this name
|
|
15
|
-
|
|
16
|
-
## What is OIDC Trusted Publishing?
|
|
17
|
-
|
|
18
|
-
OIDC trusted publishing allows package maintainers to publish packages directly from their CI/CD workflows without needing to manage npm access tokens. Instead, it uses OpenID Connect to establish trust between the CI/CD provider (like GitHub Actions) and npm.
|
|
19
|
-
|
|
20
|
-
## Setup Instructions
|
|
21
|
-
|
|
22
|
-
To properly configure OIDC trusted publishing for this package:
|
|
23
|
-
|
|
24
|
-
1. Go to [npmjs.com](https://www.npmjs.com/) and navigate to your package settings
|
|
25
|
-
2. Configure the trusted publisher (e.g., GitHub Actions)
|
|
26
|
-
3. Specify the repository and workflow that should be allowed to publish
|
|
27
|
-
4. Use the configured workflow to publish your actual package
|
|
28
|
-
|
|
29
|
-
## DO NOT USE THIS PACKAGE
|
|
30
|
-
|
|
31
|
-
This package is a placeholder for OIDC configuration only. It:
|
|
32
|
-
- Contains no executable code
|
|
33
|
-
- Provides no functionality
|
|
34
|
-
- Should not be installed as a dependency
|
|
35
|
-
- Exists only for administrative purposes
|
|
36
|
-
|
|
37
|
-
## More Information
|
|
38
|
-
|
|
39
|
-
For more details about npm's trusted publishing feature, see:
|
|
40
|
-
- [npm Trusted Publishing Documentation](https://docs.npmjs.com/generating-provenance-statements)
|
|
41
|
-
- [GitHub Actions OIDC Documentation](https://docs.github.com/en/actions/deployment/security-hardening-your-deployments/about-security-hardening-with-openid-connect)
|
|
42
|
-
|
|
43
|
-
---
|
|
44
|
-
|
|
45
|
-
**Maintained for OIDC setup purposes only**
|