namirasoft-site 1.4.44 → 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 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.44",
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.13.2",
21
- "namirasoft-core": "^1.4.108"
20
+ "axios": "^1.18.1",
21
+ "namirasoft-core": "^1.4.120"
22
22
  }
23
23
  }
@@ -1,69 +1,69 @@
1
- import { BaseMetaDatabase } from "namirasoft-core";
2
- import { NSBaseMetaTable } from "./NSBaseMetaTable";
3
- import { NSBaseServer } from "./NSBaseServer";
4
-
5
- export abstract class NSBaseMetaDatabase<Server extends NSBaseServer> extends BaseMetaDatabase
6
- {
7
- public static getServerBaseURL(product_name: string): string
8
- {
9
- throw new Error(`NSBaseMetaDatabase.getServerBaseURL was not overriden. Requested: ${product_name}`);
10
- }
11
- override tables: { [name: string]: NSBaseMetaTable<Server, any>; } = {};
12
- public product: {
13
- id: string;
14
- name: string;
15
- headline: string;
16
- description: string;
17
- logo: string;
18
- link: string;
19
- };
20
- public abstract getServer(): Server;
21
- constructor(product: {
22
- id: string;
23
- name: string;
24
- headline: string;
25
- description: string;
26
- logo: string;
27
- link: string;
28
- })
29
- {
30
- super();
31
- this.product = product;
32
- }
33
- getByShortNameOrNull(short_name: string):
34
- {
35
- product: {
36
- id: string;
37
- name: string;
38
- headline: string;
39
- description: string;
40
- logo: string;
41
- link: string;
42
- };
43
- table: NSBaseMetaTable<NSBaseServer, any>;
44
- } | null
45
- {
46
- for (let table in this.tables)
47
- if (this.tables[table].uuid.short === short_name)
48
- return { product: this.product, table: this.tables[table] };
49
- return null;
50
- }
51
- getByShortName(short_name: string):
52
- {
53
- product: {
54
- id: string;
55
- name: string;
56
- headline: string;
57
- description: string;
58
- logo: string;
59
- link: string;
60
- };
61
- table: NSBaseMetaTable<NSBaseServer, any>;
62
- }
63
- {
64
- let ans = this.getByShortNameOrNull(short_name);
65
- if (ans)
66
- return ans;
67
- throw new Error(`Result could not be found for short name: ${short_name}`);
68
- }
1
+ import { BaseMetaDatabase } from "namirasoft-core";
2
+ import { NSBaseMetaTable } from "./NSBaseMetaTable";
3
+ import { NSBaseServer } from "./NSBaseServer";
4
+
5
+ export abstract class NSBaseMetaDatabase<Server extends NSBaseServer> extends BaseMetaDatabase
6
+ {
7
+ public static getServerBaseURL(product_name: string): string
8
+ {
9
+ throw new Error(`NSBaseMetaDatabase.getServerBaseURL was not overriden. Requested: ${product_name}`);
10
+ }
11
+ override tables: { [name: string]: NSBaseMetaTable<Server, any>; } = {};
12
+ public product: {
13
+ id: string;
14
+ name: string;
15
+ headline: string;
16
+ description: string;
17
+ logo: string;
18
+ link: string;
19
+ };
20
+ public abstract getServer(): Server;
21
+ constructor(product: {
22
+ id: string;
23
+ name: string;
24
+ headline: string;
25
+ description: string;
26
+ logo: string;
27
+ link: string;
28
+ })
29
+ {
30
+ super();
31
+ this.product = product;
32
+ }
33
+ getByShortNameOrNull(short_name: string):
34
+ {
35
+ product: {
36
+ id: string;
37
+ name: string;
38
+ headline: string;
39
+ description: string;
40
+ logo: string;
41
+ link: string;
42
+ };
43
+ table: NSBaseMetaTable<NSBaseServer, any>;
44
+ } | null
45
+ {
46
+ for (let table in this.tables)
47
+ if (this.tables[table].uuid.short === short_name)
48
+ return { product: this.product, table: this.tables[table] };
49
+ return null;
50
+ }
51
+ getByShortName(short_name: string):
52
+ {
53
+ product: {
54
+ id: string;
55
+ name: string;
56
+ headline: string;
57
+ description: string;
58
+ logo: string;
59
+ link: string;
60
+ };
61
+ table: NSBaseMetaTable<NSBaseServer, any>;
62
+ }
63
+ {
64
+ let ans = this.getByShortNameOrNull(short_name);
65
+ if (ans)
66
+ return ans;
67
+ throw new Error(`Result could not be found for short name: ${short_name}`);
68
+ }
69
69
  };
@@ -1,75 +1,75 @@
1
- import { BaseMetaTable, BaseUUID, NamingConvention } from "namirasoft-core";
2
- import { NSBaseMetaTable_Frontend } from "./NSBaseMetaTable_Frontend";
3
- import { NSBaseMetaDatabase } from "./NSBaseMetaDatabase";
4
- import { NSBaseMetaTable_Backend } from "./NSBaseMetaTable_Backend";
5
- import { NSBaseServer } from "./NSBaseServer";
6
-
7
- export abstract class NSBaseMetaTable<Server extends NSBaseServer, Row> extends BaseMetaTable
8
- {
9
- private static cft_tables = ["category", "field", "tag"];
10
- static getTableAndCFTsIfExists(naming: NamingConvention, tables: string[], name: string): string[]
11
- {
12
- name = NamingConvention.auto.convert(name, naming);
13
- tables = tables.map(t => NamingConvention.auto.convert(t, naming));
14
- return NSBaseMetaTable.getTableAndCFTs(naming, name).filter(t => tables.includes(t));
15
- }
16
- static getTableAndCFTs(naming: NamingConvention, name: string): string[]
17
- {
18
- name = NamingConvention.auto.convert(name, naming);
19
- return [name, ...NSBaseMetaTable.getCFTTables(naming, name)];
20
- }
21
- static getCFTTablesIfExists(naming: NamingConvention, tables: string[], name: string): string[]
22
- {
23
- name = NamingConvention.auto.convert(name, naming);
24
- tables = tables.map(t => NamingConvention.auto.convert(t, naming));
25
- return NSBaseMetaTable.getCFTTables(naming, name).filter(t => tables.includes(t));
26
- }
27
- static getCFTTables(naming: NamingConvention, name: string): string[]
28
- {
29
- name = NamingConvention.auto.convert(name, naming);
30
- let tables = NSBaseMetaTable.cft_tables.map(cft => name + "_" + cft);
31
- return tables.map(t => NamingConvention.auto.convert(t, naming));
32
- }
33
- static HasCFTTable(naming: NamingConvention, tables: string[], name: string): boolean
34
- {
35
- name = NamingConvention.auto.convert(name, naming);
36
- tables = tables.map(t => NamingConvention.auto.convert(t, naming))
37
- return NSBaseMetaTable.getCFTTables(naming, name).some(t => tables.includes(t));
38
- }
39
- static IsCFTTable(naming: NamingConvention, name: string): boolean
40
- {
41
- name = NamingConvention.auto.convert(name, naming);
42
- for (let i = 0; i < NSBaseMetaTable.cft_tables.length; i++)
43
- {
44
- let table = NSBaseMetaTable.cft_tables[i];
45
- table = NamingConvention.auto.convert(table, naming);
46
- if (name !== table)
47
- if (name.endsWith("_" + table))
48
- return true;
49
- }
50
- return false;
51
- }
52
-
53
- override database: NSBaseMetaDatabase<Server>;
54
- public uuid: BaseUUID;
55
- public front_end: NSBaseMetaTable_Frontend;
56
- public back_end: NSBaseMetaTable_Backend<Row>;
57
- constructor(database: NSBaseMetaDatabase<Server>, name: string, text: string, uuid: BaseUUID)
58
- {
59
- super(database, name, text);
60
- this.database = database;
61
- this.uuid = uuid;
62
- this.front_end = new NSBaseMetaTable_Frontend(this, name);
63
- this.back_end = new NSBaseMetaTable_Backend<Row>();
64
- }
65
- isCFTTable(): boolean
66
- {
67
- return NSBaseMetaTable.IsCFTTable(NamingConvention.lower_case_dash, this.name);
68
- }
69
- hasFieldTables(): boolean
70
- {
71
- if (this.database)
72
- return NSBaseMetaTable.HasCFTTable(NamingConvention.lower_case_dash, Object.keys(this.database.tables), this.name);
73
- return false;
74
- }
1
+ import { BaseMetaTable, BaseUUID, NamingConvention } from "namirasoft-core";
2
+ import { NSBaseMetaTable_Frontend } from "./NSBaseMetaTable_Frontend";
3
+ import { NSBaseMetaDatabase } from "./NSBaseMetaDatabase";
4
+ import { NSBaseMetaTable_Backend } from "./NSBaseMetaTable_Backend";
5
+ import { NSBaseServer } from "./NSBaseServer";
6
+
7
+ export abstract class NSBaseMetaTable<Server extends NSBaseServer, Row> extends BaseMetaTable
8
+ {
9
+ private static cft_tables = ["category", "field", "tag"];
10
+ static getTableAndCFTsIfExists(naming: NamingConvention, tables: string[], name: string): string[]
11
+ {
12
+ name = NamingConvention.auto.convert(name, naming);
13
+ tables = tables.map(t => NamingConvention.auto.convert(t, naming));
14
+ return NSBaseMetaTable.getTableAndCFTs(naming, name).filter(t => tables.includes(t));
15
+ }
16
+ static getTableAndCFTs(naming: NamingConvention, name: string): string[]
17
+ {
18
+ name = NamingConvention.auto.convert(name, naming);
19
+ return [name, ...NSBaseMetaTable.getCFTTables(naming, name)];
20
+ }
21
+ static getCFTTablesIfExists(naming: NamingConvention, tables: string[], name: string): string[]
22
+ {
23
+ name = NamingConvention.auto.convert(name, naming);
24
+ tables = tables.map(t => NamingConvention.auto.convert(t, naming));
25
+ return NSBaseMetaTable.getCFTTables(naming, name).filter(t => tables.includes(t));
26
+ }
27
+ static getCFTTables(naming: NamingConvention, name: string): string[]
28
+ {
29
+ name = NamingConvention.auto.convert(name, naming);
30
+ let tables = NSBaseMetaTable.cft_tables.map(cft => name + "_" + cft);
31
+ return tables.map(t => NamingConvention.auto.convert(t, naming));
32
+ }
33
+ static HasCFTTable(naming: NamingConvention, tables: string[], name: string): boolean
34
+ {
35
+ name = NamingConvention.auto.convert(name, naming);
36
+ tables = tables.map(t => NamingConvention.auto.convert(t, naming))
37
+ return NSBaseMetaTable.getCFTTables(naming, name).some(t => tables.includes(t));
38
+ }
39
+ static IsCFTTable(naming: NamingConvention, name: string): boolean
40
+ {
41
+ name = NamingConvention.auto.convert(name, naming);
42
+ for (let i = 0; i < NSBaseMetaTable.cft_tables.length; i++)
43
+ {
44
+ let table = NSBaseMetaTable.cft_tables[i];
45
+ table = NamingConvention.auto.convert(table, naming);
46
+ if (name !== table)
47
+ if (name.endsWith("_" + table))
48
+ return true;
49
+ }
50
+ return false;
51
+ }
52
+
53
+ override database: NSBaseMetaDatabase<Server>;
54
+ public uuid: BaseUUID;
55
+ public front_end: NSBaseMetaTable_Frontend;
56
+ public back_end: NSBaseMetaTable_Backend<Row>;
57
+ constructor(database: NSBaseMetaDatabase<Server>, name: string, text: string, uuid: BaseUUID)
58
+ {
59
+ super(database, name, text);
60
+ this.database = database;
61
+ this.uuid = uuid;
62
+ this.front_end = new NSBaseMetaTable_Frontend(this, name);
63
+ this.back_end = new NSBaseMetaTable_Backend<Row>();
64
+ }
65
+ isCFTTable(): boolean
66
+ {
67
+ return NSBaseMetaTable.IsCFTTable(NamingConvention.lower_case_dash, this.name);
68
+ }
69
+ hasFieldTables(): boolean
70
+ {
71
+ if (this.database)
72
+ return NSBaseMetaTable.HasCFTTable(NamingConvention.lower_case_dash, Object.keys(this.database.tables), this.name);
73
+ return false;
74
+ }
75
75
  };
@@ -1,15 +1,15 @@
1
- import { FilterItem, SortItem } from "namirasoft-core";
2
-
3
- export class NSBaseMetaTable_Backend<Row>
4
- {
5
- _get?: (id: string) => Promise<Row>;
6
- get?: (id: string) => Promise<Row>;
7
- _list?: (filters: FilterItem[] | null, page: (number | null), size: (number | null), sorts: SortItem[]) => Promise<{ rows: Row[], count: number }>;
8
- list?: (filters: FilterItem[] | null, page: (number | null), size: (number | null), sorts: SortItem[]) => Promise<{ rows: Row[], count: number }>;
9
- _create?: (body: any) => Promise<any>;
10
- create?: (body: any) => Promise<any>;
11
- _update?: (id: string, body: any) => Promise<Row>;
12
- update?: (id: string, body: any) => Promise<Row>;
13
- _delete?: (id: string) => Promise<void>;
14
- delete?: (id: string) => Promise<void>;
1
+ import { FilterItem, SortItem } from "namirasoft-core";
2
+
3
+ export class NSBaseMetaTable_Backend<Row>
4
+ {
5
+ _get?: (id: string) => Promise<Row>;
6
+ get?: (id: string) => Promise<Row>;
7
+ _list?: (filters: FilterItem[] | null, page: (number | null), size: (number | null), sorts: SortItem[]) => Promise<{ rows: Row[], count: number }>;
8
+ list?: (filters: FilterItem[] | null, page: (number | null), size: (number | null), sorts: SortItem[]) => Promise<{ rows: Row[], count: number }>;
9
+ _create?: (body: any) => Promise<any>;
10
+ create?: (body: any) => Promise<any>;
11
+ _update?: (id: string, body: any) => Promise<Row>;
12
+ update?: (id: string, body: any) => Promise<Row>;
13
+ _delete?: (id: string) => Promise<void>;
14
+ delete?: (id: string) => Promise<void>;
15
15
  };
@@ -1,38 +1,38 @@
1
- import { NamingConvention } from "namirasoft-core";
2
- import { NSBaseMetaTable } from "./NSBaseMetaTable";
3
-
4
- export class NSBaseMetaTable_Frontend
5
- {
6
- private table: NSBaseMetaTable<any, any>;
7
- private base: string;
8
- constructor(table: NSBaseMetaTable<any, any>, name: string)
9
- {
10
- this.table = table;
11
- this.base = NamingConvention.lower_case_underscore.convert(name, NamingConvention.lower_case_slash)
12
- this.getBaseLink = this.getBaseLink.bind(this);
13
- this.getListLink = this.getListLink.bind(this);
14
- this.getNewLink = this.getNewLink.bind(this);
15
- this.getViewLink = this.getViewLink.bind(this);
16
- this.getUpdateLink = this.getUpdateLink.bind(this);
17
- }
18
- public getBaseLink(): string
19
- {
20
- return this.table.database.product.link + "/" + this.base;
21
- }
22
- public getListLink(): string
23
- {
24
- return this.getBaseLink() + "/list";
25
- }
26
- public getNewLink(): string
27
- {
28
- return this.getBaseLink() + "/new";
29
- }
30
- public getViewLink(id: string): string
31
- {
32
- return this.getBaseLink() + "/" + id + "/view";
33
- }
34
- public getUpdateLink(id: string): string
35
- {
36
- return this.getBaseLink() + "/" + id + "/edit";
37
- }
1
+ import { NamingConvention } from "namirasoft-core";
2
+ import { NSBaseMetaTable } from "./NSBaseMetaTable";
3
+
4
+ export class NSBaseMetaTable_Frontend
5
+ {
6
+ private table: NSBaseMetaTable<any, any>;
7
+ private base: string;
8
+ constructor(table: NSBaseMetaTable<any, any>, name: string)
9
+ {
10
+ this.table = table;
11
+ this.base = NamingConvention.lower_case_underscore.convert(name, NamingConvention.lower_case_slash)
12
+ this.getBaseLink = this.getBaseLink.bind(this);
13
+ this.getListLink = this.getListLink.bind(this);
14
+ this.getNewLink = this.getNewLink.bind(this);
15
+ this.getViewLink = this.getViewLink.bind(this);
16
+ this.getUpdateLink = this.getUpdateLink.bind(this);
17
+ }
18
+ public getBaseLink(): string
19
+ {
20
+ return this.table.database.product.link + "/" + this.base;
21
+ }
22
+ public getListLink(): string
23
+ {
24
+ return this.getBaseLink() + "/list";
25
+ }
26
+ public getNewLink(): string
27
+ {
28
+ return this.getBaseLink() + "/new";
29
+ }
30
+ public getViewLink(id: string): string
31
+ {
32
+ return this.getBaseLink() + "/" + id + "/view";
33
+ }
34
+ public getUpdateLink(id: string): string
35
+ {
36
+ return this.getBaseLink() + "/" + id + "/edit";
37
+ }
38
38
  };
@@ -1,47 +1,47 @@
1
- import { BaseServer } from "namirasoft-core";
2
- import { AxiosRequestConfig, AxiosResponse } from "axios";
3
- import { NSHeader } from "./NSHeader";
4
-
5
- export abstract class NSBaseServer extends BaseServer
6
- {
7
- static onBeforeRequest_SetVersion<ReqData>(version: string, config?: AxiosRequestConfig<ReqData>): void
8
- {
9
- let header = NSHeader.req.VERSION();
10
- if (config?.headers)
11
- config.headers[header] = version;
12
- }
13
-
14
- static onAfterRequest_GetVersion<ReqData>(res?: AxiosResponse<ReqData>): string
15
- {
16
- let header = NSHeader.req.VERSION();
17
- if (res?.headers)
18
- return res.headers[header];
19
- return "";
20
- }
21
-
22
- private version: string;
23
-
24
- public backend: {
25
- version: string
26
- } = { version: "" };
27
-
28
- constructor(base_url: string, version: string)
29
- {
30
- super(base_url);
31
- this.version = version;
32
-
33
- this.NSOnBeforeRequest = this.NSOnBeforeRequest.bind(this);
34
- this.NSOnAfterRequest = this.NSOnAfterRequest.bind(this);
35
-
36
- this.addOnBeforeRequest(this.NSOnBeforeRequest);
37
- this.addOnAfterRequest(this.NSOnAfterRequest);
38
- }
39
- private NSOnBeforeRequest<ReqData = any>(_: string, config?: AxiosRequestConfig<ReqData> | undefined): void
40
- {
41
- NSBaseServer.onBeforeRequest_SetVersion(this.version, config);
42
- }
43
- private NSOnAfterRequest<ResData = any>(_: string, res: AxiosResponse<ResData, any>): void
44
- {
45
- this.backend.version = NSBaseServer.onAfterRequest_GetVersion(res);
46
- }
1
+ import { BaseServer } from "namirasoft-core";
2
+ import { AxiosRequestConfig, AxiosResponse } from "axios";
3
+ import { NSHeader } from "./NSHeader";
4
+
5
+ export abstract class NSBaseServer extends BaseServer
6
+ {
7
+ static onBeforeRequest_SetVersion<ReqData>(version: string, config?: AxiosRequestConfig<ReqData>): void
8
+ {
9
+ let header = NSHeader.req.VERSION();
10
+ if (config?.headers)
11
+ config.headers[header] = version;
12
+ }
13
+
14
+ static onAfterRequest_GetVersion<ReqData>(res?: AxiosResponse<ReqData>): string
15
+ {
16
+ let header = NSHeader.req.VERSION();
17
+ if (res?.headers)
18
+ return res.headers[header];
19
+ return "";
20
+ }
21
+
22
+ private version: string;
23
+
24
+ public backend: {
25
+ version: string
26
+ } = { version: "" };
27
+
28
+ constructor(base_url: string, version: string)
29
+ {
30
+ super(base_url);
31
+ this.version = version;
32
+
33
+ this.NSOnBeforeRequest = this.NSOnBeforeRequest.bind(this);
34
+ this.NSOnAfterRequest = this.NSOnAfterRequest.bind(this);
35
+
36
+ this.addOnBeforeRequest(this.NSOnBeforeRequest);
37
+ this.addOnAfterRequest(this.NSOnAfterRequest);
38
+ }
39
+ private NSOnBeforeRequest<ReqData = any>(_: string, config?: AxiosRequestConfig<ReqData> | undefined): void
40
+ {
41
+ NSBaseServer.onBeforeRequest_SetVersion(this.version, config);
42
+ }
43
+ private NSOnAfterRequest<ResData = any>(_: string, res: AxiosResponse<ResData, any>): void
44
+ {
45
+ this.backend.version = NSBaseServer.onAfterRequest_GetVersion(res);
46
+ }
47
47
  };
@@ -1,3 +1,3 @@
1
- export class NSCookiesHeader
2
- {
1
+ export class NSCookiesHeader
2
+ {
3
3
  }
package/src/NSHeader.ts CHANGED
@@ -1,10 +1,10 @@
1
- import { NSCookiesHeader } from "./NSCookiesHeader";
2
- import { NSReqHeader } from "./NSReqHeader";
3
- import { NSResHeader } from "./NSResHeader";
4
-
5
- export class NSHeader
6
- {
7
- static cookies: NSCookiesHeader = new NSCookiesHeader();
8
- static req: NSReqHeader = new NSReqHeader();
9
- static res: NSResHeader = new NSResHeader();
1
+ import { NSCookiesHeader } from "./NSCookiesHeader";
2
+ import { NSReqHeader } from "./NSReqHeader";
3
+ import { NSResHeader } from "./NSResHeader";
4
+
5
+ export class NSHeader
6
+ {
7
+ static cookies: NSCookiesHeader = new NSCookiesHeader();
8
+ static req: NSReqHeader = new NSReqHeader();
9
+ static res: NSResHeader = new NSResHeader();
10
10
  }
@@ -1,144 +1,144 @@
1
- import { NamingConvention } from "namirasoft-core";
2
-
3
- export type NSNameParserStructure =
4
- {
5
- // Name
6
- name_namirasoft: string;
7
- name_short: string;
8
-
9
- // Title
10
- title_namirasoft: string;
11
- title_short: string;
12
-
13
- // Class
14
- class_namirasoft: string;
15
- class_short: string;
16
- };
17
-
18
- export class NSNameParser
19
- {
20
- // Input
21
- public name_full: string;
22
- public title_full: string;
23
-
24
- // Is
25
- public isAPI: boolean;
26
- public isConsole: boolean;
27
- public isLibrary: boolean;
28
- public isNPM: boolean;
29
- public isPHP: boolean;
30
- public isAccountAPI: boolean;
31
-
32
- public api: NSNameParserStructure = {
33
- // Name
34
- name_namirasoft: "",
35
- name_short: "",
36
-
37
- // Title
38
- title_namirasoft: "",
39
- title_short: "",
40
-
41
- // Class
42
- class_namirasoft: "",
43
- class_short: "",
44
- };
45
-
46
- public console: NSNameParserStructure = {
47
- // Name
48
- name_namirasoft: "",
49
- name_short: "",
50
-
51
- // Title
52
- title_namirasoft: "",
53
- title_short: "",
54
-
55
- // Class
56
- class_namirasoft: "",
57
- class_short: "",
58
- };
59
-
60
- public library: NSNameParserStructure = {
61
- // Name
62
- name_namirasoft: "",
63
- name_short: "",
64
-
65
- // Title
66
- title_namirasoft: "",
67
- title_short: "",
68
-
69
- // Class
70
- class_namirasoft: "",
71
- class_short: "",
72
- };
73
- public command: {
74
- name: string
75
- } = { name: "" };
76
-
77
- constructor(name_full: string, title_full: string)
78
- {
79
- // Input
80
- this.name_full = name_full;
81
- this.title_full = title_full;
82
-
83
- // Is
84
- this.isAPI = /^namirasoft(-\w*)*-api(-\w*)*-v\d+$/gm.test(name_full);
85
- this.isConsole = /^namirasoft-(\w+-)+console$/gm.test(name_full);
86
- this.isLibrary = !this.isAPI && !this.isConsole && /^namirasoft-\w+/gm.test(name_full);
87
- this.isNPM = this.isLibrary && /NPM Package$/gm.test(title_full);
88
- this.isPHP = this.isLibrary && /PHP Package$/gm.test(title_full);
89
- this.isAccountAPI = /^namirasoft-account-api-v\d+$/gm.test(name_full);
90
-
91
- if (this.isAPI)
92
- {
93
- // Name
94
- this.api.name_namirasoft = this.name_full.replace(/(-api)?-v\d+$/gm, "");
95
- this.api.name_short = this.api.name_namirasoft.replace(/^namirasoft-/gm, "");
96
-
97
- // Title
98
- this.api.title_namirasoft = this.title_full.replace(/(\sAPI)?\sV\d+$/gm, "");
99
- this.api.title_short = this.api.title_namirasoft.replace(/^Namirasoft\s/gm, "");
100
-
101
- // Class
102
- this.api.class_namirasoft = NamingConvention.auto.convert(this.api.title_namirasoft, NamingConvention.Pascal_Case);
103
- this.api.class_short = NamingConvention.auto.convert(this.api.title_short, NamingConvention.Pascal_Case);
104
-
105
- // Command
106
- this.command.name = this.api.name_namirasoft;
107
- }
108
-
109
- if (this.isConsole)
110
- {
111
- // Name
112
- this.console.name_namirasoft = this.name_full.replace(/-console$/gm, "");
113
- this.console.name_short = this.console.name_namirasoft.replace(/^namirasoft-/gm, "");
114
-
115
- // Title
116
- this.console.title_namirasoft = this.title_full.replace(/\sConsole$/gm, "");
117
- this.console.title_short = this.console.title_namirasoft.replace(/^Namirasoft\s/gm, "");
118
-
119
- // Class
120
- this.console.class_namirasoft = NamingConvention.auto.convert(this.console.title_namirasoft, NamingConvention.Pascal_Case);
121
- this.console.class_short = NamingConvention.auto.convert(this.console.title_short, NamingConvention.Pascal_Case);
122
- }
123
-
124
- if (this.isLibrary)
125
- {
126
- // Name
127
- this.library.name_namirasoft = this.name_full;
128
- this.library.name_short = this.library.name_namirasoft.replace(/^namirasoft-/gm, "");
129
-
130
- // Title
131
- this.library.title_namirasoft = this.title_full.replace(/\s(NPM|PHP)\sPackage$/gm, "");
132
- this.library.title_short = this.library.title_namirasoft.replace(/^Namirasoft\s/gm, "");
133
-
134
- // Class
135
- this.library.class_namirasoft = NamingConvention.auto.convert(this.library.title_namirasoft, NamingConvention.Pascal_Case);
136
- this.library.class_short = NamingConvention.auto.convert(this.library.title_short, NamingConvention.Pascal_Case);
137
-
138
- // Command
139
- this.command.name = this.library.name_namirasoft;
140
- }
141
-
142
- this.command.name = this.command.name.replace("namirasoft-", "ns-");
143
- }
1
+ import { NamingConvention } from "namirasoft-core";
2
+
3
+ export type NSNameParserStructure =
4
+ {
5
+ // Name
6
+ name_namirasoft: string;
7
+ name_short: string;
8
+
9
+ // Title
10
+ title_namirasoft: string;
11
+ title_short: string;
12
+
13
+ // Class
14
+ class_namirasoft: string;
15
+ class_short: string;
16
+ };
17
+
18
+ export class NSNameParser
19
+ {
20
+ // Input
21
+ public name_full: string;
22
+ public title_full: string;
23
+
24
+ // Is
25
+ public isAPI: boolean;
26
+ public isConsole: boolean;
27
+ public isLibrary: boolean;
28
+ public isNPM: boolean;
29
+ public isPHP: boolean;
30
+ public isAccountAPI: boolean;
31
+
32
+ public api: NSNameParserStructure = {
33
+ // Name
34
+ name_namirasoft: "",
35
+ name_short: "",
36
+
37
+ // Title
38
+ title_namirasoft: "",
39
+ title_short: "",
40
+
41
+ // Class
42
+ class_namirasoft: "",
43
+ class_short: "",
44
+ };
45
+
46
+ public console: NSNameParserStructure = {
47
+ // Name
48
+ name_namirasoft: "",
49
+ name_short: "",
50
+
51
+ // Title
52
+ title_namirasoft: "",
53
+ title_short: "",
54
+
55
+ // Class
56
+ class_namirasoft: "",
57
+ class_short: "",
58
+ };
59
+
60
+ public library: NSNameParserStructure = {
61
+ // Name
62
+ name_namirasoft: "",
63
+ name_short: "",
64
+
65
+ // Title
66
+ title_namirasoft: "",
67
+ title_short: "",
68
+
69
+ // Class
70
+ class_namirasoft: "",
71
+ class_short: "",
72
+ };
73
+ public command: {
74
+ name: string
75
+ } = { name: "" };
76
+
77
+ constructor(name_full: string, title_full: string)
78
+ {
79
+ // Input
80
+ this.name_full = name_full;
81
+ this.title_full = title_full;
82
+
83
+ // Is
84
+ this.isAPI = /^namirasoft(-\w*)*-api(-\w*)*-v\d+$/gm.test(name_full);
85
+ this.isConsole = /^namirasoft-(\w+-)+console$/gm.test(name_full);
86
+ this.isLibrary = !this.isAPI && !this.isConsole && /^namirasoft-\w+/gm.test(name_full);
87
+ this.isNPM = this.isLibrary && /NPM Package$/gm.test(title_full);
88
+ this.isPHP = this.isLibrary && /PHP Package$/gm.test(title_full);
89
+ this.isAccountAPI = /^namirasoft-account-api-v\d+$/gm.test(name_full);
90
+
91
+ if (this.isAPI)
92
+ {
93
+ // Name
94
+ this.api.name_namirasoft = this.name_full.replace(/(-api)?-v\d+$/gm, "");
95
+ this.api.name_short = this.api.name_namirasoft.replace(/^namirasoft-/gm, "");
96
+
97
+ // Title
98
+ this.api.title_namirasoft = this.title_full.replace(/(\sAPI)?\sV\d+$/gm, "");
99
+ this.api.title_short = this.api.title_namirasoft.replace(/^Namirasoft\s/gm, "");
100
+
101
+ // Class
102
+ this.api.class_namirasoft = NamingConvention.auto.convert(this.api.title_namirasoft, NamingConvention.Pascal_Case);
103
+ this.api.class_short = NamingConvention.auto.convert(this.api.title_short, NamingConvention.Pascal_Case);
104
+
105
+ // Command
106
+ this.command.name = this.api.name_namirasoft;
107
+ }
108
+
109
+ if (this.isConsole)
110
+ {
111
+ // Name
112
+ this.console.name_namirasoft = this.name_full.replace(/-console$/gm, "");
113
+ this.console.name_short = this.console.name_namirasoft.replace(/^namirasoft-/gm, "");
114
+
115
+ // Title
116
+ this.console.title_namirasoft = this.title_full.replace(/\sConsole$/gm, "");
117
+ this.console.title_short = this.console.title_namirasoft.replace(/^Namirasoft\s/gm, "");
118
+
119
+ // Class
120
+ this.console.class_namirasoft = NamingConvention.auto.convert(this.console.title_namirasoft, NamingConvention.Pascal_Case);
121
+ this.console.class_short = NamingConvention.auto.convert(this.console.title_short, NamingConvention.Pascal_Case);
122
+ }
123
+
124
+ if (this.isLibrary)
125
+ {
126
+ // Name
127
+ this.library.name_namirasoft = this.name_full;
128
+ this.library.name_short = this.library.name_namirasoft.replace(/^namirasoft-/gm, "");
129
+
130
+ // Title
131
+ this.library.title_namirasoft = this.title_full.replace(/\s(NPM|PHP)\sPackage$/gm, "");
132
+ this.library.title_short = this.library.title_namirasoft.replace(/^Namirasoft\s/gm, "");
133
+
134
+ // Class
135
+ this.library.class_namirasoft = NamingConvention.auto.convert(this.library.title_namirasoft, NamingConvention.Pascal_Case);
136
+ this.library.class_short = NamingConvention.auto.convert(this.library.title_short, NamingConvention.Pascal_Case);
137
+
138
+ // Command
139
+ this.command.name = this.library.name_namirasoft;
140
+ }
141
+
142
+ this.command.name = this.command.name.replace("namirasoft-", "ns-");
143
+ }
144
144
  };
@@ -1,7 +1,7 @@
1
- export class NSReqHeader
2
- {
3
- VERSION()
4
- {
5
- return `ns-site-version`;
6
- }
1
+ export class NSReqHeader
2
+ {
3
+ VERSION()
4
+ {
5
+ return `ns-site-version`;
6
+ }
7
7
  }
@@ -1,7 +1,7 @@
1
- export class NSResHeader
2
- {
3
- VERSION()
4
- {
5
- return `ns-site-version`;
6
- }
1
+ export class NSResHeader
2
+ {
3
+ VERSION()
4
+ {
5
+ return `ns-site-version`;
6
+ }
7
7
  }
package/src/index.ts CHANGED
@@ -1,8 +1,8 @@
1
- export * from "./NSBaseServer";
2
- export * from "./NSBaseMetaDatabase";
3
- export * from "./NSBaseMetaTable";
4
- export * from "./NSCookiesHeader";
5
- export * from "./NSHeader";
6
- export * from "./NSNameParser";
7
- export * from "./NSReqHeader";
1
+ export * from "./NSBaseServer";
2
+ export * from "./NSBaseMetaDatabase";
3
+ export * from "./NSBaseMetaTable";
4
+ export * from "./NSCookiesHeader";
5
+ export * from "./NSHeader";
6
+ export * from "./NSNameParser";
7
+ export * from "./NSReqHeader";
8
8
  export * from "./NSResHeader";
package/tsconfig.json CHANGED
@@ -8,6 +8,9 @@
8
8
  "es6",
9
9
  "dom"
10
10
  ],
11
+ "types": [
12
+ "node"
13
+ ],
11
14
  "allowJs": false,
12
15
  "checkJs": false,
13
16
  "strict": true,