@djangocfg/ext-base 1.0.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/README.md +346 -0
- package/dist/api.cjs +41 -0
- package/dist/api.d.cts +35 -0
- package/dist/api.d.ts +35 -0
- package/dist/api.js +2 -0
- package/dist/auth.cjs +10 -0
- package/dist/auth.d.cts +1 -0
- package/dist/auth.d.ts +1 -0
- package/dist/auth.js +2 -0
- package/dist/chunk-3RG5ZIWI.js +8 -0
- package/dist/chunk-MECBWZG4.js +44 -0
- package/dist/chunk-YQGNYUBX.js +67 -0
- package/dist/hooks.cjs +190 -0
- package/dist/hooks.d.cts +96 -0
- package/dist/hooks.d.ts +96 -0
- package/dist/hooks.js +65 -0
- package/dist/index.cjs +131 -0
- package/dist/index.d.cts +246 -0
- package/dist/index.d.ts +246 -0
- package/dist/index.js +3 -0
- package/package.json +80 -0
- package/src/api/createExtensionAPI.ts +63 -0
- package/src/api/index.ts +5 -0
- package/src/auth/index.ts +13 -0
- package/src/config/env.ts +59 -0
- package/src/config/index.ts +5 -0
- package/src/context/ExtensionProvider.tsx +102 -0
- package/src/context/createExtensionContext.tsx +78 -0
- package/src/context/index.ts +7 -0
- package/src/hooks/index.ts +6 -0
- package/src/hooks/useInfinitePagination.ts +117 -0
- package/src/hooks/usePagination.ts +155 -0
- package/src/hooks.ts +17 -0
- package/src/index.ts +21 -0
- package/src/logger/createExtensionLogger.ts +61 -0
- package/src/logger/index.ts +5 -0
- package/src/types/context.ts +93 -0
- package/src/types/error.ts +12 -0
- package/src/types/index.ts +17 -0
- package/src/types/logger.ts +17 -0
- package/src/types/pagination.ts +47 -0
- package/src/utils/errors.ts +71 -0
- package/src/utils/index.ts +10 -0
package/dist/hooks.cjs
ADDED
|
@@ -0,0 +1,190 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
var consola = require('consola');
|
|
4
|
+
var react = require('react');
|
|
5
|
+
var jsxRuntime = require('react/jsx-runtime');
|
|
6
|
+
var swr = require('swr');
|
|
7
|
+
|
|
8
|
+
var __require = /* @__PURE__ */ ((x) => typeof require !== "undefined" ? require : typeof Proxy !== "undefined" ? new Proxy(x, {
|
|
9
|
+
get: (a, b) => (typeof require !== "undefined" ? require : a)[b]
|
|
10
|
+
}) : x)(function(x) {
|
|
11
|
+
if (typeof require !== "undefined") return require.apply(this, arguments);
|
|
12
|
+
throw Error('Dynamic require of "' + x + '" is not supported');
|
|
13
|
+
});
|
|
14
|
+
|
|
15
|
+
// src/config/env.ts
|
|
16
|
+
var isDevelopment = process.env.NODE_ENV === "development";
|
|
17
|
+
var isProduction = process.env.NODE_ENV === "production";
|
|
18
|
+
var isTest = process.env.NODE_ENV === "test";
|
|
19
|
+
var isStaticBuild = process.env.NEXT_PUBLIC_STATIC_BUILD === "true";
|
|
20
|
+
var isClient = typeof window !== "undefined";
|
|
21
|
+
var isServer = !isClient;
|
|
22
|
+
var getApiUrl = () => {
|
|
23
|
+
return process.env.NEXT_PUBLIC_API_URL || "";
|
|
24
|
+
};
|
|
25
|
+
var env = {
|
|
26
|
+
isDevelopment,
|
|
27
|
+
isProduction,
|
|
28
|
+
isTest,
|
|
29
|
+
isStaticBuild,
|
|
30
|
+
isClient,
|
|
31
|
+
isServer,
|
|
32
|
+
getApiUrl
|
|
33
|
+
};
|
|
34
|
+
|
|
35
|
+
// src/api/createExtensionAPI.ts
|
|
36
|
+
function createExtensionAPI(APIClass) {
|
|
37
|
+
let storage;
|
|
38
|
+
try {
|
|
39
|
+
const { api: accountsApi } = __require("@djangocfg/api");
|
|
40
|
+
storage = accountsApi._storage;
|
|
41
|
+
} catch (error) {
|
|
42
|
+
storage = void 0;
|
|
43
|
+
}
|
|
44
|
+
const apiUrl = isStaticBuild ? "" : getApiUrl();
|
|
45
|
+
return new APIClass(apiUrl, storage ? { storage } : void 0);
|
|
46
|
+
}
|
|
47
|
+
function getSharedAuthStorage() {
|
|
48
|
+
try {
|
|
49
|
+
const { api: accountsApi } = __require("@djangocfg/api");
|
|
50
|
+
return accountsApi._storage;
|
|
51
|
+
} catch (error) {
|
|
52
|
+
return void 0;
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
// src/utils/errors.ts
|
|
57
|
+
function isExtensionError(error) {
|
|
58
|
+
return typeof error === "object" && error !== null && "message" in error && "timestamp" in error;
|
|
59
|
+
}
|
|
60
|
+
function createExtensionError(error, code, details) {
|
|
61
|
+
const message = error instanceof Error ? error.message : String(error);
|
|
62
|
+
return {
|
|
63
|
+
message,
|
|
64
|
+
code,
|
|
65
|
+
details,
|
|
66
|
+
timestamp: (/* @__PURE__ */ new Date()).toISOString()
|
|
67
|
+
};
|
|
68
|
+
}
|
|
69
|
+
function formatErrorMessage(error) {
|
|
70
|
+
if (isExtensionError(error)) {
|
|
71
|
+
return error.code ? `[${error.code}] ${error.message}` : error.message;
|
|
72
|
+
}
|
|
73
|
+
if (error instanceof Error) {
|
|
74
|
+
return error.message;
|
|
75
|
+
}
|
|
76
|
+
return String(error);
|
|
77
|
+
}
|
|
78
|
+
function handleExtensionError(error, logger, callback) {
|
|
79
|
+
const extensionError = isExtensionError(error) ? error : createExtensionError(error);
|
|
80
|
+
if (logger) {
|
|
81
|
+
logger.error("Extension error:", extensionError);
|
|
82
|
+
}
|
|
83
|
+
if (callback) {
|
|
84
|
+
callback(extensionError);
|
|
85
|
+
}
|
|
86
|
+
}
|
|
87
|
+
var isDevelopment2 = process.env.NODE_ENV === "development";
|
|
88
|
+
var LEVEL_MAP = {
|
|
89
|
+
debug: 4,
|
|
90
|
+
info: 3,
|
|
91
|
+
warn: 2,
|
|
92
|
+
error: 1
|
|
93
|
+
};
|
|
94
|
+
function createExtensionLogger(options) {
|
|
95
|
+
const { tag, level = "info", enabled = true } = options;
|
|
96
|
+
if (!enabled) {
|
|
97
|
+
const noop = () => {
|
|
98
|
+
};
|
|
99
|
+
return {
|
|
100
|
+
info: noop,
|
|
101
|
+
warn: noop,
|
|
102
|
+
error: noop,
|
|
103
|
+
debug: noop,
|
|
104
|
+
success: noop
|
|
105
|
+
};
|
|
106
|
+
}
|
|
107
|
+
const logLevel = isDevelopment2 ? LEVEL_MAP[level] : LEVEL_MAP.error;
|
|
108
|
+
const consola$1 = consola.createConsola({
|
|
109
|
+
level: logLevel
|
|
110
|
+
}).withTag(tag);
|
|
111
|
+
return {
|
|
112
|
+
info: (...args) => consola$1.info(...args),
|
|
113
|
+
warn: (...args) => consola$1.warn(...args),
|
|
114
|
+
error: (...args) => consola$1.error(...args),
|
|
115
|
+
debug: (...args) => consola$1.debug(...args),
|
|
116
|
+
success: (...args) => consola$1.success(...args)
|
|
117
|
+
};
|
|
118
|
+
}
|
|
119
|
+
function createExtensionContext({
|
|
120
|
+
displayName,
|
|
121
|
+
errorMessage
|
|
122
|
+
}) {
|
|
123
|
+
const Context = react.createContext(void 0);
|
|
124
|
+
Context.displayName = displayName;
|
|
125
|
+
const Provider = ({ value, children }) => {
|
|
126
|
+
return /* @__PURE__ */ jsxRuntime.jsx(Context.Provider, { value, children });
|
|
127
|
+
};
|
|
128
|
+
const useContextHook = () => {
|
|
129
|
+
const context = react.useContext(Context);
|
|
130
|
+
if (context === void 0) {
|
|
131
|
+
throw new Error(
|
|
132
|
+
errorMessage || `use${displayName} must be used within ${displayName}Provider`
|
|
133
|
+
);
|
|
134
|
+
}
|
|
135
|
+
return context;
|
|
136
|
+
};
|
|
137
|
+
return {
|
|
138
|
+
Context,
|
|
139
|
+
Provider,
|
|
140
|
+
useContext: useContextHook
|
|
141
|
+
};
|
|
142
|
+
}
|
|
143
|
+
var DEFAULT_OPTIONS = {
|
|
144
|
+
revalidateOnFocus: false,
|
|
145
|
+
revalidateOnReconnect: false,
|
|
146
|
+
revalidateIfStale: false
|
|
147
|
+
};
|
|
148
|
+
var registeredExtensions = /* @__PURE__ */ new Set();
|
|
149
|
+
function ExtensionProvider({ children, metadata, options = {} }) {
|
|
150
|
+
const config = { ...DEFAULT_OPTIONS, ...options };
|
|
151
|
+
react.useEffect(() => {
|
|
152
|
+
if (registeredExtensions.has(metadata.name)) {
|
|
153
|
+
if (isDevelopment) {
|
|
154
|
+
console.warn(
|
|
155
|
+
`[ExtensionProvider] Extension "${metadata.name}" is already registered. This might indicate that the extension is mounted multiple times.`
|
|
156
|
+
);
|
|
157
|
+
}
|
|
158
|
+
return;
|
|
159
|
+
}
|
|
160
|
+
registeredExtensions.add(metadata.name);
|
|
161
|
+
if (isDevelopment) {
|
|
162
|
+
const logger = createExtensionLogger({ tag: "ext-base", level: "info" });
|
|
163
|
+
logger.info(
|
|
164
|
+
`Extension registered: ${metadata.displayName || metadata.name} v${metadata.version}`
|
|
165
|
+
);
|
|
166
|
+
}
|
|
167
|
+
return () => {
|
|
168
|
+
registeredExtensions.delete(metadata.name);
|
|
169
|
+
};
|
|
170
|
+
}, [metadata.name, metadata.version, metadata.displayName]);
|
|
171
|
+
return /* @__PURE__ */ jsxRuntime.jsx(swr.SWRConfig, { value: config, children });
|
|
172
|
+
}
|
|
173
|
+
|
|
174
|
+
exports.ExtensionProvider = ExtensionProvider;
|
|
175
|
+
exports.createExtensionAPI = createExtensionAPI;
|
|
176
|
+
exports.createExtensionContext = createExtensionContext;
|
|
177
|
+
exports.createExtensionError = createExtensionError;
|
|
178
|
+
exports.createExtensionLogger = createExtensionLogger;
|
|
179
|
+
exports.env = env;
|
|
180
|
+
exports.formatErrorMessage = formatErrorMessage;
|
|
181
|
+
exports.getApiUrl = getApiUrl;
|
|
182
|
+
exports.getSharedAuthStorage = getSharedAuthStorage;
|
|
183
|
+
exports.handleExtensionError = handleExtensionError;
|
|
184
|
+
exports.isClient = isClient;
|
|
185
|
+
exports.isDevelopment = isDevelopment;
|
|
186
|
+
exports.isExtensionError = isExtensionError;
|
|
187
|
+
exports.isProduction = isProduction;
|
|
188
|
+
exports.isServer = isServer;
|
|
189
|
+
exports.isStaticBuild = isStaticBuild;
|
|
190
|
+
exports.isTest = isTest;
|
package/dist/hooks.d.cts
ADDED
|
@@ -0,0 +1,96 @@
|
|
|
1
|
+
import { ExtensionProviderProps } from './index.cjs';
|
|
2
|
+
export { ErrorHandler, ExtensionContextOptions, ExtensionError, ExtensionLogger, ExtensionMetadata, InfinitePaginationOptions, InfinitePaginationReturn, LoggerOptions, PaginatedResponse, PaginationParams, PaginationState, createExtensionError, createExtensionLogger, env, formatErrorMessage, getApiUrl, handleExtensionError, isClient, isDevelopment, isExtensionError, isProduction, isServer, isStaticBuild, isTest } from './index.cjs';
|
|
3
|
+
export { createExtensionAPI, getSharedAuthStorage } from './api.cjs';
|
|
4
|
+
import { Context, ReactNode, ReactElement } from 'react';
|
|
5
|
+
import * as react_jsx_runtime from 'react/jsx-runtime';
|
|
6
|
+
|
|
7
|
+
/**
|
|
8
|
+
* Utility for creating typed React contexts for extensions
|
|
9
|
+
*/
|
|
10
|
+
|
|
11
|
+
interface CreateExtensionContextOptions<T> {
|
|
12
|
+
/** Display name for the context (for debugging) */
|
|
13
|
+
displayName: string;
|
|
14
|
+
/** Error message when hook is used outside provider */
|
|
15
|
+
errorMessage?: string;
|
|
16
|
+
}
|
|
17
|
+
interface ExtensionContextReturn<T> {
|
|
18
|
+
/** The React Context */
|
|
19
|
+
Context: Context<T | undefined>;
|
|
20
|
+
/** Provider component */
|
|
21
|
+
Provider: (props: {
|
|
22
|
+
value: T;
|
|
23
|
+
children: ReactNode;
|
|
24
|
+
}) => ReactElement;
|
|
25
|
+
/** Hook to access context value */
|
|
26
|
+
useContext: () => T;
|
|
27
|
+
}
|
|
28
|
+
/**
|
|
29
|
+
* Creates a typed React context with provider and hook
|
|
30
|
+
*
|
|
31
|
+
* @example
|
|
32
|
+
* ```tsx
|
|
33
|
+
* interface MyContextValue {
|
|
34
|
+
* data: string[];
|
|
35
|
+
* isLoading: boolean;
|
|
36
|
+
* }
|
|
37
|
+
*
|
|
38
|
+
* const { Provider, useContext } = createExtensionContext<MyContextValue>({
|
|
39
|
+
* displayName: 'MyContext'
|
|
40
|
+
* });
|
|
41
|
+
*
|
|
42
|
+
* // In provider component:
|
|
43
|
+
* <Provider value={{ data: [], isLoading: false }}>
|
|
44
|
+
* {children}
|
|
45
|
+
* </Provider>
|
|
46
|
+
*
|
|
47
|
+
* // In consumer component:
|
|
48
|
+
* const { data, isLoading } = useContext();
|
|
49
|
+
* ```
|
|
50
|
+
*/
|
|
51
|
+
declare function createExtensionContext<T>({ displayName, errorMessage, }: CreateExtensionContextOptions<T>): ExtensionContextReturn<T>;
|
|
52
|
+
|
|
53
|
+
/**
|
|
54
|
+
* Base provider with SWR configuration for extension contexts
|
|
55
|
+
*
|
|
56
|
+
* Provides:
|
|
57
|
+
* - SWR configuration for data fetching
|
|
58
|
+
* - Extension registration and metadata management
|
|
59
|
+
* - Auth context from @djangocfg/api (automatically available via useAuth)
|
|
60
|
+
*
|
|
61
|
+
* @example
|
|
62
|
+
* ```tsx
|
|
63
|
+
* // In extension package:
|
|
64
|
+
* export function NewsletterProvider({ children }: { children: ReactNode }) {
|
|
65
|
+
* return (
|
|
66
|
+
* <ExtensionProvider
|
|
67
|
+
* metadata={{
|
|
68
|
+
* name: 'newsletter',
|
|
69
|
+
* version: '1.0.0',
|
|
70
|
+
* author: 'DjangoCFG',
|
|
71
|
+
* displayName: 'Newsletter',
|
|
72
|
+
* description: 'Newsletter subscription management',
|
|
73
|
+
* icon: '📧',
|
|
74
|
+
* license: 'MIT',
|
|
75
|
+
* githubUrl: 'https://github.com/markolofsen/django-cfg',
|
|
76
|
+
* keywords: ['newsletter', 'email', 'subscription'],
|
|
77
|
+
* }}
|
|
78
|
+
* options={{ revalidateOnFocus: true }}
|
|
79
|
+
* >
|
|
80
|
+
* {children}
|
|
81
|
+
* </ExtensionProvider>
|
|
82
|
+
* );
|
|
83
|
+
* }
|
|
84
|
+
*
|
|
85
|
+
* // In components:
|
|
86
|
+
* import { useAuth } from '@djangocfg/api/auth';
|
|
87
|
+
*
|
|
88
|
+
* function MyComponent() {
|
|
89
|
+
* const { user, isAuthenticated } = useAuth();
|
|
90
|
+
* // Auth is automatically available!
|
|
91
|
+
* }
|
|
92
|
+
* ```
|
|
93
|
+
*/
|
|
94
|
+
declare function ExtensionProvider({ children, metadata, options }: ExtensionProviderProps): react_jsx_runtime.JSX.Element;
|
|
95
|
+
|
|
96
|
+
export { type CreateExtensionContextOptions, type ExtensionContextReturn, ExtensionProvider, ExtensionProviderProps, createExtensionContext };
|
package/dist/hooks.d.ts
ADDED
|
@@ -0,0 +1,96 @@
|
|
|
1
|
+
import { ExtensionProviderProps } from './index.js';
|
|
2
|
+
export { ErrorHandler, ExtensionContextOptions, ExtensionError, ExtensionLogger, ExtensionMetadata, InfinitePaginationOptions, InfinitePaginationReturn, LoggerOptions, PaginatedResponse, PaginationParams, PaginationState, createExtensionError, createExtensionLogger, env, formatErrorMessage, getApiUrl, handleExtensionError, isClient, isDevelopment, isExtensionError, isProduction, isServer, isStaticBuild, isTest } from './index.js';
|
|
3
|
+
export { createExtensionAPI, getSharedAuthStorage } from './api.js';
|
|
4
|
+
import { Context, ReactNode, ReactElement } from 'react';
|
|
5
|
+
import * as react_jsx_runtime from 'react/jsx-runtime';
|
|
6
|
+
|
|
7
|
+
/**
|
|
8
|
+
* Utility for creating typed React contexts for extensions
|
|
9
|
+
*/
|
|
10
|
+
|
|
11
|
+
interface CreateExtensionContextOptions<T> {
|
|
12
|
+
/** Display name for the context (for debugging) */
|
|
13
|
+
displayName: string;
|
|
14
|
+
/** Error message when hook is used outside provider */
|
|
15
|
+
errorMessage?: string;
|
|
16
|
+
}
|
|
17
|
+
interface ExtensionContextReturn<T> {
|
|
18
|
+
/** The React Context */
|
|
19
|
+
Context: Context<T | undefined>;
|
|
20
|
+
/** Provider component */
|
|
21
|
+
Provider: (props: {
|
|
22
|
+
value: T;
|
|
23
|
+
children: ReactNode;
|
|
24
|
+
}) => ReactElement;
|
|
25
|
+
/** Hook to access context value */
|
|
26
|
+
useContext: () => T;
|
|
27
|
+
}
|
|
28
|
+
/**
|
|
29
|
+
* Creates a typed React context with provider and hook
|
|
30
|
+
*
|
|
31
|
+
* @example
|
|
32
|
+
* ```tsx
|
|
33
|
+
* interface MyContextValue {
|
|
34
|
+
* data: string[];
|
|
35
|
+
* isLoading: boolean;
|
|
36
|
+
* }
|
|
37
|
+
*
|
|
38
|
+
* const { Provider, useContext } = createExtensionContext<MyContextValue>({
|
|
39
|
+
* displayName: 'MyContext'
|
|
40
|
+
* });
|
|
41
|
+
*
|
|
42
|
+
* // In provider component:
|
|
43
|
+
* <Provider value={{ data: [], isLoading: false }}>
|
|
44
|
+
* {children}
|
|
45
|
+
* </Provider>
|
|
46
|
+
*
|
|
47
|
+
* // In consumer component:
|
|
48
|
+
* const { data, isLoading } = useContext();
|
|
49
|
+
* ```
|
|
50
|
+
*/
|
|
51
|
+
declare function createExtensionContext<T>({ displayName, errorMessage, }: CreateExtensionContextOptions<T>): ExtensionContextReturn<T>;
|
|
52
|
+
|
|
53
|
+
/**
|
|
54
|
+
* Base provider with SWR configuration for extension contexts
|
|
55
|
+
*
|
|
56
|
+
* Provides:
|
|
57
|
+
* - SWR configuration for data fetching
|
|
58
|
+
* - Extension registration and metadata management
|
|
59
|
+
* - Auth context from @djangocfg/api (automatically available via useAuth)
|
|
60
|
+
*
|
|
61
|
+
* @example
|
|
62
|
+
* ```tsx
|
|
63
|
+
* // In extension package:
|
|
64
|
+
* export function NewsletterProvider({ children }: { children: ReactNode }) {
|
|
65
|
+
* return (
|
|
66
|
+
* <ExtensionProvider
|
|
67
|
+
* metadata={{
|
|
68
|
+
* name: 'newsletter',
|
|
69
|
+
* version: '1.0.0',
|
|
70
|
+
* author: 'DjangoCFG',
|
|
71
|
+
* displayName: 'Newsletter',
|
|
72
|
+
* description: 'Newsletter subscription management',
|
|
73
|
+
* icon: '📧',
|
|
74
|
+
* license: 'MIT',
|
|
75
|
+
* githubUrl: 'https://github.com/markolofsen/django-cfg',
|
|
76
|
+
* keywords: ['newsletter', 'email', 'subscription'],
|
|
77
|
+
* }}
|
|
78
|
+
* options={{ revalidateOnFocus: true }}
|
|
79
|
+
* >
|
|
80
|
+
* {children}
|
|
81
|
+
* </ExtensionProvider>
|
|
82
|
+
* );
|
|
83
|
+
* }
|
|
84
|
+
*
|
|
85
|
+
* // In components:
|
|
86
|
+
* import { useAuth } from '@djangocfg/api/auth';
|
|
87
|
+
*
|
|
88
|
+
* function MyComponent() {
|
|
89
|
+
* const { user, isAuthenticated } = useAuth();
|
|
90
|
+
* // Auth is automatically available!
|
|
91
|
+
* }
|
|
92
|
+
* ```
|
|
93
|
+
*/
|
|
94
|
+
declare function ExtensionProvider({ children, metadata, options }: ExtensionProviderProps): react_jsx_runtime.JSX.Element;
|
|
95
|
+
|
|
96
|
+
export { type CreateExtensionContextOptions, type ExtensionContextReturn, ExtensionProvider, ExtensionProviderProps, createExtensionContext };
|
package/dist/hooks.js
ADDED
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
import { createExtensionLogger } from './chunk-YQGNYUBX.js';
|
|
2
|
+
export { createExtensionError, createExtensionLogger, formatErrorMessage, handleExtensionError, isExtensionError } from './chunk-YQGNYUBX.js';
|
|
3
|
+
import { isDevelopment } from './chunk-MECBWZG4.js';
|
|
4
|
+
export { createExtensionAPI, env, getApiUrl, getSharedAuthStorage, isClient, isDevelopment, isProduction, isServer, isStaticBuild, isTest } from './chunk-MECBWZG4.js';
|
|
5
|
+
import './chunk-3RG5ZIWI.js';
|
|
6
|
+
import { createContext, useEffect, useContext } from 'react';
|
|
7
|
+
import { jsx } from 'react/jsx-runtime';
|
|
8
|
+
import { SWRConfig } from 'swr';
|
|
9
|
+
|
|
10
|
+
function createExtensionContext({
|
|
11
|
+
displayName,
|
|
12
|
+
errorMessage
|
|
13
|
+
}) {
|
|
14
|
+
const Context = createContext(void 0);
|
|
15
|
+
Context.displayName = displayName;
|
|
16
|
+
const Provider = ({ value, children }) => {
|
|
17
|
+
return /* @__PURE__ */ jsx(Context.Provider, { value, children });
|
|
18
|
+
};
|
|
19
|
+
const useContextHook = () => {
|
|
20
|
+
const context = useContext(Context);
|
|
21
|
+
if (context === void 0) {
|
|
22
|
+
throw new Error(
|
|
23
|
+
errorMessage || `use${displayName} must be used within ${displayName}Provider`
|
|
24
|
+
);
|
|
25
|
+
}
|
|
26
|
+
return context;
|
|
27
|
+
};
|
|
28
|
+
return {
|
|
29
|
+
Context,
|
|
30
|
+
Provider,
|
|
31
|
+
useContext: useContextHook
|
|
32
|
+
};
|
|
33
|
+
}
|
|
34
|
+
var DEFAULT_OPTIONS = {
|
|
35
|
+
revalidateOnFocus: false,
|
|
36
|
+
revalidateOnReconnect: false,
|
|
37
|
+
revalidateIfStale: false
|
|
38
|
+
};
|
|
39
|
+
var registeredExtensions = /* @__PURE__ */ new Set();
|
|
40
|
+
function ExtensionProvider({ children, metadata, options = {} }) {
|
|
41
|
+
const config = { ...DEFAULT_OPTIONS, ...options };
|
|
42
|
+
useEffect(() => {
|
|
43
|
+
if (registeredExtensions.has(metadata.name)) {
|
|
44
|
+
if (isDevelopment) {
|
|
45
|
+
console.warn(
|
|
46
|
+
`[ExtensionProvider] Extension "${metadata.name}" is already registered. This might indicate that the extension is mounted multiple times.`
|
|
47
|
+
);
|
|
48
|
+
}
|
|
49
|
+
return;
|
|
50
|
+
}
|
|
51
|
+
registeredExtensions.add(metadata.name);
|
|
52
|
+
if (isDevelopment) {
|
|
53
|
+
const logger = createExtensionLogger({ tag: "ext-base", level: "info" });
|
|
54
|
+
logger.info(
|
|
55
|
+
`Extension registered: ${metadata.displayName || metadata.name} v${metadata.version}`
|
|
56
|
+
);
|
|
57
|
+
}
|
|
58
|
+
return () => {
|
|
59
|
+
registeredExtensions.delete(metadata.name);
|
|
60
|
+
};
|
|
61
|
+
}, [metadata.name, metadata.version, metadata.displayName]);
|
|
62
|
+
return /* @__PURE__ */ jsx(SWRConfig, { value: config, children });
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
export { ExtensionProvider, createExtensionContext };
|
package/dist/index.cjs
ADDED
|
@@ -0,0 +1,131 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
var consola = require('consola');
|
|
4
|
+
|
|
5
|
+
var __require = /* @__PURE__ */ ((x) => typeof require !== "undefined" ? require : typeof Proxy !== "undefined" ? new Proxy(x, {
|
|
6
|
+
get: (a, b) => (typeof require !== "undefined" ? require : a)[b]
|
|
7
|
+
}) : x)(function(x) {
|
|
8
|
+
if (typeof require !== "undefined") return require.apply(this, arguments);
|
|
9
|
+
throw Error('Dynamic require of "' + x + '" is not supported');
|
|
10
|
+
});
|
|
11
|
+
|
|
12
|
+
// src/config/env.ts
|
|
13
|
+
var isDevelopment = process.env.NODE_ENV === "development";
|
|
14
|
+
var isProduction = process.env.NODE_ENV === "production";
|
|
15
|
+
var isTest = process.env.NODE_ENV === "test";
|
|
16
|
+
var isStaticBuild = process.env.NEXT_PUBLIC_STATIC_BUILD === "true";
|
|
17
|
+
var isClient = typeof window !== "undefined";
|
|
18
|
+
var isServer = !isClient;
|
|
19
|
+
var getApiUrl = () => {
|
|
20
|
+
return process.env.NEXT_PUBLIC_API_URL || "";
|
|
21
|
+
};
|
|
22
|
+
var env = {
|
|
23
|
+
isDevelopment,
|
|
24
|
+
isProduction,
|
|
25
|
+
isTest,
|
|
26
|
+
isStaticBuild,
|
|
27
|
+
isClient,
|
|
28
|
+
isServer,
|
|
29
|
+
getApiUrl
|
|
30
|
+
};
|
|
31
|
+
|
|
32
|
+
// src/api/createExtensionAPI.ts
|
|
33
|
+
function createExtensionAPI(APIClass) {
|
|
34
|
+
let storage;
|
|
35
|
+
try {
|
|
36
|
+
const { api: accountsApi } = __require("@djangocfg/api");
|
|
37
|
+
storage = accountsApi._storage;
|
|
38
|
+
} catch (error) {
|
|
39
|
+
storage = void 0;
|
|
40
|
+
}
|
|
41
|
+
const apiUrl = isStaticBuild ? "" : getApiUrl();
|
|
42
|
+
return new APIClass(apiUrl, storage ? { storage } : void 0);
|
|
43
|
+
}
|
|
44
|
+
function getSharedAuthStorage() {
|
|
45
|
+
try {
|
|
46
|
+
const { api: accountsApi } = __require("@djangocfg/api");
|
|
47
|
+
return accountsApi._storage;
|
|
48
|
+
} catch (error) {
|
|
49
|
+
return void 0;
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
// src/utils/errors.ts
|
|
54
|
+
function isExtensionError(error) {
|
|
55
|
+
return typeof error === "object" && error !== null && "message" in error && "timestamp" in error;
|
|
56
|
+
}
|
|
57
|
+
function createExtensionError(error, code, details) {
|
|
58
|
+
const message = error instanceof Error ? error.message : String(error);
|
|
59
|
+
return {
|
|
60
|
+
message,
|
|
61
|
+
code,
|
|
62
|
+
details,
|
|
63
|
+
timestamp: (/* @__PURE__ */ new Date()).toISOString()
|
|
64
|
+
};
|
|
65
|
+
}
|
|
66
|
+
function formatErrorMessage(error) {
|
|
67
|
+
if (isExtensionError(error)) {
|
|
68
|
+
return error.code ? `[${error.code}] ${error.message}` : error.message;
|
|
69
|
+
}
|
|
70
|
+
if (error instanceof Error) {
|
|
71
|
+
return error.message;
|
|
72
|
+
}
|
|
73
|
+
return String(error);
|
|
74
|
+
}
|
|
75
|
+
function handleExtensionError(error, logger, callback) {
|
|
76
|
+
const extensionError = isExtensionError(error) ? error : createExtensionError(error);
|
|
77
|
+
if (logger) {
|
|
78
|
+
logger.error("Extension error:", extensionError);
|
|
79
|
+
}
|
|
80
|
+
if (callback) {
|
|
81
|
+
callback(extensionError);
|
|
82
|
+
}
|
|
83
|
+
}
|
|
84
|
+
var isDevelopment2 = process.env.NODE_ENV === "development";
|
|
85
|
+
var LEVEL_MAP = {
|
|
86
|
+
debug: 4,
|
|
87
|
+
info: 3,
|
|
88
|
+
warn: 2,
|
|
89
|
+
error: 1
|
|
90
|
+
};
|
|
91
|
+
function createExtensionLogger(options) {
|
|
92
|
+
const { tag, level = "info", enabled = true } = options;
|
|
93
|
+
if (!enabled) {
|
|
94
|
+
const noop = () => {
|
|
95
|
+
};
|
|
96
|
+
return {
|
|
97
|
+
info: noop,
|
|
98
|
+
warn: noop,
|
|
99
|
+
error: noop,
|
|
100
|
+
debug: noop,
|
|
101
|
+
success: noop
|
|
102
|
+
};
|
|
103
|
+
}
|
|
104
|
+
const logLevel = isDevelopment2 ? LEVEL_MAP[level] : LEVEL_MAP.error;
|
|
105
|
+
const consola$1 = consola.createConsola({
|
|
106
|
+
level: logLevel
|
|
107
|
+
}).withTag(tag);
|
|
108
|
+
return {
|
|
109
|
+
info: (...args) => consola$1.info(...args),
|
|
110
|
+
warn: (...args) => consola$1.warn(...args),
|
|
111
|
+
error: (...args) => consola$1.error(...args),
|
|
112
|
+
debug: (...args) => consola$1.debug(...args),
|
|
113
|
+
success: (...args) => consola$1.success(...args)
|
|
114
|
+
};
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
exports.createExtensionAPI = createExtensionAPI;
|
|
118
|
+
exports.createExtensionError = createExtensionError;
|
|
119
|
+
exports.createExtensionLogger = createExtensionLogger;
|
|
120
|
+
exports.env = env;
|
|
121
|
+
exports.formatErrorMessage = formatErrorMessage;
|
|
122
|
+
exports.getApiUrl = getApiUrl;
|
|
123
|
+
exports.getSharedAuthStorage = getSharedAuthStorage;
|
|
124
|
+
exports.handleExtensionError = handleExtensionError;
|
|
125
|
+
exports.isClient = isClient;
|
|
126
|
+
exports.isDevelopment = isDevelopment;
|
|
127
|
+
exports.isExtensionError = isExtensionError;
|
|
128
|
+
exports.isProduction = isProduction;
|
|
129
|
+
exports.isServer = isServer;
|
|
130
|
+
exports.isStaticBuild = isStaticBuild;
|
|
131
|
+
exports.isTest = isTest;
|