Skip to content

Commit

Permalink
Merge branch 'main' into test/demo-project
Browse files Browse the repository at this point in the history
  • Loading branch information
innerdvations authored Jan 30, 2025
2 parents decc9fe + 8d53805 commit 44b98a8
Show file tree
Hide file tree
Showing 17 changed files with 342 additions and 64 deletions.
4 changes: 0 additions & 4 deletions .editorconfig
Original file line number Diff line number Diff line change
Expand Up @@ -8,9 +8,5 @@ charset = utf-8
trim_trailing_whitespace = true
insert_final_newline = true

[{package.json,*.yml}]
indent_style = space
indent_size = 2

[*.md]
trim_trailing_whitespace = false
32 changes: 15 additions & 17 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -108,11 +108,10 @@ If your Strapi instance uses API tokens, configure the SDK like this:

```typescript
const sdk = strapi({
// Endpoint configuration
baseURL: 'http://localhost:1337/api',
auth: {
strategy: 'api-token',
options: { token: 'your-api-token-here' },
},
// Auth configuration
auth: 'your-api-token-here',
});
```

Expand Down Expand Up @@ -239,16 +238,15 @@ The `debug` tool allows you to control logs using wildcard patterns (`*`):

Below is a list of available namespaces to use:

| Namespace | Description |
| ---------------------------------------- | ----------------------------------------------------------------------------------------- |
| `strapi:core` | Logs SDK initialization, configuration validation, and HTTP client setup. |
| `strapi:validators:config` | Logs details related to SDK configuration validation. |
| `strapi:validators:url` | Logs URL validation processes. |
| `strapi:http` | Logs HTTP client setup, request processing, and response/error handling. |
| `strapi:auth:factory` | Logs the registration and creation of authentication providers. |
| `strapi:auth:manager` | Logs authentication lifecycle management. |
| `strapi:auth:provider:api-token` | Logs operations related to API token authentication. |
| `strapi:auth:provider:users-permissions` | Logs operations related to user and permissions-based authentication. |
| `strapi:ct:collection` | Logs interactions with collection-type content managers. |
| `strapi:ct:single` | Logs interactions with single-type content managers. |
| `strapi:utils:url-helper` | Logs URL helper utility operations (e.g., appending query parameters or formatting URLs). |
| Namespace | Description |
| -------------------------------- | ----------------------------------------------------------------------------------------- |
| `strapi:core` | Logs SDK initialization, configuration validation, and HTTP client setup. |
| `strapi:validators:config` | Logs details related to SDK configuration validation. |
| `strapi:validators:url` | Logs URL validation processes. |
| `strapi:http` | Logs HTTP client setup, request processing, and response/error handling. |
| `strapi:auth:factory` | Logs the registration and creation of authentication providers. |
| `strapi:auth:manager` | Logs authentication lifecycle management. |
| `strapi:auth:provider:api-token` | Logs operations related to API token authentication. |
| `strapi:ct:collection` | Logs interactions with collection-type content managers. |
| `strapi:ct:single` | Logs interactions with single-type content managers. |
| `strapi:utils:url-helper` | Logs URL helper utility operations (e.g., appending query parameters or formatting URLs). |
16 changes: 16 additions & 0 deletions demo/demo-node-javascript/index.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
const { strapi } = require('@strapi/sdk-js');

async function main() {
// Create the SDK instance
const sdk = strapi({ baseURL: 'http://localhost:1337/api' });

// Create a collection type query manager for the categories
const categories = sdk.collection('categories');

// Fetch the list of all categories
const docs = await categories.find();

console.dir(docs, { depth: null });
}

main().catch(console.error);
20 changes: 20 additions & 0 deletions demo/demo-node-javascript/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
{
"name": "demo-node-javascript",
"version": "1.0.0",
"description": "A Strapi SDK demo using a Node x JavaScript application",
"main": "index.js",
"scripts": {
"start": "node index.js",
"debug": "DEBUG=* node index.js"
},
"dependencies": {
"@strapi/sdk-js": "link:../.."
},
"keywords": [],
"author": {
"name": "Strapi Solutions SAS",
"email": "[email protected]",
"url": "https://strapi.io"
},
"license": "ISC"
}
12 changes: 12 additions & 0 deletions demo/demo-node-javascript/pnpm-lock.yaml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

27 changes: 27 additions & 0 deletions demo/demo-node-typescript/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
{
"name": "demo-node-typescript",
"version": "1.0.0",
"description": "A Strapi SDK demo using a Node x TypeScript application",
"main": "dist/index.js",
"private": true,
"type": "module",
"scripts": {
"build": "tsc -p tsconfig.json",
"watch": "tsc -p tsconfig.json -w",
"start": "node dist/index.js",
"debug": "DEBUG=* node dist/index.js"
},
"dependencies": {
"@strapi/sdk-js": "link:../.."
},
"devDependencies": {
"typescript": "5.7.3"
},
"keywords": [],
"author": {
"name": "Strapi Solutions SAS",
"email": "[email protected]",
"url": "https://strapi.io"
},
"license": "ISC"
}
28 changes: 28 additions & 0 deletions demo/demo-node-typescript/pnpm-lock.yaml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

12 changes: 12 additions & 0 deletions demo/demo-node-typescript/src/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
import { strapi } from '@strapi/sdk-js';

// Create the SDK instance
const sdk = strapi({ baseURL: 'http://localhost:1337/api' });

// Create a collection type query manager for the categories
const categories = sdk.collection('categories');

// Fetch the list of all categories
const docs = await categories.find();

console.dir(docs, { depth: null });
26 changes: 26 additions & 0 deletions demo/demo-node-typescript/tsconfig.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
{
"compilerOptions": {
/* Language and Environment */
"allowSyntheticDefaultImports": true,

/* Modules */
"esModuleInterop": true,
"forceConsistentCasingInFileNames": true,
"module": "NodeNext",

/* Emit */
"moduleResolution": "NodeNext",

/* Interop Constraints */

"outDir": "./dist",
"rootDir": "./src",
"skipLibCheck": false,

/* Type Checking */
"strict": true,

/* Completeness */
"target": "ESNext"
}
}
4 changes: 2 additions & 2 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -28,8 +28,8 @@
"exports": {
".": {
"types": "./dist/index.d.ts",
"require": "./dist/bundle.cjs.js",
"import": "./dist/bundle.esm.js",
"require": "./dist/bundle.cjs",
"import": "./dist/bundle.mjs",
"browser": {
"import": "./dist/bundle.browser.min.js",
"require": "./dist/bundle.browser.min.js"
Expand Down
8 changes: 4 additions & 4 deletions rollup.config.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -13,11 +13,11 @@ const isProduction = process.env.NODE_ENV === 'production';
* system, ensuring compatibility with a wide range of tools and runtimes.
*
* Outputs:
* - CommonJS (dist/bundle.cjs.js): for environments using `require`.
* - CommonJS (dist/bundle.cjs): for environments using `require`.
* Compatible with older tools and Node.js versions.
* Includes source maps for debugging.
*
* - ES Module (dist/bundle.esm.js): for modern import/export environments.
* - ES Module (dist/bundle.esm): for modern import/export environments.
* Supports tree-shaking for smaller builds and also includes source maps.
*
* Plugins Used:
Expand All @@ -35,14 +35,14 @@ const node_build = {
output: [
// CommonJS build
{
file: 'dist/bundle.cjs.js',
file: 'dist/bundle.cjs',
format: 'cjs',
sourcemap: isProduction ? 'hidden' : true,
exports: 'named',
},
// ESM build
{
file: 'dist/bundle.esm.js',
file: 'dist/bundle.mjs',
format: 'esm',
sourcemap: isProduction ? 'hidden' : true,
exports: 'named',
Expand Down
68 changes: 54 additions & 14 deletions src/index.ts
Original file line number Diff line number Diff line change
@@ -1,10 +1,46 @@
import { ApiTokenAuthProvider } from './auth';
import { Strapi } from './sdk';
import { StrapiConfigValidator } from './validators';

import type { StrapiConfig } from './sdk';

export * from './errors';

export interface Config {
/**
* The base URL of the Strapi content API.
*
* This specifies where the SDK should send requests.
*
* The URL must include the protocol (`http` or `https`) and serve
* as the root path for all later API operations.
*
* @example
* 'https://api.example.com'
*
* @remarks
* Failing to provide a valid HTTP or HTTPS URL results in a
* `StrapiInitializationError`.
*/
baseURL: string;

/**
* API token to authenticate requests (optional).
*
* When provided, this token is included in the `Authorization` header
* of every request to the Strapi API.
*
* @remarks
* - A valid token must be a non-empty string.
*
* - If the token is invalid or improperly formatted, the SDK
* throws a `StrapiValidationError` during initialization.
*
* - If excluded, the SDK operates without authentication.
*/

auth?: string;
}

/**
* Creates a new instance of the Strapi SDK with a specified configuration.
*
Expand All @@ -25,10 +61,7 @@ export * from './errors';
* // Basic configuration using API token auth
* const config = {
* baseURL: 'https://api.example.com',
* auth: {
* strategy: 'api-token',
* options: { token: 'your_token_here' }
* }
* auth: 'your_token_here',
* };
*
* // Create the SDK instance
Expand All @@ -44,13 +77,20 @@ export * from './errors';
* @throws {StrapiInitializationError} If the provided baseURL doesn't conform to a valid HTTP or HTTPS URL,
* or if the auth configuration is invalid.
*/
export const strapi = (config: StrapiConfig) => {
const configValidator = new StrapiConfigValidator();

return new Strapi<typeof config>(
// Properties
config,
// Dependencies
configValidator
);
export const strapi = (config: Config) => {
const { baseURL, auth } = config;

const sdkConfig: StrapiConfig = { baseURL };

// In this factory, while there is only one auth strategy available, users can't manually set the strategy options.
// Since the SDK constructor needs to define a proper strategy,
// it is handled here if the auth property is provided
if (auth !== undefined) {
sdkConfig.auth = {
strategy: ApiTokenAuthProvider.identifier,
options: { token: auth },
};
}

return new Strapi(sdkConfig);
};
10 changes: 9 additions & 1 deletion src/interceptors/http.ts
Original file line number Diff line number Diff line change
Expand Up @@ -26,8 +26,16 @@ export class HttpInterceptors {
*```
*/
public static setDefaultHeaders(): RequestInterceptor {
const DEFAULT_HEADERS = new Map([['Content-Type', 'application/json']]);

return ({ request }) => {
request.headers.set('Content-Type', 'application/json');
for (const [key, value] of DEFAULT_HEADERS.entries()) {
const hasHeader = request.headers.has(key);

if (!hasHeader) {
request.headers.set(key, value);
}
}

return { request };
};
Expand Down
Loading

0 comments on commit 44b98a8

Please sign in to comment.