namirasoft-site 1.4.45 → 1.4.46
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/SKILL.md +184 -0
- package/logo.png +0 -0
- package/package.json +3 -3
- package/tsconfig.json +3 -0
package/SKILL.md
ADDED
|
@@ -0,0 +1,184 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: namirasoft-site
|
|
3
|
+
description: Use the namirasoft-site package when modeling a Namirasoft product as a typed metadata graph (database -> tables -> rows) with shared HTTP versioning. Trigger when the project's package.json depends on "namirasoft-site", when subclassing NSBaseServer / NSBaseMetaDatabase / NSBaseMetaTable, when wiring an axios-based product client that must send the ns-site-version header, when generating route URLs (list/new/view/edit) for a product table, or when parsing a Namirasoft package/API/console name with NSNameParser. Skip for pure UI work — that lives in namirasoft-site-react.
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# namirasoft-site
|
|
7
|
+
|
|
8
|
+
The framework-agnostic "site" layer for Namirasoft products. It extends `namirasoft-core`'s `BaseServer` / `BaseMetaDatabase` / `BaseMetaTable` with product-aware metadata, link generation, and a shared `ns-site-version` request header convention. There is no UI here — `namirasoft-site-react` is the React companion.
|
|
9
|
+
|
|
10
|
+
## When this skill applies
|
|
11
|
+
|
|
12
|
+
Trigger when the project's `package.json` lists `namirasoft-site` as a dependency, or when the user imports anything from `"namirasoft-site"`. Typical signals:
|
|
13
|
+
|
|
14
|
+
- defining a new product's database/table metadata (`class FooDatabase extends NSBaseMetaDatabase<FooServer>`)
|
|
15
|
+
- writing an axios client that must propagate or read the `ns-site-version` header
|
|
16
|
+
- generating product-relative URLs (`/foo/list`, `/foo/{id}/view`, `/foo/{id}/edit`)
|
|
17
|
+
- introspecting a Namirasoft package/repo name to derive class names, short names, or CLI command names
|
|
18
|
+
|
|
19
|
+
Skip for plain backend services that don't model a product, and for UI rendering (use `namirasoft-site-react`).
|
|
20
|
+
|
|
21
|
+
## Cardinal rules
|
|
22
|
+
|
|
23
|
+
1. **Reuse the base classes — don't reimplement.** Every product server extends `NSBaseServer`, every product database extends `NSBaseMetaDatabase<YourServer>`, every product table extends `NSBaseMetaTable<YourServer, Row>`. Don't hand-roll axios clients or metadata containers; subclass these so version-header wiring, link generation, and CFT (category/field/tag) sibling-table detection come for free.
|
|
24
|
+
2. **Always import from the package root**: `import { NSBaseServer, NSHeader } from "namirasoft-site";` — never deep-import from `dist/...`.
|
|
25
|
+
3. **Override `NSBaseMetaDatabase.getServerBaseURL`** (the static method) at app bootstrap before any server is instantiated. The default throws. The React companion sets this from `REACT_APP_BASE_URL_<X>` env vars; non-React consumers must provide their own resolver.
|
|
26
|
+
4. **The version header is `ns-site-version` for both request and response.** Use `NSHeader.req.VERSION()` / `NSHeader.res.VERSION()` instead of hard-coding the string. `NSBaseServer` already attaches it via `addOnBeforeRequest` / `addOnAfterRequest` in its constructor — don't re-register the same hooks in subclasses.
|
|
27
|
+
5. **Pass the product to the database constructor.** `NSBaseMetaDatabase` requires `{ id, name, headline, description, logo, link }`; `link` is the URL prefix that `NSBaseMetaTable_Frontend.getBaseLink()` joins against.
|
|
28
|
+
6. **Use `NamingConvention.lower_case_dash` for CFT lookups.** `isCFTTable()` / `hasFieldTables()` already do; if you call the static helpers (`getCFTTables`, `HasCFTTable`, `IsCFTTable`) directly, pass a `NamingConvention` from `namirasoft-core` — the helpers normalize on your behalf.
|
|
29
|
+
7. **Treat `NSBaseMetaTable_Backend<Row>` slots as optional.** Each verb has both an underscore-prefixed (raw) and bare (wrapped) slot: `_get`/`get`, `_list`/`list`, `_create`/`create`, `_update`/`update`, `_delete`/`delete`. Wire only the verbs the API actually supports; consumers must null-check before calling.
|
|
30
|
+
|
|
31
|
+
## API surface
|
|
32
|
+
|
|
33
|
+
All exports come from the package root.
|
|
34
|
+
|
|
35
|
+
### Servers
|
|
36
|
+
|
|
37
|
+
- **`NSBaseServer`** (abstract, extends `BaseServer` from `namirasoft-core`) — axios-based product client.
|
|
38
|
+
- `constructor(base_url: string, version: string)` — registers before/after-request hooks that set the request `ns-site-version` header to `version` and capture the response's version into `this.backend.version`.
|
|
39
|
+
- `backend: { version: string }` — last-seen backend version, populated after each response.
|
|
40
|
+
- Static helpers: `onBeforeRequest_SetVersion(version, config)`, `onAfterRequest_GetVersion(res)` — usable standalone if you need the same wiring outside an `NSBaseServer` subclass.
|
|
41
|
+
|
|
42
|
+
### Metadata
|
|
43
|
+
|
|
44
|
+
- **`NSBaseMetaDatabase<Server extends NSBaseServer>`** (abstract, extends `BaseMetaDatabase`) — container for a product's tables.
|
|
45
|
+
- `static getServerBaseURL(product_name: string): string` — override this once at module load to map a product name to its base URL. Default throws.
|
|
46
|
+
- `product: { id, name, headline, description, logo, link }` — set via constructor.
|
|
47
|
+
- `tables: { [name: string]: NSBaseMetaTable<Server, any> }` — populate in your subclass.
|
|
48
|
+
- `abstract getServer(): Server` — returns the singleton server for this database.
|
|
49
|
+
- `getByShortName(short)` / `getByShortNameOrNull(short)` — look up a table by `uuid.short`.
|
|
50
|
+
|
|
51
|
+
- **`NSBaseMetaTable<Server, Row>`** (abstract, extends `BaseMetaTable`) — one product table.
|
|
52
|
+
- `constructor(database, name, text, uuid: BaseUUID)` — auto-creates `front_end` and `back_end`.
|
|
53
|
+
- `front_end: NSBaseMetaTable_Frontend`, `back_end: NSBaseMetaTable_Backend<Row>`.
|
|
54
|
+
- `isCFTTable()` / `hasFieldTables()` — detect category/field/tag siblings (`<name>_category`, `<name>_field`, `<name>_tag`).
|
|
55
|
+
- Static helpers: `getTableAndCFTs`, `getTableAndCFTsIfExists`, `getCFTTables`, `getCFTTablesIfExists`, `HasCFTTable`, `IsCFTTable`.
|
|
56
|
+
|
|
57
|
+
- **`NSBaseMetaTable_Frontend`** — link builder bound to a table.
|
|
58
|
+
- `getBaseLink()` -> `<product.link>/<table-in-slash-case>`
|
|
59
|
+
- `getListLink()` -> `<base>/list`
|
|
60
|
+
- `getNewLink()` -> `<base>/new`
|
|
61
|
+
- `getViewLink(id)` -> `<base>/<id>/view`
|
|
62
|
+
- `getUpdateLink(id)` -> `<base>/<id>/edit`
|
|
63
|
+
|
|
64
|
+
- **`NSBaseMetaTable_Backend<Row>`** — optional CRUD adapter slots: `_get`/`get`, `_list`/`list`, `_create`/`create`, `_update`/`update`, `_delete`/`delete`. The `_*` variants are the raw API call; the bare ones are the wrapped/cached version. Both signatures match `namirasoft-core`'s `FilterItem` / `SortItem`.
|
|
65
|
+
|
|
66
|
+
### Headers
|
|
67
|
+
|
|
68
|
+
- **`NSHeader`** — namespace with three static fields:
|
|
69
|
+
- `NSHeader.req: NSReqHeader` — `req.VERSION()` returns `"ns-site-version"`.
|
|
70
|
+
- `NSHeader.res: NSResHeader` — `res.VERSION()` returns `"ns-site-version"`.
|
|
71
|
+
- `NSHeader.cookies: NSCookiesHeader` — currently empty, reserved.
|
|
72
|
+
- **`NSReqHeader`**, **`NSResHeader`**, **`NSCookiesHeader`** — exported individually if you need to extend.
|
|
73
|
+
|
|
74
|
+
### Name parsing
|
|
75
|
+
|
|
76
|
+
- **`NSNameParser(name_full, title_full)`** — classifies a Namirasoft repo/package name and extracts canonical short/long forms.
|
|
77
|
+
- Booleans: `isAPI`, `isConsole`, `isLibrary`, `isNPM`, `isPHP`, `isAccountAPI`.
|
|
78
|
+
- Per-kind structures (`api`, `console`, `library`) of type `NSNameParserStructure` with `name_namirasoft`, `name_short`, `title_namirasoft`, `title_short`, `class_namirasoft`, `class_short`.
|
|
79
|
+
- `command.name` — derived CLI command (`namirasoft-` -> `ns-`).
|
|
80
|
+
- Detection regexes: API matches `^namirasoft(-\w*)*-api(-\w*)*-v\d+$`, Console matches `^namirasoft-(\w+-)+console$`, Library is the residual `^namirasoft-\w+`. NPM/PHP are inferred from `title_full` ending in `NPM Package` / `PHP Package`.
|
|
81
|
+
|
|
82
|
+
## Canonical examples
|
|
83
|
+
|
|
84
|
+
### Subclassing `NSBaseServer`
|
|
85
|
+
|
|
86
|
+
```ts
|
|
87
|
+
import { NSBaseServer } from "namirasoft-site";
|
|
88
|
+
|
|
89
|
+
export class FooServer extends NSBaseServer {
|
|
90
|
+
constructor(base_url: string, version: string) {
|
|
91
|
+
super(base_url, version);
|
|
92
|
+
// version header + backend.version capture are wired by the parent
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
public listFoos = () => this.axios.get("/foo");
|
|
96
|
+
}
|
|
97
|
+
```
|
|
98
|
+
|
|
99
|
+
Don't re-register `addOnBeforeRequest` / `addOnAfterRequest` for versioning — `NSBaseServer`'s constructor already does it. Read the latest backend version from `this.backend.version` after any request.
|
|
100
|
+
|
|
101
|
+
### Defining a product database + table
|
|
102
|
+
|
|
103
|
+
```ts
|
|
104
|
+
import { NSBaseMetaDatabase, NSBaseMetaTable } from "namirasoft-site";
|
|
105
|
+
import { BaseUUID } from "namirasoft-core";
|
|
106
|
+
import { FooServer } from "./FooServer";
|
|
107
|
+
|
|
108
|
+
class FooTable extends NSBaseMetaTable<FooServer, { id: string; name: string }> {
|
|
109
|
+
constructor(db: FooDatabase) {
|
|
110
|
+
super(db, "foo", "Foo", new BaseUUID(/* ... */));
|
|
111
|
+
this.back_end._list = async (filters, page, size, sorts) => {
|
|
112
|
+
const res = await db.getServer().listFoos();
|
|
113
|
+
return { rows: res.data, count: res.data.length };
|
|
114
|
+
};
|
|
115
|
+
this.back_end.list = this.back_end._list;
|
|
116
|
+
}
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
export class FooDatabase extends NSBaseMetaDatabase<FooServer> {
|
|
120
|
+
private server: FooServer;
|
|
121
|
+
constructor() {
|
|
122
|
+
super({
|
|
123
|
+
id: "foo",
|
|
124
|
+
name: "foo",
|
|
125
|
+
headline: "Foo headline",
|
|
126
|
+
description: "Foo description",
|
|
127
|
+
logo: "/logo.png",
|
|
128
|
+
link: "/foo",
|
|
129
|
+
});
|
|
130
|
+
this.server = new FooServer(
|
|
131
|
+
NSBaseMetaDatabase.getServerBaseURL("namirasoft-foo"),
|
|
132
|
+
"1.0.0",
|
|
133
|
+
);
|
|
134
|
+
this.tables["foo"] = new FooTable(this);
|
|
135
|
+
}
|
|
136
|
+
getServer() { return this.server; }
|
|
137
|
+
}
|
|
138
|
+
```
|
|
139
|
+
|
|
140
|
+
Once instantiated, `database.tables["foo"].front_end.getViewLink("123")` yields `"/foo/foo/123/view"`.
|
|
141
|
+
|
|
142
|
+
### Registering the base-URL resolver
|
|
143
|
+
|
|
144
|
+
```ts
|
|
145
|
+
import { NSBaseMetaDatabase } from "namirasoft-site";
|
|
146
|
+
|
|
147
|
+
NSBaseMetaDatabase.getServerBaseURL = (product_name: string) => {
|
|
148
|
+
const key = product_name.replace(/^namirasoft-/, "").replace(/-/g, "_").toUpperCase();
|
|
149
|
+
const url = process.env[`BASE_URL_${key}`];
|
|
150
|
+
if (!url) throw new Error(`Missing BASE_URL_${key} for ${product_name}`);
|
|
151
|
+
return url;
|
|
152
|
+
};
|
|
153
|
+
```
|
|
154
|
+
|
|
155
|
+
Do this once at app bootstrap, before any `NSBaseMetaDatabase` subclass is constructed.
|
|
156
|
+
|
|
157
|
+
### Parsing a package name
|
|
158
|
+
|
|
159
|
+
```ts
|
|
160
|
+
import { NSNameParser } from "namirasoft-site";
|
|
161
|
+
|
|
162
|
+
const p = new NSNameParser("namirasoft-account-api-v3", "Namirasoft Account API V3");
|
|
163
|
+
p.isAPI; // true
|
|
164
|
+
p.isAccountAPI; // true
|
|
165
|
+
p.api.name_short; // "account"
|
|
166
|
+
p.api.class_namirasoft; // "NamirasoftAccount"
|
|
167
|
+
p.command.name; // "ns-account"
|
|
168
|
+
```
|
|
169
|
+
|
|
170
|
+
## Common mistakes to avoid
|
|
171
|
+
|
|
172
|
+
- Hand-rolling an axios client with a hard-coded `"ns-site-version"` string instead of subclassing `NSBaseServer` and using `NSHeader.req.VERSION()`.
|
|
173
|
+
- Leaving `NSBaseMetaDatabase.getServerBaseURL` at its default — instantiating any database will throw with `"NSBaseMetaDatabase.getServerBaseURL was not overriden"`.
|
|
174
|
+
- Calling `back_end.get?.(id)` without null-checking — every CRUD slot is optional.
|
|
175
|
+
- Using `className`-style slash-cased table names directly in URLs; `NSBaseMetaTable_Frontend` already converts `lower_case_underscore` -> `lower_case_slash` via `NamingConvention`.
|
|
176
|
+
- Re-adding `addOnBeforeRequest` / `addOnAfterRequest` for versioning in an `NSBaseServer` subclass — duplicates the header write.
|
|
177
|
+
- Importing `BaseServer`, `BaseMetaTable`, `BaseUUID`, `NamingConvention`, `FilterItem`, `SortItem` from `"namirasoft-site"` — they live in `namirasoft-core`. This package only re-exports its own `NS*` extensions.
|
|
178
|
+
- Treating `NSCookiesHeader` as having members — it is currently an empty placeholder.
|
|
179
|
+
|
|
180
|
+
## Peer expectations
|
|
181
|
+
|
|
182
|
+
- **Runtime deps**: `namirasoft-core` (^1.4.108), `axios` (^1.13.x). Both are required peers in practice — `BaseServer`, `BaseMetaTable`, `BaseUUID`, `NamingConvention`, `FilterItem`, `SortItem` all come from `namirasoft-core`.
|
|
183
|
+
- **No framework binding**: this package is framework-agnostic (Node or browser). Consumers needing React UI should pair it with `namirasoft-site-react`, which depends on this package.
|
|
184
|
+
- **No env vars are read directly** — `getServerBaseURL` is a static hook the host app must implement. The React companion wires it to `REACT_APP_BASE_URL_<X>`; backend hosts typically wire it to `process.env.BASE_URL_<X>`.
|
package/logo.png
CHANGED
|
Binary file
|
package/package.json
CHANGED
|
@@ -8,7 +8,7 @@
|
|
|
8
8
|
"framework": "npm",
|
|
9
9
|
"application": "package",
|
|
10
10
|
"private": false,
|
|
11
|
-
"version": "1.4.
|
|
11
|
+
"version": "1.4.46",
|
|
12
12
|
"author": "Amir Abolhasani",
|
|
13
13
|
"license": "MIT",
|
|
14
14
|
"main": "./dist/index.js",
|
|
@@ -17,7 +17,7 @@
|
|
|
17
17
|
"build": ""
|
|
18
18
|
},
|
|
19
19
|
"dependencies": {
|
|
20
|
-
"axios": "^1.
|
|
21
|
-
"namirasoft-core": "^1.4.
|
|
20
|
+
"axios": "^1.18.1",
|
|
21
|
+
"namirasoft-core": "^1.4.120"
|
|
22
22
|
}
|
|
23
23
|
}
|